Exemple #1
0
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    cs Lmatrix, Bmatrix, *L, *B ;
    double *x ;
    int k, i, j, top, *xi, *perm ;

    if (nargout > 1 || nargin != 2)
    {
        mexErrMsgTxt ("Usage: x = cs_reach(L,b)") ;
    }

    /* get inputs */
    L = cs_mex_get_sparse (&Lmatrix, 1, 1, pargin [0]) ;
    B = cs_mex_get_sparse (&Bmatrix, 0, 1, pargin [1]) ;
    cs_mex_check (0, L->n, 1, 0, 1, 1, pargin [1]) ;
    perm = cs_malloc (L->n, sizeof (int)) ;
    for (k = 0 ; k < L->n ; k++) perm [k] = k ;

    xi = cs_calloc (3*L->n, sizeof (int)) ;

    top = cs_reach (L, B, 0, xi, perm) ;

    pargout [0] = mxCreateDoubleMatrix (L->n - top, 1, mxREAL) ;
    x = mxGetPr (pargout [0]) ;
    for (j = 0, i = top ; i < L->n ; i++, j++) x [j] = xi [i] ;

    cs_free (xi) ;
    cs_free (perm) ;
}
Exemple #2
0
/* cs_add: sparse matrix addition */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    double alpha, beta ;
    cs Amatrix, Bmatrix, *A, *B, *C, *D ;
    if (nargout > 1 || nargin < 2 || nargin > 4)
    {
        mexErrMsgTxt ("Usage: C = cs_add(A,B,alpha,beta)") ;
    }
    A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ;    /* get A */
    B = cs_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_add (A,B,alpha,beta) ;       /* C = alpha*A + beta *B */
    cs_dropzeros (C) ;                  /* drop zeros */
    D = cs_transpose (C, 1) ;           /* sort result via double transpose */
    cs_spfree (C) ;
    C = cs_transpose (D, 1) ;
    cs_spfree (D) ;
    pargout [0] = cs_mex_put_sparse (&C) ;      /* return C */
}
Exemple #3
0
/* cs_updown: sparse Cholesky update/downdate (rank-1 or multiple rank) */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    cs Lmatrix, *Lin, Cmatrix, *C, *L, Cvector, *Cvec ;
    int ignore, j, k, n, lnz, *parent, sigma = 1, cp [2] ;
    char sigma_string [20] ;

    if (nargout > 1 || nargin < 3 || nargin > 4)
    {
        mexErrMsgTxt ("Usage: L = cs_updown(L,C,parent,sigma)") ;
    }
    Lin = cs_mex_get_sparse (&Lmatrix, 1, 1, pargin [0]) ;  /* get input L */
    n = Lin->n ;
    if (nargin > 3 && mxIsChar (pargin [3]))
    {
        mxGetString (pargin [3], sigma_string, 8) ;
        sigma = (sigma_string [0] == '-') ? (-1) : 1 ;
    }
    /* make a copy of L (this can take more work than updating L itself) */
    lnz = Lin->p [n] ;
    L = cs_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_mex_get_sparse (&Cmatrix, 0, 1, pargin [1]) ;
    parent = cs_mex_get_int (n, pargin [2], &ignore, 0) ;  /* get parent */

    /* 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] ;
        cs_updown (L, sigma, Cvec, parent) ;               /* update/downdate */
    }
    pargout [0] = cs_mex_put_sparse (&L) ;                 /* return new L */ 
}
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    cs *A, Amatrix ;
    double *x ;
    int i, m, n, *imatch, *jmatch ;

    if (nargout > 1 || nargin != 1)
    {
        mexErrMsgTxt ("Usage: p = cr_maxtransr(A)") ;
    }

    /* get inputs */
    A = cs_mex_get_sparse (&Amatrix, 0, 0, pargin [0]) ;
    m = A->m ;
    n = A->n ;

    jmatch = maxtrans (A) ;
    imatch = invmatch (jmatch, m, n) ;  /* imatch = inverse of jmatch */

    pargout [0] = mxCreateDoubleMatrix (1, n, mxREAL) ;
    x = mxGetPr (pargout [0]) ;
    for (i = 0 ; i < n ; i++) x [i] = imatch [i] + 1 ;

    cs_free (jmatch) ;
    cs_free (imatch) ;
}
/* cs_permute: permute a sparse matrix */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    cs Amatrix, *A, *C, *D ;
    int ignore, *P, *Q, *Pinv ;
    if (nargout > 1 || nargin != 3)
    {
        mexErrMsgTxt ("Usage: C = cs_permute(A,p,q)") ;
    }
    A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ;    /* get A */
    P = cs_mex_get_int (A->m, pargin [1], &ignore, 1) ;     /* get P */
    Q = cs_mex_get_int (A->n, pargin [2], &ignore, 1) ;     /* get Q */
    Pinv = cs_pinv (P, A->m) ;              /* P = Pinv' */
    C = cs_permute (A, Pinv, Q, 1) ;        /* C = A(p,q) */
    D = cs_transpose (C, 1) ;               /* sort C via double transpose */
    cs_spfree (C) ;
    C = cs_transpose (D, 1) ;
    cs_spfree (D) ;
    pargout [0] = cs_mex_put_sparse (&C) ;          /* return C */
    cs_free (Pinv) ;
    cs_free (P) ;
    cs_free (Q) ;
}
Exemple #6
0
/* cs_symperm: symmetric permutation of a symmetric sparse matrix. */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    cs Amatrix, *A, *C, *D ;
    csi ignore, n, *P, *Pinv ;
    if (nargout > 1 || nargin != 2)
    {
        mexErrMsgTxt ("Usage: C = cs_symperm(A,p)") ;
    }
    A = cs_mex_get_sparse (&Amatrix, 1, 1, pargin [0]) ;
    n = A->n ;
    P = cs_mex_get_int (n, pargin [1], &ignore, 1) ;    /* get P */
    Pinv = cs_pinv (P, n) ;                             /* P=Pinv' */
    C = cs_symperm (A, Pinv, 1) ;                       /* C = A(p,p) */
    D = cs_transpose (C, 1) ;                           /* sort C */
    cs_spfree (C) ;
    C = cs_transpose (D, 1) ;
    cs_spfree (D) ;
    pargout [0] = cs_mex_put_sparse (&C) ;              /* return C */
    cs_free (P) ;
    cs_free (Pinv) ;
}
Exemple #7
0
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    cs Umatrix, Bmatrix, *U, *B, *X ;
    double *x, *b ;
    int top, nz, p, *xi ;
    if (nargout > 1 || nargin != 2)
    {
        mexErrMsgTxt ("Usage: x = cs_usolve(U,b)") ;
    }
    U = cs_mex_get_sparse (&Umatrix, 1, 1, pargin [0]) ;    /* get U */
    if (mxIsSparse (pargin [1]))
    {
        B = cs_mex_get_sparse (&Bmatrix, 0, 1, pargin [1]) ;/* get sparse b */
        cs_mex_check (0, U->n, 1, 0, 1, 1, pargin [1]) ;
        xi = cs_malloc (2*U->n, sizeof (int)) ;             /* get workspace */
        x  = cs_malloc (U->n, sizeof (double)) ;
        top = cs_spsolve (U, B, 0, xi, x, NULL, 0) ;        /* x = U\b */
        X = cs_spalloc (U->n, 1, U->n-top, 1, 0) ;          /* create sparse x*/
        X->p [0] = 0 ;
        nz = 0 ;
        for (p = top ; p < U->n ; p++)
        {
            X->i [nz] = xi [p] ;
            X->x [nz++] = x [xi [p]] ;
        }
        X->p [1] = nz ;
        pargout [0] = cs_mex_put_sparse (&X) ;
        cs_free (x) ;
        cs_free (xi) ;
    }
    else
    {
        b = cs_mex_get_double (U->n, pargin [1]) ;          /* get full b */
        x = cs_mex_put_double (U->n, b, &(pargout [0])) ;   /* x = b */
        cs_usolve (U, x) ;                                  /* x = U\x */
    }
}
Exemple #8
0
/* cs_lu: sparse LU factorization, with optional fill-reducing ordering */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    css *S ;
    csn *N ;
    cs Amatrix, *A, *D ;
    csi n, order, *p ;
    double tol ;
    if (nargout > 4 || nargin > 3 || nargin < 1)
    {
        mexErrMsgTxt ("Usage: [L,U,p,q] = cs_lu (A,tol)") ;
    }
    A = cs_mex_get_sparse (&Amatrix, 1, 1, pargin [0]) ;        /* get A */
    n = A->n ;
    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 */
    }
    S = cs_sqr (order, A, 0) ;              /* symbolic ordering, no QR bound */
    N = cs_lu (A, S, tol) ;                 /* numeric factorization */
    if (!N) mexErrMsgTxt ("cs_lu failed (singular, or out of memory)") ;
    cs_dropzeros (N->L) ;                   /* drop zeros from L and sort it */
    D = cs_transpose (N->L, 1) ;
    cs_spfree (N->L) ;
    N->L = cs_transpose (D, 1) ;
    cs_spfree (D) ;
    cs_dropzeros (N->U) ;                   /* drop zeros from U and sort it */
    D = cs_transpose (N->U, 1) ;
    cs_spfree (N->U) ;
    N->U = cs_transpose (D, 1) ;
    cs_spfree (D) ;
    p = cs_pinv (N->pinv, n) ;              /* p=pinv' */
    pargout [0] = cs_mex_put_sparse (&(N->L)) ;     /* return L */
    pargout [1] = cs_mex_put_sparse (&(N->U)) ;     /* return U */
    pargout [2] = cs_mex_put_int (p, n, 1, 1) ;     /* return p */
    /* return Q */
    if (nargout == 4) pargout [3] = cs_mex_put_int (S->q, n, 1, 0) ;
    cs_nfree (N) ;
    cs_sfree (S) ;
}
Exemple #9
0
/* cs_print: print the contents of a sparse matrix. */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    cs Amatrix, *A ;
    int brief ;
    if (nargout > 0 || nargin < 1 || nargin > 2)
    {
        mexErrMsgTxt ("Usage: cs_print(A,brief)") ;
    }
    A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ;    /* get A */
    brief = (nargin < 2) ? 0 : mxGetScalar (pargin [1]) ;   /* get brief */
    cs_print (A, brief) ;                                   /* print A */
}
Exemple #10
0
/* cs_qr: sparse QR factorization */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    css *S ;
    csn *N ;
    cs Amatrix, *A, *D ;
    csi m, n, order, *p ;
    if (nargout > 5 || nargin != 1)
    {
        mexErrMsgTxt ("Usage: [V,beta,p,R,q] = cs_qr(A)") ;
    }
    A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ;        /* get A */
    m = A->m ;
    n = A->n ;
    if (m < n) mexErrMsgTxt ("A must have # rows >= # columns") ;
    order = (nargout == 5) ? 3 : 0 ;        /* determine ordering */
    S = cs_sqr (order, A, 1) ;              /* symbolic QR ordering & analysis*/
    N = cs_qr (A, S) ;                      /* numeric QR factorization */
    if (!N) mexErrMsgTxt ("qr failed") ;
    cs_dropzeros (N->L) ;                   /* drop zeros from V and sort */
    D = cs_transpose (N->L, 1) ;
    cs_spfree (N->L) ;
    N->L = cs_transpose (D, 1) ;
    cs_spfree (D) ;
    cs_dropzeros (N->U) ;                   /* drop zeros from R and sort */
    D = cs_transpose (N->U, 1) ;
    cs_spfree (N->U) ;
    N->U = cs_transpose (D, 1) ;
    cs_spfree (D) ;
    m = N->L->m ;                                   /* m may be larger now */
    p = cs_pinv (S->pinv, m) ;                      /* p = pinv' */
    pargout [0] = cs_mex_put_sparse (&(N->L)) ;     /* return V */
    cs_mex_put_double (n, N->B, &(pargout [1])) ;   /* return beta */
    pargout [2] = cs_mex_put_int (p, m, 1, 1) ;     /* return p */
    pargout [3] = cs_mex_put_sparse (&(N->U)) ;     /* return R */
    pargout [4] = cs_mex_put_int (S->q, n, 1, 0) ;  /* return q */
    cs_nfree (N) ;
    cs_sfree (S) ;
}
Exemple #11
0
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    cs Amatrix, *A ;
    int m, n, mn, m2, n2, k, s, j, ij, sj, si, p, *Ap, *Ai ;
    double aij, *S, *Ax ;
    if (nargout > 1 || nargin < 1 || nargin > 2)
    {
        mexErrMsgTxt ("Usage: S = cs_thumb(A,k)") ;
    }
    A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ;    /* get A */
    m = A->m ;
    n = A->n ;
    mn = CS_MAX (m,n) ;
    k = (nargin == 1) ? 256 : mxGetScalar (pargin [1]) ;    /* get k */
    /* s = size of each submatrix; A(1:s,1:s) maps to S(1,1) */
    s = (mn < k) ? 1 : (int) ceil ((double) mn / (double) k) ;
    m2 = (int) ceil ((double) m / (double) s) ;
    n2 = (int) ceil ((double) n / (double) s) ;
    /* create S */
    pargout [0] = mxCreateDoubleMatrix (m2, n2, mxREAL) ;
    S = mxGetPr (pargout [0]) ;
    Ap = A->p ;
    Ai = A->i ;
    Ax = A->x ;
    for (j = 0 ; j < n ; j++)
    {
        sj = j/s ;
        for (p = Ap [j] ; p < Ap [j+1] ; p++)
        {
            si = Ai [p] / s ;
            ij = INDEX (si,sj,m2) ;
            aij = fabs (Ax [p]) ;
            if (ISNAN (aij)) aij = BIG_VALUE ;
            aij = CS_MIN (BIG_VALUE, aij) ;
            S [ij] = CS_MAX (S [ij], aij) ;
        }
    }
}
Exemple #12
0
/* cs_ltsolve: solve an upper triangular system L'*x=b */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    cs Lmatrix, *L ;
    double *x, *b ;
    if (nargout > 1 || nargin != 2)
    {
        mexErrMsgTxt ("Usage: x = cs_ltsolve(L,b)") ;
    }
    L = cs_mex_get_sparse (&Lmatrix, 1, 1, pargin [0]) ;    /* get L */
    b = cs_mex_get_double (L->n, pargin [1]) ;              /* get b */
    x = cs_mex_put_double (L->n, b, &(pargout [0])) ;       /* x = b */
    cs_ltsolve (L, x) ;                                     /* x = L'\x */
}
Exemple #13
0
/* z = cs_gaxpy (A,x,y) computes z = A*x+y */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    cs Amatrix, *A ;
    double *x, *y, *z ;
    if (nargout > 1 || nargin != 3)
    {
        mexErrMsgTxt ("Usage: z = cs_gaxpy(A,x,y)") ;
    }
    A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ;    /* get A */
    x = cs_mex_get_double (A->n, pargin [1]) ;              /* get x */
    y = cs_mex_get_double (A->m, pargin [2]) ;              /* get y */
    z = cs_mex_put_double (A->m, y, &(pargout [0])) ;       /* z = y */
    cs_gaxpy (A, x, z) ;                                    /* z = z + A*x */
}
Exemple #14
0
/* cs_amd: approximate minimum degree ordering */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    cs Amatrix, *A ;
    int *P, order ;
    if (nargout > 1 || nargin < 1 || nargin > 2)
    {
        mexErrMsgTxt ("Usage: p = cs_amd(A,order)") ;
    }
    A = cs_mex_get_sparse (&Amatrix, 0, 0, pargin [0]) ;    /* get A */
    order = (nargin > 1) ? mxGetScalar (pargin [1]) : 1 ;   /* get ordering */
    order = CS_MAX (order, 1) ;
    order = CS_MIN (order, 3) ;
    P = cs_amd (order, A) ;                         /* min. degree ordering */
    pargout [0] = cs_mex_put_int (P, A->n, 1, 1) ;  /* return P */
}
Exemple #15
0
/* cs_dmperm: maximum matching or Dulmage-Mendelsohn permutation. */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    double seed ;
    cs *A, Amatrix ;
    csd *D ;
    csi m, n, *jmatch, iseed ;
    if (nargin < 1 || nargin > 2 || nargout > 6)
    {
        mexErrMsgTxt ("Usage: [p,q,r,s,cc,rr] = cs_dmperm (A,seed)") ;
    }
    seed = (nargin > 1) ? mxGetScalar (pargin [1]) : 0 ;        /* get seed */
    iseed = (seed > 0 && seed < 1) ? (seed * RAND_MAX) : seed ;
    A = cs_mex_get_sparse (&Amatrix, 0, 0, pargin [0]) ;        /* get A */
    n = A->n ;
    m = A->m ;
    if (nargout <= 1)
    {
        jmatch = cs_maxtrans (A, iseed) ;                   /* max. matching */
        pargout [0] = cs_mex_put_int (jmatch+m, n, 1, 0) ;  /* return imatch */
        cs_free (jmatch) ;
    }
    else
    {
        D = cs_dmperm (A, iseed) ;      /* Dulmage-Mendelsohn decomposition */
        pargout [0] = cs_mex_put_int (D->p, m, 1, 0) ;
        pargout [1] = cs_mex_put_int (D->q, n, 1, 0) ;
        pargout [2] = cs_mex_put_int (D->r, D->nb+1, 1, 0) ;
        pargout [3] = cs_mex_put_int (D->s, D->nb+1, 1, 0) ;
        pargout [4] = cs_mex_put_int (D->cc, 5, 1, 0) ;
        pargout [5] = cs_mex_put_int (D->rr, 5, 1, 0) ;
        cs_dfree (D) ;
    }
}
Exemple #16
0
/* cs_lusol: solve A*x=b using a sparse LU factorization */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    cs *A, Amatrix ;
    csi order ;
    double *x, *b, tol ;
    if (nargout > 1 || nargin < 2 || nargin > 4)
    {
        mexErrMsgTxt ("Usage: x = cs_lusol(A,b,order,tol)") ;
    }
    A = cs_mex_get_sparse (&Amatrix, 1, 1, pargin [0]) ;    /* get A */
    b = cs_mex_get_double (A->n, pargin [1]) ;              /* get b */
    x = cs_mex_put_double (A->n, b, &(pargout [0])) ;       /* x = b */
    order = (nargin < 3) ? 2 : mxGetScalar (pargin [2]) ;
    order = CS_MAX (order, 0) ;
    order = CS_MIN (order, 3) ;
    if (nargin == 2)
    {
        tol = 1 ;                           /* normal partial pivoting */
    }
    else if (nargin == 3)
    {
        tol = (order == 1) ? 0.001 : 1 ;    /* tol = 0.001 for amd(A+A') */
    }
    else
    {
        tol = mxGetScalar (pargin [3]) ;
    }
    if (!cs_lusol (order, A, x, tol))                       /* x = A\x */
    {
        mexErrMsgTxt ("LU factorization failed (singular or out of memory)") ;
    }
}
Exemple #17
0
/* cs_droptol: remove small entries from A */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    cs Amatrix, *C, *A ;
    int j, k ;
    double tol ;
    if (nargout > 1 || nargin != 2)
    {
        mexErrMsgTxt ("Usage: C = cs_droptol(A,tol)") ;
    }
    A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ;    /* get A */
    tol = mxGetScalar (pargin [1]) ;                        /* get tol */
    C = cs_spalloc (A->m, A->n, A->nzmax, 1, 0) ;           /* C = A */
    for (j = 0 ; j <= A->n ; j++) C->p [j] = A->p [j] ;
    for (k = 0 ; k < A->nzmax ; k++) C->i [k] = A->i [k] ;
    for (k = 0 ; k < A->nzmax ; k++) C->x [k] = A->x [k] ;
    cs_droptol (C, tol) ;                                   /* drop from C */
    pargout [0] = cs_mex_put_sparse (&C) ;                  /* return C */
}