/* 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) ; } }
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) ; }
/* get a real or complex MATLAB sparse matrix and convert to cs_cl */ cs_cl *cs_cl_mex_get_sparse (cs_cl *A, int square, const mxArray *Amatlab) { cs_mex_check (0, -1, -1, square, 1, 1, Amatlab) ; A->m = mxGetM (Amatlab) ; A->n = mxGetN (Amatlab) ; A->p = (CS_INT *) mxGetJc (Amatlab) ; A->i = (CS_INT *) mxGetIr (Amatlab) ; A->nzmax = mxGetNzmax (Amatlab) ; A->x = cs_cl_get_vector (A->p [A->n], A->nzmax, Amatlab) ; A->nz = -1 ; /* denotes a compressed-col matrix, instead of triplet */ return (A) ; }
/* get a MATLAB sparse matrix and convert to cs */ cs *cs_mex_get_sparse (cs *A, int square, int values, const mxArray *Amatlab) { cs_mex_check (0, -1, -1, square, 1, values, Amatlab) ; A->m = mxGetM (Amatlab) ; A->n = mxGetN (Amatlab) ; A->p = mxGetJc (Amatlab) ; A->i = mxGetIr (Amatlab) ; A->x = values ? mxGetPr (Amatlab) : NULL ; A->nzmax = mxGetNzmax (Amatlab) ; A->nz = -1 ; /* denotes a compressed-col matrix, instead of triplet */ return (A) ; }
/* 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 */ }
/* get a MATLAB flint array and convert to int */ int *cs_mex_get_int (int n, const mxArray *Imatlab, int *imax, int lo) { double *p ; int i, k, *C = cs_malloc (n, sizeof (int)) ; cs_mex_check (1, n, 1, 0, 0, 1, Imatlab) ; p = mxGetPr (Imatlab) ; *imax = 0 ; for (k = 0 ; k < n ; k++) { i = p [k] ; C [k] = i - 1 ; if (i < lo) mexErrMsgTxt ("index out of bounds") ; *imax = CS_MAX (*imax, i) ; } return (C) ; }
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 */ } }
/* get a MATLAB flint array and convert to CS_INT */ CS_INT *cs_dl_mex_get_int (CS_INT n, const mxArray *Imatlab, CS_INT *imax, int lo) { double *p ; CS_INT i, k, *C = cs_dl_malloc (n, sizeof (CS_INT)) ; cs_mex_check (1, n, 1, 0, 0, 1, Imatlab) ; if (mxIsComplex (Imatlab)) { mexErrMsgTxt ("integer input cannot be complex") ; } p = mxGetPr (Imatlab) ; *imax = 0 ; for (k = 0 ; k < n ; k++) { i = p [k] ; C [k] = i - 1 ; if (i < lo) mexErrMsgTxt ("index out of bounds") ; *imax = CS_MAX (*imax, i) ; } 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) ; } }
/* get a real MATLAB dense column vector */ double *cs_dl_mex_get_double (CS_INT n, const mxArray *X) { cs_mex_check (0, n, 1, 0, 0, 1, X) ; return (mxGetPr (X)) ; }
/* get a real or complex MATLAB dense column vector, and copy to cs_complex_t */ cs_complex_t *cs_cl_mex_get_double (CS_INT n, const mxArray *X) { cs_mex_check (0, n, 1, 0, 0, 1, X) ; return (cs_cl_get_vector (n, n, X)) ; }