コード例 #1
0
 def forward(ctx, A):
     U = torch.tensor(cholesky_banded(A.data.numpy()))
     for i in range(M - 1):
         for j in range(M - 1 - i):
             U[i, j] = 0
     ctx.save_for_backward(A, U)
     return U
コード例 #2
0
ファイル: ar1_posterior.py プロジェクト: afcarl/arfit
    def log_likelihood(self, p):
        r"""Returns the log of the likelihood for the stored data given
        parameters ``p``.  The likelihood is computed in time
        proportional to :math:`\mathcal{O}(N)`, where :math:`N` is the
        number of data samples.

        """
        p = self.to_params(p)

        alphas, betas = self._alphas_betas(p)
        bc = self._banded_covariance(p)

        ys = self.ys.copy() - p['mu']
        ys[1:] = ys[1:] - alphas*ys[0:-1]

        dts = self.ts.reshape((-1, 1)) - self.ts.reshape((1, -1))
        tau = np.exp(p['lntau'])
        nu = self._inv_logit(p['logitnu'])
        sigma = np.exp(p['lnsigma'])
        full_cov = sigma*sigma*((1-nu)*np.exp(-np.abs(dts)/tau) + nu)

        llow = sl.cholesky_banded(bc, lower=True)

        logdet = np.sum(np.log(llow[0, :]))

        return -0.5*self.ts.shape[0]*np.log(2.0*np.pi) - logdet - 0.5*np.dot(ys, sl.cho_solve_banded((llow, True), ys))
コード例 #3
0
ファイル: Bspline.py プロジェクト: geoffcfchen/KCWI_DRP
def cholesky_band(ndl, mininf=0.0):
    """Compute *lower* Cholesky decomposition of a banded matrix.

    This function provides informative error messages to pass back to the
    :class:`~pydl.pydlutils.bspline.Bspline` machinery; the actual
    computation is delegated to :func:`scipy.linalg.cholesky_banded`.

    Parameters
    ----------
    ndl : :class:`numpy.ndarray`
        A matrix on which to perform the Cholesky decomposition.  The
        matrix must be in a special, *lower* form described in
        :func:`scipy.linalg.cholesky_banded`.  In addition, the input
        must be padded.  If the original, square matrix has size
        :math:`N \\times N`, and the width of the band is :math:`b`,
        `l` must be :math:`b \\times (N + b)`.
    mininf : :class:`float`, optional
        Entries in the `l` matrix are considered negative if they are less
        than this value (default 0.0).

    Returns
    -------
    :func:`tuple`
        If problems were detected, the first item will be the index or
        indexes where the problem was detected, and the second item will simply
        be the input matrix.  If no problems were detected, the first item
        will be -1, and the second item will be the Cholesky decomposition.
    """
    bw, nn = ndl.shape
    n = nn - bw
    negative = ndl[0, 0:n] <= mininf
    if negative.any() or not np.all(np.isfinite(ndl)):
        warn('Bad entries: ' + str(negative.nonzero()[0]),
             PydlutilsUserWarning)
        return negative.nonzero()[0], ndl
    try:
        lower = cholesky_banded(ndl[:, 0:n], lower=True)
    except LinAlgError:
        #
        # Figure out where the error is.
        #
        lower = ndl.copy()
        kn = bw - 1
        spot = np.arange(kn, dtype='i4') + 1
        for j in range(n):
            lower[0, j] = np.sqrt(lower[0, j])
            lower[spot, j] /= lower[0, j]
            x = lower[spot, j]
            if not np.all(np.isfinite(x)):
                warn('NaN found in cholesky_band.', PydlutilsUserWarning)
                return j, ndl
    #
    # Restore padding.
    #
    ll = np.zeros(ndl.shape, dtype=ndl.dtype)
    ll[:, 0:n] = lower
    return -1, ll
コード例 #4
0
ファイル: test_utils.py プロジェクト: vishalbelsare/pylds
def test_sample_block_tridiag():
    n, d = 10, 3
    for _ in range(5):
        H_diag, H_upper_diag = random_symm_block_tridiags(n, d)
        H = symm_block_tridiags_to_dense(H_diag, H_upper_diag)

        # Make sure H is positive definite
        min_ev = np.linalg.eigvalsh(H).min()
        if min_ev < 0:
            for i in range(n):
                H_diag[i] += (-min_ev + .1) * np.eye(d)
            H += (-min_ev + .1) * np.eye(n * d)
        assert np.allclose(H, symm_block_tridiags_to_dense(H_diag, H_upper_diag))
        assert np.all(np.linalg.eigvalsh(H) > 0)

        # Cholesky of H
        from scipy.linalg import cholesky_banded, solve_banded
        L1 = np.linalg.cholesky(H)
        Lab = convert_block_tridiag_to_banded(H_diag, H_upper_diag)
        L2 = cholesky_banded(Lab, lower=True)
        assert np.allclose(np.diag(L1), L2[0])
        for i in range(1, 2*d):
            assert np.allclose(np.diag(L1, -i), L2[i, :-i])

        U1 = L1.T
        U2 = transpose_lower_banded_matrix(L2)
        Uab = convert_block_tridiag_to_banded(H_diag, H_upper_diag, lower=False)
        U3 = cholesky_banded(Uab, lower=False)
        assert np.allclose(np.diag(U1), U2[-1])
        assert np.allclose(np.diag(U1), U3[-1])
        for i in range(1, 2 * d):
            assert np.allclose(np.diag(U1, i), U2[-(i+1), i:])
            assert np.allclose(np.diag(U1, i), U3[-(i+1), i:])

        z = np.random.randn(n*d)
        x1 = np.linalg.solve(U1, z)
        x2 = solve_banded((0, 2*d-1), U2, z)
        x3 = scipy_sample_block_tridiag(H_diag, H_upper_diag, z=z)
        assert np.allclose(x1, x2)
        assert np.allclose(x1, x3)
        print("success")
コード例 #5
0
ファイル: util.py プロジェクト: vishalbelsare/pylds
def scipy_sample_block_tridiag(H_diag, H_upper_diag, size=1, ab=None, z=None):
    from scipy.linalg import cholesky_banded, solve_banded

    ab = convert_block_tridiag_to_banded(H_diag, H_upper_diag, lower=False) \
        if ab is None else ab

    Uab = cholesky_banded(ab, lower=False)
    z = np.random.randn(ab.shape[1], size) if z is None else z

    # If lower = False, we have (U^T U)^{-1} = U^{-1} U^{-T} = AA^T = Sigma
    # where A = U^{-1}.  Samples are Az = U^{-1}z = x, or equivalently Ux = z.
    return solve_banded((0, Uab.shape[0] - 1), Uab, z)
コード例 #6
0
ファイル: quadratic.py プロジェクト: gmelikian/regreg
 def __init__(self, Q, cholesky=None, banded=False):
     self.primal_shape = Q.shape[0]
     self.dual_shape = Q.shape[0]
     self.affine_offset = None
     self._Q = Q
     self.banded = banded
     if cholesky is None:
         if not self.banded:
             self._cholesky = cho_factor(Q)
         else:
             self._cholesky = cholesky_banded(Q)
     else:
         self._cholesky = cholesky
コード例 #7
0
ファイル: quadratic.py プロジェクト: matthew-brett/regreg
 def __init__(self, Q, cholesky=None, banded=False):
     self.input_shape = Q.shape[0]
     self.output_shape = Q.shape[0]
     self.affine_offset = None
     self._Q = Q
     self.banded = banded
     if cholesky is None:
         if not self.banded:
             self._cholesky = cho_factor(Q)
         else:
             self._cholesky = cholesky_banded(Q)
     else:
         self._cholesky = cholesky
