def observe(self, obs_mesh, obs_V): __doc__ = Covariance.observe.__doc__ ndim = obs_mesh.shape[1] nobs = obs_mesh.shape[0] if self.ndim is not None: if not ndim==self.ndim: raise ValueError, "Dimension of observation mesh is not equal to dimension of base mesh." else: self.ndim = ndim # bases_o is the basis evaluated on the observation mesh. basis_o = asmatrix(self.eval_basis(obs_mesh, regularize=False)) # chol(basis_o.T * coef_cov * basis_o) chol_inner = self.coef_U * basis_o # chol(basis_o.T * coef_cov * basis_o + diag(obs_V)). Really should do this as low-rank update of covariance # of V. U, piv, m = ichol_basis(basis=chol_inner, nug=obs_V, reltol=self.relative_precision) U = asmatrix(U) piv_new = piv[:m] self.obs_piv = piv_new obs_mesh_new = obs_mesh[piv_new,:] self.Uo = U[:m,:m] # chol(basis_o.T * coef_cov * basis_o + diag(obs_V)) ^ -T * basis_o.T self.Uo_cov = trisolve(self.Uo, basis_o[:,piv[:m]].T, uplo='U', transa='T') # chol(basis_o.T * coef_cov * basis_o + diag(obs_V)).T.I * basis_o.T * coef_cov self.Uo_cov = self.Uo_cov * self.coef_cov # coef_cov -= coef_cov * basis_o * (basis_o.T * coef_cov * basis_o + diag(obs_V)).I * basis_o.T * coef_cov self.coef_cov -= self.Uo_cov.T * self.Uo_cov # coef_U = chol(coef_cov) U, m, piv = ichol_full(c=self.coef_cov, reltol=self.relative_precision) U = asmatrix(U) self.coef_U = U[:m,argsort(piv)] self.m = m return piv_new, obs_mesh_new, None
def observe(self, obs_mesh, obs_V, output_type='o'): __doc__ = Covariance.observe.__doc__ ndim = obs_mesh.shape[1] nobs = obs_mesh.shape[0] if self.ndim is not None: if not ndim == self.ndim: raise ValueError, "Dimension of observation mesh is not equal to dimension of base mesh." else: self.ndim = ndim # bases_o is the basis evaluated on the observation mesh. basis_o = asmatrix(self.eval_basis(obs_mesh, regularize=False)) # chol(basis_o.T * coef_cov * basis_o) chol_inner = self.coef_U * basis_o if output_type == 's': C_eval = dot(chol_inner.T, chol_inner).copy('F') U_eval = linalg.cholesky(C_eval).T.copy('F') U = U_eval m = U_eval.shape[0] piv = arange(m) else: # chol(basis_o.T * coef_cov * basis_o + diag(obs_V)). Really should do this as low-rank update of covariance # of V. U, piv, m = ichol_basis(basis=chol_inner, nug=obs_V, reltol=self.relative_precision) U = asmatrix(U) piv_new = piv[:m] self.obs_piv = piv_new obs_mesh_new = obs_mesh[piv_new, :] self.Uo = U[:m, :m] # chol(basis_o.T * coef_cov * basis_o + diag(obs_V)) ^ -T * basis_o.T self.Uo_cov = trisolve(self.Uo, basis_o[:, piv[:m]].T, uplo='U', transa='T') # chol(basis_o.T * coef_cov * basis_o + diag(obs_V)).T.I * basis_o.T * coef_cov self.Uo_cov = self.Uo_cov * self.coef_cov # coef_cov = coef_cov - coef_cov * basis_o * (basis_o.T * coef_cov * basis_o + diag(obs_V)).I * basis_o.T * coef_cov self.coef_cov = self.coef_cov - self.Uo_cov.T * self.Uo_cov # coef_U = chol(coef_cov) U, m, piv = ichol_full(c=self.coef_cov, reltol=self.relative_precision) U = asmatrix(U) self.coef_U = U[:m, argsort(piv)] self.m = m if output_type == 'o': return piv_new, obs_mesh_new if output_type == 's': return U_eval, C_eval, basis_o raise ValueError, 'Output type not recognized.'