Skip to content

Commit 2084ce2

Browse files
committed
fixes to cov.py, fix to how tests handle active_dims and lengthscales
1 parent b565c67 commit 2084ce2

File tree

2 files changed

+40
-36
lines changed

2 files changed

+40
-36
lines changed

pymc3/gp/cov.py

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import theano.tensor as tt
33
import numpy as np
44
from functools import reduce
5+
from operator import mul, add
56

67
__all__ = ['ExpQuad',
78
'RatQuad',
@@ -91,9 +92,8 @@ def __array_wrap__(self, result):
9192

9293
class Combination(Covariance):
9394
def __init__(self, factor_list):
94-
input_dim = np.max([factor.input_dim for factor in
95-
filter(lambda x: isinstance(x, Covariance),
96-
factor_list)])
95+
input_dim = max([factor.input_dim for factor in factor_list
96+
if isinstance(factor, Covariance)])
9797
super(Combination, self).__init__(input_dim=input_dim)
9898
self.factor_list = []
9999
for factor in factor_list:
@@ -103,45 +103,36 @@ def __init__(self, factor_list):
103103
self.factor_list.append(factor)
104104

105105
def merge_factors(self, X, Xs=None, diag=False):
106-
# this function makes sure diag=True is handled properly
107106
factor_list = []
108107
for factor in self.factor_list:
109-
110-
# if factor is a Covariance
108+
# make sure diag=True is handled properly
111109
if isinstance(factor, Covariance):
112110
factor_list.append(factor(X, Xs, diag))
113-
continue
114-
115-
# if factor is a numpy array
116-
if isinstance(factor, np.ndarray):
117-
if np.ndim(factor) == 2:
118-
if diag:
119-
factor_list.append(np.diag(factor))
120-
continue
121-
122-
# if factor is a theano variable with ndim attribute
123-
if isinstance(factor, (tt.TensorConstant,
111+
elif isinstance(factor, np.ndarray):
112+
if np.ndim(factor) == 2 and diag:
113+
factor_list.append(np.diag(factor))
114+
else:
115+
factor_list.append(factor)
116+
elif isinstance(factor, (tt.TensorConstant,
124117
tt.TensorVariable,
125118
tt.sharedvar.TensorSharedVariable)):
126-
if factor.ndim == 2:
127-
if diag:
128-
factor_list.append(tt.diag(factor))
129-
continue
130-
131-
# othewise
132-
factor_list.append(factor)
133-
119+
if factor.ndim == 2 and diag:
120+
factor_list.append(tt.diag(factor))
121+
else:
122+
factor_list.append(factor)
123+
else:
124+
factor_list.append(factor)
134125
return factor_list
135126

136127

137128
class Add(Combination):
138129
def __call__(self, X, Xs=None, diag=False):
139-
return reduce((lambda x, y: x + y), self.merge_factors(X, Xs, diag))
130+
return reduce(add, self.merge_factors(X, Xs, diag))
140131

141132

142133
class Prod(Combination):
143134
def __call__(self, X, Xs=None, diag=False):
144-
return reduce((lambda x, y: x * y), self.merge_factors(X, Xs, diag))
135+
return reduce(mul, self.merge_factors(X, Xs, diag))
145136

146137

147138
class Constant(Covariance):
@@ -205,7 +196,7 @@ def __init__(self, input_dim, ls=None, ls_inv=None, active_dims=None):
205196
if (ls is None and ls_inv is None) or (ls is not None and ls_inv is not None):
206197
raise ValueError("Only one of 'ls' or 'ls_inv' must be provided")
207198
elif ls_inv is not None:
208-
if isinstance(ls_inv, (np.ndarray, list, tuple)):
199+
if isinstance(ls_inv, (list, tuple)):
209200
ls = 1.0 / np.asarray(ls_inv)
210201
else:
211202
ls = 1.0 / ls_inv
@@ -229,7 +220,8 @@ def euclidean_dist(self, X, Xs):
229220
return tt.sqrt(r2 + 1e-12)
230221

231222
def diag(self, X):
232-
return tt.ones(tt.stack([X.shape[0], ]))
223+
return tt.alloc(1.0, X.shape[0])
224+
#return tt.ones(tt.stack([X.shape[0], ]))
233225

234226
def full(self, X, Xs=None):
235227
raise NotImplementedError
@@ -274,7 +266,7 @@ class RatQuad(Stationary):
274266
k(x, x') = \left(1 + \frac{(x - x')^2}{2\alpha\ell^2} \right)^{-\alpha}
275267
"""
276268

277-
def __init__(self, input_dim, alpha, ls, ls_inv, active_dims=None):
269+
def __init__(self, input_dim, alpha, ls=None, ls_inv=None, active_dims=None):
278270
super(RatQuad, self).__init__(input_dim, ls, ls_inv, active_dims)
279271
self.alpha = alpha
280272

@@ -337,7 +329,7 @@ class Cosine(Stationary):
337329
The Cosine kernel.
338330
339331
.. math::
340-
k(x, x') = \mathrm{cos}\left( \frac{||x - x'||}{ \ell^2} \right)
332+
k(x, x') = \mathrm{cos}\left( \pi \frac{||x - x'||}{ \ell^2} \right)
341333
"""
342334

343335
def full(self, X, Xs=None):

pymc3/tests/test_gp.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import numpy.testing as npt
88
import pytest
99

10+
1011
class TestZeroMean(object):
1112
def test_value(self):
1213
X = np.linspace(0, 1, 10)[:, None]
@@ -125,6 +126,17 @@ def test_rightadd_matrix(self):
125126
Kd = theano.function([], cov(X, diag=True))()
126127
npt.assert_allclose(np.diag(K), Kd, atol=1e-5)
127128

129+
def test_leftadd_matrixt(self):
130+
X = np.linspace(0, 1, 10)[:, None]
131+
M = 2 * tt.ones((10, 10))
132+
with Model() as model:
133+
cov = M + gp.cov.ExpQuad(1, 0.1)
134+
K = theano.function([], cov(X))()
135+
npt.assert_allclose(K[0, 1], 2.53940, atol=1e-3)
136+
# check diagonal
137+
Kd = theano.function([], cov(X, diag=True))()
138+
npt.assert_allclose(np.diag(K), Kd, atol=1e-5)
139+
128140
def test_leftprod_matrix(self):
129141
X = np.linspace(0, 1, 3)[:, None]
130142
M = np.array([[1, 2, 3], [2, 1, 2], [3, 2, 1]])
@@ -222,7 +234,7 @@ def test_slice1(self):
222234
def test_slice2(self):
223235
X = np.linspace(0, 1, 30).reshape(10, 3)
224236
with Model() as model:
225-
cov = gp.cov.ExpQuad(3, [0.1, 0.1], active_dims=[False, True, True])
237+
cov = gp.cov.ExpQuad(3, ls=[0.1, 0.1], active_dims=[1,2])
226238
K = theano.function([], cov(X))()
227239
npt.assert_allclose(K[0, 1], 0.34295549, atol=1e-3)
228240
# check diagonal
@@ -232,7 +244,7 @@ def test_slice2(self):
232244
def test_slice3(self):
233245
X = np.linspace(0, 1, 30).reshape(10, 3)
234246
with Model() as model:
235-
cov = gp.cov.ExpQuad(3, np.array([0.1, 0.1]), active_dims=[False, True, True])
247+
cov = gp.cov.ExpQuad(3, ls=np.array([0.1, 0.1]), active_dims=[1,2])
236248
K = theano.function([], cov(X))()
237249
npt.assert_allclose(K[0, 1], 0.34295549, atol=1e-3)
238250
# check diagonal
@@ -242,7 +254,7 @@ def test_slice3(self):
242254
def test_diffslice(self):
243255
X = np.linspace(0, 1, 30).reshape(10, 3)
244256
with Model() as model:
245-
cov = gp.cov.ExpQuad(3, 0.1, [1, 0, 0]) + gp.cov.ExpQuad(3, [0.1, 0.2, 0.3])
257+
cov = gp.cov.ExpQuad(3, ls=0.1, active_dims=[1, 0, 0]) + gp.cov.ExpQuad(3, ls=[0.1, 0.2, 0.3])
246258
K = theano.function([], cov(X))()
247259
npt.assert_allclose(K[0, 1], 0.683572, atol=1e-3)
248260
# check diagonal
@@ -303,7 +315,7 @@ class TestRatQuad(object):
303315
def test_1d(self):
304316
X = np.linspace(0, 1, 10)[:, None]
305317
with Model() as model:
306-
cov = gp.cov.RatQuad(1, 0.1, 0.5)
318+
cov = gp.cov.RatQuad(1, ls=0.1, alpha=0.5)
307319
K = theano.function([], cov(X))()
308320
npt.assert_allclose(K[0, 1], 0.66896, atol=1e-3)
309321
K = theano.function([], cov(X, X))()
@@ -442,7 +454,7 @@ def test_raises(self):
442454
with pytest.raises(NotImplementedError):
443455
gp.cov.Gibbs(2, lambda x: x)
444456
with pytest.raises(NotImplementedError):
445-
gp.cov.Gibbs(3, lambda x: x, active_dims=[True, True, False])
457+
gp.cov.Gibbs(3, lambda x: x, active_dims=[0,1])
446458

447459

448460
class TestHandleArgs(object):

0 commit comments

Comments
 (0)