コード例 #8
0
    def test_lower_real(self):
        # Symmetric positive definite banded matrix `a`
        a = array([[4.0, 1.0, 0.0, 0.0], [1.0, 4.0, 0.5, 0.0], [0.0, 0.5, 4.0, 0.2], [0.0, 0.0, 0.2, 4.0]])
        # Banded storage form of `a`.
        ab = array([[4.0, 4.0, 4.0, 4.0], [1.0, 0.5, 0.2, -1.0]])
        c = cholesky_banded(ab, lower=True)
        lfac = zeros_like(a)
        lfac[list(range(4)), list(range(4))] = c[0]
        lfac[(1, 2, 3), (0, 1, 2)] = c[1, :3]
        assert_array_almost_equal(a, dot(lfac, lfac.T))

        b = array([0.0, 0.5, 4.2, 4.2])
        x = cho_solve_banded((c, True), b)
        assert_array_almost_equal(x, [0.0, 0.0, 1.0, 1.0])
コード例 #9
0
    def test_lower_complex(self):
        # Hermitian positive definite banded matrix `a`
        a = array([[4.0, 1.0, 0.0, 0.0], [1.0, 4.0, 0.5, 0.0], [0.0, 0.5, 4.0, -0.2j], [0.0, 0.0, 0.2j, 4.0]])
        # Banded storage form of `a`.
        ab = array([[4.0, 4.0, 4.0, 4.0], [1.0, 0.5, 0.2j, -1.0]])
        c = cholesky_banded(ab, lower=True)
        lfac = zeros_like(a)
        lfac[list(range(4)), list(range(4))] = c[0]
        lfac[(1, 2, 3), (0, 1, 2)] = c[1, :3]
        assert_array_almost_equal(a, dot(lfac, lfac.conj().T))

        b = array([0.0, 0.5j, 3.8j, 3.8])
        x = cho_solve_banded((c, True), b)
        assert_array_almost_equal(x, [0.0, 0.0, 1.0j, 1.0])
コード例 #10
0
    def test_upper_real(self):
        # Symmetric positive definite banded matrix `a`
        a = array([[4.0, 1.0, 0.0, 0.0], [1.0, 4.0, 0.5, 0.0], [0.0, 0.5, 4.0, 0.2], [0.0, 0.0, 0.2, 4.0]])
        # Banded storage form of `a`.
        ab = array([[-1.0, 1.0, 0.5, 0.2], [4.0, 4.0, 4.0, 4.0]])
        c = cholesky_banded(ab, lower=False)
        ufac = zeros_like(a)
        ufac[list(range(4)), list(range(4))] = c[-1]
        ufac[(0, 1, 2), (1, 2, 3)] = c[0, 1:]
        assert_array_almost_equal(a, dot(ufac.T, ufac))

        b = array([0.0, 0.5, 4.2, 4.2])
        x = cho_solve_banded((c, False), b)
        assert_array_almost_equal(x, [0.0, 0.0, 1.0, 1.0])
コード例 #11
0
    def test_upper_complex(self):
        # Hermitian positive definite banded matrix `a`
        a = array([[4.0, 1.0, 0.0, 0.0], [1.0, 4.0, 0.5, 0.0],
                   [0.0, 0.5, 4.0, -0.2j], [0.0, 0.0, 0.2j, 4.0]])
        # Banded storage form of `a`.
        ab = array([[-1.0, 1.0, 0.5, -0.2j], [4.0, 4.0, 4.0, 4.0]])
        c = cholesky_banded(ab, lower=False)
        ufac = zeros_like(a)
        ufac[range(4), range(4)] = c[-1]
        ufac[(0, 1, 2), (1, 2, 3)] = c[0, 1:]
        assert_array_almost_equal(a, dot(ufac.conj().T, ufac))

        b = array([0.0, 0.5, 4.0 - 0.2j, 0.2j + 4.0])
        x = cho_solve_banded((c, False), b)
        assert_array_almost_equal(x, [0.0, 0.0, 1.0, 1.0])
コード例 #12
0
    def test_lower_real(self):
        # Symmetric positive definite banded matrix `a`
        a = array([[4.0, 1.0, 0.0, 0.0], [1.0, 4.0, 0.5, 0.0],
                   [0.0, 0.5, 4.0, 0.2], [0.0, 0.0, 0.2, 4.0]])
        # Banded storage form of `a`.
        ab = array([[4.0, 4.0, 4.0, 4.0], [1.0, 0.5, 0.2, -1.0]])
        c = cholesky_banded(ab, lower=True)
        lfac = zeros_like(a)
        lfac[list(range(4)), list(range(4))] = c[0]
        lfac[(1, 2, 3), (0, 1, 2)] = c[1, :3]
        assert_array_almost_equal(a, dot(lfac, lfac.T))

        b = array([0.0, 0.5, 4.2, 4.2])
        x = cho_solve_banded((c, True), b)
        assert_array_almost_equal(x, [0.0, 0.0, 1.0, 1.0])
コード例 #13
0
    def test_lower_complex(self):
        # Hermitian positive definite banded matrix `a`
        a = array([[4.0, 1.0, 0.0, 0.0], [1.0, 4.0, 0.5, 0.0],
                   [0.0, 0.5, 4.0, -0.2j], [0.0, 0.0, 0.2j, 4.0]])
        # Banded storage form of `a`.
        ab = array([[4.0, 4.0, 4.0, 4.0], [1.0, 0.5, 0.2j, -1.0]])
        c = cholesky_banded(ab, lower=True)
        lfac = zeros_like(a)
        lfac[list(range(4)), list(range(4))] = c[0]
        lfac[(1, 2, 3), (0, 1, 2)] = c[1, :3]
        assert_array_almost_equal(a, dot(lfac, lfac.conj().T))

        b = array([0.0, 0.5j, 3.8j, 3.8])
        x = cho_solve_banded((c, True), b)
        assert_array_almost_equal(x, [0.0, 0.0, 1.0j, 1.0])
コード例 #14
0
    def test_upper_real(self):
        # Symmetric positive definite banded matrix `a`
        a = array([[4.0, 1.0, 0.0, 0.0], [1.0, 4.0, 0.5, 0.0],
                   [0.0, 0.5, 4.0, 0.2], [0.0, 0.0, 0.2, 4.0]])
        # Banded storage form of `a`.
        ab = array([[-1.0, 1.0, 0.5, 0.2], [4.0, 4.0, 4.0, 4.0]])
        c = cholesky_banded(ab, lower=False)
        ufac = zeros_like(a)
        ufac[list(range(4)), list(range(4))] = c[-1]
        ufac[(0, 1, 2), (1, 2, 3)] = c[0, 1:]
        assert_array_almost_equal(a, dot(ufac.T, ufac))

        b = array([0.0, 0.5, 4.2, 4.2])
        x = cho_solve_banded((c, False), b)
        assert_array_almost_equal(x, [0.0, 0.0, 1.0, 1.0])
コード例 #15
0
ファイル: dps.py プロジェクト: anassBelcaid/MyPython
def gemanPriorMatrix(lam,size,factorized=True):
	"""
	generate the banded compressed truncated matrix
	:param self  :
	:param lam   : regularization
	:param size  : size of the matrix
	:return:
	"""
	lam2=lam*lam;
	Ab=np.zeros((2,size));
	Ab[0,0]=1+lam2; Ab[0,size-1]=1+lam2;
	Ab[0,1:-1]=1+2*lam2;
	Ab[1,:]=-lam2;
	if(not factorized):
		return Ab;
	else:
		Ab=linAlg.cholesky_banded(Ab,overwrite_ab=True,lower=True);
		return Ab;
