From 8ef16f5529a43b9930e020f32709fdb263510182 Mon Sep 17 00:00:00 2001 From: mzwiessele Date: Mon, 30 Jun 2014 09:20:56 -0700 Subject: [PATCH] [parameterized] bugfix: downstream parameters did not get constraint update on add_parameter --- GPy/core/parameterization/parameter_core.py | 5 ++++ GPy/core/parameterization/parameterized.py | 27 ++++++++++++--------- GPy/testing/parameterized_tests.py | 27 ++++++++++++++++++--- 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/GPy/core/parameterization/parameter_core.py b/GPy/core/parameterization/parameter_core.py index 3549fd11..7bd00849 100644 --- a/GPy/core/parameterization/parameter_core.py +++ b/GPy/core/parameterization/parameter_core.py @@ -835,6 +835,11 @@ class OptimizationHandlable(Indexable): 1.) connect param_array of children to self.param_array 2.) tell all children to propagate further """ + if self.param_array.size != self.size: + self._param_array_ = np.empty(self.size, dtype=np.float64) + if self.gradient.size != self.size: + self._gradient_array_ = np.empty(self.size, dtype=np.float64) + pi_old_size = 0 for pi in self.parameters: pislice = slice(pi_old_size, pi_old_size + pi.size) diff --git a/GPy/core/parameterization/parameterized.py b/GPy/core/parameterization/parameterized.py index 0e879088..896261e1 100644 --- a/GPy/core/parameterization/parameterized.py +++ b/GPy/core/parameterization/parameterized.py @@ -124,16 +124,20 @@ class Parameterized(Parameterizable): param.traverse_parents(visit, self) param._parent_.remove_parameter(param) # make sure the size is set - if index is None: start = self.size - else: start = sum(p.size for p in self.parameters[:index]) - - self.constraints.shift_right(start, param.size) - self.priors.shift_right(start, param.size) - self.constraints.update(param.constraints, self.size) - self.priors.update(param.priors, self.size) - - if index is None: self.parameters.append(param) - else: self.parameters.insert(index, param) + if index is None: + start = sum(p.size for p in self.parameters) + self.constraints.shift_right(start, param.size) + self.priors.shift_right(start, param.size) + self.constraints.update(param.constraints, self.size) + self.priors.update(param.priors, self.size) + self.parameters.append(param) + else: + start = sum(p.size for p in self.parameters[:index]) + self.constraints.shift_right(start, param.size) + self.priors.shift_right(start, param.size) + self.constraints.update(param.constraints, start) + self.priors.update(param.priors, start) + self.parameters.insert(index, param) param.add_observer(self, self._pass_through_notify_observers, -np.inf) @@ -143,6 +147,7 @@ class Parameterized(Parameterizable): parent = parent._parent_ self._connect_parameters() + self._notify_parent_change() self._highest_parent_._connect_parameters(ignore_added_names=_ignore_added_names) self._highest_parent_._notify_parent_change() @@ -197,7 +202,7 @@ class Parameterized(Parameterizable): # no parameters for this class return if self.param_array.size != self.size: - self.param_array = np.empty(self.size, dtype=np.float64) + self._param_array_ = np.empty(self.size, dtype=np.float64) if self.gradient.size != self.size: self._gradient_array_ = np.empty(self.size, dtype=np.float64) diff --git a/GPy/testing/parameterized_tests.py b/GPy/testing/parameterized_tests.py index fa15d66d..c647c6eb 100644 --- a/GPy/testing/parameterized_tests.py +++ b/GPy/testing/parameterized_tests.py @@ -8,6 +8,7 @@ import GPy import numpy as np from GPy.core.parameterization.parameter_core import HierarchyError from GPy.core.parameterization.observable_array import ObsAr +from GPy.core.parameterization.transformations import NegativeLogexp class ArrayCoreTest(unittest.TestCase): def setUp(self): @@ -38,10 +39,25 @@ class ParameterizedTest(unittest.TestCase): self.test1.kern = self.rbf+self.white self.test1.add_parameter(self.test1.kern) self.test1.add_parameter(self.param, 0) + # print self.test1: + #============================================================================= + # test_model. | Value | Constraint | Prior | Tied to + # param | (25L, 2L) | {0.0,1.0} | | + # add.rbf.variance | 1.0 | 0.0,1.0 +ve | | + # add.rbf.lengthscale | 1.0 | 0.0,1.0 +ve | | + # add.white.variance | 1.0 | 0.0,1.0 +ve | | + #============================================================================= x = np.linspace(-2,6,4)[:,None] y = np.sin(x) self.testmodel = GPy.models.GPRegression(x,y) + # print self.testmodel: + #============================================================================= + # GP_regression. | Value | Constraint | Prior | Tied to + # rbf.variance | 1.0 | +ve | | + # rbf.lengthscale | 1.0 | +ve | | + # Gaussian_noise.variance | 1.0 | +ve | | + #============================================================================= def test_add_parameter(self): self.assertEquals(self.rbf._parent_index_, 0) @@ -142,8 +158,13 @@ class ParameterizedTest(unittest.TestCase): self.testmodel.randomize() self.assertEqual(val, self.testmodel.kern.lengthscale) - - + def test_add_parameter_in_hierarchy(self): + from GPy.core import Param + self.test1.kern.rbf.add_parameter(Param("NEW", np.random.rand(2), NegativeLogexp()), 1) + self.assertListEqual(self.test1.constraints[NegativeLogexp()].tolist(), range(self.param.size+1, self.param.size+1 + 2)) + self.assertListEqual(self.test1.constraints[GPy.transformations.Logistic(0,1)].tolist(), range(self.param.size)) + self.assertListEqual(self.test1.constraints[GPy.transformations.Logexp(0,1)].tolist(), np.r_[50, 53:55].tolist()) + def test_regular_expression_misc(self): self.testmodel.kern.lengthscale.fix() val = float(self.testmodel.kern.lengthscale) @@ -174,4 +195,4 @@ class ParameterizedTest(unittest.TestCase): if __name__ == "__main__": #import sys;sys.argv = ['', 'Test.test_add_parameter'] - unittest.main() \ No newline at end of file + unittest.main()