Ejemplo n.º 1
0
/* cs_lusol: solve A*x=b using a sparse LU factorization */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    double tol ;
    CS_INT order ;
    if (nargout > 1 || nargin < 2 || nargin > 4)
    {
        mexErrMsgTxt ("Usage: x = cs_lusol(A,b,order,tol)") ;
    }
    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 (mxIsComplex (pargin [0]) || mxIsComplex (pargin [1]))
    {
#ifndef NCOMPLEX
        cs_cl *A, Amatrix ;
        cs_complex_t *x ;
        A = cs_cl_mex_get_sparse (&Amatrix, 1, pargin [0]) ;    /* get A */
        x = cs_cl_mex_get_double (A->n, pargin [1]) ;           /* x = b */
        if (!cs_cl_lusol (order, A, x, tol))                    /* x = A\x */
        {
            mexErrMsgTxt ("failed (singular or out of memory)") ;
        }
        cs_cl_free (A->x) ;     /* complex copy no longer needed */
        pargout [0] = cs_cl_mex_put_double (A->n, x) ;          /* return x */
#else
        mexErrMsgTxt ("complex matrices not supported") ;
#endif
    }
    else
    {
        cs_dl *A, Amatrix ;
        double *x, *b ;
        A = cs_dl_mex_get_sparse (&Amatrix, 1, 1, pargin [0]) ;    /* get A */
        b = cs_dl_mex_get_double (A->n, pargin [1]) ;           /* get b */
        x = cs_dl_mex_put_double (A->n, b, &(pargout [0])) ;    /* x = b */
        if (!cs_dl_lusol (order, A, x, tol))                    /* x = A\x */
        {
            mexErrMsgTxt ("failed (singular or out of memory)") ;
        }
    }
}
Ejemplo n.º 2
0
/* solve a linear system using Cholesky, LU, and QR, with various orderings */
cs_long_t demo2 (problem *Prob)
{
    cs_cl *A, *C ;
    cs_complex_t *b, *x, *resid ;
    double t, tol ;
    cs_long_t k, m, n, ok, order, nb, ns, *r, *s, *rr, sprank ;
    cs_cld *D ;
    if (!Prob) return (0) ;
    A = Prob->A ; C = Prob->C ; b = Prob->b ; x = Prob->x ; resid = Prob->resid;
    m = A->m ; n = A->n ;
    tol = Prob->sym ? 0.001 : 1 ;               /* partial pivoting tolerance */
    D = cs_cl_dmperm (C, 1) ;                      /* randomized dmperm analysis */
    if (!D) return (0) ;
    nb = D->nb ; r = D->r ; s = D->s ; rr = D->rr ;
    sprank = rr [3] ;
    for (ns = 0, k = 0 ; k < nb ; k++)
    {
        ns += ((r [k+1] == r [k]+1) && (s [k+1] == s [k]+1)) ;
    }
    printf ("blocks: %g singletons: %g structural rank: %g\n",
        (double) nb, (double) ns, (double) sprank) ;
    cs_cl_dfree (D) ;
    for (order = 0 ; order <= 3 ; order += 3)   /* natural and amd(A'*A) */
    {
        if (!order && m > 1000) continue ;
        printf ("QR   ") ;
        print_order (order) ;
        rhs (x, b, m) ;                         /* compute right-hand side */
        t = tic () ;
        ok = cs_cl_qrsol (order, C, x) ;           /* min norm(Ax-b) with QR */
        printf ("time: %8.2f ", toc (t)) ;
        print_resid (ok, C, x, b, resid) ;      /* print residual */
    }
    if (m != n || sprank < n) return (1) ;      /* return if rect. or singular*/
    for (order = 0 ; order <= 3 ; order++)      /* try all orderings */
    {
        if (!order && m > 1000) continue ;
        printf ("LU   ") ;
        print_order (order) ;
        rhs (x, b, m) ;                         /* compute right-hand side */
        t = tic () ;
        ok = cs_cl_lusol (order, C, x, tol) ;      /* solve Ax=b with LU */
        printf ("time: %8.2f ", toc (t)) ;
        print_resid (ok, C, x, b, resid) ;      /* print residual */
    }
    if (!Prob->sym) return (1) ;
    for (order = 0 ; order <= 1 ; order++)      /* natural and amd(A+A') */
    {
        if (!order && m > 1000) continue ;
        printf ("Chol ") ;
        print_order (order) ;
        rhs (x, b, m) ;                         /* compute right-hand side */
        t = tic () ;
        ok = cs_cl_cholsol (order, C, x) ;         /* solve Ax=b with Cholesky */
        printf ("time: %8.2f ", toc (t)) ;
        print_resid (ok, C, x, b, resid) ;      /* print residual */
    }
    return (1) ;
}