コード例 #16
0
ファイル: test_decomp_cholesky.py プロジェクト: 87/scipy
    def test_upper_complex(self):
        # Hermitian positive definite banded matrix `a`
        a = array([[4.0, 1.0,  0.0,  0.0],
                    [1.0, 4.0,  0.5,  0.0],
                    [0.0, 0.5,  4.0, -0.2j],
                    [0.0, 0.0,  0.2j, 4.0]])
        # Banded storage form of `a`.
        ab = array([[-1.0, 1.0, 0.5, -0.2j],
                     [4.0, 4.0, 4.0,  4.0]])
        c = cholesky_banded(ab, lower=False)
        ufac = zeros_like(a)
        ufac[range(4),range(4)] = c[-1]
        ufac[(0,1,2),(1,2,3)] = c[0,1:]
        assert_array_almost_equal(a, dot(ufac.conj().T, ufac))

        b = array([0.0, 0.5, 4.0-0.2j, 0.2j + 4.0])
        x = cho_solve_banded((c, False), b)
        assert_array_almost_equal(x, [0.0, 0.0, 1.0, 1.0])
コード例 #17
0
    def __init__(self, model, Bdata, sigo_squared, window, obsloc, Cb):
        """Initializes the class object to the specified inputs.

        Descriptions of each data member is provided in the comments
        above.

        """
        self.model = model
        self.Bdata = Bdata
        self.sigo_squared = sigo_squared
        self.window = window
        self.obsloc = obsloc
        self.Cb = Cb

        # Computation of data members derived from arguments
        self.sqrtCb = la.cholesky_banded(Cb, lower=True)
        self.nobs = len(obsloc[0])
        self.sigo = np.sqrt(sigo_squared)
コード例 #18
0
ファイル: operators.py プロジェクト: nbarbey/linear_operators
    def cholesky(self, overwrite_ab=False):
        """
        Chlesky decomposition.
        Operator needs to be positive-definite.

        Uses scipy.linalg.cholesky_banded.

        Returns a matrix in ab form
        """
        from scipy.linalg import cholesky_banded

        ab_chol = cholesky_banded(self.ab,
                                  overwrite_ab=overwrite_ab,
                                  lower=self.lower)
        if self.lower:
            out = LowerTriangularOperator(self.shape, ab_chol, **self.kwargs)
        else:
            out = UpperTriangularOperator(self.shape, ab_chol, **self.kwargs)
        return out
コード例 #19
0
ファイル: operators.py プロジェクト: nbarbey/linear_operators
    def cholesky(self, overwrite_ab=False):
        """
        Chlesky decomposition.
        Operator needs to be positive-definite.

        Uses scipy.linalg.cholesky_banded.

        Returns a matrix in ab form
        """
        from scipy.linalg import cholesky_banded

        ab_chol = cholesky_banded(self.ab,
                               overwrite_ab=overwrite_ab,
                               lower=self.lower)
        if self.lower:
            out = LowerTriangularOperator(self.shape, ab_chol, **self.kwargs)
        else:
            out = UpperTriangularOperator(self.shape, ab_chol, **self.kwargs)
        return out
コード例 #20
0
ファイル: ode_solve.py プロジェクト: mokhairy2019/Kratos
    def __init__(self, grid, coef):
        self.coef = coef
        self.grid = grid
        self.qp = self.quadrature_points()
        # self.t=t

        # create functions which return the coefficients in the operator
        term_M1 = self._term_M1(self.coef)
        term_M2 = self._term_M2(self.coef)
        term_D1 = self._term_D1(self.coef)
        term_D2 = self._term_D2(self.coef)
        term_D0 = self._term_D0(self.coef)
        # create the matrices from the coefficient functions
        self.M1 = self.mass_matrix(term_M1)
        self.M2 = self.mass_matrix(term_M2)
        self.D1 = self.crossterm_diffusion_matrix(term_D1)
        self.D2 = self.crossterm_diffusion_matrix(term_D2)
        self.D0 = self.diffusion_matrix(term_D0)
        self.L2_vec = self.coef(self.grid[:])**(17 / 6)
        self.sqrtM = cholesky_banded(self.M1[1:, :], lower=True)
コード例 #21
0
    def _choleskify(n: int, k: Tuple[int], ρ: Tuple[np.float64]) -> np.ndarray:
        """cholesky decomposition needed for linear solves in trend estimate.

        Args:
            n: number of points in signal
            k: tuple of integer trend filter orders
            ρ: ADMM parameter for each order in k

        Returns:
            Cholesky decomposition
        """
        DTD = TrendFilter._D_DTD(n, k)[1]
        A = np.eye(n) + sum(ρ[i] * DTD[i] for i in range(len(k)))
        # A is a banded Hermitian positive definite matrix with upper/lower
        # bandwidth bw. Express in upper diagonal ordered form
        bw = max(k)
        Ab = np.zeros((bw + 1, A.shape[1]))
        for u in range(bw + 1):
            Ab[-(1 + u), u:] = np.diag(A, k=u)

        return cholesky_banded(Ab, check_finite=False)
コード例 #22
0
ファイル: dps.py プロジェクト: anassBelcaid/MyPython
def LpMatrix(lp,lam,factorized=True):
    """
    compute the banded compressed dps matrix for a given line process
    :param lp: numpy array representing the line process
    :param lam: characteristic lenth
    : factorisze: if the function should return the factorized version or not
    """
    lam2=lam*lam;
    size=len(lp)+1;
    Ab=np.zeros((2,size));
    #adding the ones for the  matrix
    Ab[0,:]=1;
    for (i,l) in enumerate(lp):
        if(not l):
            Ab[1,i]-=lam2;
            Ab[0,i]+=lam2;
            Ab[0,i+1]+=lam2;
    if(not factorized):
        return Ab;
    else:
        Ab=linAlg.cholesky_banded(Ab,overwrite_ab=True,lower=True)
        return Ab;
コード例 #23
0
def influence_matrix_diag_chol(p, Q, R, y, w, N):
    ## Following Hutchinson & de Hoog 1985:
    #LDL factorization of Bp = 6*(1-p)*QT*D2*QT' + p*R
    D2 = sparse.diags(1./np.sqrt(w), 0, shape=(N,N))
    Bp = 6*(1-p) * Q.T*D2*Q + p*R
    Bp = Bp.todia()
    u = la.cholesky_banded(Bp.data[Bp.offsets >= 0][::-1])
    U = sparse.dia_matrix((u, Bp.offsets[Bp.offsets >= 0][::-1]), Bp.shape)
    ## may fail as the input is sparse (if so use todense), need testing
    #U = la.cholesky(A , lower=False)
    ## To get from ut u -> Ut D U:
    ## U you are looking for is the above matrix with diagonal elements
    ## replaced by 1, and D is the diagonal matrix whose diagonal elements are 
    ## the squares of the diagonal elements in the above matrix.
    d = 1./u[-1]
    U = sparse.diags(d, 0, shape=U.shape)*U
    d = d**2
    ## TODO: this should probably change...
    #5 central bands in the inverse of 6*(1-p)*QT*diag(1 ./ w)*QT' + p*R
    Binv = banded_matrix_inverse(d, U, 2)
    Hd = np.diag( sparse.eye(N,N) - (6*(1-p))*D2*Q*Binv*Q.T )
    return Hd
コード例 #24
0
def influence_matrix_diag_chol(p, Q, R, y, w, N):
    ## Following Hutchinson & de Hoog 1985:
    #LDL factorization of Bp = 6*(1-p)*QT*D2*QT' + p*R
    D2 = sparse.diags(1. / np.sqrt(w), 0, shape=(N, N))
    Bp = 6 * (1 - p) * Q.T * D2 * Q + p * R
    Bp = Bp.todia()
    u = la.cholesky_banded(Bp.data[Bp.offsets >= 0][::-1])
    U = sparse.dia_matrix((u, Bp.offsets[Bp.offsets >= 0][::-1]), Bp.shape)
    ## may fail as the input is sparse (if so use todense), need testing
    #U = la.cholesky(A , lower=False)
    ## To get from ut u -> Ut D U:
    ## U you are looking for is the above matrix with diagonal elements
    ## replaced by 1, and D is the diagonal matrix whose diagonal elements are
    ## the squares of the diagonal elements in the above matrix.
    d = 1. / u[-1]
    U = sparse.diags(d, 0, shape=U.shape) * U
    d = d**2
    ## TODO: this should probably change...
    #5 central bands in the inverse of 6*(1-p)*QT*diag(1 ./ w)*QT' + p*R
    Binv = banded_matrix_inverse(d, U, 2)
    Hd = np.diag(sparse.eye(N, N) - (6 * (1 - p)) * D2 * Q * Binv * Q.T)
    return Hd
