diff --git a/GPy/inference/latent_function_inference/posterior.py b/GPy/inference/latent_function_inference/posterior.py index c4b0ec62..82de1419 100644 --- a/GPy/inference/latent_function_inference/posterior.py +++ b/GPy/inference/latent_function_inference/posterior.py @@ -25,6 +25,8 @@ class Posterior(object): Not all of the above need to be supplied! You *must* supply: K (for lazy computation) + or + K_chol (for lazy computation) You may supply either: @@ -35,11 +37,10 @@ class Posterior(object): mean cov - K_chol (for lazy computation) - Of course, you can supply more than that, but this class will lazily compute all other quantites on demand. + Of course, you can supply more than that, but this class will lazily + compute all other quantites on demand. - From the supplied quantities, all of the others will be computed on demand (lazy computation) """ #obligatory self._K = K @@ -49,6 +50,8 @@ class Posterior(object): else: raise ValueError, "insufficient information to compute the posterior" + self._K_chol = K_chol + self._K = K #option 1: self._woodbury_chol = woodbury_chol self._woodbury_vector = woodbury_vector @@ -56,7 +59,6 @@ class Posterior(object): #option 2: self._mean = mean self._covariance = cov - self._K_chol = K_chol #compute this lazily self._precision = None @@ -95,6 +97,12 @@ class Posterior(object): self._woodbury_vector, _ = dpotrs(self._K_chol, self.mean) return self._woodbury_vector + @property + def K_chol(self): + if self._K_chol is None: + self._K_chol = dportf(self._K) + return self._K_chol + diff --git a/GPy/inference/latent_function_inference/varDTC.py b/GPy/inference/latent_function_inference/varDTC.py index bd4a59e1..fcbe54f9 100644 --- a/GPy/inference/latent_function_inference/varDTC.py +++ b/GPy/inference/latent_function_inference/varDTC.py @@ -33,6 +33,9 @@ class VarDTC(object): #if Y in self.cache, return self.Cache[Y], else stor Y in cache and return L. raise NotImplementedError, 'TODO' #TODO + def get_VVTfactor(self, Y, prec): + return Y * prec # TODO chache this, and make it effective + def inference(self, kern, X, X_variance, Z, likelihood, Y): num_inducing, _ = Z.shape @@ -79,12 +82,12 @@ class VarDTC(object): LB = jitchol(B) # VVT_factor is a matrix such that tdot(VVT_factor) = VVT...this is for efficiency! - psi1Vf = np.dot(psi1.T, likelihood.VVT_factor) + VVT_factor = self.get_VVTfactor(Y, likelihood.precision) + psi1Vf = np.dot(psi1.T, VVT_factor) # back substutue C into psi1Vf tmp, info1 = dtrtrs(Lm, np.asfortranarray(psi1Vf), lower=1, trans=0) _LBi_Lmi_psi1Vf, _ = dtrtrs(LB, np.asfortranarray(tmp), lower=1, trans=0) - # tmp, info2 = dpotrs(LB, tmp, lower=1) tmp, info2 = dtrtrs(LB, _LBi_Lmi_psi1Vf, lower=1, trans=1) Cpsi1Vf, info3 = dtrtrs(Lm, tmp, lower=1, trans=1) @@ -163,3 +166,14 @@ class VarDTC(object): partial_for_likelihood += likelihood.precision * (0.5 * np.sum(_A * DBi_plus_BiPBi) - data_fit) + #get sufficient things for posterior prediction + if VVT_factor.shape[1] == Y.shape[1]: + Cpsi1V = Cpsi1Vf + else: + raise NotImplementedError #TODO + + #construct a posterior object + post = Posterior(woodbury_chol=None, woodbury_vector=Cpsi1V, K=None, mean=None, cov=None, K_chol=None): + return + +