Merge pull request #1 from SheffieldML/master

merge updates from upstream
This commit is contained in:
mellorjc 2015-04-30 13:46:10 +01:00
commit f6559a4b43
4 changed files with 62 additions and 6 deletions

View file

@ -6,6 +6,20 @@ from kern import CombinationKernel
from ...util.caching import Cache_this
import itertools
def numpy_invalid_op_as_exception(func):
"""
A decorator that allows catching numpy invalid operations
as exceptions (the default behaviour is raising warnings).
"""
def func_wrapper(*args, **kwargs):
np.seterr(invalid='raise')
result = func(*args, **kwargs)
np.seterr(invalid='warn')
return result
return func_wrapper
class Prod(CombinationKernel):
"""
Computes the product of 2 kernels
@ -41,21 +55,35 @@ class Prod(CombinationKernel):
which_parts = self.parts
return reduce(np.multiply, (p.Kdiag(X) for p in which_parts))
@numpy_invalid_op_as_exception
def update_gradients_full(self, dL_dK, X, X2=None):
k = self.K(X,X2)*dL_dK
for p in self.parts:
p.update_gradients_full(k/p.K(X,X2),X,X2)
try:
for p in self.parts:
p.update_gradients_full(k/p.K(X,X2),X,X2)
except FloatingPointError:
for combination in itertools.combinations(self.parts, len(self.parts) - 1):
prod = reduce(np.multiply, [p.K(X, X2) for p in combination])
to_update = list(set(self.parts) - set(combination))[0]
to_update.update_gradients_full(dL_dK * prod, X, X2)
def update_gradients_diag(self, dL_dKdiag, X):
k = self.Kdiag(X)*dL_dKdiag
for p in self.parts:
p.update_gradients_diag(k/p.Kdiag(X),X)
@numpy_invalid_op_as_exception
def gradients_X(self, dL_dK, X, X2=None):
target = np.zeros(X.shape)
k = self.K(X,X2)*dL_dK
for p in self.parts:
target += p.gradients_X(k/p.K(X,X2),X,X2)
try:
for p in self.parts:
target += p.gradients_X(k/p.K(X,X2),X,X2)
except FloatingPointError:
for combination in itertools.combinations(self.parts, len(self.parts) - 1):
prod = reduce(np.multiply, [p.K(X, X2) for p in combination])
to_update = list(set(self.parts) - set(combination))[0]
target += to_update.gradients_X(dL_dK * prod, X, X2)
return target
def gradients_X_diag(self, dL_dKdiag, X):
@ -64,3 +92,5 @@ class Prod(CombinationKernel):
for p in self.parts:
target += p.gradients_X_diag(k/p.Kdiag(X),X)
return target

View file

@ -401,11 +401,27 @@ class Coregionalize_weave_test(unittest.TestCase):
GPy.util.config.config.set('weave', 'working', 'False')
class KernelTestsProductWithZeroValues(unittest.TestCase):
def setUp(self):
self.X = np.array([[0,1],[1,0]])
self.k = GPy.kern.Linear(2) * GPy.kern.Bias(2)
def test_zero_valued_kernel_full(self):
self.k.update_gradients_full(1, self.X)
self.assertFalse(np.isnan(self.k['linear.variances'].gradient),
"Gradient resulted in NaN")
def test_zero_valued_kernel_gradients_X(self):
target = self.k.gradients_X(1, self.X)
self.assertFalse(np.any(np.isnan(target)),
"Gradient resulted in NaN")
if __name__ == "__main__":
print "Running unit tests, please be (very) patient..."
unittest.main()
# np.random.seed(0)
# N0 = 3
# N1 = 9

View file

@ -1,6 +1,6 @@
import numpy as np
import scipy as sp
from ..util.linalg import jitchol
from ..util.linalg import jitchol,trace_dot
class LinalgTests(np.testing.TestCase):
def setUp(self):
@ -33,3 +33,13 @@ class LinalgTests(np.testing.TestCase):
return False
except sp.linalg.LinAlgError:
return True
def test_trace_dot(self):
N = 5
A = np.random.rand(N,N)
B = np.random.rand(N,N)
trace = np.trace(A.dot(B))
test_trace = trace_dot(A,B)
np.testing.assert_allclose(trace,test_trace,atol=1e-13)

View file

@ -191,7 +191,7 @@ def trace_dot(a, b):
"""
Efficiently compute the trace of the matrix product of a and b
"""
return np.sum(a * b)
return np.einsum('ij,ji->', a, b)
def mdot(*args):
"""