inline int report_triplet (int n_row, int n_col, int nz, int const* Ti, int const* Tj, double const* Tx, double const* Control) { return umfpack_di_report_triplet (n_row, n_col, nz, Ti, Tj, Tx, Control); }
int main (int argc, char **argv) { int i, j, k, n, nz, *Ap, *Ai, *Ti, *Tj, status, *Pamd, nrow, ncol, rhs ; double *Ax, *b, *x, Control [UMFPACK_CONTROL], Info [UMFPACK_INFO], aij, *Tx, *r, amd_Control [AMD_CONTROL], amd_Info [AMD_INFO], tamd [2], stats [2], droptol ; void *Symbolic, *Numeric ; FILE *f, *f2 ; char s [SMAX] ; /* ---------------------------------------------------------------------- */ /* set controls */ /* ---------------------------------------------------------------------- */ printf ("\n===========================================================\n" "=== UMFPACK v%d.%d.%d ========================================\n" "===========================================================\n", UMFPACK_MAIN_VERSION, UMFPACK_SUB_VERSION, UMFPACK_SUBSUB_VERSION) ; umfpack_di_defaults (Control) ; Control [UMFPACK_PRL] = 3 ; Control [UMFPACK_BLOCK_SIZE] = 32 ; f = fopen ("tmp/control.umf4", "r") ; if (f != (FILE *) NULL) { printf ("Reading control file tmp/control.umf4\n") ; for (i = 0 ; i < UMFPACK_CONTROL ; i++) { fscanf (f, "%lg\n", & Control [i]) ; } fclose (f) ; } if (argc > 1) { char *t = argv [1] ; /* get the strategy */ if (t [0] == 'u') { Control [UMFPACK_STRATEGY] = UMFPACK_STRATEGY_UNSYMMETRIC ; } else if (t [0] == 'a') { Control [UMFPACK_STRATEGY] = UMFPACK_STRATEGY_AUTO ; } else if (t [0] == 's') { Control [UMFPACK_STRATEGY] = UMFPACK_STRATEGY_SYMMETRIC ; } else if (t [0] == '2') { printf ("unrecognized strategy: %s\n", argv [1]) ; } else if (t [0] == 'U') { Control [UMFPACK_STRATEGY] = UMFPACK_STRATEGY_UNSYMMETRIC ; Control [UMFPACK_SCALE] = UMFPACK_SCALE_MAX ; } else if (t [0] == 'A') { Control [UMFPACK_STRATEGY] = UMFPACK_STRATEGY_AUTO ; Control [UMFPACK_SCALE] = UMFPACK_SCALE_MAX ; } else if (t [0] == 'S') { Control [UMFPACK_STRATEGY] = UMFPACK_STRATEGY_SYMMETRIC ; Control [UMFPACK_SCALE] = UMFPACK_SCALE_MAX ; } else if (t [0] == 'T') { printf ("unrecognized strategy: %s\n", argv [1]) ; } else { printf ("unrecognized strategy: %s\n", argv [1]) ; } if (t [1] == 'n') { /* no aggressive absorption */ Control [UMFPACK_AGGRESSIVE] = FALSE ; } } if (argc > 2) { /* get the drop tolerance */ sscanf (argv [2], "%lg", &droptol) ; printf ("droptol %g\n", droptol) ; Control [UMFPACK_DROPTOL] = droptol ; } umfpack_di_report_control (Control) ; /* ---------------------------------------------------------------------- */ /* open the matrix file (tmp/A) */ /* ---------------------------------------------------------------------- */ printf ("File: tmp/A\n") ; f = fopen ("tmp/A", "r") ; if (!f) { printf ("Unable to open file\n") ; exit (1) ; } /* ---------------------------------------------------------------------- */ /* get n and nz */ /* ---------------------------------------------------------------------- */ printf ("File: tmp/Asize\n") ; f2 = fopen ("tmp/Asize", "r") ; if (f2) { fscanf (f2, "%d %d %d\n", &nrow, &ncol, &nz) ; fclose (f2) ; } else { nrow = 1 ; ncol = 1 ; } nz = 0 ; while (fgets (s, SMAX, f) != (char *) NULL) { sscanf (s, "%d %d %lg", &i, &j, &aij) ; #ifdef ZERO_BASED /* matrix is zero based */ i++ ; j++ ; #endif nrow = MAX (nrow, i) ; ncol = MAX (ncol, j) ; nz++ ; } fclose (f) ; n = MAX (nrow, ncol) ; printf ("n %d nrow %d ncol %d nz %d\n", n, nrow, ncol, nz) ; /* ---------------------------------------------------------------------- */ /* allocate space for the input triplet form */ /* ---------------------------------------------------------------------- */ Ti = (int *) malloc (nz * sizeof (int)) ; Tj = (int *) malloc (nz * sizeof (int)) ; Tx = (double *) malloc (nz * sizeof (double)) ; if (!Ti || !Tj || !Tx) { printf ("out of memory for input matrix\n") ; exit (1) ; } /* ---------------------------------------------------------------------- */ /* read in the triplet form */ /* ---------------------------------------------------------------------- */ f2 = fopen ("tmp/A", "r") ; if (!f2) { printf ("Unable to open file\n") ; exit (1) ; } k = 0 ; while (fgets (s, SMAX, f2) != (char *) NULL) { sscanf (s, "%d %d %lg", &i, &j, &aij) ; #ifndef ZERO_BASED i-- ; /* convert to 0-based */ j-- ; #endif if (k >= nz) { printf ("Error! Matrix size is wrong\n") ; exit (1) ; } Ti [k] = i ; Tj [k] = j ; Tx [k] = aij ; k++ ; } fclose (f2) ; (void) umfpack_di_report_triplet (nrow, ncol, nz, Ti, Tj, Tx, Control) ; /* ---------------------------------------------------------------------- */ /* convert to column form */ /* ---------------------------------------------------------------------- */ /* convert to column form */ Ap = (int *) malloc ((n+1) * sizeof (int)) ; Ai = (int *) malloc (nz * sizeof (int)) ; Ax = (double *) malloc (nz * sizeof (double)) ; b = (double *) malloc (n * sizeof (double)) ; r = (double *) malloc (n * sizeof (double)) ; x = (double *) malloc (n * sizeof (double)) ; if (!Ap || !Ai || !Ax || !b || !r) { printf ("out of memory") ; exit (1) ; } umfpack_tic (stats) ; status = umfpack_di_triplet_to_col (nrow, ncol, nz, Ti, Tj, Tx, Ap, Ai, Ax, (int *) NULL) ; umfpack_toc (stats) ; printf ("triplet-to-col time: wall %g cpu %g\n", stats [0], stats [1]) ; if (status != UMFPACK_OK) { umfpack_di_report_status (Control, status) ; printf ("umfpack_di_triplet_to_col failed") ; exit (1) ; } /* print the column-form of A */ (void) umfpack_di_report_matrix (nrow, ncol, Ap, Ai, Ax, 1, Control) ; /* b = A * xtrue */ rhs = FALSE ; if (nrow == ncol) { f = fopen ("tmp/b", "r") ; if (f != (FILE *) NULL) { printf ("Reading tmp/b\n") ; rhs = TRUE ; for (i = 0 ; i < n ; i++) { fscanf (f, "%lg\n", &b [i]) ; } fclose (f) ; } else { Atimesx (n, Ap, Ai, Ax, b, FALSE) ; } } /* ---------------------------------------------------------------------- */ /* free the triplet form */ /* ---------------------------------------------------------------------- */ free (Ti) ; free (Tj) ; free (Tx) ; /* ---------------------------------------------------------------------- */ /* symbolic factorization */ /* ---------------------------------------------------------------------- */ status = umfpack_di_symbolic (nrow, ncol, Ap, Ai, Ax, &Symbolic, Control, Info) ; umfpack_di_report_info (Control, Info) ; if (status != UMFPACK_OK) { umfpack_di_report_status (Control, status) ; printf ("umfpack_di_symbolic failed") ; exit (1) ; } /* print the symbolic factorization */ (void) umfpack_di_report_symbolic (Symbolic, Control) ; /* ---------------------------------------------------------------------- */ /* numeric factorization */ /* ---------------------------------------------------------------------- */ status = umfpack_di_numeric (Ap, Ai, Ax, Symbolic, &Numeric, Control, Info); if (status < UMFPACK_OK) { umfpack_di_report_info (Control, Info) ; umfpack_di_report_status (Control, status) ; fprintf (stderr, "umfpack_di_numeric failed: %d\n", status) ; printf ("umfpack_di_numeric failed\n") ; exit (1) ; } /* print the numeric factorization */ (void) umfpack_di_report_numeric (Numeric, Control) ; /* ---------------------------------------------------------------------- */ /* solve Ax=b */ /* ---------------------------------------------------------------------- */ if (nrow == ncol && status == UMFPACK_OK) { status = umfpack_di_solve (UMFPACK_A, Ap, Ai, Ax, x, b, Numeric, Control, Info) ; umfpack_di_report_info (Control, Info) ; umfpack_di_report_status (Control, status) ; if (status < UMFPACK_OK) { printf ("umfpack_di_solve failed\n") ; exit (1) ; } (void) umfpack_di_report_vector (n, x, Control) ; printf ("relative maxnorm of residual, ||Ax-b||/||b||: %g\n", resid (n, Ap, Ai, Ax, x, r, b, FALSE)) ; if (!rhs) { printf ("relative maxnorm of error, ||x-xtrue||/||xtrue||: %g\n\n", err (n, x)) ; } f = fopen ("tmp/x", "w") ; if (f != (FILE *) NULL) { printf ("Writing tmp/x\n") ; for (i = 0 ; i < n ; i++) { fprintf (f, "%30.20e\n", x [i]) ; } fclose (f) ; } else { printf ("Unable to write output x!\n") ; exit (1) ; } f = fopen ("tmp/info.umf4", "w") ; if (f != (FILE *) NULL) { printf ("Writing tmp/info.umf4\n") ; for (i = 0 ; i < UMFPACK_INFO ; i++) { fprintf (f, "%30.20e\n", Info [i]) ; } fclose (f) ; } else { printf ("Unable to write output info!\n") ; exit (1) ; } } else { /* don't solve, just report the results */ umfpack_di_report_info (Control, Info) ; umfpack_di_report_status (Control, status) ; } /* ---------------------------------------------------------------------- */ /* free the Symbolic and Numeric factorization */ /* ---------------------------------------------------------------------- */ umfpack_di_free_symbolic (&Symbolic) ; umfpack_di_free_numeric (&Numeric) ; printf ("umf4 done, strategy: %g\n", Control [UMFPACK_STRATEGY]) ; /* ---------------------------------------------------------------------- */ /* test just AMD ordering (not part of UMFPACK, but a separate test) */ /* ---------------------------------------------------------------------- */ /* first make the matrix square */ if (ncol < n) { for (j = ncol+1 ; j <= n ; j++) { Ap [j] = Ap [ncol] ; } } printf ( "\n\n===========================================================\n" "=== AMD ===================================================\n" "===========================================================\n") ; printf ("\n\n------- Now trying the AMD ordering. This not part of\n" "the UMFPACK analysis or factorization, above, but a separate\n" "test of just the AMD ordering routine.\n") ; Pamd = (int *) malloc (n * sizeof (int)) ; if (!Pamd) { printf ("out of memory\n") ; exit (1) ; } amd_defaults (amd_Control) ; amd_control (amd_Control) ; umfpack_tic (tamd) ; status = amd_order (n, Ap, Ai, Pamd, amd_Control, amd_Info) ; umfpack_toc (tamd) ; printf ("AMD ordering time: cpu %10.2f wall %10.2f\n", tamd [1], tamd [0]) ; if (status != AMD_OK) { printf ("amd failed: %d\n", status) ; exit (1) ; } amd_info (amd_Info) ; free (Pamd) ; printf ("AMD test done\n") ; free (Ap) ; free (Ai) ; free (Ax) ; free (b) ; free (r) ; free (x) ; return (0) ; }