Exemplo n.º 1
0
// Given column compressed form of matrix A
// perform LU decomposition and store the result in Numeric
// n is the dimension of matrix A
void Algebra::LU_decomposition(int n, UF_long * Ap, UF_long * Ai, double * Ax, 
		void ** p_Numeric){
	int status;
	double Control [UMFPACK_CONTROL];
	umfpack_dl_defaults (Control) ;
	
	double *null = (double *) NULL;
	void * Symbolic;

	// perform ordering
	status = umfpack_dl_symbolic(n, n, Ap, Ai, Ax, 
			&Symbolic, Control, null); 
	if( status < 0 ){
		umfpack_dl_report_status (Control, status) ;
		report_exit("umfpack_dl_symbolic failed\n") ;
	}

	// LU decomposition
	status = umfpack_dl_numeric(Ap, Ai, Ax, Symbolic, 
			p_Numeric, Control, null) ;
	if( status < 0 ){
		umfpack_dl_report_status (Control, status) ;
		report_exit("umfpack_dl_numeric failed\n") ;
	}

	umfpack_dl_free_symbolic (&Symbolic) ;
}
Exemplo n.º 2
0
int main (int argc, char **argv)
{
   double Info [UMFPACK_INFO], Control [UMFPACK_CONTROL], *Ax, *Cx, *Lx, *Ux,
          *W, t [2], *Dx, rnorm, *Rb, *y, *Rs ;
   UF_long *Ap, *Ai, *Cp, *Ci, row, col, p, lnz, unz, nr, nc, *Lp, *Li, *Ui, *Up,
           *P, *Q, *Lj, i, j, k, anz, nfr, nchains, *Qinit, fnpiv, lnz1, unz1, nz1,
           status, *Front_npivcol, *Front_parent, *Chain_start, *Wi, *Pinit, n1,
           *Chain_maxrows, *Chain_maxcols, *Front_1strow, *Front_leftmostdesc,
           nzud, do_recip ;
   void *Symbolic, *Numeric ;

   /* ---------------------------------------------------------------------- */
   /* initializations */
   /* ---------------------------------------------------------------------- */

   umfpack_tic (t) ;

   printf ("\nUMFPACK V%d.%d (%s) demo: _dl_ version\n",
           UMFPACK_MAIN_VERSION, UMFPACK_SUB_VERSION, UMFPACK_DATE) ;

   /* get the default control parameters */
   umfpack_dl_defaults (Control) ;

   /* change the default print level for this demo */
   /* (otherwise, nothing will print) */
   Control [UMFPACK_PRL] = 6 ;

   /* print the license agreement */
   umfpack_dl_report_status (Control, UMFPACK_OK) ;
   Control [UMFPACK_PRL] = 5 ;

   /* print the control parameters */
   umfpack_dl_report_control (Control) ;

   /* ---------------------------------------------------------------------- */
   /* print A and b, and convert A to column-form */
   /* ---------------------------------------------------------------------- */

   /* print the right-hand-side */
   printf ("\nb: ") ;
   (void) umfpack_dl_report_vector (n, b, Control) ;

   /* print the triplet form of the matrix */
   printf ("\nA: ") ;
   (void) umfpack_dl_report_triplet (n, n, nz, Arow, Acol, Aval,
                                     Control) ;

   /* convert to column form */
   nz1 = MAX (nz,1) ;	/* ensure arrays are not of size zero. */
   Ap = (UF_long *) malloc ((n+1) * sizeof (UF_long)) ;
   Ai = (UF_long *) malloc (nz1 * sizeof (UF_long)) ;
   Ax = (double *) malloc (nz1 * sizeof (double)) ;
   if (!Ap || !Ai || !Ax)
   {
      error ("out of memory") ;
   }

   status = umfpack_dl_triplet_to_col (n, n, nz, Arow, Acol, Aval,
                                       Ap, Ai, Ax, (UF_long *) NULL) ;

   if (status < 0)
   {
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_triplet_to_col failed") ;
   }

   /* print the column-form of A */
   printf ("\nA: ") ;
   (void) umfpack_dl_report_matrix (n, n, Ap, Ai, Ax, 1, Control) ;

   /* ---------------------------------------------------------------------- */
   /* symbolic factorization */
   /* ---------------------------------------------------------------------- */

   status = umfpack_dl_symbolic (n, n, Ap, Ai, Ax, &Symbolic,
                                 Control, Info) ;
   if (status < 0)
   {
      umfpack_dl_report_info (Control, Info) ;
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_symbolic failed") ;
   }

   /* print the symbolic factorization */

   printf ("\nSymbolic factorization of A: ") ;
   (void) umfpack_dl_report_symbolic (Symbolic, Control) ;

   /* ---------------------------------------------------------------------- */
   /* numeric factorization */
   /* ---------------------------------------------------------------------- */

   status = umfpack_dl_numeric (Ap, Ai, Ax, Symbolic, &Numeric,
                                Control, Info) ;
   if (status < 0)
   {
      umfpack_dl_report_info (Control, Info) ;
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_numeric failed") ;
   }

   /* print the numeric factorization */
   printf ("\nNumeric factorization of A: ") ;
   (void) umfpack_dl_report_numeric (Numeric, Control) ;

   /* ---------------------------------------------------------------------- */
   /* solve Ax=b */
   /* ---------------------------------------------------------------------- */

   status = umfpack_dl_solve (UMFPACK_A, Ap, Ai, Ax, x, b,
                              Numeric, Control, Info) ;
   umfpack_dl_report_info (Control, Info) ;
   umfpack_dl_report_status (Control, status) ;
   if (status < 0)
   {
      error ("umfpack_dl_solve failed") ;
   }
   printf ("\nx (solution of Ax=b): ") ;
   (void) umfpack_dl_report_vector (n, x, Control) ;
   rnorm = resid (FALSE, Ap, Ai, Ax) ;
   printf ("maxnorm of residual: %g\n\n", rnorm) ;

   /* ---------------------------------------------------------------------- */
   /* compute the determinant */
   /* ---------------------------------------------------------------------- */

   status = umfpack_dl_get_determinant (x, r, Numeric, Info) ;
   umfpack_dl_report_status (Control, status) ;
   if (status < 0)
   {
      error ("umfpack_dl_get_determinant failed") ;
   }
   printf ("determinant: (%g", x [0]) ;
   printf (") * 10^(%g)\n", r [0]) ;

   /* ---------------------------------------------------------------------- */
   /* solve Ax=b, broken down into steps */
   /* ---------------------------------------------------------------------- */

   /* Rb = R*b */
   Rb  = (double *) malloc (n * sizeof (double)) ;
   y   = (double *) malloc (n * sizeof (double)) ;
   if (!Rb || !y) error ("out of memory") ;

   status = umfpack_dl_scale (Rb, b, Numeric) ;
   if (status < 0) error ("umfpack_dl_scale failed") ;
   /* solve Ly = P*(Rb) */
   status = umfpack_dl_solve (UMFPACK_Pt_L, Ap, Ai, Ax, y, Rb,
                              Numeric, Control, Info) ;
   if (status < 0) error ("umfpack_dl_solve failed") ;
   /* solve UQ'x=y */
   status = umfpack_dl_solve (UMFPACK_U_Qt, Ap, Ai, Ax, x, y,
                              Numeric, Control, Info) ;
   if (status < 0) error ("umfpack_dl_solve failed") ;
   printf ("\nx (solution of Ax=b, solve is split into 3 steps): ") ;
   (void) umfpack_dl_report_vector (n, x, Control) ;
   rnorm = resid (FALSE, Ap, Ai, Ax) ;
   printf ("maxnorm of residual: %g\n\n", rnorm) ;

   free (Rb) ;
   free (y) ;

   /* ---------------------------------------------------------------------- */
   /* solve A'x=b */
   /* ---------------------------------------------------------------------- */

   status = umfpack_dl_solve (UMFPACK_At, Ap, Ai, Ax, x, b,
                              Numeric, Control, Info) ;
   umfpack_dl_report_info (Control, Info) ;
   if (status < 0)
   {
      error ("umfpack_dl_solve failed") ;
   }
   printf ("\nx (solution of A'x=b): ") ;
   (void) umfpack_dl_report_vector (n, x, Control) ;
   rnorm = resid (TRUE, Ap, Ai, Ax) ;
   printf ("maxnorm of residual: %g\n\n", rnorm) ;

   /* ---------------------------------------------------------------------- */
   /* modify one numerical value in the column-form of A */
   /* ---------------------------------------------------------------------- */

   /* change A (1,4), look for row index 1 in column 4. */
   row = 1 ;
   col = 4 ;
   for (p = Ap [col] ; p < Ap [col+1] ; p++)
   {
      if (row == Ai [p])
      {
         printf ("\nchanging A (%ld,%ld) to zero\n", row, col) ;
         Ax [p] = 0.0 ;
         break ;
      }
   }
   printf ("\nmodified A: ") ;
   (void) umfpack_dl_report_matrix (n, n, Ap, Ai, Ax, 1, Control) ;

   /* ---------------------------------------------------------------------- */
   /* redo the numeric factorization */
   /* ---------------------------------------------------------------------- */

   /* The pattern (Ap and Ai) hasn't changed, so the symbolic factorization */
   /* doesn't have to be redone, no matter how much we change Ax. */

   /* We don't need the Numeric object any more, so free it. */
   umfpack_dl_free_numeric (&Numeric) ;

   /* Note that a memory leak would have occurred if the old Numeric */
   /* had not been free'd with umfpack_dl_free_numeric above. */
   status = umfpack_dl_numeric (Ap, Ai, Ax, Symbolic, &Numeric,
                                Control, Info) ;
   if (status < 0)
   {
      umfpack_dl_report_info (Control, Info) ;
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_numeric failed") ;
   }
   printf ("\nNumeric factorization of modified A: ") ;
   (void) umfpack_dl_report_numeric (Numeric, Control) ;

   /* ---------------------------------------------------------------------- */
   /* solve Ax=b, with the modified A */
   /* ---------------------------------------------------------------------- */

   status = umfpack_dl_solve (UMFPACK_A, Ap, Ai, Ax, x, b,
                              Numeric, Control, Info) ;
   umfpack_dl_report_info (Control, Info) ;
   if (status < 0)
   {
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_solve failed") ;
   }
   printf ("\nx (with modified A): ") ;
   (void) umfpack_dl_report_vector (n, x, Control) ;
   rnorm = resid (FALSE, Ap, Ai, Ax) ;
   printf ("maxnorm of residual: %g\n\n", rnorm) ;

   /* ---------------------------------------------------------------------- */
   /* modify all of the numerical values of A, but not the pattern */
   /* ---------------------------------------------------------------------- */

   for (col = 0 ; col < n ; col++)
   {
      for (p = Ap [col] ; p < Ap [col+1] ; p++)
      {
         row = Ai [p] ;
         printf ("changing ") ;
         printf ("A (%ld,%ld) from %g", row, col, Ax [p]) ;
         Ax [p] = Ax [p] + col*10 - row ;
         printf (" to %g\n", Ax [p]) ;
      }
   }
   printf ("\ncompletely modified A (same pattern): ") ;
   (void) umfpack_dl_report_matrix (n, n, Ap, Ai, Ax, 1, Control) ;

   /* ---------------------------------------------------------------------- */
   /* save the Symbolic object to file, free it, and load it back in */
   /* ---------------------------------------------------------------------- */

   /* use the default filename, "symbolic.umf" */
   printf ("\nSaving symbolic object:\n") ;
   status = umfpack_dl_save_symbolic (Symbolic, (char *) NULL) ;
   if (status < 0)
   {
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_save_symbolic failed") ;
   }
   printf ("\nFreeing symbolic object:\n") ;
   umfpack_dl_free_symbolic (&Symbolic) ;
   printf ("\nLoading symbolic object:\n") ;
   status = umfpack_dl_load_symbolic (&Symbolic, (char *) NULL) ;
   if (status < 0)
   {
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_load_symbolic failed") ;
   }
   printf ("\nDone loading symbolic object\n") ;

   /* ---------------------------------------------------------------------- */
   /* redo the numeric factorization */
   /* ---------------------------------------------------------------------- */

   umfpack_dl_free_numeric (&Numeric) ;
   status = umfpack_dl_numeric (Ap, Ai, Ax, Symbolic, &Numeric,
                                Control, Info) ;
   if (status < 0)
   {
      umfpack_dl_report_info (Control, Info) ;
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_numeric failed") ;
   }
   printf ("\nNumeric factorization of completely modified A: ") ;
   (void) umfpack_dl_report_numeric (Numeric, Control) ;

   /* ---------------------------------------------------------------------- */
   /* solve Ax=b, with the modified A */
   /* ---------------------------------------------------------------------- */

   status = umfpack_dl_solve (UMFPACK_A, Ap, Ai, Ax, x, b,
                              Numeric, Control, Info) ;
   umfpack_dl_report_info (Control, Info) ;
   if (status < 0)
   {
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_solve failed") ;
   }
   printf ("\nx (with completely modified A): ") ;
   (void) umfpack_dl_report_vector (n, x, Control) ;
   rnorm = resid (FALSE, Ap, Ai, Ax) ;
   printf ("maxnorm of residual: %g\n\n", rnorm) ;

   /* ---------------------------------------------------------------------- */
   /* free the symbolic and numeric factorization */
   /* ---------------------------------------------------------------------- */

   umfpack_dl_free_symbolic (&Symbolic) ;
   umfpack_dl_free_numeric (&Numeric) ;

   /* ---------------------------------------------------------------------- */
   /* C = transpose of A */
   /* ---------------------------------------------------------------------- */

   Cp = (UF_long *) malloc ((n+1) * sizeof (UF_long)) ;
   Ci = (UF_long *) malloc (nz1 * sizeof (UF_long)) ;
   Cx = (double *) malloc (nz1 * sizeof (double)) ;
   if (!Cp || !Ci || !Cx)
   {
      error ("out of memory") ;
   }
   status = umfpack_dl_transpose (n, n, Ap, Ai, Ax,
                                  (UF_long *) NULL, (UF_long *) NULL, Cp, Ci, Cx) ;
   if (status < 0)
   {
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_transpose failed: ") ;
   }
   printf ("\nC (transpose of A): ") ;
   (void) umfpack_dl_report_matrix (n, n, Cp, Ci, Cx, 1, Control) ;

   /* ---------------------------------------------------------------------- */
   /* symbolic factorization of C */
   /* ---------------------------------------------------------------------- */

   status = umfpack_dl_symbolic (n, n, Cp, Ci, Cx, &Symbolic,
                                 Control, Info) ;
   if (status < 0)
   {
      umfpack_dl_report_info (Control, Info) ;
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_symbolic failed") ;
   }
   printf ("\nSymbolic factorization of C: ") ;
   (void) umfpack_dl_report_symbolic (Symbolic, Control) ;

   /* ---------------------------------------------------------------------- */
   /* copy the contents of Symbolic into user arrays print them */
   /* ---------------------------------------------------------------------- */

   printf ("\nGet the contents of the Symbolic object for C:\n") ;
   printf ("(compare with umfpack_dl_report_symbolic output, above)\n") ;
   Pinit = (UF_long *) malloc ((n+1) * sizeof (UF_long)) ;
   Qinit = (UF_long *) malloc ((n+1) * sizeof (UF_long)) ;
   Front_npivcol = (UF_long *) malloc ((n+1) * sizeof (UF_long)) ;
   Front_1strow = (UF_long *) malloc ((n+1) * sizeof (UF_long)) ;
   Front_leftmostdesc = (UF_long *) malloc ((n+1) * sizeof (UF_long)) ;
   Front_parent = (UF_long *) malloc ((n+1) * sizeof (UF_long)) ;
   Chain_start = (UF_long *) malloc ((n+1) * sizeof (UF_long)) ;
   Chain_maxrows = (UF_long *) malloc ((n+1) * sizeof (UF_long)) ;
   Chain_maxcols = (UF_long *) malloc ((n+1) * sizeof (UF_long)) ;
   if (!Pinit || !Qinit || !Front_npivcol || !Front_parent || !Chain_start ||
       !Chain_maxrows || !Chain_maxcols || !Front_1strow ||
       !Front_leftmostdesc)
   {
      error ("out of memory") ;
   }

   status = umfpack_dl_get_symbolic (&nr, &nc, &n1, &anz, &nfr, &nchains,
                                     Pinit, Qinit, Front_npivcol, Front_parent, Front_1strow,
                                     Front_leftmostdesc, Chain_start, Chain_maxrows, Chain_maxcols,
                                     Symbolic) ;

   if (status < 0)
   {
      error ("symbolic factorization invalid") ;
   }

   printf ("From the Symbolic object, C is of dimension %ld-by-%ld\n", nr, nc);
   printf ("   with nz = %ld, number of fronts = %ld,\n", nz, nfr) ;
   printf ("   number of frontal matrix chains = %ld\n", nchains) ;

   printf ("\nPivot columns in each front, and parent of each front:\n") ;
   k = 0 ;
   for (i = 0 ; i < nfr ; i++)
   {
      fnpiv = Front_npivcol [i] ;
      printf ("    Front %ld: parent front: %ld number of pivot cols: %ld\n",
              i, Front_parent [i], fnpiv) ;
      for (j = 0 ; j < fnpiv ; j++)
      {
         col = Qinit [k] ;
         printf (
            "        %ld-th pivot column is column %ld in original matrix\n",
            k, col) ;
         k++ ;
      }
   }

   printf ("\nNote that the column ordering, above, will be refined\n") ;
   printf ("in the numeric factorization below.  The assignment of pivot\n") ;
   printf ("columns to frontal matrices will always remain unchanged.\n") ;

   printf ("\nTotal number of pivot columns in frontal matrices: %ld\n", k) ;

   printf ("\nFrontal matrix chains:\n") ;
   for (j = 0 ; j < nchains ; j++)
   {
      printf ("   Frontal matrices %ld to %ld are factorized in a single\n",
              Chain_start [j], Chain_start [j+1] - 1) ;
      printf ("        working array of size %ld-by-%ld\n",
              Chain_maxrows [j], Chain_maxcols [j]) ;
   }

   /* ---------------------------------------------------------------------- */
   /* numeric factorization of C */
   /* ---------------------------------------------------------------------- */

   status = umfpack_dl_numeric (Cp, Ci, Cx, Symbolic, &Numeric,
                                Control, Info) ;
   if (status < 0)
   {
      error ("umfpack_dl_numeric failed") ;
   }
   printf ("\nNumeric factorization of C: ") ;
   (void) umfpack_dl_report_numeric (Numeric, Control) ;

   /* ---------------------------------------------------------------------- */
   /* extract the LU factors of C and print them */
   /* ---------------------------------------------------------------------- */

   if (umfpack_dl_get_lunz (&lnz, &unz, &nr, &nc, &nzud, Numeric) < 0)
   {
      error ("umfpack_dl_get_lunz failed") ;
   }
   /* ensure arrays are not of zero size */
   lnz1 = MAX (lnz,1) ;
   unz1 = MAX (unz,1) ;
   Lp = (UF_long *) malloc ((n+1) * sizeof (UF_long)) ;
   Lj = (UF_long *) malloc (lnz1 * sizeof (UF_long)) ;
   Lx = (double *) malloc (lnz1 * sizeof (double)) ;
   Up = (UF_long *) malloc ((n+1) * sizeof (UF_long)) ;
   Ui = (UF_long *) malloc (unz1 * sizeof (UF_long)) ;
   Ux = (double *) malloc (unz1 * sizeof (double)) ;
   P = (UF_long *) malloc (n * sizeof (UF_long)) ;
   Q = (UF_long *) malloc (n * sizeof (UF_long)) ;
   Dx = (double *) NULL ;	/* D vector not requested */
   Rs  = (double *) malloc (n * sizeof (double)) ;
   if (!Lp || !Lj || !Lx || !Up || !Ui || !Ux || !P || !Q || !Rs)
   {
      error ("out of memory") ;
   }
   status = umfpack_dl_get_numeric (Lp, Lj, Lx, Up, Ui, Ux,
                                    P, Q, Dx, &do_recip, Rs, Numeric) ;
   if (status < 0)
   {
      error ("umfpack_dl_get_numeric failed") ;
   }

   printf ("\nL (lower triangular factor of C): ") ;
   (void) umfpack_dl_report_matrix (n, n, Lp, Lj, Lx, 0, Control) ;
   printf ("\nU (upper triangular factor of C): ") ;
   (void) umfpack_dl_report_matrix (n, n, Up, Ui, Ux, 1, Control) ;
   printf ("\nP: ") ;
   (void) umfpack_dl_report_perm (n, P, Control) ;
   printf ("\nQ: ") ;
   (void) umfpack_dl_report_perm (n, Q, Control) ;
   printf ("\nScale factors: row i of A is to be ") ;
   if (do_recip)
   {
      printf ("multiplied by the ith scale factor\n") ;
   }
   else
   {
      printf ("divided by the ith scale factor\n") ;
   }
   for (i = 0 ; i < n ; i++) printf ("%ld: %g\n", i, Rs [i]) ;

   /* ---------------------------------------------------------------------- */
   /* convert L to triplet form and print it */
   /* ---------------------------------------------------------------------- */

   /* Note that L is in row-form, so it is the row indices that are created */
   /* by umfpack_dl_col_to_triplet. */

   printf ("\nConverting L to triplet form, and printing it:\n") ;
   Li = (UF_long *) malloc (lnz1 * sizeof (UF_long)) ;
   if (!Li)
   {
      error ("out of memory") ;
   }
   if (umfpack_dl_col_to_triplet (n, Lp, Li) < 0)
   {
      error ("umfpack_dl_col_to_triplet failed") ;
   }
   printf ("\nL, in triplet form: ") ;
   (void) umfpack_dl_report_triplet (n, n, lnz, Li, Lj, Lx, Control) ;

   /* ---------------------------------------------------------------------- */
   /* save the Numeric object to file, free it, and load it back in */
   /* ---------------------------------------------------------------------- */

   /* use the default filename, "numeric.umf" */
   printf ("\nSaving numeric object:\n") ;
   status = umfpack_dl_save_numeric (Numeric, (char *) NULL) ;
   if (status < 0)
   {
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_save_numeric failed") ;
   }
   printf ("\nFreeing numeric object:\n") ;
   umfpack_dl_free_numeric (&Numeric) ;
   printf ("\nLoading numeric object:\n") ;
   status = umfpack_dl_load_numeric (&Numeric, (char *) NULL) ;
   if (status < 0)
   {
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_load_numeric failed") ;
   }
   printf ("\nDone loading numeric object\n") ;

   /* ---------------------------------------------------------------------- */
   /* solve C'x=b */
   /* ---------------------------------------------------------------------- */

   status = umfpack_dl_solve (UMFPACK_At, Cp, Ci, Cx, x, b,
                              Numeric, Control, Info) ;
   umfpack_dl_report_info (Control, Info) ;
   if (status < 0)
   {
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_solve failed") ;
   }
   printf ("\nx (solution of C'x=b): ") ;
   (void) umfpack_dl_report_vector (n, x, Control) ;
   rnorm = resid (TRUE, Cp, Ci, Cx) ;
   printf ("maxnorm of residual: %g\n\n", rnorm) ;

   /* ---------------------------------------------------------------------- */
   /* solve C'x=b again, using umfpack_dl_wsolve instead */
   /* ---------------------------------------------------------------------- */

   printf ("\nSolving C'x=b again, using umfpack_dl_wsolve instead:\n") ;
   Wi = (UF_long *) malloc (n * sizeof (UF_long)) ;
   W = (double *) malloc (5*n * sizeof (double)) ;
   if (!Wi || !W)
   {
      error ("out of memory") ;
   }

   status = umfpack_dl_wsolve (UMFPACK_At, Cp, Ci, Cx, x, b,
                               Numeric, Control, Info, Wi, W) ;
   umfpack_dl_report_info (Control, Info) ;
   if (status < 0)
   {
      umfpack_dl_report_status (Control, status) ;
      error ("umfpack_dl_wsolve failed") ;
   }
   printf ("\nx (solution of C'x=b): ") ;
   (void) umfpack_dl_report_vector (n, x, Control) ;
   rnorm = resid (TRUE, Cp, Ci, Cx) ;
   printf ("maxnorm of residual: %g\n\n", rnorm) ;

   /* ---------------------------------------------------------------------- */
   /* free everything */
   /* ---------------------------------------------------------------------- */

   /* This is not strictly required since the process is exiting and the */
   /* system will reclaim the memory anyway.  It's useful, though, just as */
   /* a list of what is currently malloc'ed by this program.  Plus, it's */
   /* always a good habit to explicitly free whatever you malloc. */

   free (Ap) ;
   free (Ai) ;
   free (Ax) ;

   free (Cp) ;
   free (Ci) ;
   free (Cx) ;

   free (Pinit) ;
   free (Qinit) ;
   free (Front_npivcol) ;
   free (Front_1strow) ;
   free (Front_leftmostdesc) ;
   free (Front_parent) ;
   free (Chain_start) ;
   free (Chain_maxrows) ;
   free (Chain_maxcols) ;

   free (Lp) ;
   free (Lj) ;
   free (Lx) ;

   free (Up) ;
   free (Ui) ;
   free (Ux) ;

   free (P) ;
   free (Q) ;

   free (Li) ;

   free (Wi) ;
   free (W) ;

   umfpack_dl_free_symbolic (&Symbolic) ;
   umfpack_dl_free_numeric (&Numeric) ;

   /* ---------------------------------------------------------------------- */
   /* print the total time spent in this demo */
   /* ---------------------------------------------------------------------- */

   umfpack_toc (t) ;
   printf ("\numfpack_dl_demo complete.\nTotal time: %5.2f seconds"
           " (CPU time), %5.2f seconds (wallclock time)\n", t [1], t [0]) ;
   return (0) ;
}
Exemplo n.º 3
0
// solve x for linear system Ax=b
// NOTE: UF_long and size_t must have the same size!
void Algebra::solve(const Matrix & A, const Vec & b, Vec & x){
	assert(x.size() == b.size());
	assert(sizeof(UF_long) == sizeof(size_t));
	clock_t t1,t2;

	size_t n = b.size();
	//Vec x(n);
	double * _x = x.val;
	double * _b = b.val;

	size_t n_row = n;
	size_t n_col = n;
	size_t nz = A.size();

	// NOTE: DO NOT MODIFY. size must be n_col+1, see UMFPACK manual
	UF_long * Ti = new UF_long[nz];
	UF_long * Tj = new UF_long[nz];
	double * Tx = new double[nz];
	A.to_arrays((size_t*)Ti,(size_t*)Tj,Tx);

	UF_long * Ap = new UF_long[n_col+1]; 
	UF_long * Ai = new UF_long[nz];
	double *Ax = new double [nz];

	int status;
	double Control [UMFPACK_CONTROL];
	umfpack_dl_defaults (Control) ;
	status = umfpack_dl_triplet_to_col(n_row, n_col, nz, Ti, Tj, Tx, 
			Ap, Ai, Ax, (UF_long *) NULL);

	if( status < 0 ) {
		umfpack_dl_report_status (Control, status) ;
		report_exit("umfpack_zi_triplet_to_col failed\n") ;
	}

	double *null = (double *) NULL;
	void *Symbolic, *Numeric;

	t1=clock();
	status = umfpack_dl_symbolic(n, n, Ap, Ai, Ax, 
			&Symbolic, Control, null); 
	t2=clock();
	clog<<"Symbolic time = "<<1.0*(t2-t1)/CLOCKS_PER_SEC<<endl;
	if( status < 0 ){
		umfpack_dl_report_status (Control, status) ;
		report_exit("umfpack_dl_symbolic failed\n") ;
	}

	t1=clock();
	status = umfpack_dl_numeric(Ap, Ai, Ax, Symbolic, 
			&Numeric, Control, null) ;
	t2=clock();
	clog<<"Numeric time = "<<1.0*(t2-t1)/CLOCKS_PER_SEC<<endl;
	if( status < 0 ){
		umfpack_dl_report_status (Control, status) ;
		report_exit("umfpack_dl_numeric failed\n") ;
	}

	umfpack_dl_free_symbolic (&Symbolic) ;

	t1=clock();
	status = umfpack_dl_solve(UMFPACK_A, Ap, Ai, Ax, _x, _b, 
				Numeric, Control, null) ;
	t2=clock();
	clog<<"Solve time = "<<1.0*(t2-t1)/CLOCKS_PER_SEC<<endl;
	if( status < 0 ){
		umfpack_dl_report_status (Control, status) ;
		report_exit("umfpack_dl_solve failed\n") ;
	}
	umfpack_dl_free_numeric (&Numeric) ;

	delete [] Ti;
	delete [] Tj;
	delete [] Tx;
	delete [] Ax;
	delete [] Ai;
	delete [] Ap;

	//return x;
}