diff --git a/GPy/kern/_src/stationary.py b/GPy/kern/_src/stationary.py index cc5634e9..cd209d9d 100644 --- a/GPy/kern/_src/stationary.py +++ b/GPy/kern/_src/stationary.py @@ -10,6 +10,7 @@ from ... import util import numpy as np from scipy import integrate from ...util.caching import Cache_this +from ...util.config import config # for assesing whether to use weave class Stationary(Kern): """ @@ -139,7 +140,17 @@ class Stationary(Kern): #self.lengthscale.gradient = -((dL_dr*rinv)[:,:,None]*x_xl3).sum(0).sum(0)/self.lengthscale**3 tmp = dL_dr*self._inv_dist(X, X2) if X2 is None: X2 = X - 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)]) + + + 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)]) else: r = self._scaled_dist(X, X2) self.lengthscale.gradient = -np.sum(dL_dr*r)/self.lengthscale @@ -154,10 +165,43 @@ class Stationary(Kern): dist = self._scaled_dist(X, X2).copy() 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