Esempio n. 1
0
/* C = cs_transpose (A), computes C=A', where A must be sparse.
   C = cs_transpose (A,kind) computes C=A.' if kind <= 0, C=A' if kind > 0 */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    CS_INT values ;
    if (nargout > 1 || nargin < 1 || nargin > 2)
    {
        mexErrMsgTxt ("Usage: C = cs_transpose(A,kind)") ;
    }
    values = (nargin > 1) ? mxGetScalar (pargin [1]) : 1 ;
    values = (values <= 0) ? -1 : 1 ;
    if (mxIsComplex (pargin [0]))
    {
#ifndef NCOMPLEX
        cs_cl Amatrix, *A, *C ;
        A = cs_cl_mex_get_sparse (&Amatrix, 0, pargin [0]) ;    /* get A */
        C = cs_cl_transpose (A, values) ;                       /* C = A' */
        pargout [0] = cs_cl_mex_put_sparse (&C) ;               /* return C */
#else
        mexErrMsgTxt ("complex matrices not supported") ;
#endif
    }
    else
    {
        cs_dl Amatrix, *A, *C ;
        A = cs_dl_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ; /* get A */
        C = cs_dl_transpose (A, values) ;                       /* C = A' */
        pargout [0] = cs_dl_mex_put_sparse (&C) ;               /* return C */
    }
}
Esempio n. 2
0
/* cs_sparse: convert triplet form into compress-column form sparse matrix */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    if (nargout > 1 || nargin != 3)
    {
        mexErrMsgTxt ("Usage: A = cs_sparse(i,j,x)") ;
    }
    if (mxIsComplex (pargin [2]))
    {
#ifndef NCOMPLEX
        cs_cl *A, *C, *T, Tmatrix ;
        T = &Tmatrix ;                  /* get i,j,x and copy to triplet form */
        T->nz = mxGetM (pargin [0]) ;
        T->p = cs_dl_mex_get_int (T->nz, pargin [0], &(T->n), 1) ;
        T->i = cs_dl_mex_get_int (T->nz, pargin [1], &(T->m), 1) ;
        cs_mex_check (1, T->nz, 1, 0, 0, 1, pargin [2]) ;
        T->x = cs_cl_mex_get_double (T->nz, pargin [2]) ;
        T->nzmax = T->nz ;
        C = cs_cl_compress (T) ;                /* create sparse matrix C */
        cs_cl_dupl (C) ;                        /* remove duplicates from C */
        cs_cl_dropzeros (C) ;                   /* remove zeros from C */
        A = cs_cl_transpose (C, -1) ;           /* A=C.' */
        cs_cl_spfree (C) ;
        pargout [0] = cs_cl_mex_put_sparse (&A) ;       /* return A */
        cs_free (T->p) ;
        cs_free (T->i) ;
        cs_free (T->x) ;                        /* free copy of complex values*/
#else
        mexErrMsgTxt ("complex matrices not supported") ;
#endif
    }
    else
    {
        cs_dl *A, *C, *T, Tmatrix ;
        T = &Tmatrix ;                  /* get i,j,x and copy to triplet form */
        T->nz = mxGetM (pargin [0]) ;
        T->p = cs_dl_mex_get_int (T->nz, pargin [0], &(T->n), 1) ;
        T->i = cs_dl_mex_get_int (T->nz, pargin [1], &(T->m), 1) ;
        cs_mex_check (1, T->nz, 1, 0, 0, 1, pargin [2]) ;
        T->x = mxGetPr (pargin [2]) ;
        T->nzmax = T->nz ;
        C = cs_dl_compress (T) ;                /* create sparse matrix C */
        cs_dl_dupl (C) ;                        /* remove duplicates from C */
        cs_dl_dropzeros (C) ;                   /* remove zeros from C */
        A = cs_dl_transpose (C, 1) ;            /* A=C' */
        cs_dl_spfree (C) ;
        pargout [0] = cs_dl_mex_put_sparse (&A) ;       /* return A */
        cs_free (T->p) ;
        cs_free (T->i) ;
    }
}
Esempio n. 3
0
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    if (nargout > 1 || nargin < 2 || nargin > 4)
    {
        mexErrMsgTxt ("Usage: C = cs_add(A,B,alpha,beta)") ;
    }
    if (mxIsComplex (pargin [0]) || mxIsComplex (pargin [1])
        || (nargin > 2 && mxIsComplex (pargin [2]))
        || (nargin > 3 && mxIsComplex (pargin [3])))
    {
#ifndef NCOMPLEX
        cs_complex_t alpha, beta ;
        cs_cl Amatrix, Bmatrix, *A, *B, *C, *D ;
        A = cs_cl_mex_get_sparse (&Amatrix, 0, pargin [0]) ;    /* get A */
        B = cs_cl_mex_get_sparse (&Bmatrix, 0, pargin [1]) ;    /* get B */
        alpha = (nargin < 3) ? 1 : get_complex (pargin [2]) ;   /* get alpha */
        beta  = (nargin < 4) ? 1 : get_complex (pargin [3]) ;   /* get beta */
        C = cs_cl_add (A,B,alpha,beta) ;    /* C = alpha*A + beta *B */
        cs_cl_dropzeros (C) ;           /* drop zeros */
        D = cs_cl_transpose (C, 1) ;    /* sort result via double transpose */
        cs_cl_spfree (C) ;
        C = cs_cl_transpose (D, 1) ;
        cs_cl_spfree (D) ;
        pargout [0] = cs_cl_mex_put_sparse (&C) ;       /* return C */
#else
        mexErrMsgTxt ("complex matrices not supported") ;
#endif
    }
    else
    {
        double alpha, beta ;
        cs_dl Amatrix, Bmatrix, *A, *B, *C, *D ;
        A = cs_dl_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ;    /* get A */
        B = cs_dl_mex_get_sparse (&Bmatrix, 0, 1, pargin [1]) ;    /* get B */
        alpha = (nargin < 3) ? 1 : mxGetScalar (pargin [2]) ;   /* get alpha */
        beta  = (nargin < 4) ? 1 : mxGetScalar (pargin [3]) ;   /* get beta */
        C = cs_dl_add (A,B,alpha,beta) ;        /* C = alpha*A + beta *B */
        cs_dl_dropzeros (C) ;           /* drop zeros */
        D = cs_dl_transpose (C, 1) ;    /* sort result via double transpose */
        cs_dl_spfree (C) ;
        C = cs_dl_transpose (D, 1) ;
        cs_dl_spfree (D) ;
        pargout [0] = cs_dl_mex_put_sparse (&C) ;       /* return C */
    }
}
/* cs_updown: sparse Cholesky update/downdate (rank-1 or multiple rank) */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    CS_INT ignore, j, k, n, lnz, *parent, sigma = 1, cp [2], ok ;
    char sigma_string [20] ;
    if (nargout > 1 || nargin < 3 || nargin > 4)
    {
        mexErrMsgTxt ("Usage: L = cs_updown(L,C,parent,sigma)") ;
    }
    if (nargin > 3 && mxIsChar (pargin [3]))
    {
        mxGetString (pargin [3], sigma_string, 8) ;
        sigma = (sigma_string [0] == '-') ? (-1) : 1 ;
    }
    n = mxGetN (pargin [0]) ;
    parent = cs_dl_mex_get_int (n, pargin [2], &ignore, 0) ; /* get parent*/

    if (mxIsComplex (pargin [0]) || mxIsComplex (pargin [1]))
    {

#ifndef NCOMPLEX
        cs_cl Lmatrix, *Lin, Cmatrix, *C, *L, Cvector, *Cvec ;
        /* get input L, and copy MATLAB complex to C complex type */
        Lin = cs_cl_mex_get_sparse (&Lmatrix, 1, pargin [0]) ;

        /* make a copy of L (this can take more work than updating L itself) */
        lnz = Lin->p [n] ;
        L = cs_cl_spalloc (n, n, lnz, 0, 0) ;
        for (j = 0 ; j <= n ; j++) L->p [j] = Lin->p [j] ;
        for (k = 0 ; k < lnz ; k++) L->i [k] = Lin->i [k] ;

        /* complex values already copied into Lin->x, use shallow copy for L */
        L->x = Lin->x ;

        cs_mex_check (0, n, -1, 0, 1, 1, pargin [1]) ;     /* get C */
        C = cs_cl_mex_get_sparse (&Cmatrix, 0, pargin [1]) ;

        /* do the update one column at a time */
        Cvec = &Cvector ;
        Cvec->m = n ;
        Cvec->n = 1 ;
        Cvec->p = cp ;
        Cvec->nz = -1 ;
        cp [0] = 0 ;
        for (k = 0 ; k < C->n ; k++)
        {
            /* extract C(:,k) */ 
            cp [1] = C->p [k+1] - C->p [k] ;
            Cvec->nzmax = cp [1] ;
            Cvec->i = C->i + C->p [k] ;
            Cvec->x = C->x + C->p [k] ;
            /* update/downdate */
            ok = cs_cl_updown (L, sigma, Cvec, parent) ;
            if (!ok) mexErrMsgTxt ("matrix is not positive definite") ;
        }
        /* return new L */ 
        pargout [0] = cs_cl_mex_put_sparse (&L) ;

        cs_free (C->x) ;        /* free complex copy of C */
#else
        mexErrMsgTxt ("complex matrices not supported") ;
#endif

    }
    else
    {

        cs_dl Lmatrix, *Lin, Cmatrix, *C, *L, Cvector, *Cvec ;
        /* get input L */
        Lin = cs_dl_mex_get_sparse (&Lmatrix, 1, 1, pargin [0]) ;
        /* make a copy of L (this can take more work than updating L itself) */
        lnz = Lin->p [n] ;
        L = cs_dl_spalloc (n, n, lnz, 1, 0) ;
        for (j = 0 ; j <= n ; j++) L->p [j] = Lin->p [j] ;
        for (k = 0 ; k < lnz ; k++) L->i [k] = Lin->i [k] ;
        for (k = 0 ; k < lnz ; k++) L->x [k] = Lin->x [k] ;
        cs_mex_check (0, n, -1, 0, 1, 1, pargin [1]) ;     /* get C */
        C = cs_dl_mex_get_sparse (&Cmatrix, 0, 1, pargin [1]) ;

        /* do the update one column at a time */
        Cvec = &Cvector ;
        Cvec->m = n ;
        Cvec->n = 1 ;
        Cvec->p = cp ;
        Cvec->nz = -1 ;
        cp [0] = 0 ;
        for (k = 0 ; k < C->n ; k++)
        {
            /* extract C(:,k) */ 
            cp [1] = C->p [k+1] - C->p [k] ;
            Cvec->nzmax = cp [1] ;
            Cvec->i = C->i + C->p [k] ;
            Cvec->x = C->x + C->p [k] ;
            /* update/downdate */
            ok = cs_dl_updown (L, sigma, Cvec, parent) ;
            if (!ok) mexErrMsgTxt ("matrix is not positive definite") ;
        }
        /* return new L */ 
        pargout [0] = cs_dl_mex_put_sparse (&L) ;
    }
}
Esempio n. 5
0
/* cs_lu: sparse LU factorization, with optional fill-reducing ordering */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    CS_INT n, order, *p ;
    double tol ;
    if (nargout > 4 || nargin > 3 || nargin < 1)
    {
        mexErrMsgTxt ("Usage: [L,U,p,q] = cs_lu (A,tol)") ;
    }
    if (nargin == 2)                        /* determine tol and ordering */
    {
        tol = mxGetScalar (pargin [1]) ;
        order = (nargout == 4) ? 1 : 0 ;    /* amd (A+A'), or natural */
    }
    else
    {
        tol = 1 ;
        order = (nargout == 4) ? 2 : 0 ;    /* amd(S'*S) w/dense rows or I */
    }
    if (mxIsComplex (pargin [0]))
    {
#ifndef NCOMPLEX
        cs_cls *S ;
        cs_cln *N ;
        cs_cl Amatrix, *A, *D ;
        A = cs_cl_mex_get_sparse (&Amatrix, 1, pargin [0]) ;    /* get A */
        n = A->n ;
        S = cs_cl_sqr (order, A, 0) ;       /* symbolic ordering, no QR bound */
        N = cs_cl_lu (A, S, tol) ;          /* numeric factorization */
        if (!N) mexErrMsgTxt ("cs_lu failed (singular, or out of memory)") ;
        cs_cl_free (A->x) ;                 /* complex copy no longer needed */
        cs_cl_dropzeros (N->L) ;            /* drop zeros from L and sort it */
        D = cs_cl_transpose (N->L, 1) ;
        cs_cl_spfree (N->L) ;
        N->L = cs_cl_transpose (D, 1) ;
        cs_cl_spfree (D) ;
        cs_cl_dropzeros (N->U) ;            /* drop zeros from U and sort it */
        D = cs_cl_transpose (N->U, 1) ;
        cs_cl_spfree (N->U) ;
        N->U = cs_cl_transpose (D, 1) ;
        cs_cl_spfree (D) ;
        p = cs_cl_pinv (N->pinv, n) ;                       /* p=pinv' */
        pargout [0] = cs_cl_mex_put_sparse (&(N->L)) ;      /* return L */
        pargout [1] = cs_cl_mex_put_sparse (&(N->U)) ;      /* return U */
        pargout [2] = cs_dl_mex_put_int (p, n, 1, 1) ;      /* return p */
        /* return Q */
        if (nargout == 4) pargout [3] = cs_dl_mex_put_int (S->q, n, 1, 0) ;
        cs_cl_nfree (N) ;
        cs_cl_sfree (S) ;
#else
        mexErrMsgTxt ("complex matrices not supported") ;
#endif
    }
    else
    {
        cs_dls *S ;
        cs_dln *N ;
        cs_dl Amatrix, *A, *D ;
        A = cs_dl_mex_get_sparse (&Amatrix, 1, 1, pargin [0]) ; /* get A */
        n = A->n ;
        S = cs_dl_sqr (order, A, 0) ;       /* symbolic ordering, no QR bound */
        N = cs_dl_lu (A, S, tol) ;          /* numeric factorization */
        if (!N) mexErrMsgTxt ("cs_lu failed (singular, or out of memory)") ;
        cs_dl_dropzeros (N->L) ;            /* drop zeros from L and sort it */
        D = cs_dl_transpose (N->L, 1) ;
        cs_dl_spfree (N->L) ;
        N->L = cs_dl_transpose (D, 1) ;
        cs_dl_spfree (D) ;
        cs_dl_dropzeros (N->U) ;            /* drop zeros from U and sort it */
        D = cs_dl_transpose (N->U, 1) ;
        cs_dl_spfree (N->U) ;
        N->U = cs_dl_transpose (D, 1) ;
        cs_dl_spfree (D) ;
        p = cs_dl_pinv (N->pinv, n) ;                       /* p=pinv' */
        pargout [0] = cs_dl_mex_put_sparse (&(N->L)) ;      /* return L */
        pargout [1] = cs_dl_mex_put_sparse (&(N->U)) ;      /* return U */
        pargout [2] = cs_dl_mex_put_int (p, n, 1, 1) ;      /* return p */
        /* return Q */
        if (nargout == 4) pargout [3] = cs_dl_mex_put_int (S->q, n, 1, 0) ;
        cs_dl_nfree (N) ;
        cs_dl_sfree (S) ;
    }
}
Esempio n. 6
0
/* cs_qr: sparse QR factorization */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    CS_INT m, n, order, *p ;
    if (nargout > 5 || nargin != 1)
    {
        mexErrMsgTxt ("Usage: [V,beta,p,R,q] = cs_qr(A)") ;
    }
    order = (nargout == 5) ? 3 : 0 ;        /* determine ordering */
    m = mxGetM (pargin [0]) ;
    n = mxGetN (pargin [0]) ;
    if (m < n) mexErrMsgTxt ("A must have # rows >= # columns") ;
    if (mxIsComplex (pargin [0]))
    {
#ifndef NCOMPLEX
        cs_cls *S ;
        cs_cln *N ;
        cs_cl Amatrix, *A, *D ;
        A = cs_cl_mex_get_sparse (&Amatrix, 0, pargin [0]) ;    /* get A */
        S = cs_cl_sqr (order, A, 1) ;       /* symbolic QR ordering & analysis*/
        N = cs_cl_qr (A, S) ;               /* numeric QR factorization */
        cs_free (A->x) ;
        if (!N) mexErrMsgTxt ("qr failed") ;
        cs_cl_dropzeros (N->L) ;            /* drop zeros from V and sort */
        D = cs_cl_transpose (N->L, 1) ;
        cs_cl_spfree (N->L) ;
        N->L = cs_cl_transpose (D, 1) ;
        cs_cl_spfree (D) ;
        cs_cl_dropzeros (N->U) ;            /* drop zeros from R and sort */
        D = cs_cl_transpose (N->U, 1) ;
        cs_cl_spfree (N->U) ;
        N->U = cs_cl_transpose (D, 1) ;
        cs_cl_spfree (D) ;
        m = N->L->m ;                               /* m may be larger now */
        p = cs_cl_pinv (S->pinv, m) ;                   /* p = pinv' */
        pargout [0] = cs_cl_mex_put_sparse (&(N->L)) ;  /* return V */
        cs_dl_mex_put_double (n, N->B, &(pargout [1])) ;   /* return beta */
        pargout [2] = cs_dl_mex_put_int (p, m, 1, 1) ;  /* return p */
        pargout [3] = cs_cl_mex_put_sparse (&(N->U)) ;  /* return R */
        pargout [4] = cs_dl_mex_put_int (S->q, n, 1, 0) ;  /* return q */
        cs_cl_nfree (N) ;
        cs_cl_sfree (S) ;
#else
        mexErrMsgTxt ("complex matrices not supported") ;
#endif
    }
    else
    {
        cs_dls *S ;
        cs_dln *N ;
        cs_dl Amatrix, *A, *D ;
        A = cs_dl_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ; /* get A */
        S = cs_dl_sqr (order, A, 1) ;       /* symbolic QR ordering & analysis*/
        N = cs_dl_qr (A, S) ;               /* numeric QR factorization */
        if (!N) mexErrMsgTxt ("qr failed") ;
        cs_dl_dropzeros (N->L) ;            /* drop zeros from V and sort */
        D = cs_dl_transpose (N->L, 1) ;
        cs_dl_spfree (N->L) ;
        N->L = cs_dl_transpose (D, 1) ;
        cs_dl_spfree (D) ;
        cs_dl_dropzeros (N->U) ;            /* drop zeros from R and sort */
        D = cs_dl_transpose (N->U, 1) ;
        cs_dl_spfree (N->U) ;
        N->U = cs_dl_transpose (D, 1) ;
        cs_dl_spfree (D) ;
        m = N->L->m ;                               /* m may be larger now */
        p = cs_dl_pinv (S->pinv, m) ;                   /* p = pinv' */
        pargout [0] = cs_dl_mex_put_sparse (&(N->L)) ;  /* return V */
        cs_dl_mex_put_double (n, N->B, &(pargout [1])) ;   /* return beta */
        pargout [2] = cs_dl_mex_put_int (p, m, 1, 1) ;  /* return p */
        pargout [3] = cs_dl_mex_put_sparse (&(N->U)) ;  /* return R */
        pargout [4] = cs_dl_mex_put_int (S->q, n, 1, 0) ;  /* return q */
        cs_dl_nfree (N) ;
        cs_dl_sfree (S) ;
    }
}