예제 #1
0
    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
예제 #2
0
    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.'