コード例 #1
0
def test_get_cholesky_inv_upper(test_mat):
    """test get_cholesky_inv with upper triangular"""
    A = test_mat.A.copy()
    A_i = test_mat.A_i.copy()
    chol_test_inv = get_cholesky_inv(A,lower=False)
    chol_test = get_cholesky_inv(A_i,lower=False)

    assert check_is_cholesky(chol_test_inv,A_i,lower=False,atol_rel=atol_rel_use,rtol=rtol_use)
    assert check_is_cholesky(chol_test,A,lower=False,atol_rel=atol_rel_use,rtol=rtol_use)
コード例 #2
0
ファイル: sph_klim_fast.py プロジェクト: mcdigman/SuperSCRAM
    def perturb_and_project_covar(self, perturb_v, project_v, perturb_sigma2s):
        r"""get the variance  (v.T).C_lw.v where v=\frac{\partial\bar{\delta}}{\delta_\alpha} in the given geometry"""
        perturb_v = np.ascontiguousarray(perturb_v.T)
        denom_result = np.zeros((perturb_v.shape[1], perturb_v.shape[1]),
                                order='F')
        covar_result = np.zeros((project_v.shape[1], project_v.shape[1]),
                                order='F')
        itr_ll = 0
        for ll in range(0, self.n_l):
            n_k = self.C_compact[ll].shape[0]
            res = cholesky_inplace(self.C_compact[ll],
                                   inplace=False,
                                   lower=True,
                                   clean=False)
            n_break = n_k
            for _m_itr in range(0, self.lm_map[ll, 2].size):
                rhs1 = spl.blas.dtrmm(1.,
                                      res,
                                      perturb_v[itr_ll:itr_ll + n_break],
                                      trans_a=True,
                                      lower=True)
                rhs2 = spl.blas.dtrmm(1.,
                                      res,
                                      project_v[itr_ll:itr_ll + n_break],
                                      trans_a=True,
                                      lower=True)
                denom_result = spl.blas.dsyrk(1.,
                                              rhs1,
                                              1.,
                                              denom_result,
                                              lower=True,
                                              trans=True)
                covar_result = spl.blas.dsyrk(1.,
                                              rhs2,
                                              1.,
                                              covar_result,
                                              lower=True,
                                              trans=True)
                rhs1 = None
                rhs2 = None
                itr_ll += n_k
            res = None

        mult_mat = np.asfortranarray(np.diag(
            1. / perturb_sigma2s)) + denom_result
        denom_result = None
        mult_mat_chol_inv = get_cholesky_inv(mult_mat,
                                             lower=True,
                                             inplace=False,
                                             clean=True)
        mult_mat = None
        pert_in = spl.blas.dtrmm(1.,
                                 mult_mat_chol_inv,
                                 perturb_v.T,
                                 side=False,
                                 lower=True,
                                 trans_a=True)
        mult_mat_chol_inv = None

        proj_out = np.zeros_like(project_v, order='F')
        itr_ll = 0
        for ll in range(0, self.n_l):
            n_k = self.C_compact[ll].shape[0]
            res = self.C_compact[ll]
            n_break = n_k
            for _m_itr in range(0, self.lm_map[ll, 2].size):
                proj_out[itr_ll:itr_ll + n_break] = spl.blas.dsymm(
                    1., res, project_v[itr_ll:itr_ll + n_break], lower=True)
                itr_ll += n_k
            res = None
        rhs_req = np.asfortranarray(np.dot(pert_in, proj_out))
        mit_result = spl.blas.dsyrk(
            -1., rhs_req, 1., covar_result, lower=True,
            trans=True)  #covar_result-np.dot(rhs_req.T,rhs_req)
        return covar_result, mit_result
