From 6242a75f6a28b41fbe699a1210442b5d7354c12f Mon Sep 17 00:00:00 2001 From: Max Zwiessele Date: Mon, 3 Nov 2014 14:19:38 +0000 Subject: [PATCH] [parameterized] handle updates inside init --- GPy/core/parameterization/index_operations.py | 20 +++++++++---------- GPy/core/parameterization/parameter_core.py | 6 +++--- GPy/core/parameterization/parameterized.py | 15 ++++++++++---- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/GPy/core/parameterization/index_operations.py b/GPy/core/parameterization/index_operations.py index 78c0d2b9..ddd689ed 100644 --- a/GPy/core/parameterization/index_operations.py +++ b/GPy/core/parameterization/index_operations.py @@ -26,39 +26,39 @@ class ParameterIndexOperations(object): This object wraps a dictionary, whos keys are _operations_ that we'd like to apply to a parameter array, and whose values are np integer arrays which index the parameter array appropriately. - + A model instance will contain one instance of this class for each thing that needs indexing (i.e. constraints, ties and priors). Parameters within the model constain instances of the ParameterIndexOperationsView class, which can map from a 'local' index (starting 0) to this global index. - + Here's an illustration: - + #======================================================================= model : 0 1 2 3 4 5 6 7 8 9 key1: 4 5 key2: 7 8 - + param1: 0 1 2 3 4 5 key1: 2 3 key2: 5 - + param2: 0 1 2 3 4 key1: 0 key2: 2 3 #======================================================================= - + The views of this global index have a subset of the keys in this global (model) index. - + Adding a new key (e.g. a constraint) to a view will cause the view to pass the new key to the global index, along with the local index and an offset. This global index then stores the key and the appropriate global index (which can be seen by the view). - + See also: ParameterIndexOperationsView - + """ _offset = 0 def __init__(self, constraints=None): @@ -221,8 +221,6 @@ class ParameterIndexOperationsView(object): def shift_left(self, start, size): self._param_index_ops.shift_left(start+self._offset, size) - self._offset -= size - self._size -= size def clear(self): for i, ind in self.items(): diff --git a/GPy/core/parameterization/parameter_core.py b/GPy/core/parameterization/parameter_core.py index b1e0d8d2..115acf3a 100644 --- a/GPy/core/parameterization/parameter_core.py +++ b/GPy/core/parameterization/parameter_core.py @@ -18,7 +18,7 @@ import numpy as np import re import logging -__updated__ = '2014-10-28' +__updated__ = '2014-11-03' class HierarchyError(Exception): """ @@ -924,7 +924,7 @@ class Parameterizable(OptimizationHandlable): !WARNING!: setting the parameter array MUST always be done in memory: m.param_array[:] = m_copy.param_array """ - if self.__dict__.get('_param_array_', None) is None: + if (self.__dict__.get('_param_array_', None) is None) or (self._param_array_.size != self.size): self._param_array_ = np.empty(self.size, dtype=np.float64) return self._param_array_ @@ -1002,7 +1002,7 @@ class Parameterizable(OptimizationHandlable): #========================================================================= @property def gradient(self): - if self.__dict__.get('_gradient_array_', None) is None: + if (self.__dict__.get('_gradient_array_', None) is None) or self._gradient_array_.size != self.size: self._gradient_array_ = np.empty(self.size, dtype=np.float64) return self._gradient_array_ diff --git a/GPy/core/parameterization/parameterized.py b/GPy/core/parameterization/parameterized.py index 0bd72be4..2c91b235 100644 --- a/GPy/core/parameterization/parameterized.py +++ b/GPy/core/parameterization/parameterized.py @@ -9,6 +9,7 @@ from param import ParamConcatenation from parameter_core import HierarchyError, Parameterizable, adjust_name_for_printing import logging +from GPy.core.parameterization.index_operations import ParameterIndexOperationsView logger = logging.getLogger("parameters changed meta") class ParametersChangedMeta(type): @@ -20,7 +21,7 @@ class ParametersChangedMeta(type): self._in_init_ = False logger.debug("connecting parameters") self._highest_parent_._connect_parameters() - self._highest_parent_._notify_parent_change() + #self._highest_parent_._notify_parent_change() self._highest_parent_._connect_fixes() logger.debug("calling parameters changed") self.parameters_changed() @@ -140,6 +141,8 @@ class Parameterized(Parameterizable): self.priors.shift_right(start, param.size) self.constraints.update(param.constraints, self.size) self.priors.update(param.priors, self.size) + param._parent_ = self + param._parent_index_ = len(self.parameters) self.parameters.append(param) else: start = sum(p.size for p in self.parameters[:index]) @@ -147,19 +150,23 @@ class Parameterized(Parameterizable): self.priors.shift_right(start, param.size) self.constraints.update(param.constraints, start) self.priors.update(param.priors, start) + param._parent_ = self + param._parent_index_ = index if index>=0 else len(self.parameters[:index]) + for p in self.parameters[index:]: + p._parent_index_ += 1 self.parameters.insert(index, param) - self._notify_parent_change() param.add_observer(self, self._pass_through_notify_observers, -np.inf) parent = self while parent is not None: parent.size += param.size parent = parent._parent_ + self._notify_parent_change() if not self._in_init_: - self._connect_parameters() - self._notify_parent_change() + #self._connect_parameters() + #self._notify_parent_change() self._highest_parent_._connect_parameters(ignore_added_names=_ignore_added_names) self._highest_parent_._notify_parent_change()