This commit is contained in:
James Hensman 2014-01-28 09:44:18 +00:00
parent ca1cb4eb22
commit 2921e71020
2 changed files with 28 additions and 6 deletions

View file

@ -25,6 +25,8 @@ class Posterior(object):
Not all of the above need to be supplied! You *must* supply: Not all of the above need to be supplied! You *must* supply:
K (for lazy computation) K (for lazy computation)
or
K_chol (for lazy computation)
You may supply either: You may supply either:
@ -35,11 +37,10 @@ class Posterior(object):
mean mean
cov 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 #obligatory
self._K = K self._K = K
@ -49,6 +50,8 @@ class Posterior(object):
else: else:
raise ValueError, "insufficient information to compute the posterior" raise ValueError, "insufficient information to compute the posterior"
self._K_chol = K_chol
self._K = K
#option 1: #option 1:
self._woodbury_chol = woodbury_chol self._woodbury_chol = woodbury_chol
self._woodbury_vector = woodbury_vector self._woodbury_vector = woodbury_vector
@ -56,7 +59,6 @@ class Posterior(object):
#option 2: #option 2:
self._mean = mean self._mean = mean
self._covariance = cov self._covariance = cov
self._K_chol = K_chol
#compute this lazily #compute this lazily
self._precision = None self._precision = None
@ -95,6 +97,12 @@ class Posterior(object):
self._woodbury_vector, _ = dpotrs(self._K_chol, self.mean) self._woodbury_vector, _ = dpotrs(self._K_chol, self.mean)
return self._woodbury_vector 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

View file

@ -33,6 +33,9 @@ class VarDTC(object):
#if Y in self.cache, return self.Cache[Y], else stor Y in cache and return L. #if Y in self.cache, return self.Cache[Y], else stor Y in cache and return L.
raise NotImplementedError, 'TODO' #TODO 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): def inference(self, kern, X, X_variance, Z, likelihood, Y):
num_inducing, _ = Z.shape num_inducing, _ = Z.shape
@ -79,12 +82,12 @@ class VarDTC(object):
LB = jitchol(B) LB = jitchol(B)
# VVT_factor is a matrix such that tdot(VVT_factor) = VVT...this is for efficiency! # 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 # back substutue C into psi1Vf
tmp, info1 = dtrtrs(Lm, np.asfortranarray(psi1Vf), lower=1, trans=0) tmp, info1 = dtrtrs(Lm, np.asfortranarray(psi1Vf), lower=1, trans=0)
_LBi_Lmi_psi1Vf, _ = dtrtrs(LB, np.asfortranarray(tmp), 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) tmp, info2 = dtrtrs(LB, _LBi_Lmi_psi1Vf, lower=1, trans=1)
Cpsi1Vf, info3 = dtrtrs(Lm, tmp, 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) 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