mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-04-28 06:16:24 +02:00
weaved some slow functions in the stationary class. We now fall back (and latch) to numpy if weave fails
This commit is contained in:
parent
5962035b54
commit
f9a16059e4
1 changed files with 73 additions and 1 deletions
|
|
@ -10,6 +10,7 @@ from ... import util
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy import integrate
|
from scipy import integrate
|
||||||
from ...util.caching import Cache_this
|
from ...util.caching import Cache_this
|
||||||
|
from ...util.config import config # for assesing whether to use weave
|
||||||
|
|
||||||
class Stationary(Kern):
|
class Stationary(Kern):
|
||||||
"""
|
"""
|
||||||
|
|
@ -139,6 +140,16 @@ class Stationary(Kern):
|
||||||
#self.lengthscale.gradient = -((dL_dr*rinv)[:,:,None]*x_xl3).sum(0).sum(0)/self.lengthscale**3
|
#self.lengthscale.gradient = -((dL_dr*rinv)[:,:,None]*x_xl3).sum(0).sum(0)/self.lengthscale**3
|
||||||
tmp = dL_dr*self._inv_dist(X, X2)
|
tmp = dL_dr*self._inv_dist(X, X2)
|
||||||
if X2 is None: X2 = X
|
if X2 is None: X2 = X
|
||||||
|
|
||||||
|
|
||||||
|
if config.getboolean('weave', 'working'):
|
||||||
|
try:
|
||||||
|
self.lengthscale.gradient = self.weave_lengthscale_grads(tmp, X, X2)
|
||||||
|
except:
|
||||||
|
print "\n Weave compilation failed. Falling back to (slower) numpy implementation\n"
|
||||||
|
config.set('weave', 'working', 'False')
|
||||||
|
self.lengthscale.gradient = np.array([np.einsum('ij,ij,...', tmp, np.square(X[:,q:q+1] - X2[:,q:q+1].T), -1./self.lengthscale[q]**3) for q in xrange(self.input_dim)])
|
||||||
|
else:
|
||||||
self.lengthscale.gradient = np.array([np.einsum('ij,ij,...', tmp, np.square(X[:,q:q+1] - X2[:,q:q+1].T), -1./self.lengthscale[q]**3) for q in xrange(self.input_dim)])
|
self.lengthscale.gradient = np.array([np.einsum('ij,ij,...', tmp, np.square(X[:,q:q+1] - X2[:,q:q+1].T), -1./self.lengthscale[q]**3) for q in xrange(self.input_dim)])
|
||||||
else:
|
else:
|
||||||
r = self._scaled_dist(X, X2)
|
r = self._scaled_dist(X, X2)
|
||||||
|
|
@ -154,10 +165,43 @@ class Stationary(Kern):
|
||||||
dist = self._scaled_dist(X, X2).copy()
|
dist = self._scaled_dist(X, X2).copy()
|
||||||
return 1./np.where(dist != 0., dist, np.inf)
|
return 1./np.where(dist != 0., dist, np.inf)
|
||||||
|
|
||||||
|
def weave_lengthscale_grads(self, tmp, X, X2):
|
||||||
|
N,M = tmp.shape
|
||||||
|
Q = X.shape[1]
|
||||||
|
if hasattr(X, 'values'):X = X.values
|
||||||
|
if hasattr(X2, 'values'):X2 = X2.values
|
||||||
|
grads = np.zeros(self.input_dim)
|
||||||
|
code = """
|
||||||
|
double gradq;
|
||||||
|
for(int q=0; q<Q; q++){
|
||||||
|
gradq = 0;
|
||||||
|
for(int n=0; n<N; n++){
|
||||||
|
for(int m=0; m<M; m++){
|
||||||
|
gradq += tmp(n,m)*(X(n,q)-X2(m,q))*(X(n,q)-X2(m,q));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grads[q] = gradq;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
from scipy import weave
|
||||||
|
weave.inline(code, ['tmp', 'X', 'X2', 'grads', 'N', 'M', 'Q'], type_converters=weave.converters.blitz, support_code="#include <math.h>")
|
||||||
|
return -grads/self.lengthscale**3
|
||||||
|
|
||||||
def gradients_X(self, dL_dK, X, X2=None):
|
def gradients_X(self, dL_dK, X, X2=None):
|
||||||
"""
|
"""
|
||||||
Given the derivative of the objective wrt K (dL_dK), compute the derivative wrt X
|
Given the derivative of the objective wrt K (dL_dK), compute the derivative wrt X
|
||||||
"""
|
"""
|
||||||
|
if config.getboolean('weave', 'working'):
|
||||||
|
try:
|
||||||
|
return self.gradients_X_weave(dL_dK, X, X2)
|
||||||
|
except:
|
||||||
|
print "\n Weave compilation failed. Falling back to (slower) numpy implementation\n"
|
||||||
|
config.set('weave', 'working', 'False')
|
||||||
|
return self.gradients_X_(dL_dK, X, X2)
|
||||||
|
else:
|
||||||
|
return self.gradients_X_(dL_dK, X, X2)
|
||||||
|
|
||||||
|
def gradients_X_(self, dL_dK, X, X2=None):
|
||||||
invdist = self._inv_dist(X, X2)
|
invdist = self._inv_dist(X, X2)
|
||||||
dL_dr = self.dK_dr_via_X(X, X2) * dL_dK
|
dL_dr = self.dK_dr_via_X(X, X2) * dL_dK
|
||||||
tmp = invdist*dL_dr
|
tmp = invdist*dL_dr
|
||||||
|
|
@ -177,6 +221,34 @@ class Stationary(Kern):
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def gradients_X_weave(self, dL_dK, X, X2=None):
|
||||||
|
invdist = self._inv_dist(X, X2)
|
||||||
|
dL_dr = self.dK_dr_via_X(X, X2) * dL_dK
|
||||||
|
tmp = invdist*dL_dr
|
||||||
|
if X2 is None:
|
||||||
|
tmp = tmp + tmp.T
|
||||||
|
X2 = X
|
||||||
|
|
||||||
|
ret = np.zeros(X.shape)
|
||||||
|
code = """
|
||||||
|
int n,q,d;
|
||||||
|
double retnd;
|
||||||
|
for(n=0;n<N;n++){
|
||||||
|
for(d=0;d<D;d++){
|
||||||
|
retnd = 0;
|
||||||
|
for(q=0;q<Q;q++){
|
||||||
|
retnd += tmp(n,q)*(X(n,d)-X2(q,d));
|
||||||
|
}
|
||||||
|
ret(n,d) = retnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
from scipy import weave
|
||||||
|
N,D = X.shape
|
||||||
|
Q = tmp.shape[1]
|
||||||
|
weave.inline(code, ['ret', 'N', 'D', 'Q', 'tmp', 'X', 'X2'], type_converters=weave.converters.blitz)
|
||||||
|
return ret/self.lengthscale**2
|
||||||
|
|
||||||
def gradients_X_diag(self, dL_dKdiag, X):
|
def gradients_X_diag(self, dL_dKdiag, X):
|
||||||
return np.zeros(X.shape)
|
return np.zeros(X.shape)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue