Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/umfpack/demo/umfpack_xx_demo.c
3196 views
1
/* ========================================================================== */
2
/* === umfpack_xx_demo ====================================================== */
3
/* ========================================================================== */
4
5
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
6
:: Do not attempt to compile this file! It is processed via sed scripts into
7
:: four different C demo programs:
8
::
9
:: umfpack_di_demo.c: double precision, int integers
10
:: umfpack_dl_demo.c: double precision, long integers
11
:: umfpack_zi_demo.c: complex double precision, int integers
12
:: umfpack_zl_demo.c: complex double precision, long integers
13
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
14
15
/* -------------------------------------------------------------------------- */
16
/* UMFPACK Version 4.4, Copyright (c) 2005 by Timothy A. Davis. CISE Dept, */
17
/* Univ. of Florida. All Rights Reserved. See ../Doc/License for License. */
18
/* web: http://www.cise.ufl.edu/research/sparse/umfpack */
19
/* -------------------------------------------------------------------------- */
20
21
/*
22
A demo of UMFPACK: umfpack_xx_* version.
23
24
First, factor and solve a 5-by-5 system, Ax=b, using default parameters.
25
Then solve A'x=b using the factors of A. Modify one entry (A (1,4) = 0,
26
where the row and column indices range from 0 to 4. The pattern of A
27
has not changed (it has explicitly zero entry), so a reanalysis with
28
umfpack_xx_symbolic does not need to be done. Refactorize (with
29
umfpack_xx_numeric), and solve Ax=b. Note that the pivot ordering has
30
changed. Next, change all of the entries in A, but not the pattern.
31
32
Finally, compute C = A', and do the symbolic and numeric factorization of C.
33
Factorizing A' can sometimes be better than factorizing A itself (less work
34
and memory usage). Solve C'x=b twice; the solution is the same as the
35
solution to Ax=b.
36
37
A note about zero-sized arrays: UMFPACK uses many user-provided arrays of
38
size n (order of the matrix), and of size nz (the number of nonzeros in a
39
matrix). n cannot be zero; UMFPACK does not handle zero-dimensioned arrays.
40
However, nz can be zero. If you attempt to malloc an array of size nz = 0,
41
however, malloc will return a null pointer which UMFPACK will report as a
42
"missing argument." Thus, nz1 in this code is set to MAX (nz,1), and
43
similarly for lnz and unz. Lnz can never be zero, however, since L is always
44
unit diagonal.
45
*/
46
47
/* -------------------------------------------------------------------------- */
48
/* definitions */
49
/* -------------------------------------------------------------------------- */
50
51
#include <stdio.h>
52
#include <stdlib.h>
53
#include "umfpack.h"
54
55
/* use a cheap approximate absolute value for complex numbers: */
56
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
57
:: ABS is |xreal|+|ximag| for the complex case, and |x| for the real case.
58
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
59
#define ABS
60
61
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
62
#ifndef TRUE
63
#define TRUE (1)
64
#endif
65
#ifndef FALSE
66
#define FALSE (0)
67
#endif
68
69
/* -------------------------------------------------------------------------- */
70
/* triplet form of the matrix. The triplets can be in any order. */
71
/* -------------------------------------------------------------------------- */
72
73
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
74
:: Int is either int or long:
75
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
76
static Int n = 5, nz = 12 ;
77
static Int Arow [ ] = { 0, 4, 1, 1, 2, 2, 0, 1, 2, 3, 4, 4} ;
78
static Int Acol [ ] = { 0, 4, 0, 2, 1, 2, 1, 4, 3, 2, 1, 2} ;
79
static double Aval [ ] = {2., 1., 3., 4., -1., -3., 3., 6., 2., 1., 4., 2.} ;
80
static double Avalz[ ] = {1., .4, .1, .2, -1., -.2, 0., 6., 3., 0., .3, .3} ;
81
static double b [ ] = {8., 45., -3., 3., 19.}, x [5], r [5] ;
82
static double bz[ ] = {1., -5., -2., 0., 2.2}, xz[5], rz[5] ;
83
84
/* Avalz, bz: imaginary part of A and b */
85
86
/* -------------------------------------------------------------------------- */
87
/* error: print a message and exit */
88
/* -------------------------------------------------------------------------- */
89
90
static void error
91
(
92
char *message
93
)
94
{
95
printf ("\n\n====== error: %s =====\n\n", message) ;
96
exit (1) ;
97
}
98
99
100
/* -------------------------------------------------------------------------- */
101
/* resid: compute the residual, r = Ax-b or r = A'x=b and return maxnorm (r) */
102
/* A' is the complex conjugate transpose, not the array transpose */
103
/* -------------------------------------------------------------------------- */
104
105
static double resid
106
(
107
Int transpose,
108
Int Ap [ ],
109
Int Ai [ ],
110
double Ax [ ]
111
, double Az [ ]
112
)
113
{
114
Int i, j, p ;
115
double norm ;
116
117
for (i = 0 ; i < n ; i++)
118
{
119
r [i] = -b [i] ;
120
rz[i] = -bz[i] ;
121
}
122
if (transpose)
123
{
124
for (j = 0 ; j < n ; j++)
125
{
126
for (p = Ap [j] ; p < Ap [j+1] ; p++)
127
{
128
i = Ai [p] ;
129
/* complex: r(j) += conj (Aij) * x (i) */
130
r [j] += Ax [p] * x [i] ;
131
r [j] += Az [p] * xz[i] ;
132
rz[j] -= Az [p] * x [i] ;
133
rz[j] += Ax [p] * xz[i] ;
134
}
135
}
136
}
137
else
138
{
139
for (j = 0 ; j < n ; j++)
140
{
141
for (p = Ap [j] ; p < Ap [j+1] ; p++)
142
{
143
i = Ai [p] ;
144
r [i] += Ax [p] * x [j] ;
145
r [i] -= Az [p] * xz[j] ;
146
rz[i] += Az [p] * x [j] ;
147
rz[i] += Ax [p] * xz[j] ;
148
}
149
}
150
}
151
norm = 0. ;
152
for (i = 0 ; i < n ; i++)
153
{
154
norm = MAX (ABS (r [i], rz [i]), norm) ;
155
}
156
return (norm) ;
157
}
158
159
160
/* -------------------------------------------------------------------------- */
161
/* main program */
162
/* -------------------------------------------------------------------------- */
163
164
int main (int argc, char **argv)
165
{
166
double Info [UMFPACK_INFO], Control [UMFPACK_CONTROL], *Ax, *Cx, *Lx, *Ux,
167
*W, t [2], *Dx, rnorm, *Rb, *y, *Rs ;
168
double *Az, *Lz, *Uz, *Dz, *Cz, *Rbz, *yz ;
169
Int *Ap, *Ai, *Cp, *Ci, row, col, p, lnz, unz, nr, nc, *Lp, *Li, *Ui, *Up,
170
*P, *Q, *Lj, i, j, k, anz, nfr, nchains, *Qinit, fnpiv, lnz1, unz1, nz1,
171
status, *Front_npivcol, *Front_parent, *Chain_start, *Wi, *Pinit, n1,
172
*Chain_maxrows, *Chain_maxcols, *Front_1strow, *Front_leftmostdesc,
173
nzud, do_recip ;
174
void *Symbolic, *Numeric ;
175
176
/* ---------------------------------------------------------------------- */
177
/* initializations */
178
/* ---------------------------------------------------------------------- */
179
180
umfpack_tic (t) ;
181
182
printf ("\n%s demo: _xx_ version\n", UMFPACK_VERSION) ;
183
184
/* get the default control parameters */
185
umfpack_xx_defaults (Control) ;
186
187
/* change the default print level for this demo */
188
/* (otherwise, nothing will print) */
189
Control [UMFPACK_PRL] = 6 ;
190
191
/* print the license agreement */
192
umfpack_xx_report_status (Control, UMFPACK_OK) ;
193
Control [UMFPACK_PRL] = 5 ;
194
195
/* print the control parameters */
196
umfpack_xx_report_control (Control) ;
197
198
/* ---------------------------------------------------------------------- */
199
/* print A and b, and convert A to column-form */
200
/* ---------------------------------------------------------------------- */
201
202
/* print the right-hand-side */
203
printf ("\nb: ") ;
204
(void) umfpack_xx_report_vector (n, b, bz, Control) ;
205
206
/* print the triplet form of the matrix */
207
printf ("\nA: ") ;
208
(void) umfpack_xx_report_triplet (n, n, nz, Arow, Acol, Aval, Avalz,
209
Control) ;
210
211
/* convert to column form */
212
nz1 = MAX (nz,1) ; /* ensure arrays are not of size zero. */
213
Ap = (Int *) malloc ((n+1) * sizeof (Int)) ;
214
Ai = (Int *) malloc (nz1 * sizeof (Int)) ;
215
Ax = (double *) malloc (nz1 * sizeof (double)) ;
216
Az = (double *) malloc (nz1 * sizeof (double)) ;
217
if (!Ap || !Ai || !Ax || !Az)
218
{
219
error ("out of memory") ;
220
}
221
222
status = umfpack_xx_triplet_to_col (n, n, nz, Arow, Acol, Aval, Avalz,
223
Ap, Ai, Ax, Az, (Int *) NULL) ;
224
225
if (status < 0)
226
{
227
umfpack_xx_report_status (Control, status) ;
228
error ("umfpack_xx_triplet_to_col failed") ;
229
}
230
231
/* print the column-form of A */
232
printf ("\nA: ") ;
233
(void) umfpack_xx_report_matrix (n, n, Ap, Ai, Ax, Az, 1, Control) ;
234
235
/* ---------------------------------------------------------------------- */
236
/* symbolic factorization */
237
/* ---------------------------------------------------------------------- */
238
239
status = umfpack_xx_symbolic (n, n, Ap, Ai, Ax, Az, &Symbolic,
240
Control, Info) ;
241
if (status < 0)
242
{
243
umfpack_xx_report_info (Control, Info) ;
244
umfpack_xx_report_status (Control, status) ;
245
error ("umfpack_xx_symbolic failed") ;
246
}
247
248
/* print the symbolic factorization */
249
250
printf ("\nSymbolic factorization of A: ") ;
251
(void) umfpack_xx_report_symbolic (Symbolic, Control) ;
252
253
/* ---------------------------------------------------------------------- */
254
/* numeric factorization */
255
/* ---------------------------------------------------------------------- */
256
257
status = umfpack_xx_numeric (Ap, Ai, Ax, Az, Symbolic, &Numeric,
258
Control, Info) ;
259
if (status < 0)
260
{
261
umfpack_xx_report_info (Control, Info) ;
262
umfpack_xx_report_status (Control, status) ;
263
error ("umfpack_xx_numeric failed") ;
264
}
265
266
/* print the numeric factorization */
267
printf ("\nNumeric factorization of A: ") ;
268
(void) umfpack_xx_report_numeric (Numeric, Control) ;
269
270
/* ---------------------------------------------------------------------- */
271
/* solve Ax=b */
272
/* ---------------------------------------------------------------------- */
273
274
status = umfpack_xx_solve (UMFPACK_A, Ap, Ai, Ax, Az, x, xz, b, bz,
275
Numeric, Control, Info) ;
276
umfpack_xx_report_info (Control, Info) ;
277
umfpack_xx_report_status (Control, status) ;
278
if (status < 0)
279
{
280
error ("umfpack_xx_solve failed") ;
281
}
282
printf ("\nx (solution of Ax=b): ") ;
283
(void) umfpack_xx_report_vector (n, x, xz, Control) ;
284
rnorm = resid (FALSE, Ap, Ai, Ax, Az) ;
285
printf ("maxnorm of residual: %g\n\n", rnorm) ;
286
287
/* ---------------------------------------------------------------------- */
288
/* compute the determinant */
289
/* ---------------------------------------------------------------------- */
290
291
status = umfpack_xx_get_determinant (x, xz, r, Numeric, Info) ;
292
umfpack_xx_report_status (Control, status) ;
293
if (status < 0)
294
{
295
error ("umfpack_xx_get_determinant failed") ;
296
}
297
printf ("determinant: (%g", x [0]) ;
298
printf ("+ (%g)i", xz [0]) ; /* complex */
299
printf (") * 10^(%g)\n", r [0]) ;
300
301
/* ---------------------------------------------------------------------- */
302
/* solve Ax=b, broken down into steps */
303
/* ---------------------------------------------------------------------- */
304
305
/* Rb = R*b */
306
Rb = (double *) malloc (n * sizeof (double)) ;
307
Rbz = (double *) malloc (n * sizeof (double)) ;
308
y = (double *) malloc (n * sizeof (double)) ;
309
yz = (double *) malloc (n * sizeof (double)) ;
310
if (!Rb || !y) error ("out of memory") ;
311
if (!Rbz || !yz) error ("out of memory") ;
312
313
status = umfpack_xx_scale (Rb, Rbz, b, bz, Numeric) ;
314
if (status < 0) error ("umfpack_xx_scale failed") ;
315
/* solve Ly = P*(Rb) */
316
status = umfpack_xx_solve (UMFPACK_Pt_L, Ap, Ai, Ax, Az, y, yz, Rb, Rbz,
317
Numeric, Control, Info) ;
318
if (status < 0) error ("umfpack_xx_solve failed") ;
319
/* solve UQ'x=y */
320
status = umfpack_xx_solve (UMFPACK_U_Qt, Ap, Ai, Ax, Az, x, xz, y, yz,
321
Numeric, Control, Info) ;
322
if (status < 0) error ("umfpack_xx_solve failed") ;
323
printf ("\nx (solution of Ax=b, solve is split into 3 steps): ") ;
324
(void) umfpack_xx_report_vector (n, x, xz, Control) ;
325
rnorm = resid (FALSE, Ap, Ai, Ax, Az) ;
326
printf ("maxnorm of residual: %g\n\n", rnorm) ;
327
328
free (Rb) ;
329
free (Rbz) ;
330
free (y) ;
331
free (yz) ;
332
333
/* ---------------------------------------------------------------------- */
334
/* solve A'x=b */
335
/* ---------------------------------------------------------------------- */
336
337
/* note that this is the complex conjugate transpose, A' */
338
status = umfpack_xx_solve (UMFPACK_At, Ap, Ai, Ax, Az, x, xz, b, bz,
339
Numeric, Control, Info) ;
340
umfpack_xx_report_info (Control, Info) ;
341
if (status < 0)
342
{
343
error ("umfpack_xx_solve failed") ;
344
}
345
printf ("\nx (solution of A'x=b): ") ;
346
(void) umfpack_xx_report_vector (n, x, xz, Control) ;
347
rnorm = resid (TRUE, Ap, Ai, Ax, Az) ;
348
printf ("maxnorm of residual: %g\n\n", rnorm) ;
349
350
/* ---------------------------------------------------------------------- */
351
/* modify one numerical value in the column-form of A */
352
/* ---------------------------------------------------------------------- */
353
354
/* change A (1,4), look for row index 1 in column 4. */
355
row = 1 ;
356
col = 4 ;
357
for (p = Ap [col] ; p < Ap [col+1] ; p++)
358
{
359
if (row == Ai [p])
360
{
361
printf ("\nchanging A (%ld,%ld) to zero\n", row, col) ;
362
Ax [p] = 0.0 ;
363
Az [p] = 0.0 ;
364
break ;
365
}
366
}
367
printf ("\nmodified A: ") ;
368
(void) umfpack_xx_report_matrix (n, n, Ap, Ai, Ax, Az, 1, Control) ;
369
370
/* ---------------------------------------------------------------------- */
371
/* redo the numeric factorization */
372
/* ---------------------------------------------------------------------- */
373
374
/* The pattern (Ap and Ai) hasn't changed, so the symbolic factorization */
375
/* doesn't have to be redone, no matter how much we change Ax. */
376
377
/* We don't need the Numeric object any more, so free it. */
378
umfpack_xx_free_numeric (&Numeric) ;
379
380
/* Note that a memory leak would have occurred if the old Numeric */
381
/* had not been free'd with umfpack_xx_free_numeric above. */
382
status = umfpack_xx_numeric (Ap, Ai, Ax, Az, Symbolic, &Numeric,
383
Control, Info) ;
384
if (status < 0)
385
{
386
umfpack_xx_report_info (Control, Info) ;
387
umfpack_xx_report_status (Control, status) ;
388
error ("umfpack_xx_numeric failed") ;
389
}
390
printf ("\nNumeric factorization of modified A: ") ;
391
(void) umfpack_xx_report_numeric (Numeric, Control) ;
392
393
/* ---------------------------------------------------------------------- */
394
/* solve Ax=b, with the modified A */
395
/* ---------------------------------------------------------------------- */
396
397
status = umfpack_xx_solve (UMFPACK_A, Ap, Ai, Ax, Az, x, xz, b, bz,
398
Numeric, Control, Info) ;
399
umfpack_xx_report_info (Control, Info) ;
400
if (status < 0)
401
{
402
umfpack_xx_report_status (Control, status) ;
403
error ("umfpack_xx_solve failed") ;
404
}
405
printf ("\nx (with modified A): ") ;
406
(void) umfpack_xx_report_vector (n, x, xz, Control) ;
407
rnorm = resid (FALSE, Ap, Ai, Ax, Az) ;
408
printf ("maxnorm of residual: %g\n\n", rnorm) ;
409
410
/* ---------------------------------------------------------------------- */
411
/* modify all of the numerical values of A, but not the pattern */
412
/* ---------------------------------------------------------------------- */
413
414
for (col = 0 ; col < n ; col++)
415
{
416
for (p = Ap [col] ; p < Ap [col+1] ; p++)
417
{
418
row = Ai [p] ;
419
printf ("changing ") ;
420
/* complex: */ printf ("real part of ") ;
421
printf ("A (%ld,%ld) from %g", row, col, Ax [p]) ;
422
Ax [p] = Ax [p] + col*10 - row ;
423
printf (" to %g\n", Ax [p]) ;
424
}
425
}
426
printf ("\ncompletely modified A (same pattern): ") ;
427
(void) umfpack_xx_report_matrix (n, n, Ap, Ai, Ax, Az, 1, Control) ;
428
429
/* ---------------------------------------------------------------------- */
430
/* save the Symbolic object to file, free it, and load it back in */
431
/* ---------------------------------------------------------------------- */
432
433
/* use the default filename, "symbolic.umf" */
434
printf ("\nSaving symbolic object:\n") ;
435
status = umfpack_xx_save_symbolic (Symbolic, (char *) NULL) ;
436
if (status < 0)
437
{
438
umfpack_xx_report_status (Control, status) ;
439
error ("umfpack_xx_save_symbolic failed") ;
440
}
441
printf ("\nFreeing symbolic object:\n") ;
442
umfpack_xx_free_symbolic (&Symbolic) ;
443
printf ("\nLoading symbolic object:\n") ;
444
status = umfpack_xx_load_symbolic (&Symbolic, (char *) NULL) ;
445
if (status < 0)
446
{
447
umfpack_xx_report_status (Control, status) ;
448
error ("umfpack_xx_load_symbolic failed") ;
449
}
450
printf ("\nDone loading symbolic object\n") ;
451
452
/* ---------------------------------------------------------------------- */
453
/* redo the numeric factorization */
454
/* ---------------------------------------------------------------------- */
455
456
umfpack_xx_free_numeric (&Numeric) ;
457
status = umfpack_xx_numeric (Ap, Ai, Ax, Az, Symbolic, &Numeric,
458
Control, Info) ;
459
if (status < 0)
460
{
461
umfpack_xx_report_info (Control, Info) ;
462
umfpack_xx_report_status (Control, status) ;
463
error ("umfpack_xx_numeric failed") ;
464
}
465
printf ("\nNumeric factorization of completely modified A: ") ;
466
(void) umfpack_xx_report_numeric (Numeric, Control) ;
467
468
/* ---------------------------------------------------------------------- */
469
/* solve Ax=b, with the modified A */
470
/* ---------------------------------------------------------------------- */
471
472
status = umfpack_xx_solve (UMFPACK_A, Ap, Ai, Ax, Az, x, xz, b, bz,
473
Numeric, Control, Info) ;
474
umfpack_xx_report_info (Control, Info) ;
475
if (status < 0)
476
{
477
umfpack_xx_report_status (Control, status) ;
478
error ("umfpack_xx_solve failed") ;
479
}
480
printf ("\nx (with completely modified A): ") ;
481
(void) umfpack_xx_report_vector (n, x, xz, Control) ;
482
rnorm = resid (FALSE, Ap, Ai, Ax, Az) ;
483
printf ("maxnorm of residual: %g\n\n", rnorm) ;
484
485
/* ---------------------------------------------------------------------- */
486
/* free the symbolic and numeric factorization */
487
/* ---------------------------------------------------------------------- */
488
489
umfpack_xx_free_symbolic (&Symbolic) ;
490
umfpack_xx_free_numeric (&Numeric) ;
491
492
/* ---------------------------------------------------------------------- */
493
/* C = transpose of A */
494
/* ---------------------------------------------------------------------- */
495
496
Cp = (Int *) malloc ((n+1) * sizeof (Int)) ;
497
Ci = (Int *) malloc (nz1 * sizeof (Int)) ;
498
Cx = (double *) malloc (nz1 * sizeof (double)) ;
499
Cz = (double *) malloc (nz1 * sizeof (double)) ;
500
if (!Cp || !Ci || !Cx || !Cz)
501
{
502
error ("out of memory") ;
503
}
504
status = umfpack_xx_transpose (n, n, Ap, Ai, Ax, Az,
505
(Int *) NULL, (Int *) NULL, Cp, Ci, Cx, Cz, TRUE) ;
506
if (status < 0)
507
{
508
umfpack_xx_report_status (Control, status) ;
509
error ("umfpack_xx_transpose failed: ") ;
510
}
511
printf ("\nC (transpose of A): ") ;
512
(void) umfpack_xx_report_matrix (n, n, Cp, Ci, Cx, Cz, 1, Control) ;
513
514
/* ---------------------------------------------------------------------- */
515
/* symbolic factorization of C */
516
/* ---------------------------------------------------------------------- */
517
518
status = umfpack_xx_symbolic (n, n, Cp, Ci, Cx, Cz, &Symbolic,
519
Control, Info) ;
520
if (status < 0)
521
{
522
umfpack_xx_report_info (Control, Info) ;
523
umfpack_xx_report_status (Control, status) ;
524
error ("umfpack_xx_symbolic failed") ;
525
}
526
printf ("\nSymbolic factorization of C: ") ;
527
(void) umfpack_xx_report_symbolic (Symbolic, Control) ;
528
529
/* ---------------------------------------------------------------------- */
530
/* copy the contents of Symbolic into user arrays print them */
531
/* ---------------------------------------------------------------------- */
532
533
printf ("\nGet the contents of the Symbolic object for C:\n") ;
534
printf ("(compare with umfpack_xx_report_symbolic output, above)\n") ;
535
Pinit = (Int *) malloc ((n+1) * sizeof (Int)) ;
536
Qinit = (Int *) malloc ((n+1) * sizeof (Int)) ;
537
Front_npivcol = (Int *) malloc ((n+1) * sizeof (Int)) ;
538
Front_1strow = (Int *) malloc ((n+1) * sizeof (Int)) ;
539
Front_leftmostdesc = (Int *) malloc ((n+1) * sizeof (Int)) ;
540
Front_parent = (Int *) malloc ((n+1) * sizeof (Int)) ;
541
Chain_start = (Int *) malloc ((n+1) * sizeof (Int)) ;
542
Chain_maxrows = (Int *) malloc ((n+1) * sizeof (Int)) ;
543
Chain_maxcols = (Int *) malloc ((n+1) * sizeof (Int)) ;
544
if (!Pinit || !Qinit || !Front_npivcol || !Front_parent || !Chain_start ||
545
!Chain_maxrows || !Chain_maxcols || !Front_1strow ||
546
!Front_leftmostdesc)
547
{
548
error ("out of memory") ;
549
}
550
551
status = umfpack_xx_get_symbolic (&nr, &nc, &n1, &anz, &nfr, &nchains,
552
Pinit, Qinit, Front_npivcol, Front_parent, Front_1strow,
553
Front_leftmostdesc, Chain_start, Chain_maxrows, Chain_maxcols,
554
Symbolic) ;
555
556
if (status < 0)
557
{
558
error ("symbolic factorization invalid") ;
559
}
560
561
printf ("From the Symbolic object, C is of dimension %ld-by-%ld\n", nr, nc);
562
printf (" with nz = %ld, number of fronts = %ld,\n", nz, nfr) ;
563
printf (" number of frontal matrix chains = %ld\n", nchains) ;
564
565
printf ("\nPivot columns in each front, and parent of each front:\n") ;
566
k = 0 ;
567
for (i = 0 ; i < nfr ; i++)
568
{
569
fnpiv = Front_npivcol [i] ;
570
printf (" Front %ld: parent front: %ld number of pivot cols: %ld\n",
571
i, Front_parent [i], fnpiv) ;
572
for (j = 0 ; j < fnpiv ; j++)
573
{
574
col = Qinit [k] ;
575
printf (
576
" %ld-th pivot column is column %ld in original matrix\n",
577
k, col) ;
578
k++ ;
579
}
580
}
581
582
printf ("\nNote that the column ordering, above, will be refined\n") ;
583
printf ("in the numeric factorization below. The assignment of pivot\n") ;
584
printf ("columns to frontal matrices will always remain unchanged.\n") ;
585
586
printf ("\nTotal number of pivot columns in frontal matrices: %ld\n", k) ;
587
588
printf ("\nFrontal matrix chains:\n") ;
589
for (j = 0 ; j < nchains ; j++)
590
{
591
printf (" Frontal matrices %ld to %ld are factorized in a single\n",
592
Chain_start [j], Chain_start [j+1] - 1) ;
593
printf (" working array of size %ld-by-%ld\n",
594
Chain_maxrows [j], Chain_maxcols [j]) ;
595
}
596
597
/* ---------------------------------------------------------------------- */
598
/* numeric factorization of C */
599
/* ---------------------------------------------------------------------- */
600
601
status = umfpack_xx_numeric (Cp, Ci, Cx, Cz, Symbolic, &Numeric,
602
Control, Info) ;
603
if (status < 0)
604
{
605
error ("umfpack_xx_numeric failed") ;
606
}
607
printf ("\nNumeric factorization of C: ") ;
608
(void) umfpack_xx_report_numeric (Numeric, Control) ;
609
610
/* ---------------------------------------------------------------------- */
611
/* extract the LU factors of C and print them */
612
/* ---------------------------------------------------------------------- */
613
614
if (umfpack_xx_get_lunz (&lnz, &unz, &nr, &nc, &nzud, Numeric) < 0)
615
{
616
error ("umfpack_xx_get_lunz failed") ;
617
}
618
/* ensure arrays are not of zero size */
619
lnz1 = MAX (lnz,1) ;
620
unz1 = MAX (unz,1) ;
621
Lp = (Int *) malloc ((n+1) * sizeof (Int)) ;
622
Lj = (Int *) malloc (lnz1 * sizeof (Int)) ;
623
Lx = (double *) malloc (lnz1 * sizeof (double)) ;
624
Lz = (double *) malloc (lnz1 * sizeof (double)) ;
625
Up = (Int *) malloc ((n+1) * sizeof (Int)) ;
626
Ui = (Int *) malloc (unz1 * sizeof (Int)) ;
627
Ux = (double *) malloc (unz1 * sizeof (double)) ;
628
Uz = (double *) malloc (unz1 * sizeof (double)) ;
629
P = (Int *) malloc (n * sizeof (Int)) ;
630
Q = (Int *) malloc (n * sizeof (Int)) ;
631
Dx = (double *) NULL ; /* D vector not requested */
632
Dz = (double *) NULL ;
633
Rs = (double *) malloc (n * sizeof (double)) ;
634
if (!Lp || !Lj || !Lx || !Lz || !Up || !Ui || !Ux || !Uz || !P || !Q || !Rs)
635
{
636
error ("out of memory") ;
637
}
638
status = umfpack_xx_get_numeric (Lp, Lj, Lx, Lz, Up, Ui, Ux, Uz,
639
P, Q, Dx, Dz, &do_recip, Rs, Numeric) ;
640
if (status < 0)
641
{
642
error ("umfpack_xx_get_numeric failed") ;
643
}
644
645
printf ("\nL (lower triangular factor of C): ") ;
646
(void) umfpack_xx_report_matrix (n, n, Lp, Lj, Lx, Lz, 0, Control) ;
647
printf ("\nU (upper triangular factor of C): ") ;
648
(void) umfpack_xx_report_matrix (n, n, Up, Ui, Ux, Uz, 1, Control) ;
649
printf ("\nP: ") ;
650
(void) umfpack_xx_report_perm (n, P, Control) ;
651
printf ("\nQ: ") ;
652
(void) umfpack_xx_report_perm (n, Q, Control) ;
653
printf ("\nScale factors: row i of A is to be ") ;
654
if (do_recip)
655
{
656
printf ("multiplied by the ith scale factor\n") ;
657
}
658
else
659
{
660
printf ("divided by the ith scale factor\n") ;
661
}
662
for (i = 0 ; i < n ; i++) printf ("%ld: %g\n", i, Rs [i]) ;
663
664
/* ---------------------------------------------------------------------- */
665
/* convert L to triplet form and print it */
666
/* ---------------------------------------------------------------------- */
667
668
/* Note that L is in row-form, so it is the row indices that are created */
669
/* by umfpack_xx_col_to_triplet. */
670
671
printf ("\nConverting L to triplet form, and printing it:\n") ;
672
Li = (Int *) malloc (lnz1 * sizeof (Int)) ;
673
if (!Li)
674
{
675
error ("out of memory") ;
676
}
677
if (umfpack_xx_col_to_triplet (n, Lp, Li) < 0)
678
{
679
error ("umfpack_xx_col_to_triplet failed") ;
680
}
681
printf ("\nL, in triplet form: ") ;
682
(void) umfpack_xx_report_triplet (n, n, lnz, Li, Lj, Lx, Lz, Control) ;
683
684
/* ---------------------------------------------------------------------- */
685
/* save the Numeric object to file, free it, and load it back in */
686
/* ---------------------------------------------------------------------- */
687
688
/* use the default filename, "numeric.umf" */
689
printf ("\nSaving numeric object:\n") ;
690
status = umfpack_xx_save_numeric (Numeric, (char *) NULL) ;
691
if (status < 0)
692
{
693
umfpack_xx_report_status (Control, status) ;
694
error ("umfpack_xx_save_numeric failed") ;
695
}
696
printf ("\nFreeing numeric object:\n") ;
697
umfpack_xx_free_numeric (&Numeric) ;
698
printf ("\nLoading numeric object:\n") ;
699
status = umfpack_xx_load_numeric (&Numeric, (char *) NULL) ;
700
if (status < 0)
701
{
702
umfpack_xx_report_status (Control, status) ;
703
error ("umfpack_xx_load_numeric failed") ;
704
}
705
printf ("\nDone loading numeric object\n") ;
706
707
/* ---------------------------------------------------------------------- */
708
/* solve C'x=b */
709
/* ---------------------------------------------------------------------- */
710
711
status = umfpack_xx_solve (UMFPACK_At, Cp, Ci, Cx, Cz, x, xz, b, bz,
712
Numeric, Control, Info) ;
713
umfpack_xx_report_info (Control, Info) ;
714
if (status < 0)
715
{
716
umfpack_xx_report_status (Control, status) ;
717
error ("umfpack_xx_solve failed") ;
718
}
719
printf ("\nx (solution of C'x=b): ") ;
720
(void) umfpack_xx_report_vector (n, x, xz, Control) ;
721
rnorm = resid (TRUE, Cp, Ci, Cx, Cz) ;
722
printf ("maxnorm of residual: %g\n\n", rnorm) ;
723
724
/* ---------------------------------------------------------------------- */
725
/* solve C'x=b again, using umfpack_xx_wsolve instead */
726
/* ---------------------------------------------------------------------- */
727
728
printf ("\nSolving C'x=b again, using umfpack_xx_wsolve instead:\n") ;
729
Wi = (Int *) malloc (n * sizeof (Int)) ;
730
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
731
:: WSIZE is 5 for the real case, 10 for complex.
732
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
733
W = (double *) malloc (WSIZE*n * sizeof (double)) ;
734
if (!Wi || !W)
735
{
736
error ("out of memory") ;
737
}
738
739
status = umfpack_xx_wsolve (UMFPACK_At, Cp, Ci, Cx, Cz, x, xz, b, bz,
740
Numeric, Control, Info, Wi, W) ;
741
umfpack_xx_report_info (Control, Info) ;
742
if (status < 0)
743
{
744
umfpack_xx_report_status (Control, status) ;
745
error ("umfpack_xx_wsolve failed") ;
746
}
747
printf ("\nx (solution of C'x=b): ") ;
748
(void) umfpack_xx_report_vector (n, x, xz, Control) ;
749
rnorm = resid (TRUE, Cp, Ci, Cx, Cz) ;
750
printf ("maxnorm of residual: %g\n\n", rnorm) ;
751
752
/* ---------------------------------------------------------------------- */
753
/* free everything */
754
/* ---------------------------------------------------------------------- */
755
756
/* This is not strictly required since the process is exiting and the */
757
/* system will reclaim the memory anyway. It's useful, though, just as */
758
/* a list of what is currently malloc'ed by this program. Plus, it's */
759
/* always a good habit to explicitly free whatever you malloc. */
760
761
free (Ap) ;
762
free (Ai) ;
763
free (Ax) ;
764
free (Az) ;
765
766
free (Cp) ;
767
free (Ci) ;
768
free (Cx) ;
769
free (Cz) ;
770
771
free (Pinit) ;
772
free (Qinit) ;
773
free (Front_npivcol) ;
774
free (Front_1strow) ;
775
free (Front_leftmostdesc) ;
776
free (Front_parent) ;
777
free (Chain_start) ;
778
free (Chain_maxrows) ;
779
free (Chain_maxcols) ;
780
781
free (Lp) ;
782
free (Lj) ;
783
free (Lx) ;
784
free (Lz) ;
785
786
free (Up) ;
787
free (Ui) ;
788
free (Ux) ;
789
free (Uz) ;
790
791
free (P) ;
792
free (Q) ;
793
794
free (Li) ;
795
796
free (Wi) ;
797
free (W) ;
798
799
umfpack_xx_free_symbolic (&Symbolic) ;
800
umfpack_xx_free_numeric (&Numeric) ;
801
802
/* ---------------------------------------------------------------------- */
803
/* print the total time spent in this demo */
804
/* ---------------------------------------------------------------------- */
805
806
umfpack_toc (t) ;
807
printf ("\numfpack_xx_demo complete.\nTotal time: %5.2f seconds"
808
" (CPU time), %5.2f seconds (wallclock time)\n", t [1], t [0]) ;
809
return (0) ;
810
}
811
812