Exemple #1
0
int main (void)
{
    cs_dl *T, *A, *Eye, *AT, *C, *D ;
    UF_long i, m ;
    T = cs_dl_load (stdin) ;               /* load triplet matrix T from stdin */
    printf ("T:\n") ; cs_dl_print (T, 0) ; /* print T */
    A = cs_dl_compress (T) ;               /* A = compressed-column form of T */
    printf ("A:\n") ; cs_dl_print (A, 0) ; /* print A */
    cs_dl_spfree (T) ;                     /* clear T */
    AT = cs_dl_transpose (A, 1) ;          /* AT = A' */
    printf ("AT:\n") ; cs_dl_print (AT, 0) ; /* print AT */
    m = A ? A->m : 0 ;                  /* m = # of rows of A */
    T = cs_dl_spalloc (m, m, m, 1, 1) ;    /* create triplet identity matrix */
    for (i = 0 ; i < m ; i++) cs_dl_entry (T, i, i, 1) ;
    Eye = cs_dl_compress (T) ;             /* Eye = speye (m) */
    cs_dl_spfree (T) ;
    C = cs_dl_multiply (A, AT) ;           /* C = A*A' */
    D = cs_dl_add (C, Eye, 1, cs_dl_norm (C)) ;   /* D = C + Eye*norm (C,1) */
    printf ("D:\n") ; cs_dl_print (D, 0) ; /* print D */
    cs_dl_spfree (A) ;                     /* clear A AT C D Eye */
    cs_dl_spfree (AT) ;
    cs_dl_spfree (C) ;
    cs_dl_spfree (D) ;
    cs_dl_spfree (Eye) ;
    return (0) ;
}
Exemple #2
0
cs_dl *cs_dl_frand (CS_INT n, CS_INT nel, CS_INT s)
{
    CS_INT ss = s*s, nz = nel*ss, e, i, j, *P ;
    cs *A, *T = cs_dl_spalloc (n, n, nz, 1, 1) ;
    if (!T) return (NULL) ;
    P = cs_dl_malloc (s, sizeof (CS_INT)) ;
    if (!P) return (cs_dl_spfree (T)) ;
    for (e = 0 ; e < nel ; e++)
    {
        for (i = 0 ; i < s ; i++) P [i] = rand () % n ;
        for (j = 0 ; j < s ; j++)
        {
            for (i = 0 ; i < s ; i++)
            {
                cs_dl_entry (T, P [i], P [j], rand () / (double) RAND_MAX) ;
            }
        }
    }
    for (i = 0 ; i < n ; i++) cs_dl_entry (T, i, i, 1) ;
    A = cs_dl_compress (T) ;
    cs_dl_spfree (T) ;
    return (cs_dl_dupl (A) ? A : cs_dl_spfree (A)) ;
}
/* 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) ;
    }
}