コード例 #25
0
    def whitened_residuals(self, p):
        r"""Returns an array of the same shape as the input data, but whose
        values are indepenent :math:`N(0,1)` variables under the model
        with parameters ``p``.

        """
        p = self.to_params(p)

        alpha = self._alpha_matrix(p)
        beta = self._beta_matrix(p)

        xs = np.zeros(self.n)

        al.log_likelihood_xs_loop(self.n, self.p, alpha, self.ys - p['mu'], xs)

        beta12 = sl.cholesky_banded(beta, lower=False)
        beta12T = np.zeros((self.p, self.n))

        for i in range(self.p):
            beta12T[-(i+1), :self.n-self.p+1+i] = beta12[i, self.p-1-i:]

        return sl.solve_banded((self.p-1, 0), beta12T, xs)
コード例 #26
0
ファイル: dps.py プロジェクト: anassBelcaid/MyPython
def gemanDiscontMatrix(lam,size,position):
        """
        return the same matrix but considering position as a discontinuity
        :param lam:
        :param size:
        :param position: position of the discontinuity
        :return:
        """
        lam2 = lam * lam;
        Ab = np.zeros((2, size));
        Ab[0, 0] = 1 + lam2;
        Ab[0, size - 1] = 1+lam2;
        Ab[0, 1:-1] = 1 + 2 * lam2;
        Ab[1, :] = -lam2;

        #adding the discontinuity
        Ab[1,position]=0;
        Ab[0,position]-=lam2;
        Ab[0,position+1]-=lam2;

        Ab=linAlg.cholesky_banded(Ab, overwrite_ab=True, lower=True);

        return Ab;
コード例 #27
0
    L = np.triu(L, -(M - 1))
    mat = L @ L.T

    banded_mat = np.zeros([M, N])
    for i in range(M):
        banded_mat[(M - 1 - i), i:] = mat[range(N - i), range(i, N)]

    gradcheck(gbtrf, (torch.tensor(banded_mat, requires_grad=True), ),
              eps=1e-6,
              atol=1e-4)

    N = 10000000
    M = 4

    A = np.zeros([M, N])
    for od in range(M):
        A[M - od - 1, :] = 2**(-od)

    U = cholesky_banded(A)
    dA = np.zeros_like(A)
    dU = np.random.randn(*A.shape)
    dUp = np.copy(dU)

    inner(A, U, dA, dU, dUp)

    start = time.time()
    #U = cholesky_banded(A)
    inner(A, U, dA, dU, dUp)
    end = time.time()
    print("Elapsed (after compilation) = %s" % (end - start))
コード例 #28
0
ファイル: test_decomp_cholesky.py プロジェクト: 87/scipy
 def test_cho_solve_banded(self):
     x = array([[0, -1, -1], [2, 2, 2]])
     xcho = cholesky_banded(x)
     assert_no_overwrite(lambda b: cho_solve_banded((xcho, False), b),
                         [(3,)])
コード例 #29
0
ファイル: _bsplines.py プロジェクト: Eric89GXL/scipy
def make_lsq_spline(x, y, t, k=3, w=None, axis=0, check_finite=True):
    r"""Compute the (coefficients of) an LSQ B-spline.

    The result is a linear combination

    .. math::

            S(x) = \sum_j c_j B_j(x; t)

    of the B-spline basis elements, :math:`B_j(x; t)`, which minimizes

    .. math::

        \sum_{j} \left( w_j \times (S(x_j) - y_j) \right)^2

    Parameters
    ----------
    x : array_like, shape (m,)
        Abscissas.
    y : array_like, shape (m, ...)
        Ordinates.
    t : array_like, shape (n + k + 1,).
        Knots.
        Knots and data points must satisfy Schoenberg-Whitney conditions.
    k : int, optional
        B-spline degree. Default is cubic, k=3.
    w : array_like, shape (n,), optional
        Weights for spline fitting. Must be positive. If ``None``,
        then weights are all equal.
        Default is ``None``.
    axis : int, optional
        Interpolation axis. Default is zero.
    check_finite : bool, optional
        Whether to check that the input arrays contain only finite numbers.
        Disabling may give a performance gain, but may result in problems
        (crashes, non-termination) if the inputs do contain infinities or NaNs.
        Default is True.

    Returns
    -------
    b : a BSpline object of the degree `k` with knots `t`.

    Notes
    -----

    The number of data points must be larger than the spline degree `k`.

    Knots `t` must satisfy the Schoenberg-Whitney conditions,
    i.e., there must be a subset of data points ``x[j]`` such that
    ``t[j] < x[j] < t[j+k+1]``, for ``j=0, 1,...,n-k-2``.

    Examples
    --------
    Generate some noisy data:

    >>> x = np.linspace(-3, 3, 50)
    >>> y = np.exp(-x**2) + 0.1 * np.random.randn(50)

    Now fit a smoothing cubic spline with a pre-defined internal knots.
    Here we make the knot vector (k+1)-regular by adding boundary knots:

    >>> from scipy.interpolate import make_lsq_spline, BSpline
    >>> t = [-1, 0, 1]
    >>> k = 3
    >>> t = np.r_[(x[0],)*(k+1),
    ...           t,
    ...           (x[-1],)*(k+1)]
    >>> spl = make_lsq_spline(x, y, t, k)

    For comparison, we also construct an interpolating spline for the same
    set of data:

    >>> from scipy.interpolate import make_interp_spline
    >>> spl_i = make_interp_spline(x, y)

    Plot both:

    >>> import matplotlib.pyplot as plt
    >>> xs = np.linspace(-3, 3, 100)
    >>> plt.plot(x, y, 'ro', ms=5)
    >>> plt.plot(xs, spl(xs), 'g-', lw=3, label='LSQ spline')
    >>> plt.plot(xs, spl_i(xs), 'b-', lw=3, alpha=0.7, label='interp spline')
    >>> plt.legend(loc='best')
    >>> plt.show()

    **NaN handling**: If the input arrays contain ``nan`` values, the result is
    not useful since the underlying spline fitting routines cannot deal with
    ``nan``. A workaround is to use zero weights for not-a-number data points:

    >>> y[8] = np.nan
    >>> w = np.isnan(y)
    >>> y[w] = 0.
    >>> tck = make_lsq_spline(x, y, t, w=~w)

    Notice the need to replace a ``nan`` by a numerical value (precise value
    does not matter as long as the corresponding weight is zero.)

    See Also
    --------
    BSpline : base class representing the B-spline objects
    make_interp_spline : a similar factory function for interpolating splines
    LSQUnivariateSpline : a FITPACK-based spline fitting routine
    splrep : a FITPACK-based fitting routine

    """
    x = _as_float_array(x, check_finite)
    y = _as_float_array(y, check_finite)
    t = _as_float_array(t, check_finite)
    if w is not None:
        w = _as_float_array(w, check_finite)
    else:
        w = np.ones_like(x)
    k = operator.index(k)

    if not -y.ndim <= axis < y.ndim:
        raise ValueError("axis {} is out of bounds".format(axis))
    if axis < 0:
        axis += y.ndim

    y = np.rollaxis(y, axis)    # now internally interp axis is zero

    if x.ndim != 1 or np.any(x[1:] - x[:-1] <= 0):
        raise ValueError("Expect x to be a 1-D sorted array_like.")
    if x.shape[0] < k+1:
        raise ValueError("Need more x points.")
    if k < 0:
        raise ValueError("Expect non-negative k.")
    if t.ndim != 1 or np.any(t[1:] - t[:-1] < 0):
        raise ValueError("Expect t to be a 1-D sorted array_like.")
    if x.size != y.shape[0]:
        raise ValueError('x & y are incompatible.')
    if k > 0 and np.any((x < t[k]) | (x > t[-k])):
        raise ValueError('Out of bounds w/ x = %s.' % x)
    if x.size != w.size:
        raise ValueError('Incompatible weights.')

    # number of coefficients
    n = t.size - k - 1

    # construct A.T @ A and rhs with A the collocation matrix, and
    # rhs = A.T @ y for solving the LSQ problem  ``A.T @ A @ c = A.T @ y``
    lower = True
    extradim = prod(y.shape[1:])
    ab = np.zeros((k+1, n), dtype=np.float_, order='F')
    rhs = np.zeros((n, extradim), dtype=y.dtype, order='F')
    _bspl._norm_eq_lsq(x, t, k,
                      y.reshape(-1, extradim),
                      w,
                      ab, rhs)
    rhs = rhs.reshape((n,) + y.shape[1:])

    # have observation matrix & rhs, can solve the LSQ problem
    cho_decomp = cholesky_banded(ab, overwrite_ab=True, lower=lower,
                                 check_finite=check_finite)
    c = cho_solve_banded((cho_decomp, lower), rhs, overwrite_b=True,
                         check_finite=check_finite)

    c = np.ascontiguousarray(c)
    return BSpline.construct_fast(t, c, k, axis=axis)
