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