/* solve a linear system using Cholesky, LU, and QR, with various orderings */ int demo2 (problem *Prob) { cs *A, *C ; double *b, *x, *resid, t, tol ; int k, m, n, ok, order, nb, ns, *r, *s, *rr, sprank ; csd *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_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_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_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_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_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) ; }
/* 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) ; } }