Пример #1
0
 def project_covar(self, v):
     r"""get the variance  (v.T).C_lw.v where v=\frac{\partial\bar{\delta}}{\delta_\alpha} in the given geometry"""
     result = np.zeros((v.shape[1], 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):
             rhs = spl.blas.dtrmm(1.,
                                  res,
                                  v[itr_ll:itr_ll + n_break],
                                  trans_a=True,
                                  lower=True)
             result = spl.blas.dsyrk(1.,
                                     rhs,
                                     1.,
                                     result,
                                     lower=True,
                                     trans=True)
             rhs = None
             itr_ll += n_k
         res = None
     return mirror_symmetrize(result, lower=True, inplace=True)
Пример #2
0
    def get_fisher(self, copy_output=False, inplace=False, internal=False):
        """get fisher matrix
                inputs:
                    inplace: if True, will mutate _internal_mat to be the fisher 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_FISHER)

        if self.internal_state == REP_FISHER:
            if not self.silent:
                print("FisherMatrix " + str(id(self)) +
                      ": retrieved fisher matrix from cache")
            result = self._internal_mat
        elif self.internal_state == REP_COVAR or self.internal_state == REP_CHOL:
            chol_cov = np.asfortranarray(
                self.get_cov_cholesky(copy_output=False,
                                      internal=True,
                                      inplace=inplace))
            result, info = spl.lapack.dpotri(chol_cov,
                                             lower=True,
                                             overwrite_c=inplace)
            chol_cov = None
            if info != 0:
                raise RuntimeError('dpotri failed with error code ' +
                                   str(info))
        else:
            if not self.silent:
                print("FisherMatrix " + str(id(self)) +
                      ": fisher matrix cache miss")
            chol_res = np.asfortranarray(
                self.get_cov_cholesky_inv(copy_output=False,
                                          internal=True,
                                          inplace=inplace))
            result, info = spl.lapack.dlauum(chol_res,
                                             lower=True,
                                             overwrite_c=inplace)
            chol_res = None
            if info != 0:
                raise RuntimeError('dlauum failed with error code ' +
                                   str(info))

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

        #make sure symmetric if not for internal use by FisherMatrix
        if not internal:
            result = mirror_symmetrize(result, lower=True, inplace=True)

        if copy_output:
            return result.copy()
        else:
            return result
Пример #3
0
    def get_covar(self, inplace=False, copy_output=False, internal=False):
        """get covariance matrix
                inputs:
                    inplace: if True, will mutate _internal_mat to be 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_COVAR)

        if not self.silent:
            print("FisherMatrix " + str(id(self)) + ": getting covariance")
        if self.internal_state == REP_COVAR:
            if not self.silent:
                print("FisherMatrix " + str(id(self)) +
                      ": covar retrieved from cache")
            result = self._internal_mat
        else:
            if not self.silent:
                print("FisherMatrix " + str(id(self)) + ": covar cache miss")
            chol_cov = self.get_cov_cholesky(inplace=inplace,
                                             internal=True,
                                             copy_output=False)
            #dlauum calculates L^TL but have LL^T cholesky convention, rot90s flip to correct convention
            result, info = spl.lapack.dlauum(np.asfortranarray(
                np.rot90(chol_cov, 2)),
                                             lower=False,
                                             overwrite_c=inplace)
            chol_cov = None
            if info != 0:
                raise RuntimeError('dlauum failed with error code ' +
                                   str(info))
            result = np.rot90(result, 2)

        result = np.asfortranarray(result)

        #make sure guaranteed to change _internal_mat if inplace was true
        if inplace:
            self._internal_mat = result
            self.internal_state = REP_COVAR

        #make sure symmetric if not for internal use by FisherMatrix
        if not internal:
            result = mirror_symmetrize(result, lower=True, inplace=True)

        if copy_output:
            return result.copy()
        else:
            return result