コード例 #3
0
    def get_cov_cholesky(self,
                         inplace=False,
                         copy_output=False,
                         internal=False):
        """get lower triangular cholesky decomposition of covariance
                inputs:
                    inplace: if True, will mutate _internal_mat to be the cholesky decompostion of the covariance matrix
                    copy_output: whether to copy the output matrix, to be safe from mutating _internal_mat later
                    internal: should be True only if being called from another FisherMatrix routine, do not need to clean upper triangle"""

        #if _internal_mat changes must change internal state
        if inplace and not internal:
            self.switch_rep(REP_CHOL)

        if self.internal_state == REP_CHOL:
            if not self.silent:
                print(
                    "FisherMatrix ",
                    str(id(self)) + ": cholesky stored, size: " +
                    str(self._internal_mat.nbytes / 10**6) + " megabytes")
            result = self._internal_mat
        else:
            if self.internal_state == REP_CHOL_INV:
                if not self.silent:
                    print(
                        "FisherMatrix " + str(id(self)),
                        ": getting cholesky of covariance from its inverse, size: "
                        + str(self._internal_mat.nbytes / 10**6) + " mb")
                result = invert_triangular(self._internal_mat,
                                           lower=True,
                                           inplace=inplace,
                                           clean=False)
            elif self.internal_state == REP_COVAR:
                if not self.silent:
                    print(
                        "FisherMatrix " + str(id(self)),
                        ": getting cholesky from covariance directly: " +
                        str(self._internal_mat.nbytes / 10**6) + " mb")
                result = cholesky_inplace(self._internal_mat,
                                          inplace=inplace,
                                          lower=True,
                                          clean=False)
            elif self.internal_state == REP_FISHER:
                if not self.silent:
                    print(
                        "FisherMatrix " + str(id(self)),
                        ": getting cholesky of covariance from fisher, size: "
                        + str(self._internal_mat.nbytes / 10**6) + " mb")
                result = get_cholesky_inv(self._internal_mat,
                                          lower=True,
                                          inplace=inplace,
                                          clean=False)
            else:
                raise ValueError("FisherMatrix " + str(id(self)) +
                                 ": unrecognized internal state " +
                                 str(self.internal_state))

            if not self.silent:
                print(
                    "FisherMatrix " + str(id(self)),
                    ": found cholesky decomposition of covariance matrix, size: "
                    + str(result.nbytes / 10**6) + " megabytes")

        if inplace:
            self._internal_mat = result
            self.internal_state = REP_CHOL

        #if not being requested internally to FisherMatrix, make sure the upper triangle is all zeros
        if not internal:
            result = clean_triangle(result, lower=True, inplace=True)

        if copy_output:
            return result.copy()
        else:
            return result
コード例 #4
0
    def perturb_fisher(self, vs, sigma2s, force_sherman=False):
        """add perturbation the fisher matrix in the form sigma2*v^Tv,
        use Sherman-Morrison formula/Woodbury Matrix identity to avoid inverting/for numerical stability"""
        if not self.silent:
            print("FisherMatrix ", id(self), " perturbing fisher matrix")
        #internal state must be fisher to add right now: could possibly be changed back
        if np.any(sigma2s < 0.):
            raise ValueError('perturbation must be positive semidefinite ' +
                             str(sigma2s))

        if self.internal_state == REP_FISHER or self.internal_state == REP_CHOL_INV:
            self.switch_rep(REP_FISHER)
            self._internal_mat = np.asfortranarray(self._internal_mat)
            self._internal_mat = spl.blas.dsyrk(1.,
                                                (vs.T * np.sqrt(sigma2s)).T,
                                                1.,
                                                c=self._internal_mat,
                                                overwrite_c=True,
                                                trans=True,
                                                lower=True)
        else:
            self.switch_rep(REP_COVAR)
            self._internal_mat = np.asfortranarray(self._internal_mat)
            if force_sherman:
                for itr in range(0, sigma2s.size):
                    v = vs[itr:itr + 1]
                    lhs = spl.blas.dsymm(1.,
                                         self._internal_mat,
                                         v.T,
                                         lower=True,
                                         overwrite_c=False,
                                         side=False)
                    #use more numerically stable form for large sigma2s, although mathematically equivalent
                    if sigma2s[itr] > 1.:
                        mult = -1. / (1. / sigma2s[itr] + np.dot(v, lhs)[0, 0])
                    elif sigma2s[itr] > 0.:
                        mult = -sigma2s[itr] / (
                            1. + sigma2s[itr] * np.dot(v, lhs)[0, 0])
                    else:  #don't bother perturbing the matrix if nothing to add
                        continue
                    self._internal_mat = spl.blas.dsyrk(mult,
                                                        lhs,
                                                        1.,
                                                        c=self._internal_mat,
                                                        lower=True,
                                                        trans=False,
                                                        overwrite_c=True)
            else:
                lhs1 = np.asfortranarray(
                    spl.blas.dsymm(1.,
                                   self._internal_mat,
                                   vs,
                                   lower=True,
                                   overwrite_c=False,
                                   side=True))
                mult_mat = np.asfortranarray(np.diag(
                    1. / sigma2s)) + spl.blas.dgemm(1., vs, lhs1, trans_b=True)
                mult_mat_chol_inv = get_cholesky_inv(mult_mat,
                                                     lower=True,
                                                     inplace=False,
                                                     clean=False)
                mult_mat = None

                lhs2 = spl.blas.dtrmm(1.,
                                      mult_mat_chol_inv,
                                      lhs1,
                                      side=False,
                                      lower=True,
                                      trans_a=True)
                mult_mat_chol_inv = None
                lhs1 = None
                self._internal_mat = spl.blas.dsyrk(-1.,
                                                    lhs2,
                                                    1.,
                                                    self._internal_mat,
                                                    trans=True,
                                                    lower=True,
                                                    overwrite_c=True)

        if not self.silent:
            print("FisherMatrix ", id(self),
                  " finished perturbing fisher matrix")