コード例 #30
0
ファイル: qso_fit.py プロジェクト: MeetGandhi/ClaReTi
def qso_engine(time,
               data,
               error,
               ltau=3.,
               lvar=-1.7,
               sys_err=0.,
               return_model=False):
    """Calculates the fit quality of a damped random walk to a qso lightcurve.
    Written by N. Butler ([email protected]), Feb. 2010.
    Version 1.0

    The formalism is from Rybicki & Press (1994; arXiv:comp-gas/9405004)

    Data are modelled with a covariance function
        Lij = 0.5*var*tau*exp(-|time_i-time_j|/tau) .

    Input:
        time - measurement times, typically days
        data - measured magnitudes
        error - uncertainty in measured magnitudes

    Output (dictionary):

        chi2/nu - classical variability measure
        chi2_qso/nu - for goodness of fit given fixed parameters
        chi2_qso/nu_extra - for parameter fitting, add to chi2/nu
        chi^2/nu_NULL - expected chi2/nu for non-qso variable

        signif_qso - significance chi^2/nu<chi^2/nu_NULL (rule out false alarm)
        signif_not_qso - significance chi^2/nu>1 (rule out qso)
        signif_vary - significance that source is variable
        class - resulting source type (ambiguous, not_qso, qso)

        model - time series prediction for each datum given all others (iff return_model==True)
        dmodel - model uncertainty, including uncertainty in data

    Notes:
        T = L^(-1)
        Data variance is D
        Full covariance C^(-1) = (L+D)^(-1) = T [T+D^(-1)]^(-1) D^(-1)
        Code takes advantage of the tridiagonality of T and T+D^(-1)."""

    out_dict = {}
    out_dict['chi2_qso/nu'] = 999
    out_dict['chi2_qso/nu_extra'] = 0.
    out_dict['signif_qso'] = 0.
    out_dict['signif_not_qso'] = 0.
    out_dict['signif_vary'] = 0.
    out_dict['chi2_qso/nu_NULL'] = 0.
    out_dict['chi2/nu'] = 0.
    out_dict['nu'] = 0
    out_dict['model'] = []
    out_dict['dmodel'] = []
    out_dict['class'] = 'ambiguous'

    lvar0 = log10(0.5) + lvar + ltau

    ln = len(data)
    dt = abs(time[1:] - time[:-1])

    # first make sure all dt>0
    g = where(dt > 0.)[0]
    lg = len(g)
    # must have at least 2 data points
    if (lg <= 0):
        return out_dict

    if (return_model):
        model = 1. * data
        dmodel = -1. * error

    if (lg < ln):
        dt = dt[g]
        gg = zeros(lg + 1, dtype='int64')
        gg[1:] = g + 1
        dat = data[gg]
        wt = 1. / (sys_err**2 + error[gg]**2)
        ln = lg + 1
    else:
        dat = 1. * data
        wt = 1. / (sys_err**2 + error**2)

    out_dict['nu'] = ln - 1.
    varx = var(dat)
    dat0 = (dat * wt).sum() / wt.sum()
    out_dict['chi2/nu'] = ((dat - dat0)**2 * wt).sum() / out_dict['nu']

    # define tridiagonal matrix T = L^(-1)
    # sparse matrix form: ab[u + i - j, j] == a[i,j]   i<=j, (here u=1)
    T = zeros((2, ln), dtype='float64')
    arg = dt * exp(-log(10) * ltau)
    ri = exp(-arg)
    ei = 1. / (1. / ri - ri)
    T[0, 1:] = -ei
    T[1, :-1] = 1. + ri * ei
    T[1, 1:] += ri * ei
    T[1, ln - 1] += 1.
    T0 = median(T[1, :])
    T /= T0

    # equation for chi2_qso is [ (dat-x0) T Tp^(-1) D^(-1) (dat-x0) ]  , where Tp=T+D^(-1) and D^(-1)=wt
    fac = exp(log(10) * lvar0) / T0
    Tp = 1. * T
    Tp[1, :] += wt * fac
    # solve Tp*z=y for z (y=wt*dat)
    (Tpc, z) = solveh_banded(Tp, (wt * dat).reshape((1, ln)))
    z = z[0, :]
    (Tpc, z0) = solveh_banded(Tp, wt.reshape((1, ln)))
    z0 = z0[0, :]

    #finally, get u=T*z
    u = T[1, :] * z
    u[1:] += T[0, 1:] * z[:-1]
    u[:-1] += T[0, 1:] * z[1:]
    u0 = T[1, :] * z0
    u0[1:] += T[0, 1:] * z0[:-1]
    u0[:-1] += T[0, 1:] * z0[1:]

    # magnitude offset x0, error = 1./sqrt(u0sum)
    u0sum = u0.sum()
    x0 = u.sum() / u0sum

    # fit statistic
    out_dict['chi2_qso/nu'] = dot(dat - x0, u - u0 * x0) / out_dict['nu']

    # -2*log(likelihood) = chi2_qso + ldet_C + log(u0sum)
    #   first term: use chi2_qso/nu for goodness of fit with fixed parameters;
    #   all terms: use chi2_qso/nu + chi2_qso/nu_extra for fitting with variable parameters
    # get log of determinant for use later
    Tc = cholesky_banded(T)
    ldet_Tp = 2 * log(Tpc[1, :]).sum()
    ldet_T = 2 * log(Tc[1, :]).sum()
    ldet_C = ldet_Tp - ldet_T - log(wt).sum()
    out_dict['chi2_qso/nu_extra'] = (ldet_C + log(u0sum)) / out_dict['nu']

    # get trace of C^(-1) for significance calculation
    Tpm = chol_inverse_diag(Tpc)
    diagC = T[1, :] * wt * Tpm[1, :]
    diagC[:-1] += T[0, 1:] * wt[0:-1] * Tpm[0, 1:]
    diagC[1:] += T[0, 1:] * wt[1:] * Tpm[0, 1:]
    TrC = diagC.sum()

    # significance in sigma units (large means false alarm unlikely)
    # (expected value of chi2_qso under the NULL hypothesis is TrC*varx)
    out_dict['chi2_qso/nu_NULL'] = TrC * varx / out_dict['nu']
    a = ln / 2.
    x = (out_dict['chi2_qso/nu'] + 1.e-8) / (out_dict['chi2_qso/nu_NULL'] +
                                             out_dict['chi2_qso/nu'] + 1.e-8)
    prob = betainc(a, a, x)
    if (prob <= 0):
        lprob = a * log(x) - log(a) + gammaln(2 * a) - 2 * gammaln(a)
    else:
        lprob = log(prob)
    out_dict['signif_qso'] = lprob2sigma(lprob)

    a = ln / 2.
    x = 1. / (1. + out_dict['chi2_qso/nu'])
    prob = betainc(a, a, x)
    if (prob <= 0):
        lprob = a * log(x) - log(a) + gammaln(2 * a) - 2 * gammaln(a)
    else:
        lprob = log(prob)
    out_dict['signif_not_qso'] = lprob2sigma(lprob)

    x = out_dict['chi2/nu'] * out_dict['nu']
    prob = gammaincc(0.5 * out_dict['nu'], 0.5 * x)
    if (prob <= 0):
        lprob = (0.5 * out_dict['nu'] - 1) * log(
            x) - 0.5 * x - 0.5 * out_dict['nu'] * log(2) - gammaln(
                0.5 * out_dict['nu'])
    else:
        lprob = log(prob)
    out_dict['signif_vary'] = lprob2sigma(lprob)

    if (out_dict['signif_vary'] > 3):
        if (out_dict['signif_qso'] > 3):
            out_dict['class'] = 'qso'
        elif (out_dict['signif_not_qso'] > 3):
            out_dict['class'] = 'not_qso'

    # best-fit model for the lightcurve
    if (return_model):
        model[gg] = dat - (u - u0 * x0) / diagC
        dmodel[gg] = 1. / sqrt(diagC)
        out_dict['model'] = model
        out_dict['dmodel'] = dmodel

    return out_dict
