/* 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)") ; } } }
/* 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) ; }