Пример #4
0
def test_mirror_symmetrize(test_mat):
    """test cleaning matrix to be triangular"""
    #A should already be symmetric, so test on the non symmetric triangles
    A = test_mat.A.copy()
    AHL = np.tril(A.copy())
    AHU = np.triu(A.copy())
    AL1 = mirror_symmetrize(A.copy(),lower=True,inplace=False)
    AL2 = mirror_symmetrize(A.copy(),lower=True,inplace=True)
    AL3 = mirror_symmetrize(AHL.copy(),lower=True,inplace=False)
    AL4 = mirror_symmetrize(AHL.copy(),lower=True,inplace=True)
    AL5 = mirror_symmetrize(AHU.copy(),lower=True,inplace=False)
    AL6 = mirror_symmetrize(AHU.copy(),lower=True,inplace=True)
    assert np.all(AL1==AL1.T)
    assert np.all(AL2==AL2.T)
    assert np.all(AL3==AL3.T)
    assert np.all(AL4==AL4.T)
    assert np.all(AL5==AL5.T)
    assert np.all(AL6==AL6.T)
    assert np.all(np.tril(AL1)==np.tril(A))
    assert np.all(np.tril(AL2)==np.tril(A))
    assert np.all(np.tril(AL3)==np.tril(AHL))
    assert np.all(np.tril(AL4)==np.tril(AHL))
    assert np.all(np.tril(AL5)==np.tril(AHU))
    assert np.all(np.tril(AL6)==np.tril(AHU))
    AU1 = mirror_symmetrize(A.copy(),lower=False,inplace=False)
    AU2 = mirror_symmetrize(A.copy(),lower=False,inplace=True)
    AU3 = mirror_symmetrize(AHL.copy(),lower=False,inplace=False)
    AU4 = mirror_symmetrize(AHL.copy(),lower=False,inplace=True)
    AU5 = mirror_symmetrize(AHU.copy(),lower=False,inplace=False)
    AU6 = mirror_symmetrize(AHU.copy(),lower=False,inplace=True)
    assert np.all(AU1==AU1.T)
    assert np.all(AU2==AU2.T)
    assert np.all(AU3==AU3.T)
    assert np.all(AU4==AU4.T)
    assert np.all(AU5==AU5.T)
    assert np.all(AU6==AU6.T)
    assert np.all(np.triu(AU1)==np.triu(A))
    assert np.all(np.triu(AU2)==np.triu(A))
    assert np.all(np.triu(AU3)==np.triu(AHL))
    assert np.all(np.triu(AU4)==np.triu(AHL))
    assert np.all(np.triu(AU5)==np.triu(AHU))
    assert np.all(np.triu(AU6)==np.triu(AHU))
Пример #5
0
    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 mirror_symmetrize(covar_result, lower=True,
                                 inplace=True), mirror_symmetrize(mit_result,
                                                                  lower=True,
                                                                  inplace=True)
Пример #6
0
    def contract_fisher(self,
                        v1,
                        v2,
                        identical_inputs=False,
                        return_fisher=False,
                        destructive=False):
        """calculates (v1.T).Fisher matrix.v2 for getting variance/projecting to another basis
            inputs:
                v1,v2: vectors with one dimension aligned with _internal_mat
                identical_inputs: if True, assume v2=v1 and ignore v2 completely
                return_fisher: if True, return a FisherMatrix object
                destructive: if True, destroy the internal representation of self for a performance gain
        """
        if not self.silent:
            print("FisherMatrix " + str(id(self)) + ": contracting fisher")

        if return_fisher and not identical_inputs:
            raise ValueError(
                'cannot get FisherMatrix object if inputs not identical')

        if self.internal_state == REP_FISHER:
            if identical_inputs:
                right_res = spl.blas.dsymm(1.,
                                           self._internal_mat,
                                           v1,
                                           lower=True)
            else:
                right_res = spl.blas.dsymm(1.,
                                           self._internal_mat,
                                           v2,
                                           lower=True)
            if destructive:
                self._internal_mat = None
            result = np.dot(v1.T, right_res)
            right_res = None
            if identical_inputs and not return_fisher:
                result = mirror_symmetrize(result, lower=True, inplace=True)
        else:
            if self.internal_state == REP_COVAR:
                chol_cov = self.get_cov_cholesky(copy_output=False,
                                                 inplace=destructive,
                                                 internal=True)
                if destructive:
                    self._internal_mat = None
                res1 = spl.solve_triangular(chol_cov,
                                            v1,
                                            lower=True,
                                            check_finite=DEBUG)
                if not identical_inputs:
                    res2 = spl.solve_triangular(chol_cov,
                                                v2,
                                                lower=True,
                                                check_finite=DEBUG)
                chol_cov = None
            elif self.internal_state == REP_CHOL_INV:
                res1 = spl.blas.dtrmm(1.,
                                      self._internal_mat,
                                      v1,
                                      lower=True,
                                      trans_a=False)
                if not identical_inputs:
                    res2 = spl.blas.dtrmm(1.,
                                          self._internal_mat,
                                          v2,
                                          lower=True,
                                          trans_a=False)
            elif self.internal_state == REP_CHOL:
                res1 = spl.solve_triangular(self._internal_mat,
                                            v1,
                                            lower=True,
                                            check_finite=DEBUG)
                if not identical_inputs:
                    res2 = spl.solve_triangular(self._internal_mat,
                                                v2,
                                                lower=True,
                                                check_finite=DEBUG)
            else:
                raise ValueError('unknown internal state ' +
                                 str(self.internal_state))

            if destructive:
                self._internal_mat = None

            if identical_inputs:
                result = spl.blas.dsyrk(1.,
                                        np.asfortranarray(res1),
                                        lower=True,
                                        trans=True,
                                        overwrite_c=True)
                res1 = None
                if not return_fisher:
                    result = mirror_symmetrize(result,
                                               lower=True,
                                               inplace=True)
            else:
                result = np.dot(res1.T, res2)
                res1 = None
                res2 = None
        if destructive:
            self._internal_mat = None

        if return_fisher:
            return FisherMatrix(result,
                                input_type=REP_FISHER,
                                initial_state=REP_FISHER,
                                fix_input=False,
                                silent=self.silent)
        else:
            return result