コード例 #31
0
def make_lsq_spline(x, y, t, k=3, w=None, axis=0, check_finite=True):
    r"""Compute the (coefficients of) an LSQ B-spline.

    The result is a linear combination

    .. math::

            S(x) = \sum_j c_j B_j(x; t)

    of the B-spline basis elements, :math:`B_j(x; t)`, which minimizes

    .. math::

        \sum_{j} \left( w_j \times (S(x_j) - y_j) \right)^2

    Parameters
    ----------
    x : array_like, shape (m,)
        Abscissas.
    y : array_like, shape (m, ...)
        Ordinates.
    t : array_like, shape (n + k + 1,).
        Knots.
        Knots and data points must satisfy Schoenberg-Whitney conditions.
    k : int, optional
        B-spline degree. Default is cubic, k=3.
    w : array_like, shape (n,), optional
        Weights for spline fitting. Must be positive. If ``None``,
        then weights are all equal.
        Default is ``None``.
    axis : int, optional
        Interpolation axis. Default is zero.
    check_finite : bool, optional
        Whether to check that the input arrays contain only finite numbers.
        Disabling may give a performance gain, but may result in problems
        (crashes, non-termination) if the inputs do contain infinities or NaNs.
        Default is True.

    Returns
    -------
    b : a BSpline object of the degree `k` with knots `t`.

    Notes
    -----

    The number of data points must be larger than the spline degree `k`.

    Knots `t` must satisfy the Schoenberg-Whitney conditions,
    i.e., there must be a subset of data points ``x[j]`` such that
    ``t[j] < x[j] < t[j+k+1]``, for ``j=0, 1,...,n-k-2``.

    Examples
    --------
    Generate some noisy data:

    >>> x = np.linspace(-3, 3, 50)
    >>> y = np.exp(-x**2) + 0.1 * np.random.randn(50)

    Now fit a smoothing cubic spline with a pre-defined internal knots.
    Here we make the knot vector (k+1)-regular by adding boundary knots:

    >>> from scipy.interpolate import make_lsq_spline, BSpline
    >>> t = [-1, 0, 1]
    >>> k = 3
    >>> t = np.r_[(x[0],)*(k+1),
    ...           t,
    ...           (x[-1],)*(k+1)]
    >>> spl = make_lsq_spline(x, y, t, k)

    For comparison, we also construct an interpolating spline for the same
    set of data:

    >>> from scipy.interpolate import make_interp_spline
    >>> spl_i = make_interp_spline(x, y)

    Plot both:

    >>> import matplotlib.pyplot as plt
    >>> xs = np.linspace(-3, 3, 100)
    >>> plt.plot(x, y, 'ro', ms=5)
    >>> plt.plot(xs, spl(xs), 'g-', lw=3, label='LSQ spline')
    >>> plt.plot(xs, spl_i(xs), 'b-', lw=3, alpha=0.7, label='interp spline')
    >>> plt.legend(loc='best')
    >>> plt.show()

    **NaN handling**: If the input arrays contain ``nan`` values, the result is
    not useful since the underlying spline fitting routines cannot deal with
    ``nan``. A workaround is to use zero weights for not-a-number data points:

    >>> y[8] = np.nan
    >>> w = np.isnan(y)
    >>> y[w] = 0.
    >>> tck = make_lsq_spline(x, y, t, w=~w)

    Notice the need to replace a ``nan`` by a numerical value (precise value
    does not matter as long as the corresponding weight is zero.)

    See Also
    --------
    BSpline : base class representing the B-spline objects
    make_interp_spline : a similar factory function for interpolating splines
    LSQUnivariateSpline : a FITPACK-based spline fitting routine
    splrep : a FITPACK-based fitting routine

    """
    x = _as_float_array(x, check_finite)
    y = _as_float_array(y, check_finite)
    t = _as_float_array(t, check_finite)
    if w is not None:
        w = _as_float_array(w, check_finite)
    else:
        w = np.ones_like(x)
    k = operator.index(k)

    axis = normalize_axis_index(axis, y.ndim)

    y = np.rollaxis(y, axis)  # now internally interp axis is zero

    if x.ndim != 1 or np.any(x[1:] - x[:-1] <= 0):
        raise ValueError("Expect x to be a 1-D sorted array_like.")
    if x.shape[0] < k + 1:
        raise ValueError("Need more x points.")
    if k < 0:
        raise ValueError("Expect non-negative k.")
    if t.ndim != 1 or np.any(t[1:] - t[:-1] < 0):
        raise ValueError("Expect t to be a 1-D sorted array_like.")
    if x.size != y.shape[0]:
        raise ValueError('x & y are incompatible.')
    if k > 0 and np.any((x < t[k]) | (x > t[-k])):
        raise ValueError('Out of bounds w/ x = %s.' % x)
    if x.size != w.size:
        raise ValueError('Incompatible weights.')

    # number of coefficients
    n = t.size - k - 1

    # construct A.T @ A and rhs with A the collocation matrix, and
    # rhs = A.T @ y for solving the LSQ problem  ``A.T @ A @ c = A.T @ y``
    lower = True
    extradim = prod(y.shape[1:])
    ab = np.zeros((k + 1, n), dtype=np.float_, order='F')
    rhs = np.zeros((n, extradim), dtype=y.dtype, order='F')
    _bspl._norm_eq_lsq(x, t, k, y.reshape(-1, extradim), w, ab, rhs)
    rhs = rhs.reshape((n, ) + y.shape[1:])

    # have observation matrix & rhs, can solve the LSQ problem
    cho_decomp = cholesky_banded(ab,
                                 overwrite_ab=True,
                                 lower=lower,
                                 check_finite=check_finite)
    c = cho_solve_banded((cho_decomp, lower),
                         rhs,
                         overwrite_b=True,
                         check_finite=check_finite)

    c = np.ascontiguousarray(c)
    return BSpline.construct_fast(t, c, k, axis=axis)
コード例 #32
0
ファイル: qso_model.py プロジェクト: acrellin/cesium
def qso_engine(time,data,error,ltau=3.,lvar=-1.7,sys_err=0.,return_model=False):
    """Calculates the fit quality of a damped random walk to a qso lightcurve.
    The formalism is from Rybicki & Press (1994; arXiv:comp-gas/9405004)

    Data are modelled with a covariance function
        Lij = 0.5*var*tau*exp(-|time_i-time_j|/tau) .

    Input:
        time - measurement times, typically days
        data - measured magnitudes
        error - uncertainty in measured magnitudes

    Output (dictionary):

        chi2/nu - classical variability measure
        chi2_qso/nu - for goodness of fit given fixed parameters
        chi2_qso/nu_extra - for parameter fitting, add to chi2/nu
        chi^2/nu_NULL - expected chi2/nu for non-qso variable

        signif_qso - significance chi^2/nu<chi^2/nu_NULL (rule out false alarm)
        signif_not_qso - significance chi^2/nu>1 (rule out qso)
        signif_vary - significance that source is variable
        class - resulting source type (ambiguous, not_qso, qso)

        model - time series prediction for each datum given all others (iff return_model==True)
        dmodel - model uncertainty, including uncertainty in data

    Notes:
        T = L^(-1)
        Data variance is D
        Full covariance C^(-1) = (L+D)^(-1) = T [T+D^(-1)]^(-1) D^(-1)
        Code takes advantage of the tridiagonality of T and T+D^(-1).
    """

    out_dict = {}
    out_dict['chi2_qso/nu']=999; out_dict['chi2_qso/nu_extra']=0.;
    out_dict['signif_qso']=0.; out_dict['signif_not_qso']=0.;  out_dict['signif_vary']=0.
    out_dict['chi2_qso/nu_NULL']=0.; out_dict['chi2/nu']=0.; out_dict['nu']=0
    out_dict['model']=[]; out_dict['dmodel']=[];
    out_dict['class']='ambiguous'

    lvar0 = np.log10(0.5) + lvar + ltau

    ln = len(data)
    dt = abs(time[1:]-time[:-1])

    # first make sure all dt>0
    g = np.where(dt>0.)[0]; lg = len(g)
    # must have at least 2 data points
    if lg <= 0:
        return out_dict

    if return_model:
        model = 1.*data; dmodel = -1.*error

    if lg < ln:
      dt = dt[g]
      gg = np.zeros(lg+1,dtype='int64'); gg[1:] = g+1
      dat = data[gg]; wt = 1./(sys_err**2+error[gg]**2)
      ln = lg+1
    else:
      dat = 1.*data
      wt = 1./(sys_err**2+error**2)

    out_dict['nu'] = ln-1.
    varx = np.var(dat)
    dat0 = (dat * wt).sum() / wt.sum()
    out_dict['chi2/nu'] = ((dat - dat0)**2 * wt).sum() / out_dict['nu']

    # define tridiagonal matrix T = L^(-1)
    # sparse matrix form: ab[u + i - j, j] == a[i,j]   i<=j, (here u=1)
    T = np.zeros((2,ln),dtype='float64')
    arg = dt*np.exp(-np.log(10)*ltau); ri = np.exp(-arg); ei = 1./(1./ri-ri)
    T[0,1:] = -ei; T[1,:-1] = 1.+ri*ei; T[1,1:] += ri*ei; T[1,ln-1] += 1.
    T0 = np.median(T[1,:]); T /= T0

    # equation for chi2_qso is [ (dat-x0) T Tp^(-1) D^(-1) (dat-x0) ]  , where Tp=T+D^(-1) and D^(-1)=wt
    fac = np.exp(np.log(10)*lvar0)/T0
    Tp = 1.*T
    Tp[1,:] += wt*fac
    # solve Tp*z=y for z (y=wt*dat)
    # This works for scipy __version__>='0.9.0' on anathem (20120809)
    b1 = (wt*dat).reshape((1,ln))
    b2 = b1.T
    #(Tpc,z) = solveh_banded(Tp,b2)
    z = solveh_banded(Tp,b2)
    Tpc = cholesky_banded(Tp) # the solveh_banded() function used to return the cholesky matrix, now we get seperately
    z = z.T
    z = z[0,:]
    c1 = wt.reshape((1,ln))
    c2 = c1.T
    #(Tpc,z0) = solveh_banded(Tp,c2)
    z0 = solveh_banded(Tp,c2)
    #HAS NOT CHANGED#Tpc2 = cholesky_banded(Tp)
    z0 = z0.T
    z0 = z0[0,:]


    #finally, get u=T*z
    u = T[1,:]*z; u[1:] += T[0,1:]*z[:-1]; u[:-1] += T[0,1:]*z[1:]
    u0 = T[1,:]*z0; u0[1:] += T[0,1:]*z0[:-1]; u0[:-1] += T[0,1:]*z0[1:]

    # magnitude offset x0, error = 1./sqrt(u0sum)
    u0sum = u0.sum(); x0 = u.sum()/u0sum;

    # fit statistic
    out_dict['chi2_qso/nu'] = np.dot(dat-x0,u-u0*x0)/out_dict['nu']

    # -2*log(likelihood) = chi2_qso + ldet_C + log(u0sum)
    #   first term: use chi2_qso/nu for goodness of fit with fixed parameters;
    #   all terms: use chi2_qso/nu + chi2_qso/nu_extra for fitting with variable parameters
    # get log of determinant for use later
    Tc = cholesky_banded(T)
    ldet_Tp = 2*np.log(Tpc[1,:]).sum()
    ldet_T = 2*np.log(Tc[1,:]).sum()
    ldet_C = ldet_Tp-ldet_T-np.log(wt).sum()
    out_dict['chi2_qso/nu_extra'] = (ldet_C + np.log(u0sum))/out_dict['nu']

    # get trace of C^(-1) for significance calculation
    Tpm = chol_inverse_diag(Tpc)
    diagC = T[1,:]*wt*Tpm[1,:]
    diagC[:-1] += T[0,1:]*wt[0:-1]*Tpm[0,1:]
    diagC[1:] += T[0,1:]*wt[1:]*Tpm[0,1:]
    TrC = diagC.sum()

    # significance in sigma units (large means false alarm unlikely)
    # (expected value of chi2_qso under the NULL hypothesis is TrC*varx)
    out_dict['chi2_qso/nu_NULL'] = TrC*varx/out_dict['nu']
    a=ln/2.; x = (out_dict['chi2_qso/nu']+1.e-8)/(out_dict['chi2_qso/nu_NULL']+out_dict['chi2_qso/nu']+1.e-8)
    prob = betainc(a,a,x)
    if prob <= 0:
      lprob = a*np.log(x) - np.log(a) + gammaln(2*a) - 2*gammaln(a)
    else:
      lprob = np.log(prob)
    out_dict['signif_qso'] = lprob2sigma(lprob)

    a=ln/2.; x = 1./(1.+out_dict['chi2_qso/nu'])
    prob = betainc(a,a,x)
    if prob <= 0:
      lprob = a*np.log(x) - np.log(a) + gammaln(2*a) - 2*gammaln(a)
    else:
      lprob = np.log(prob)
    out_dict['signif_not_qso'] = lprob2sigma(lprob)

    x = out_dict['chi2/nu']*out_dict['nu']
    prob = gammaincc(0.5*out_dict['nu'],0.5*x)
    if prob <= 0:
      lprob = (0.5*out_dict['nu']-1)*np.log(x) - 0.5*x - 0.5*out_dict['nu']*np.log(2) - gammaln(0.5*out_dict['nu'])
    else:
      lprob = np.log( prob )
    out_dict['signif_vary'] = lprob2sigma(lprob)

    if out_dict['signif_vary'] > 3:
        if out_dict['signif_qso'] > 3:
            out_dict['class']='qso'
        elif out_dict['signif_not_qso'] > 3:
            out_dict['class']='not_qso'

    # best-fit model for the lightcurve
    if return_model:
      model[gg] = dat - (u-u0*x0)/diagC
      dmodel[gg] = 1./np.sqrt(diagC)
      out_dict['model'] = model
      out_dict['dmodel'] = dmodel

    return out_dict
コード例 #33
0
 def test_cho_solve_banded(self):
     x = array([[0, -1, -1], [2, 2, 2]])
     xcho = cholesky_banded(x)
     assert_no_overwrite(lambda b: cho_solve_banded((xcho, False), b),
                         [(3,)])
コード例 #34
0
ファイル: l2appr.py プロジェクト: rishus/ipp_polyalgo
def l2appr(n_dim, K, vec_timestamps, vec_obs, numObs, knots, weight):

    #  CONSTRUCTS THE (WEIGHTED DISCRETE) L2-APPROXIMATION BY SPLINES OF ORDER
    #  K WITH KNOT SEQUENCE T(1), .., T(N+K) TO GIVEN DATA POINTS
    #  (TAU(I),GTAU(I)), I=1,...,NTAU. THE B-SPLINE COEFFICIENTS
    #   B C O E F  OF THE APPROXIMATING SPLINE ARE DETERMINED FROM THE
    #  NORMAL EQUATIONS USING CHOLESKY'S METHOD.

    # n_dim : dimension of the B-spline space
    # K : order
    # numObs : number of data points
    # number of knots = n_dim + K

    bcoeff = np.asarray([0.0 for i in range(n_dim)])
    biatx = np.asarray([0.0 for i in range(K)])
    Q = np.zeros((K, n_dim))

    left_py = K - 1
    leftmk_py = -1  # left - K
    # Note that left cors. to the index of the knot just left of x, by Dr. Watson's notes indices.
    # The knots t run from t_1 to t_{n_dim+K}.
    # The python vector t will, however, go from 0 to n_dim+K-1.
    # t_1 is stored at location t[0].
    # t_2 is stored at location t[1].
    # t_K is stored at location t[K-1]
    # t[i] is stored at location t[i-1].
    # If we identify an index 'left' st. t[left] < x < t[left+1], then
    # x is actually in between t_{left} and t_{left+1}
    for ll in range(0, numObs):
        #        print 'll =', ll, 'x_ll =', vec_timestamps[ll],
        #        print 'knots[left_py]', knots[left_py], 'vec_timestamps[ll] >= knots[left_py]', vec_timestamps[ll] >= knots[left_py]
        # corner case
        if (left_py == n_dim - 1) or (vec_timestamps[ll] < knots[left_py + 1]):
            # we want: vec_timestamps(ll) \in (knots(left_fort) , knots(left_fort+1))
            # i.e., vec_timestamps(ll) \in (knots(left_py - 1) , knots(left_py))
            # call bsplvb directly
            left_fort = left_py + 1
            biatx[0:K + 1] = bsplvb(knots, K, 1, vec_timestamps[ll], left_fort)
        else:
            # Locate left st. vec_timestamps(ll) \in (knots(left_fort) , knots(left_fort+1))
            # i.e., vec_timestamps(ll) \in (knots(left_py - 1) , knots(left_py))
            while (vec_timestamps[ll] >= knots[left_py + 1]):
                left_py += 1
                leftmk_py += 1
            # now call bsplvb
            left_fort = left_py + 1
            biatx[0:K + 1] = bsplvb(knots, K, 1, vec_timestamps[ll], left_fort)

        # BIATX(MM-1)   (originally, BIATX(MM) in Fortran)
        # CONTAINS THE VALUE OF B(LEFT-K+MM), MM = 1,2,...,K,  AT TAU(LL).
        # HENCE, WITH DW := BIATX(MM-1)*WEIGHT(LL), (originally, BIATX(MM)*WEIGHT(LL) in Fortran)
        # THE NUMBER DW*GTAU(LL)
        # IS A SUMMAND IN THE INNER PRODUCT
        # (B(LEFT-K+MM),G) WHICH GOES INTO BCOEF(LEFT-K+MM-1)  (originally, BCOEF(LEFT-K+MM) in Fortran)
        # AND THE NUMBER BIATX(JJ)*DW IS A SUMMAND IN THE INNER PRODUCT
        # (B(LEFT-K+JJ),B(LEFT-K+MM)), INTO Q(JJ-MM+1,LEFT-K+MM)
        # SINCE (LEFT-K+JJ) - (LEFT-K+MM) + 1 = JJ - MM + 1 .

        # Solving:             min || Ax - b ||
        # So, we solve:       A^tA x = A^t b
        #
        # Entries of A^t A:
        #
        #                  ---
        #                  \
        # [AtA]_{ij} =          B_i(x_l) * B_j(x_j) * w(l)
        #                  /
        #                  ---
        #                  i,j=
        #
        # AtA is a symmetric banded matrix due to local support of B-splines.
        # No point storing (or even calculating) all entries.
        # Only nonzero entries are calculated.
        #
        # Entries of A^t b:
        #
        for mm in range(1, K + 1):
            dw = biatx[mm - 1] * weight[ll]
            j = (leftmk_py + 1) + mm
            # The rhs < A^t, b >
            bcoeff[j - 1] = dw * vec_obs[ll] + bcoeff[j - 1]
            i = 1
            for jj in range(mm, K + 1):
                Q[i - 1, j - 1] = biatx[jj - 1] * dw + Q[
                    i - 1, j - 1]  # j is fixed for currnt x_ll and current mm.
                # only i and jj are incrementing.
                # Q[*, j-1] is getting filled.
                # Then mm increments. j will also increment.
                # Q[*, j_old+1] will get filled.
                #
                # Then next x_ll comes in.
                # Suppose x_ll is in the same knot interval.
                # mm will still run from 1 to K.
                # j, by formula, will again take same values as previous loop.
                # So same columns of Q will get updated.
                # i will also take same values as previous ll-loop.
                # So, same rows of Q will update.
                # Essentially, for fixed [left, left+1), same entries
                # of Q will update.
                #
                # Suppose x_ll is in a different interval.
                # i.e., left is different, say, left_new = left_old+1
                # Then, j takes 1 higher values than prevoius ll-loops.
                # Meaning, a new (1 up) set of columns is filled.
                # mm and K are always same. So each row is filled again,
                # just in a different column.
                # That's the story of 'matrix filling' here.
                # Figure out the actual working of bandedness etc. -- TODO.
                i += 1


#       Get the CHOLESKY FACTORIZATION FOR banded matrix Q, THEN USE
#       IT TO SOLVE THE NORMAL EQUATIONS
#         C*X = BCOEF
#       FOR X , AND STORE X IN BCOEF
#    print 'In l2appr'
#    print  'n_dim =', n_dim
#    with open("ltr_python_output.csv", "a") as fh:
#        fh.write('writing Q:' + '\n')
#        for i in range(K):
#            fh.write('  '.join([str(Q[i, col]) for col in range(n_dim)] ) + '\n ')
#    fh.close()
    cb = la.cholesky_banded(Q,
                            overwrite_ab=False,
                            lower=True,
                            check_finite=True)
    bcoeff = la.cho_solve_banded((cb, True),
                                 bcoeff,
                                 overwrite_b=True,
                                 check_finite=True)

    return bcoeff
コード例 #35
0
ファイル: p1q4.py プロジェクト: elvisigkeit/graduate-stuff
                set_banded(getIndex(linX, linY), getIndex(colX, colY), val)


bandKeys = range(0, max(bandsDic.keys())+1)
bandKeys.sort()
bandKeys.reverse()
bands = []
for key in bandKeys:
    if (key in bandsDic):
        bands.append(bandsDic[key])
    else:
        bands.append([-1.0]*key + [0.0]*(N-key))
bands = np.matrix(bands)
#print 'bands:', bands

choA = la.cholesky_banded(bands, lower=False)


lines = []
for linY in xrange(1, Ny+1):
    for linX in xrange(1, Nx+1):
        cols = []
        for colY in xrange(1, Ny+1):
            for colX in xrange(1, Nx+1):
                val = 0.0
                
                if ((colX, colY) == (linX - 1, linY)):
                    val = -p*dt*dy*dy
                elif ((colX, colY) == (linX + 1, linY)):
                    val = -p*dt*dy*dy
                elif ((colX, colY) == (linX, linY - 1)):