1 /* ========================================================================== */
2 /* === umfpack tcov ========================================================= */
3 /* ========================================================================== */
4 
5 /* -------------------------------------------------------------------------- */
6 /* Copyright (c) 2005-2012 by Timothy A. Davis, http://www.suitesparse.com.   */
7 /* All Rights Reserved.  See ../Doc/License.txt for License.                  */
8 /* -------------------------------------------------------------------------- */
9 
10 /* (Nearly) exhaustive statement-coverage testing for UMFPACK.  */
11 
12 /* #define DEBUGGING */
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <math.h>
17 #include <sys/types.h>
18 #include <dirent.h>
19 #include <errno.h>
20 #include "umfpack.h"
21 #include "amd.h"
22 #include "umf_internal.h"
23 #include "umf_is_permutation.h"
24 /*
25 #include "umf_free.h"
26 #include "umf_malloc.h"
27 */
28 #include "umf_report_perm.h"
29 #include "umf_realloc.h"
30 #include "umf_free.h"
31 #include "umf_malloc.h"
32 #include "umf_cholmod.h"
33 
34 /*
35 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
36 #include "umf_malloc.h"
37 #endif
38 */
39 
40 #define TOL 1e-3
41 
42 #define INULL ((Int *) NULL)
43 #define DNULL ((double *) NULL)
44 
45 #ifdef COMPLEX
46 #define CARG(real,imag) real,imag
47 #define C1ARG(a) ,a
48 #else
49 #define CARG(real,imag) real
50 #define C1ARG(a)
51 #endif
52 
53 
54 int check_tol ;
55 
divide(double x,double y)56 static double divide (double x, double y)
57 {
58     return (x/y) ;
59 }
60 
61 /* ========================================================================== */
62 /* my_ordering */
63 /* ========================================================================== */
64 
my_ordering(Int nrow,Int ncol,Int sym,Int * Ap,Int * Ai,Int * P,void * params,double * info)65 int my_ordering
66 (
67     Int nrow,
68     Int ncol,
69     Int sym,
70     Int *Ap,
71     Int *Ai,
72     Int *P,         /* size ncol */
73     void *params,
74     double *info
75 )
76 {
77     /* return a valid permutation for use by UMFPACK ... using AMD/COLAMD */
78     return (UMF_cholmod (nrow, ncol, sym, Ap, Ai, P, params, info)) ;
79 }
80 
my_bad_ordering(Int nrow,Int ncol,Int sym,Int * Ap,Int * Ai,Int * P,void * params,double * info)81 int my_bad_ordering
82 (
83     Int nrow,
84     Int ncol,
85     Int sym,
86     Int *Ap,
87     Int *Ai,
88     Int *P,         /* size ncol */
89     void *params,
90     double *info
91 )
92 {
93     /* return an invalid permutation, for testing */
94     Int k, *p ;
95     for (k = 0 ; k < ncol ; k++) P [k] = EMPTY ;
96     p = (Int *) params ;
97     return (p [0]) ;
98 }
99 
100 /* ========================================================================== */
101 /* inv_umfpack_dense: inverse of UMFPACK_DENSE_COUNT */
102 /* ========================================================================== */
103 
104 /* the inverse of UMFPACK_DENSE_COUNT: given a col count, find alpha */
105 
inv_umfpack_dense(Int d,Int n)106 static double inv_umfpack_dense (Int d, Int n)
107 {
108     if (d <= 16)
109     {
110 	return (0.0) ;
111     }
112     else
113     {
114 	return (((double) d) / (16 * sqrt ((double) n))) ;
115     }
116 }
117 
118 
119 /* ========================================================================== */
120 
121 
dump_mat(char * name,Int m,Int n,Int Ap[],Int Ai[],double Ax[],double Az[])122 static void dump_mat (char *name, Int m, Int n, Int Ap [ ], Int Ai [ ], double Ax [ ]
123 #ifdef COMPLEX
124 	, double Az [ ]
125 #endif
126 	)
127 {
128     Entry aa ;
129     Int j, p ;
130 
131     printf ("\n%s = sparse ("ID", "ID") ;\n", name, m, n) ;
132     for (j = 0 ; j < n ; j++)
133     {
134     	for (p = Ap [j] ; p < Ap [j+1] ; p++)
135 	{
136 #ifdef COMPLEX
137 	    ASSIGN (aa, Ax, Az, p, SPLIT (Az)) ;
138 	    printf ("%s ("ID","ID") = %30.20g + (1i * %30.20g);\n",
139 			name, 1+Ai [p], j+1, REAL_COMPONENT(aa), IMAG_COMPONENT(aa)) ;
140 #else
141 	    printf ("%s ("ID","ID") = %30.20g ;\n",
142 			name, 1+Ai [p], j+1, Ax [p]) ;
143 #endif
144 	}
145     }
146 
147 }
148 
149 /* ========================================================================== */
150 
dump_vec(char * name,Int n,double X[],double Xz[])151 static void dump_vec (char *name, Int n, double X [ ], double Xz[ ])
152 {
153     Int j ;
154     printf ("\n%s = [\n", name) ;
155     for (j = 0 ; j < n ; j++)
156     {
157 	printf ("%30.20g", X [j]) ;
158 	if (Xz) printf (" + (1i*%30.20g)", Xz[j]) ;
159 	printf ("\n") ;
160     }
161     printf ("] ; \n") ;
162 }
163 
164 /* ========================================================================== */
165 
dump_perm(char * name,Int n,Int P[])166 static void dump_perm (char *name, Int n, Int P [ ])
167 {
168     Int j ;
169     printf ("\n%s = [\n", name) ;
170     for (j = 0 ; j < n ; j++)
171     {
172 	printf (""ID"\n", 1+P [j]) ;
173     }
174     printf ("] ; \n") ;
175     printf ("%s = %s' ;\n", name, name) ;
176 }
177 
178 /* ========================================================================== */
179 /* error: display message and exit */
180 /* ========================================================================== */
181 
error(char * s,double x)182 static void error (char *s, double x)
183 {
184     printf ("TEST FAILURE: %s %g   ", s, x) ;
185 
186 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
187     printf (" umf_malloc_count "ID"\n", UMF_malloc_count) ;
188 #endif
189 
190     printf ("\n") ;
191     exit (1) ;
192 }
193 
194 /* ========================================================================== */
195 /* resid: compute the (possibly permuted) residual.  return maxnorm of resid */
196 /* ========================================================================== */
197 
resid(Int n,Int Ap[],Int Ai[],double Ax[],double Az[],double x[],double xz[],double b[],double bz[],double r[],double rz[],Int transpose,Int P[],Int Q[],double Wx[])198 static double resid
199 (
200     Int n,
201     Int Ap [ ],
202     Int Ai [ ],
203     double Ax [ ],	double Az [ ],
204     double x [ ],	double xz [ ],
205     double b [ ],	double bz [ ],
206     double r [ ],	double rz [ ],
207     Int transpose,
208     Int P [ ],
209     Int Q [ ],
210     double Wx [ ]	/* size 2*n double workspace */
211 )
212 {
213     Int i, j, k, p ;
214     double norm, ra, *wx, *wz ;
215     Entry bb, xx, aa ;
216 
217     wx = Wx ;
218     wz = wx + n ;
219 
220 /*
221     transpose: UMFPACK_A
222 
223 	r = P'AQ'x - b
224 	Pr = AQ'x - Pb
225 	we compute and return Pr, not r.
226 
227     transpose: UMFPACK_At
228 
229 	r = QA'Px - b
230 	Q'r = A'Px - Q'b
231 	we compute and return Q'r, not r.
232 
233     transpose: UMFPACK_Aat
234 
235 	r = QA.'Px - b
236 	Q'r = A.'Px - Q'b
237 	we compute and return Q'r, not r.
238 
239 */
240 
241     if (transpose == UMFPACK_A)
242     {
243 
244 	if (!P)		/* r = -b */
245 	{
246 	    for (i = 0 ; i < n ; i++)
247 	    {
248 		ASSIGN (bb, b, bz, i, SPLIT(bz)) ;
249 	        r [i] = -REAL_COMPONENT (bb) ;
250 	        rz[i] = -IMAG_COMPONENT (bb) ;
251 	    }
252 	}
253 	else		/* r = -Pb */
254 	{
255 	    for (k = 0 ; k < n ; k++)
256 	    {
257 		ASSIGN (bb, b, bz, P [k], SPLIT(bz)) ;
258 	        r [k] = -REAL_COMPONENT (bb) ;
259 	        rz[k] = -IMAG_COMPONENT (bb) ;
260 	    }
261 	}
262 
263 	if (!Q)		/* w = x */
264 	{
265 	    for (j = 0 ; j < n ; j++)
266 	    {
267 		ASSIGN (xx, x, xz, j, SPLIT(xz)) ;
268 	        wx[j] = REAL_COMPONENT (xx) ;
269 	        wz[j] = IMAG_COMPONENT (xx) ;
270 	    }
271 	}
272 	else		/* w = Q'x */
273 	{
274 	    for (k = 0 ; k < n ; k++)
275 	    {
276 		ASSIGN (xx, x, xz, Q [k], SPLIT(xz)) ;
277 	        wx[k] = REAL_COMPONENT (xx) ;
278 	        wz[k] = IMAG_COMPONENT (xx) ;
279 	    }
280 	}
281 
282 	/* r = r + Aw */
283 	for (j = 0 ; j < n ; j++)
284 	{
285 	    for (p = Ap [j] ; p < Ap [j+1] ; p++)
286 	    {
287 		i = Ai [p] ;
288 		ASSIGN (aa, Ax, Az, p, SPLIT(Az)) ;
289 		r [i] += REAL_COMPONENT(aa) * wx[j] ;
290                 r [i] -= IMAG_COMPONENT(aa) * wz[j] ;
291                 rz[i] += IMAG_COMPONENT(aa) * wx[j] ;
292                 rz[i] += REAL_COMPONENT(aa) * wz[j] ;
293 	    }
294 	}
295 
296 	/* note that we just computed Pr, not r */
297 
298     }
299     else if (transpose == UMFPACK_At)
300     {
301 
302 	if (!Q)		/* r = -b */
303 	{
304 	    for (i = 0 ; i < n ; i++)
305 	    {
306 		ASSIGN (bb, b, bz, i, SPLIT(bz)) ;
307 	        r [i] = -REAL_COMPONENT (bb) ;
308 	        rz[i] = -IMAG_COMPONENT (bb) ;
309 	    }
310 	}
311 	else		/* r = -Q'b */
312 	{
313 	    for (k = 0 ; k < n ; k++)
314 	    {
315 		ASSIGN (bb, b, bz, Q [k], SPLIT(bz)) ;
316 	        r [k] = -REAL_COMPONENT (bb) ;
317 	        rz[k] = -IMAG_COMPONENT (bb) ;
318 	    }
319 	}
320 
321 	if (!P)		/* w = x */
322 	{
323 	    for (j = 0 ; j < n ; j++)
324 	    {
325 		ASSIGN (xx, x, xz, j, SPLIT(xz)) ;
326 	        wx[j] = REAL_COMPONENT (xx) ;
327 	        wz[j] = IMAG_COMPONENT (xx) ;
328 	    }
329 	}
330 	else		/* w = Px */
331 	{
332 	    for (k = 0 ; k < n ; k++)
333 	    {
334 		ASSIGN (xx, x, xz, P [k], SPLIT(xz)) ;
335 	        wx[k] = REAL_COMPONENT (xx) ;
336 	        wz[k] = IMAG_COMPONENT (xx) ;
337 	    }
338 	}
339 
340 	/* r = r + A'w */
341 	for (j = 0 ; j < n ; j++)
342 	{
343 	    for (p = Ap [j] ; p < Ap [j+1] ; p++)
344 	    {
345 		i = Ai [p] ;
346 		ASSIGN (aa, Ax, Az, p, SPLIT(Az)) ;
347 		/* complex conjugate */
348 		r [j] += REAL_COMPONENT(aa) * wx[i] ;
349                 r [j] += IMAG_COMPONENT(aa) * wz[i] ;
350                 rz[j] -= IMAG_COMPONENT(aa) * wx[i] ;
351                 rz[j] += REAL_COMPONENT(aa) * wz[i] ;
352 	    }
353 	}
354 
355 	/* note that we just computed Q'r, not r */
356 
357     }
358     else if (transpose == UMFPACK_Aat)
359     {
360 
361 	if (!Q)		/* r = -b */
362 	{
363 	    for (i = 0 ; i < n ; i++)
364 	    {
365 		ASSIGN (bb, b, bz, i, SPLIT(bz)) ;
366 	        r [i] = -REAL_COMPONENT (bb) ;
367 	        rz[i] = -IMAG_COMPONENT (bb) ;
368 	    }
369 	}
370 	else		/* r = -Q'b */
371 	{
372 	    for (k = 0 ; k < n ; k++)
373 	    {
374 		ASSIGN (bb, b, bz, Q [k], SPLIT(bz)) ;
375 	        r [k] = -REAL_COMPONENT (bb) ;
376 	        rz[k] = -IMAG_COMPONENT (bb) ;
377 	    }
378 	}
379 
380 	if (!P)		/* w = x */
381 	{
382 	    for (j = 0 ; j < n ; j++)
383 	    {
384 		ASSIGN (xx, x, xz, j, SPLIT(xz)) ;
385 	        wx[j] = REAL_COMPONENT (xx) ;
386 	        wz[j] = IMAG_COMPONENT (xx) ;
387 	    }
388 	}
389 	else		/* w = Px */
390 	{
391 	    for (k = 0 ; k < n ; k++)
392 	    {
393 		ASSIGN (xx, x, xz, P [k], SPLIT(xz)) ;
394 	        wx[k] = REAL_COMPONENT (xx) ;
395 	        wz[k] = IMAG_COMPONENT (xx) ;
396 	    }
397 	}
398 
399 	/* r = r + A.'w */
400 	for (j = 0 ; j < n ; j++)
401 	{
402 	    for (p = Ap [j] ; p < Ap [j+1] ; p++)
403 	    {
404 		i = Ai [p] ;
405 		ASSIGN (aa, Ax, Az, p, SPLIT(Az)) ;
406 		/* not complex conjugate */
407 		r [j] += REAL_COMPONENT(aa) * wx[i] ;
408                 r [j] -= IMAG_COMPONENT(aa) * wz[i] ;
409                 rz[j] += IMAG_COMPONENT(aa) * wx[i] ;
410                 rz[j] += REAL_COMPONENT(aa) * wz[i] ;
411 	    }
412 	}
413 
414 	/* note that we just computed Q'r, not r */
415 
416     }
417 
418     norm = 0. ;
419     for (i = 0 ; i < n ; i++)
420     {
421 	Entry rr ;
422 
423 	/* --- */
424 	/* ASSIGN (rr, r [i], rz [i]) ; */
425 	ASSIGN (rr, r, rz, i, TRUE) ;
426 	/* --- */
427 
428 	ABS (ra, rr) ;
429 	norm = MAX (norm, ra) ;
430     }
431     return (norm) ;
432 }
433 
434 
435 /* ========================================================================== */
436 /* irand:  return a random Integer in the range 0 to n-1 */
437 /* ========================================================================== */
438 
irand(Int n)439 static Int irand (Int n)
440 {
441     return (rand ( ) % n) ;
442 }
443 
444 /* ========================================================================== */
445 /* xrand:  return a random double, > 0 and <= 1 */
446 /* ========================================================================== */
447 
448 /* rand ( ) returns an Integer in the range 0 to RAND_MAX */
449 
xrand()450 static double xrand ( )
451 {
452     return ((1.0 + (double) rand ( )) / (1.0 + (double) RAND_MAX)) ;
453 }
454 
455 
456 /* ========================================================================== */
457 /* randperm:  generate a random permutation of 0..n-1 */
458 /* ========================================================================== */
459 
randperm(Int n,Int P[])460 static void randperm (Int n, Int P [ ])
461 {
462     Int i, t, k ;
463     for (i = 0 ; i < n ; i++)
464     {
465 	P [i] = i ;
466     }
467     for (i = n-1 ; i > 0 ; i--)
468     {
469 	k = irand (i) ;
470 	/* swap positions i and k */
471 	t = P [k] ;
472 	P [k] = P [i] ;
473 	P [i] = t ;
474     }
475 }
476 
477 /* ========================================================================== */
478 /* do_solvers:  test Ax=b, etc */
479 /* ========================================================================== */
480 
do_solvers(Int n_row,Int n_col,Int Ap[],Int Ai[],double Ax[],double Az[],double b[],double bz[],double Control[],double Info[],void * Numeric,Int Lp[],Int Li[],double Lx[],double Lz[],Int Up[],Int Ui[],double Ux[],double Uz[],Int P[],Int Q[],double x[],double xz[],double r[],double rz[],Int W[],double Wx[],Int split)481 static double do_solvers
482 (
483     Int n_row,
484     Int n_col,
485     Int Ap [ ],
486     Int Ai [ ],
487     double Ax [ ],		double Az [ ],
488     double b [ ],		double bz [ ],
489     double Control [ ],
490     double Info [ ],
491     void *Numeric,
492     Int Lp [ ],
493     Int Li [ ],
494     double Lx [ ],		double Lz [ ],
495     Int Up [ ],
496     Int Ui [ ],
497     double Ux [ ],		double Uz [ ],
498     Int P [ ],
499     Int Q [ ],
500     double x [ ],		double xz [ ],
501     double r [ ],		double rz [ ],
502     Int W [ ],
503     double Wx [ ],
504     Int split	    /* TRUE if complex variables split, FALSE if merged */
505 )
506 {
507     double maxrnorm = 0.0, rnorm, xnorm, xa, xaz, *Rb, *Rbz,
508 	*y, *yz, *Rs, *Cx, *Cz ;
509     double Con [UMFPACK_CONTROL] ;
510     Int *noP = INULL, *noQ = INULL, irstep, orig, i, prl, status, n,
511 	s1, s2, do_recip, *Cp, *Ci, nz, scale ;
512     Entry bb, xx, xtrue ;
513     NumericType *Num ;
514 
515 #ifdef COMPLEX
516     if (split)
517     {
518 	if (!Az || !bz || !xz || !Lz || !Uz || !xz) error ("bad split\n", 0.) ;
519     }
520     else
521     {
522 	if ( Az ||  bz ||  xz ||  Lz ||  Uz ||  xz) error ("bad merge\n", 0.) ;
523     }
524     /* rz is never passed to umfpack, and is always split in ut.c */
525     if (!rz) error ("bad rz\n", 0.) ;
526 #endif
527 
528     /* ---------------------------------------------------------------------- */
529     /* get parameters */
530     /* ---------------------------------------------------------------------- */
531 
532     n = MAX (n_row, n_col) ;
533     if (n == 0) error ("n zero", 0.) ;
534     /* n = MAX (n,1) ; */
535     /* n_inner = MIN (n_row, n_col) ; */
536 
537     if (Control)
538     {
539 	orig = Control [UMFPACK_IRSTEP] ;
540 	prl = Control [UMFPACK_PRL] ;
541     }
542     else
543     {
544 	prl = UMFPACK_DEFAULT_PRL ;
545     }
546 
547     if (n_row == n_col)
548     {
549 	nz = Ap [n_col] ;
550 	nz = MAX (nz, Lp [n_col]) ;
551 	nz = MAX (nz, Up [n_col]) ;
552 	Cp = (Int *) malloc ((n_col+1) * sizeof (Int)) ;
553 	Ci = (Int *) malloc ((nz+1) * sizeof (Int)) ;
554 	Cx = (double *) calloc (2*(nz+1) , sizeof (double)) ;
555 	if (split)
556 	{
557 	    Cz = Cx + nz ;
558 	}
559 	else
560 	{
561 	    Cz = DNULL ;
562 	}
563 	if (!Cp || !Ci || !Cx) error ("out of memory (0)", 0.) ;
564     }
565     else
566     {
567 	Cp = INULL ;
568 	Ci = INULL ;
569 	Cx = DNULL ;
570     }
571 
572     Num = (NumericType *) Numeric ;
573     scale = (Num->Rs != DNULL) ;
574 
575     /* ---------------------------------------------------------------------- */
576     /* error handling */
577     /* ---------------------------------------------------------------------- */
578 
579     if (n_row != n_col)
580     {
581 	status = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(Ax,Az) , CARG(x,xz), CARG(b,bz), Numeric, DNULL, DNULL) ;
582 	if (status != UMFPACK_ERROR_invalid_system) error ("rectangular Ax=b should have failed\n", 0.) ;
583     }
584     else
585     {
586 	status = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(Ax,Az) , CARG(DNULL,xz), CARG(b,bz), Numeric, DNULL, DNULL) ;
587 	if (status != UMFPACK_ERROR_argument_missing) error ("missing x should have failed\n", 0.) ;
588 	status = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(DNULL,Az) , CARG(DNULL,xz), CARG(b,bz), Numeric, DNULL, DNULL) ;
589 	if (status != UMFPACK_ERROR_argument_missing) error ("missing Ax should have failed\n", 0.) ;
590     }
591 
592     /* ---------------------------------------------------------------------- */
593     /* Ax=b */
594     /* ---------------------------------------------------------------------- */
595 
596     for (irstep = -1 ; irstep <= 3 ; irstep++)
597     {
598 	if (Control)
599 	{
600 	    for (i = 0 ; i < UMFPACK_CONTROL ; i++) Con [i] = Control [i] ;
601 	}
602 	else
603 	{
604 	    UMFPACK_defaults (Con) ;
605 	}
606 	Con [UMFPACK_PRL] = prl ;
607 	Con [UMFPACK_IRSTEP] = MAX (0, irstep) ;
608 
609 	if (prl >= 2) printf ("1: do solve: Ax=b: "ID"\n", irstep) ;
610 	if (irstep == -1)
611 	{
612 	    status = UMFPACK_solve (UMFPACK_A, INULL, INULL, CARG(DNULL,DNULL) , CARG(x,xz), CARG(b,bz), Numeric, Con, Info) ;
613 	}
614 	else
615 	{
616 	    status = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(Ax,Az) , CARG(x,xz), CARG(b,bz), Numeric, Con, Info) ;
617 	}
618 	UMFPACK_report_status (Con, status) ;
619 	UMFPACK_report_info (Con, Info) ;
620 	if (n_row != n_col)
621 	{
622 	    if (status != UMFPACK_ERROR_invalid_system)
623 	    {
624 		dump_mat ("A", n_row, n_col, Ap, Ai, CARG(Ax,Az)) ;
625 	    	error ("rectangular Ax=b should have failed\n", 0.) ;
626 	    }
627 	    /* return immediately if the matrix is rectangular */
628 	    return (0.) ;
629 	}
630 	if (status == UMFPACK_WARNING_singular_matrix)
631 	{
632 	    if (prl >= 2) printf ("Ax=b singular\n") ;
633 	}
634 	else if (status != UMFPACK_OK)
635 	{
636 	    dump_mat ("A", n, n, Ap, Ai, CARG(Ax,Az)) ;
637 	    error ("Ax=b failed\n", 0.) ;
638 	}
639 	else
640 	{
641 	    rnorm = resid (n, Ap, Ai, Ax, Az, x, xz, b, bz, r, rz, UMFPACK_A, noP, noQ, Wx) ;
642 	    if (prl >= 2) printf ("1: rnorm Ax=b is %g\n", rnorm) ;
643 	    maxrnorm = MAX (rnorm, maxrnorm) ;
644 
645 	    /* compare x with xtrue */
646 	    xnorm = 0. ;
647 	    for (i = 0 ; i < n ; i++)
648 	    {
649 	        REAL_COMPONENT(xtrue) = 1.0 + ((double) i) / ((double) n) ;
650 #ifdef COMPLEX
651 	        IMAG_COMPONENT(xtrue) = 1.3 - ((double) i) / ((double) n) ;
652 #endif
653 		/* --- */
654 		/* ASSIGN (xx, x [i] - xtrue, xz[i]-xtruez) ; */
655 		ASSIGN (xx, x, xz, i, SPLIT(xz)) ;
656 		DECREMENT (xx, xtrue) ;
657 		/* --- */
658 
659 	        ABS (xa, xx) ;
660 	        xnorm = MAX (xnorm, xa) ;
661 	    }
662 
663 #if 0
664 	    { FILE *f ;
665 		char s [200] ;
666 		sprintf (s, "b_XXXXXX") ;
667 		mkstemp (s) ;
668 		f = fopen (s, "w") ;
669 		for (i = 0 ; i < n ; i++) fprintf (f, "%40.25e %40.25e\n", b [i], bz [i]) ;
670 		fclose (f) ;
671 		s [0] = 'x' ;
672 		f = fopen (s, "w") ;
673 		for (i = 0 ; i < n ; i++) fprintf (f, "%40.25e %40.25e\n", x [i], xz [i]) ;
674 		fclose (f) ;
675 	    }
676 #endif
677 
678 	    if (check_tol && (status == UMFPACK_OK && (rnorm > TOL || xnorm > TOL)))
679 	    {
680 		Con [UMFPACK_PRL] = 5 ;
681 		UMFPACK_report_control (Con) ;
682 	        printf ("Ax=b inaccurate %g %g\n", rnorm, xnorm) ;
683 		dump_mat ("A", n, n, Ap, Ai, CARG(Ax,Az)) ;
684 	        printf ("\nb: ") ;
685 	        UMFPACK_report_vector (n, CARG(b,bz), Con) ;
686 	        printf ("\nx: ") ;
687 	        UMFPACK_report_vector (n, CARG(x,xz), Con) ;
688 		error ("Ax=b inaccurate", MAX (rnorm, xnorm)) ;
689 	    }
690 
691 	    maxrnorm = MAX (xnorm, maxrnorm) ;
692 	}
693 
694 #ifdef DEBUGGING
695 	printf ("\n") ;
696 #endif
697 	if (prl >= 2) printf ("Ax=b irstep "ID" attempted %g\n", irstep, Info [UMFPACK_IR_ATTEMPTED]) ;
698 	if (irstep > Info [UMFPACK_IR_ATTEMPTED])
699 	{
700 	    break ;
701 	}
702     }
703 
704     if (n != n_row && n != n_col && n <= 0) error ("huh?", 0.) ;
705 
706     /* ---------------------------------------------------------------------- */
707     /* A'x=b */
708     /* ---------------------------------------------------------------------- */
709 
710     for (irstep = 0 ; irstep <= 3 ; irstep++)
711     {
712 	if (Control)
713 	{
714 	    for (i = 0 ; i < UMFPACK_CONTROL ; i++) Con [i] = Control [i] ;
715 	}
716 	else
717 	{
718 	    UMFPACK_defaults (Con) ;
719 	}
720 	Con [UMFPACK_PRL] = prl ;
721 	Con [UMFPACK_IRSTEP] = irstep ;
722 
723 	if (prl >= 2) printf ("do solve: A'x=b: "ID"\n", irstep) ;
724 	status = UMFPACK_solve (UMFPACK_At, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Con, Info) ;
725 	UMFPACK_report_status (Con, status) ;
726 	/* UMFPACK_report_info (Con, Info) ; */
727 	if (status == UMFPACK_WARNING_singular_matrix)
728 	{
729 	    if (prl >= 2) printf ("A'x=b singular\n") ;
730 	}
731 	else if (status != UMFPACK_OK)
732 	{
733 	    dump_mat ("A", n, n, Ap, Ai, CARG(Ax,Az)) ;
734 	    error ("A'x=b failed\n", 0.) ;
735 	}
736 	else
737 	{
738 	    rnorm = resid (n, Ap, Ai, Ax, Az, x, xz, b, bz, r, rz, UMFPACK_At, noP, noQ, Wx) ;
739 
740 	    if (prl  >= 2) printf ("2: rnorm A'x=b is %g\n", rnorm) ;
741 	    if (check_tol && rnorm > TOL)
742 	    {
743 		Con [UMFPACK_PRL] = 99 ;
744 	        printf ("A'x=b inaccurate %g\n", rnorm) ;
745 		dump_mat ("A", n, n, Ap, Ai, CARG(Ax,Az)) ;
746 		/*
747 	        printf ("\nA: ") ;
748 	        UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Con) ;
749 	        printf ("\nb: ") ;
750 	        UMFPACK_report_vector (n, CARG(b,bz), Con) ;
751 	        printf ("\nx: ") ;
752 	        UMFPACK_report_vector (n, CARG(x,xz), Con) ;
753 		error ("A'x=b inaccurate", MAX (rnorm, xnorm)) ;
754 		*/
755 	    }
756 	    maxrnorm = MAX (rnorm, maxrnorm) ;
757 
758 	    /* also check using UMFPACK_transpose */
759 	    status = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), noP, noQ, Cp, Ci, CARG(Cx,Cz) C1ARG(1)) ;
760 	    if (status != UMFPACK_OK)
761 	    {
762 		error ("transposed A'x=b failed\n", 0.) ;
763 	    }
764 
765 	    rnorm = resid (n, Cp, Ci, Cx, Cz, x, xz, b, bz, r, rz, UMFPACK_A, noP, noQ, Wx) ;
766 
767 	    if (prl  >= 2) printf ("2b: rnorm A'x=b is %g\n", rnorm) ;
768 	    if (check_tol && rnorm > TOL)
769 	    {
770 		Con [UMFPACK_PRL] = 99 ;
771 	        printf ("transpose A'x=b inaccurate %g\n", rnorm) ;
772 		/*
773 	        printf ("\nA: ") ;
774 	        UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Con) ;
775 	        printf ("\nb: ") ;
776 	        UMFPACK_report_vector (n, CARG(b,bz), Con) ;
777 	        printf ("\nx: ") ;
778 	        UMFPACK_report_vector (n, CARG(x,xz), Con) ;
779 		error ("A'x=b inaccurate", MAX (rnorm, xnorm)) ;
780 		*/
781 	    }
782 	    maxrnorm = MAX (rnorm, maxrnorm) ;
783 
784 	}
785 	if (prl >= 2) printf ("A'x=b irstep "ID" attempted %g\n", irstep, Info [UMFPACK_IR_ATTEMPTED]) ;
786 	if (irstep > Info [UMFPACK_IR_ATTEMPTED])
787 	{
788 	    break ;
789 	}
790     }
791 
792     /* ---------------------------------------------------------------------- */
793     /* A.'x=b */
794     /* ---------------------------------------------------------------------- */
795 
796     for (irstep = 0 ; irstep <= 3 ; irstep++)
797     {
798 	if (Control)
799 	{
800 	    for (i = 0 ; i < UMFPACK_CONTROL ; i++) Con [i] = Control [i] ;
801 	}
802 	else
803 	{
804 	    UMFPACK_defaults (Con) ;
805 	}
806 	Con [UMFPACK_PRL] = prl ;
807 	Con [UMFPACK_IRSTEP] = irstep ;
808 
809 	if (prl >= 2) printf ("do solve: A.'x=b: "ID"\n", irstep) ;
810 	status = UMFPACK_solve (UMFPACK_Aat, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Con, Info) ;
811 	UMFPACK_report_status (Con, status) ;
812 	/* UMFPACK_report_info (Con, Info) ; */
813 	if (status == UMFPACK_WARNING_singular_matrix)
814 	{
815 	    if (prl >= 2) printf ("A.'x=b singular\n") ;
816 	}
817 	else if (status != UMFPACK_OK)
818 	{
819 	    dump_mat ("A", n, n, Ap, Ai, CARG(Ax,Az)) ;
820 	    error ("A.'x=b failed\n", 0.) ;
821 	}
822 	else
823 	{
824 	    rnorm = resid (n, Ap, Ai, Ax, Az, x, xz, b, bz, r, rz, UMFPACK_Aat, noP, noQ, Wx) ;
825 	    if (prl >= 2) printf ("3: rnorm A.'x=b is %g\n", rnorm) ;
826 	    if (check_tol && rnorm > TOL)
827 	    {
828 		Con [UMFPACK_PRL] = 99 ;
829 	        printf ("A.'x=b inaccurate %g\n", rnorm) ;
830 		/*
831 		dump_mat ("A", n, n, Ap, Ai, CARG(Ax,Az)) ;
832 	        printf ("\nA: ") ;
833 	        UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Con) ;
834 	        printf ("\nb: ") ;
835 	        UMFPACK_report_vector (n, CARG(b,bz), Con) ;
836 	        printf ("\nx: ") ;
837 	        UMFPACK_report_vector (n, CARG(x,xz), Con) ;
838 	        error ("A.'x=b inaccurate %g\n", MAX (rnorm, xnorm)) ;
839 		*/
840 	    }
841 	    maxrnorm = MAX (rnorm, maxrnorm) ;
842 
843 	    /* also check using UMFPACK_transpose */
844 	    status = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), noP, noQ, Cp, Ci, CARG(Cx,Cz) C1ARG(0)) ;
845 	    if (status != UMFPACK_OK)
846 	    {
847 		error ("transposed A.'x=b failed\n", 0.) ;
848 	    }
849 
850 	    rnorm = resid (n, Cp, Ci, Cx, Cz, x, xz, b, bz, r, rz, UMFPACK_A, noP, noQ, Wx) ;
851 
852 	    if (prl  >= 2) printf ("2b: rnorm A'x=b is %g\n", rnorm) ;
853 	    if (check_tol && rnorm > TOL)
854 	    {
855 		Con [UMFPACK_PRL] = 99 ;
856 	        printf ("transpose A'x=b inaccurate %g\n", rnorm) ;
857 		/*
858 	        printf ("\nA: ") ;
859 	        UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Con) ;
860 	        printf ("\nb: ") ;
861 	        UMFPACK_report_vector (n, CARG(b,bz), Con) ;
862 	        printf ("\nx: ") ;
863 	        UMFPACK_report_vector (n, CARG(x,xz), Con) ;
864 		error ("A'x=b inaccurate", MAX (rnorm, xnorm)) ;
865 		*/
866 	    }
867 	    maxrnorm = MAX (rnorm, maxrnorm) ;
868 	}
869 	if (prl >= 2) printf ("A.'x=b irstep "ID" attempted %g\n", irstep, Info [UMFPACK_IR_ATTEMPTED]) ;
870 	if (irstep > Info [UMFPACK_IR_ATTEMPTED])
871 	{
872 	    break ;
873 	}
874     }
875 
876     if (Control)
877     {
878 	for (i = 0 ; i < UMFPACK_CONTROL ; i++) Con [i] = Control [i] ;
879     }
880     else
881     {
882 	UMFPACK_defaults (Con) ;
883     }
884 
885     /* ---------------------------------------------------------------------- */
886     /* wsolve Ax=b */
887     /* ---------------------------------------------------------------------- */
888 
889     /* printf ("do wsolve: Ax=b:\n") ; */
890     if (Control) Control [UMFPACK_IRSTEP] = 1 ;
891     if (prl >= 2) printf ("2: do solve: Ax=b: "ID" (wsolve) \n", irstep) ;
892     status = UMFPACK_wsolve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info, W, Wx) ;
893     /* UMFPACK_report_info (Control, Info) ; */
894     if (status == UMFPACK_WARNING_singular_matrix)
895     {
896 	if (prl >= 2) printf ("Ax=b wsolve singular\n") ;
897     }
898     else if (status != UMFPACK_OK)
899     {
900 	dump_mat ("A", n, n, Ap, Ai, CARG(Ax,Az)) ;
901 	error ("Ax=b wsolve failure\n", 0.) ;
902     }
903     else
904     {
905         rnorm = resid (n, Ap, Ai, Ax, Az, x, xz, b, bz, r, rz, UMFPACK_A, noP, noQ, Wx) ;
906 	if (prl >= 2) printf ("4: rnorm Ax=b is %g\n", rnorm) ;
907         if (check_tol && rnorm > TOL)
908         {
909 	    dump_mat ("A", n, n, Ap, Ai, CARG(Ax,Az)) ;
910     	    error ("wsolve inaccurate %g\n", rnorm) ;
911         }
912 	maxrnorm = MAX (rnorm, maxrnorm) ;
913     }
914 
915     if (Control) Control [UMFPACK_IRSTEP] = orig ;
916 
917     /* ---------------------------------------------------------------------- */
918     /* allocate workspace */
919     /* ---------------------------------------------------------------------- */
920 
921     /*
922     prl = 999 ;
923     */
924 
925     Rs  = (double *) malloc (n * sizeof (double)) ;  /* [ */
926     Rb  = (double *) calloc (2*n , sizeof (double)) ;  /* [ */
927     y   = (double *) calloc (2*n , sizeof (double)) ;  /* [ */
928 
929     /* ---------------------------------------------------------------------- */
930     /* Ax=b with individual calls */
931     /* ---------------------------------------------------------------------- */
932 
933     if (split)
934     {
935 	yz = y + n ;
936 	Rbz = Rb + n ;
937     }
938     else
939     {
940 	yz = DNULL ;
941 	Rbz = DNULL ;
942     }
943 
944     /* status = UMFPACK_get_scale (Rs, Numeric) ; */
945     status = UMFPACK_get_numeric (
946 	    INULL, INULL, CARG(DNULL,DNULL),
947 	    INULL, INULL, CARG(DNULL,DNULL),
948 	    INULL, INULL, CARG (DNULL,DNULL), &do_recip, Rs, Numeric) ;
949     if (status != UMFPACK_OK) error ("get Rs failed", (double) status) ;
950 
951     /*
952     printf ("Rs:\n") ;
953     for (i = 0 ; i < n ; i++)
954     {
955 	printf ("   Rs [%d] = %g\n", i, Rs [i]) ;
956     }
957     */
958 
959     if (prl >= 2) printf ("3: do solve: Ax=b in different steps:\n") ;
960     /* Rb = R*b */
961     /* dump_vec ("b", n, b, bz) ; */
962     status = UMFPACK_scale (CARG (Rb, Rbz), CARG (b,bz), Numeric) ;
963     if (status != UMFPACK_OK) error ("Rb failed", (double) status) ;
964     /* dump_vec ("R*b", n, Rb, Rbz) ; */
965 
966     /*
967     UMFPACK_defaults (Con) ;
968     Con [UMFPACK_PRL] = 999 ;
969     printf ("Rb:\n") ;
970     UMFPACK_report_vector (n, CARG(Rb,Rbz), Con) ;
971     printf ("b:\n") ;
972     UMFPACK_report_vector (n, CARG(b,bz), Con) ;
973     error ("finish early\n", rnorm) ;
974     */
975 
976     /* solve Ly = P*(Rb) */
977     s1 = UMFPACK_solve (UMFPACK_Pt_L, Ap, Ai, CARG(Ax,Az), CARG(y,yz), CARG(Rb,Rbz), Numeric, Control, Info) ;
978     if (! (s1 == UMFPACK_OK || s1 == UMFPACK_WARNING_singular_matrix))
979     {
980 	error ("P'Ly=Rb failed", (double) status) ;
981     }
982     /* solve UQ'x=y */
983     s2 = UMFPACK_solve (UMFPACK_U_Qt, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(y,yz), Numeric, Control, Info) ;
984     if (! (s2 == UMFPACK_OK || s2 == UMFPACK_WARNING_singular_matrix))
985     {
986 	error ("UQ'x=y  failed", (double) status) ;
987     }
988     if (s1 == UMFPACK_OK && s2 == UMFPACK_OK)
989     {
990 	rnorm = resid (n, Ap, Ai, Ax, Az, x, xz, b, bz, r, rz, UMFPACK_A, noP, noQ, Wx) ;
991 	if (prl >= 2) printf ("5: rnorm Ax=b is %g\n", rnorm) ;
992         if (check_tol && rnorm > TOL)
993         {
994 	    /* error ("Ax=b (different steps) inaccurate ", rnorm) ; */
995 	    printf ("Ax=b (different steps) inaccurate  %g !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", rnorm) ;
996         }
997 	maxrnorm = MAX (rnorm, maxrnorm) ;
998     }
999 
1000     if (prl >= 2) printf ("4: do solve: Ax=b, different steps, own scale:\n") ;
1001     /* Rb = R*b */
1002 
1003     if (do_recip)
1004     {
1005 	for (i = 0 ; i < n ; i++)
1006 	{
1007 	    ASSIGN (bb, b, bz, i, SPLIT(bz)) ;
1008 	    SCALE (bb, Rs [i]) ;
1009 
1010 	    if (split)
1011 	    {
1012 		Rb  [i] = REAL_COMPONENT(bb) ;
1013 		Rbz [i] = IMAG_COMPONENT(bb) ;
1014 	    }
1015 	    else
1016 	    {
1017 		Rb [2*i] = REAL_COMPONENT(bb) ;
1018 		Rb [2*i+1] = IMAG_COMPONENT(bb) ;
1019 	    }
1020 
1021 	    /*
1022 	    Rb  [i] = REAL_COMPONENT(bb) * Rs [i] ;
1023 	    Rbz [i] = IMAG_COMPONENT(bb) * Rs [i] ;
1024 	    */
1025 	}
1026     }
1027     else
1028     {
1029 	for (i = 0 ; i < n ; i++)
1030 	{
1031 	    ASSIGN (bb, b, bz, i, SPLIT(bz)) ;
1032 	    SCALE_DIV (bb, Rs [i]) ;
1033 
1034 	    if (split)
1035 	    {
1036 		Rb  [i] = REAL_COMPONENT(bb) ;
1037 		Rbz [i] = IMAG_COMPONENT(bb) ;
1038 	    }
1039 	    else
1040 	    {
1041 		Rb [2*i] = REAL_COMPONENT(bb) ;
1042 		Rb [2*i+1] = IMAG_COMPONENT(bb) ;
1043 	    }
1044 
1045 	    /*
1046 	    Rb  [i] = REAL_COMPONENT(bb) / Rs [i] ;
1047 	    Rbz [i] = IMAG_COMPONENT(bb) / Rs [i] ;
1048 	    */
1049 	}
1050     }
1051 
1052     /* solve Ly = P*(Rb) */
1053     s1 = UMFPACK_solve (UMFPACK_Pt_L, Ap, Ai, CARG(Ax,Az), CARG(y,yz), CARG(Rb,Rbz), Numeric, Control, Info) ;
1054     if (! (s1 == UMFPACK_OK || s1 == UMFPACK_WARNING_singular_matrix))
1055     {
1056 	error ("P'Ly=Rb failed", (double) status) ;
1057     }
1058     /* solve UQ'x=y */
1059     s2 = UMFPACK_solve (UMFPACK_U_Qt, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(y,yz), Numeric, Control, Info) ;
1060     if (! (s2 == UMFPACK_OK || s2 == UMFPACK_WARNING_singular_matrix))
1061     {
1062 	error ("UQ'x=y  failed", (double) status) ;
1063     }
1064     if (s1 == UMFPACK_OK && s2 == UMFPACK_OK)
1065     {
1066 	rnorm = resid (n, Ap, Ai, Ax, Az, x, xz, b, bz, r, rz, UMFPACK_A, noP, noQ, Wx) ;
1067 	if (prl >= 2) printf ("6: rnorm Ax=b is %g\n", rnorm) ;
1068         if (check_tol && rnorm > TOL)
1069         {
1070 	    error ("Ax=b (different steps, own scale) inaccurate ", rnorm) ;
1071         }
1072 	maxrnorm = MAX (rnorm, maxrnorm) ;
1073     }
1074 
1075     /* ---------------------------------------------------------------------- */
1076     /* (PAQ)'x=b with individual calls, no scaling */
1077     /* ---------------------------------------------------------------------- */
1078 
1079     if (!scale)
1080     {
1081 	int k ;
1082 
1083 	s1 = UMFPACK_solve (UMFPACK_Ut, Ap, Ai, CARG(Ax,Az), CARG(y,yz), CARG(b,bz), Numeric, Control, Info) ;
1084 	if (! (s1 == UMFPACK_OK || s1 == UMFPACK_WARNING_singular_matrix))
1085 	{
1086 	    error ("U'y=b failed", (double) status) ;
1087 	}
1088 	s2 = UMFPACK_solve (UMFPACK_Lt, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(y,yz), Numeric, Control, Info) ;
1089 	if (! (s2 == UMFPACK_OK || s2 == UMFPACK_WARNING_singular_matrix))
1090 	{
1091 	    error ("L'x=y failed", (double) status) ;
1092 	}
1093 
1094 	/* check using UMFPACK_transpose */
1095 	if (s1 == UMFPACK_OK && s2 == UMFPACK_OK)
1096 	{
1097 	    status = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), P, Q, Cp, Ci, CARG(Cx,Cz) C1ARG(1)) ;
1098 	    if (status != UMFPACK_OK)
1099 	    {
1100 		error ("transposed (PAQ)'x=b failed\n", 0.) ;
1101 	    }
1102 	    rnorm = resid (n, Cp, Ci, Cx, Cz, x, xz, b, bz, r, rz, UMFPACK_A, noP, noQ, Wx) ;
1103 	    if (prl >= 2) printf ("99b: rnorm (PAQ)'x=b is %g\n", rnorm) ;
1104 	    if (check_tol && rnorm > TOL)
1105 	    {
1106 		dump_mat ("A", n, n, Ap, Ai, CARG(Ax,Az)) ;
1107 		dump_mat ("C", n, n, Cp, Ci, CARG(Cx,Cz)) ;
1108 		dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1109 		dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1110 
1111 		printf ("P = [ ") ;
1112                 for (k = 0 ; k < n ; k++)
1113                 {
1114                     printf (ID" ", P [k]) ;
1115                 }
1116                 printf ("]\n") ;
1117 		printf ("Q = [ ") ;
1118                 for (k = 0 ; k < n ; k++)
1119                 {
1120                     printf (ID" ", Q [k]) ;
1121                 }
1122                 printf ("]\n") ;
1123 
1124 		error ("transposed (PAQ)'x=b inaccurate\n",rnorm) ;
1125 	    }
1126 	    maxrnorm = MAX (rnorm, maxrnorm) ;
1127 	}
1128     }
1129 
1130     /* ---------------------------------------------------------------------- */
1131     /* (PAQ).'x=b with individual calls, no scaling */
1132     /* ---------------------------------------------------------------------- */
1133 
1134     if (!scale)
1135     {
1136 	int k ;
1137 
1138 	s1 = UMFPACK_solve (UMFPACK_Uat, Ap, Ai, CARG(Ax,Az), CARG(y,yz), CARG(b,bz), Numeric, Control, Info) ;
1139 	if (! (s1 == UMFPACK_OK || s1 == UMFPACK_WARNING_singular_matrix))
1140 	{
1141 	    error ("U'y=b failed", (double) status) ;
1142 	}
1143 	s2 = UMFPACK_solve (UMFPACK_Lat, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(y,yz), Numeric, Control, Info) ;
1144 	if (! (s2 == UMFPACK_OK || s2 == UMFPACK_WARNING_singular_matrix))
1145 	{
1146 	    error ("L'x=y failed", (double) status) ;
1147 	}
1148 
1149 	/* check using UMFPACK_transpose */
1150 	if (s1 == UMFPACK_OK && s2 == UMFPACK_OK)
1151 	{
1152 	    status = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), P, Q, Cp, Ci, CARG(Cx,Cz) C1ARG(0)) ;
1153 	    if (status != UMFPACK_OK)
1154 	    {
1155 		error ("transposed (PAQ).'x=b failed\n", 0.) ;
1156 	    }
1157 	    rnorm = resid (n, Cp, Ci, Cx, Cz, x, xz, b, bz, r, rz, UMFPACK_A, noP, noQ, Wx) ;
1158 	    /* printf ("98b: rnorm (PAQ)'x=b is %g\n", rnorm) ; */
1159 	    if (check_tol && rnorm > TOL)
1160 	    {
1161 		dump_mat ("A", n, n, Ap, Ai, CARG(Ax,Az)) ;
1162 		dump_mat ("C", n, n, Cp, Ci, CARG(Cx,Cz)) ;
1163 		dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1164 		dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1165 		printf ("P = [ ") ;
1166                 for (k = 0 ; k < n ; k++)
1167                 {
1168                     printf (ID" ", P [k]) ;
1169                 }
1170                 printf ("]\n") ;
1171 		printf ("Q = [ ") ;
1172                 for (k = 0 ; k < n ; k++)
1173                 {
1174                     printf (ID" ", Q [k]) ;
1175                 }
1176                 printf ("]\n") ;
1177 		error ("transposed (PAQ).'x=b inaccurate\n",rnorm) ;
1178 	    }
1179 	    maxrnorm = MAX (rnorm, maxrnorm) ;
1180 	}
1181     }
1182 
1183 
1184     /* ---------------------------------------------------------------------- */
1185     /* free workspace */
1186     /* ---------------------------------------------------------------------- */
1187 
1188     free (y) ;	    /* ] */
1189     free (Rb) ;	    /* ] */
1190     free (Rs) ;	    /* ] */
1191 
1192     /* ---------------------------------------------------------------------- */
1193     /* Lx=b */
1194     /* ---------------------------------------------------------------------- */
1195 
1196     if (prl >= 2) printf ("do solve: Lx=b:\n") ;
1197     status = UMFPACK_solve (UMFPACK_L, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info) ;
1198     /* UMFPACK_report_info (Control, Info) ; */
1199     if (status == UMFPACK_WARNING_singular_matrix)
1200     {
1201 	error ("Lx=b solve singular!", 0.) ;
1202     }
1203     else if (status != UMFPACK_OK)
1204     {
1205 	dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1206 	error ("Lx=b failed\n", 0.) ;
1207     }
1208     else
1209     {
1210         rnorm = resid (n, Lp, Li, Lx, Lz, x, xz, b, bz, r, rz, UMFPACK_A, noP, noQ, Wx) ;
1211 	if (prl >= 2) printf ("7: rnorm Lx=b is %g\n", rnorm) ;
1212         if (check_tol && rnorm > TOL)
1213         {
1214 	    dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1215 	    error ("Lx=b inaccurate %g", rnorm) ;
1216         }
1217 	maxrnorm = MAX (rnorm, maxrnorm) ;
1218     }
1219 
1220     /* ---------------------------------------------------------------------- */
1221     /* L'x=b */
1222     /* ---------------------------------------------------------------------- */
1223 
1224     if (prl >= 2) printf ("do solve: L'x=b:\n") ;
1225     status = UMFPACK_solve (UMFPACK_Lt, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info) ;
1226     /* UMFPACK_report_info (Control, Info) ; */
1227     if (status == UMFPACK_WARNING_singular_matrix)
1228     {
1229 	dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1230 	error ("L'x=b solve singular!", 0.) ;
1231     }
1232     else if (status != UMFPACK_OK)
1233     {
1234 	dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1235 	error ("L'x=b failed\n", 0.) ;
1236     }
1237     else
1238     {
1239         rnorm = resid (n, Lp, Li, Lx, Lz, x, xz, b, bz, r, rz, UMFPACK_At, noP, noQ, Wx) ;
1240 	if (prl >= 2) printf ("7: rnorm L'x=b is %g\n", rnorm) ;
1241         if (check_tol && rnorm > TOL)
1242         {
1243 	    dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1244     	    error ("L'x=b inaccurate %g\n",rnorm) ;
1245 	}
1246 	maxrnorm = MAX (rnorm, maxrnorm) ;
1247 
1248 	/* also check using UMFPACK_transpose */
1249 	status = UMFPACK_transpose (n, n, Lp, Li, CARG(Lx,Lz), noP, noQ, Cp, Ci, CARG(Cx,Cz) C1ARG(1)) ;
1250 	if (status != UMFPACK_OK)
1251 	{
1252 	    error ("transposed L'x=b failed\n", 0.) ;
1253 	}
1254         rnorm = resid (n, Cp, Ci, Cx, Cz, x, xz, b, bz, r, rz, UMFPACK_A, noP, noQ, Wx) ;
1255 	if (prl >= 2) printf ("7b: rnorm L'x=b is %g\n", rnorm) ;
1256         if (check_tol && rnorm > TOL)
1257         {
1258 	    dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1259     	    error ("transposed L'x=b inaccurate %g\n",rnorm) ;
1260 	}
1261 	maxrnorm = MAX (rnorm, maxrnorm) ;
1262 
1263     }
1264 
1265     /* ---------------------------------------------------------------------- */
1266     /* L.'x=b */
1267     /* ---------------------------------------------------------------------- */
1268 
1269     if (prl >= 2) printf ("do solve: L.'x=b:\n") ;
1270     status = UMFPACK_solve (UMFPACK_Lat, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info) ;
1271     /* UMFPACK_report_info (Control, Info) ; */
1272     if (status == UMFPACK_WARNING_singular_matrix)
1273     {
1274 	dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1275 	error ("L.'x=b solve singular!", 0.) ;
1276     }
1277     else if (status != UMFPACK_OK)
1278     {
1279 	dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1280 	error ("L.'x=b failed\n", 0.) ;
1281     }
1282     else
1283     {
1284         rnorm = resid (n, Lp, Li, Lx, Lz, x, xz, b, bz, r, rz, UMFPACK_Aat, noP, noQ, Wx) ;
1285 	if (prl >= 2) printf ("8: rnorm L.'x=b is %g\n", rnorm) ;
1286         if (check_tol && rnorm > TOL)
1287         {
1288 	    dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1289     	    error ("L.'x=b inaccurate %g\n",rnorm) ;
1290 	}
1291 	maxrnorm = MAX (rnorm, maxrnorm) ;
1292 
1293 	/* also check using UMFPACK_transpose */
1294 	status = UMFPACK_transpose (n, n, Lp, Li, CARG(Lx,Lz), noP, noQ, Cp, Ci, CARG(Cx,Cz) C1ARG(0)) ;
1295 	if (status != UMFPACK_OK)
1296 	{
1297 	    error ("transposed L'x=b failed\n", 0.) ;
1298 	}
1299         rnorm = resid (n, Cp, Ci, Cx, Cz, x, xz, b, bz, r, rz, UMFPACK_A, noP, noQ, Wx) ;
1300 	if (prl >= 2) printf ("8b: rnorm L'x=b is %g\n", rnorm) ;
1301         if (check_tol && rnorm > TOL)
1302         {
1303 	    dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1304     	    error ("8b transposed L'x=b inaccurate %g\n",rnorm) ;
1305 	}
1306 	maxrnorm = MAX (rnorm, maxrnorm) ;
1307 
1308     }
1309 
1310     /* ---------------------------------------------------------------------- */
1311     /* Ux=b */
1312     /* ---------------------------------------------------------------------- */
1313 
1314     if (prl >= 2) printf ("do solve: Ux=b:\n") ;
1315     status = UMFPACK_solve (UMFPACK_U, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info) ;
1316     /* UMFPACK_report_info (Control, Info) ; */
1317     if (status == UMFPACK_WARNING_singular_matrix)
1318     {
1319 	if (prl >= 2) printf ("Ux=b solve singular\n") ;
1320     }
1321     else if (status != UMFPACK_OK)
1322     {
1323 	dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1324 	error ("Ux=b failed\n", 0.) ;
1325     }
1326     else
1327     {
1328 	rnorm = resid (n, Up, Ui, Ux, Uz, x, xz, b, bz, r, rz, UMFPACK_A, noP, noQ, Wx) ;
1329 	if (prl >= 2) printf ("9: rnorm Ux=b is %g\n", rnorm) ;
1330         if (check_tol && rnorm > TOL)
1331         {
1332 	    dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1333     	    error ("Ux=b inaccurate %g\n",rnorm) ;
1334         }
1335         maxrnorm = MAX (rnorm, maxrnorm) ;
1336     }
1337 
1338     /* ---------------------------------------------------------------------- */
1339     /* U'x=b */
1340     /* ---------------------------------------------------------------------- */
1341 
1342     if (prl >= 2) printf ("do solve: U'x=b:\n") ;
1343     status = UMFPACK_solve (UMFPACK_Ut, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info) ;
1344     /* UMFPACK_report_info (Control, Info) ; */
1345     if (status == UMFPACK_WARNING_singular_matrix)
1346     {
1347 	if (prl >= 2) printf ("U'x=b solve singular\n") ;
1348     }
1349     else if (status != UMFPACK_OK)
1350     {
1351 	dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1352 	error ("U'x=b failed\n", 0.) ;
1353     }
1354     else
1355     {
1356         rnorm = resid (n, Up, Ui, Ux, Uz, x, xz, b, bz, r, rz, UMFPACK_At, noP, noQ, Wx) ;
1357 	if (prl >= 2) printf ("10: rnorm U'x=b is %g\n", rnorm) ;
1358         if (check_tol && rnorm > TOL)
1359         {
1360 	    dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1361 	    error ("U'x=b inaccurate %g\n",rnorm) ;
1362         }
1363         maxrnorm = MAX (rnorm, maxrnorm) ;
1364 
1365 	/* also check using UMFPACK_transpose */
1366 	status = UMFPACK_transpose (n, n, Up, Ui, CARG(Ux,Uz), noP, noQ, Cp, Ci, CARG(Cx,Cz) C1ARG(1)) ;
1367 	if (status != UMFPACK_OK)
1368 	{
1369 	    error ("transposed U'x=b failed\n", 0.) ;
1370 	}
1371         rnorm = resid (n, Cp, Ci, Cx, Cz, x, xz, b, bz, r, rz, UMFPACK_A, noP, noQ, Wx) ;
1372 	if (prl >= 2) printf ("10b: rnorm U'x=b is %g\n", rnorm) ;
1373         if (check_tol && rnorm > TOL)
1374         {
1375 	    dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1376     	    error ("10b transposed U'x=b inaccurate %g\n",rnorm) ;
1377 	}
1378 	maxrnorm = MAX (rnorm, maxrnorm) ;
1379 
1380     }
1381 
1382     /* ---------------------------------------------------------------------- */
1383     /* U.'x=b */
1384     /* ---------------------------------------------------------------------- */
1385 
1386     if (prl >= 2) printf ("do solve: U.'x=b:\n") ;
1387     status = UMFPACK_solve (UMFPACK_Uat, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info) ;
1388     /* UMFPACK_report_info (Control, Info) ; */
1389     if (status == UMFPACK_WARNING_singular_matrix)
1390     {
1391 	if (prl >= 2) printf ("U.'x=b solve singular\n") ;
1392     }
1393     else if (status != UMFPACK_OK)
1394     {
1395 	dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1396 	error ("U.'x=b failed\n", 0.) ;
1397     }
1398     else
1399     {
1400         rnorm = resid (n, Up, Ui, Ux, Uz, x, xz, b, bz, r, rz, UMFPACK_Aat, noP, noQ, Wx) ;
1401 	if (prl >= 2) printf ("11: rnorm U.'x=b is %g\n", rnorm) ;
1402         if (check_tol && rnorm > TOL)
1403         {
1404 	    dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1405 	    error ("U.'x=b inaccurate %g\n",rnorm) ;
1406         }
1407         maxrnorm = MAX (rnorm, maxrnorm) ;
1408 
1409 	/* also check using UMFPACK_transpose */
1410 	status = UMFPACK_transpose (n, n, Up, Ui, CARG(Ux,Uz), noP, noQ, Cp, Ci, CARG(Cx,Cz) C1ARG(0)) ;
1411 	if (status != UMFPACK_OK)
1412 	{
1413 	    error ("11b transposed U.'x=b failed\n", 0.) ;
1414 	}
1415         rnorm = resid (n, Cp, Ci, Cx, Cz, x, xz, b, bz, r, rz, UMFPACK_A, noP, noQ, Wx) ;
1416 	if (prl >= 2) printf ("11b: rnorm U'x=b is %g\n", rnorm) ;
1417         if (check_tol && rnorm > TOL)
1418         {
1419 	    dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1420     	    error ("11b transposed U'x=b inaccurate %g\n",rnorm) ;
1421 	}
1422 	maxrnorm = MAX (rnorm, maxrnorm) ;
1423 
1424     }
1425 
1426     /* ---------------------------------------------------------------------- */
1427     /* P'Lx=b */
1428     /* ---------------------------------------------------------------------- */
1429 
1430     if (prl >= 2) printf ("do solve: P'Lx=b:\n") ;
1431     status = UMFPACK_solve (UMFPACK_Pt_L, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info) ;
1432     /* UMFPACK_report_info (Control, Info) ; */
1433     if (status == UMFPACK_WARNING_singular_matrix)
1434     {
1435 	dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1436 	error ("P'Lx=b solve singular!", 0.) ;
1437     }
1438     else if (status != UMFPACK_OK)
1439     {
1440 	dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1441 	error ("P'Lx=b failed\n", 0.) ;
1442     }
1443     else
1444     {
1445         rnorm = resid (n, Lp, Li, Lx, Lz, x, xz, b, bz, r, rz, UMFPACK_A, P, noQ, Wx) ;
1446 	if (prl >= 2) printf ("12: rnorm P'Lx=b is %g\n", rnorm) ;
1447         if (check_tol && rnorm > TOL)
1448         {
1449 	    dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1450 	    error ("P'Lx=b inaccurate: %g\n",rnorm) ;
1451         }
1452         maxrnorm = MAX (rnorm, maxrnorm) ;
1453 
1454     }
1455 
1456     /* ---------------------------------------------------------------------- */
1457     /* L'Px=b */
1458     /* ---------------------------------------------------------------------- */
1459 
1460     if (prl >= 2) printf ("do solve: L'Px=b:\n") ;
1461     status = UMFPACK_solve (UMFPACK_Lt_P, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info) ;
1462     /* UMFPACK_report_info (Control, Info) ; */
1463     if (status == UMFPACK_WARNING_singular_matrix)
1464     {
1465 	error ("L'Px=b solve singular!", 0.) ;
1466     }
1467     else if (status != UMFPACK_OK)
1468     {
1469 	dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1470 	error ("L'Px=b failed\n", 0.) ;
1471     }
1472     else
1473     {
1474         rnorm = resid (n, Lp, Li, Lx, Lz, x, xz, b, bz, r, rz, UMFPACK_At, P, noQ, Wx) ;
1475 	if (prl >= 2) printf ("13: rnorm L'Px=b is %g\n", rnorm) ;
1476         if (check_tol && rnorm > TOL)
1477         {
1478 	    dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1479 	    error ("L'Px=b inaccurate %g\n",rnorm) ;
1480         }
1481         maxrnorm = MAX (rnorm, maxrnorm) ;
1482 
1483     }
1484 
1485     /* ---------------------------------------------------------------------- */
1486     /* L.'Px=b */
1487     /* ---------------------------------------------------------------------- */
1488 
1489     if (prl >= 2) printf ("do solve: L.'Px=b:\n") ;
1490     status = UMFPACK_solve (UMFPACK_Lat_P, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info) ;
1491     /* UMFPACK_report_info (Control, Info) ; */
1492     if (status == UMFPACK_WARNING_singular_matrix)
1493     {
1494 	error ("L.'Px=b solve singular!", 0.) ;
1495     }
1496     else if (status != UMFPACK_OK)
1497     {
1498 	dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1499 	error ("L.'Px=b failed\n", 0.) ;
1500     }
1501     else
1502     {
1503         rnorm = resid (n, Lp, Li, Lx, Lz, x, xz, b, bz, r, rz, UMFPACK_Aat, P, noQ, Wx) ;
1504 	if (prl >= 2) printf ("14: rnorm L.'Px=b is %g\n", rnorm) ;
1505         if (check_tol && rnorm > TOL)
1506         {
1507 	    dump_mat ("L", n, n, Lp, Li, CARG(Lx,Lz)) ;
1508 	    error ("L.'Px=b inaccurate %g\n",rnorm) ;
1509         }
1510         maxrnorm = MAX (rnorm, maxrnorm) ;
1511     }
1512 
1513     /* ---------------------------------------------------------------------- */
1514     /* UQ'x=b */
1515     /* ---------------------------------------------------------------------- */
1516 
1517     if (prl >= 2) printf ("do solve: UQ'x=b:\n") ;
1518     status = UMFPACK_solve (UMFPACK_U_Qt, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info) ;
1519     /* UMFPACK_report_info (Control, Info) ; */
1520     if (status == UMFPACK_WARNING_singular_matrix)
1521     {
1522 	if (prl >= 2) printf ("UQ'x=b solve singular\n") ;
1523     }
1524     else if (status != UMFPACK_OK)
1525     {
1526 	dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1527 	error ("UQ'x=b failed\n", 0.) ;
1528     }
1529     else
1530     {
1531         rnorm = resid (n, Up, Ui, Ux, Uz, x, xz, b, bz, r, rz, UMFPACK_A, noP, Q, Wx) ;
1532 	if (prl >= 2) printf ("15: rnorm UQ'x=b is %g\n", rnorm) ;
1533         if (check_tol && status == UMFPACK_OK && rnorm > TOL)
1534         {
1535 	    dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1536 	    error ("UQ'x=b inaccurate %g\n",rnorm) ;
1537         }
1538         maxrnorm = MAX (rnorm, maxrnorm) ;
1539     }
1540 
1541     /* ---------------------------------------------------------------------- */
1542     /* QU'x=b */
1543     /* ---------------------------------------------------------------------- */
1544 
1545     if (prl >= 2) printf ("do solve: QU'x=b:\n") ;
1546     status = UMFPACK_solve (UMFPACK_Q_Ut, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info) ;
1547     /* UMFPACK_report_info (Control, Info) ; */
1548     if (status == UMFPACK_WARNING_singular_matrix)
1549     {
1550 	if (prl >= 2) printf ("QU'x=b solve singular\n") ;
1551     }
1552     else if (status != UMFPACK_OK)
1553     {
1554 	dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1555 	error ("QU'x=b failed\n", 0.) ;
1556     }
1557     else
1558     {
1559         rnorm = resid (n, Up, Ui, Ux, Uz, x, xz, b, bz, r, rz, UMFPACK_At, noP, Q, Wx) ;
1560 	if (prl >= 2) printf ("16: rnorm QU'x=b is %g\n", rnorm) ;
1561         if (check_tol && rnorm > TOL)
1562         {
1563 	    dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1564 	    error ("QU'x=b inaccurate %g\n",rnorm) ;
1565         }
1566         maxrnorm = MAX (rnorm, maxrnorm) ;
1567     }
1568 
1569     /* ---------------------------------------------------------------------- */
1570     /* QU.'x=b */
1571     /* ---------------------------------------------------------------------- */
1572 
1573     if (prl >= 2) printf ("do solve: QU.'x=b:\n") ;
1574     status = UMFPACK_solve (UMFPACK_Q_Uat, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info) ;
1575     /* UMFPACK_report_info (Control, Info) ; */
1576     if (status == UMFPACK_WARNING_singular_matrix)
1577     {
1578 	if (prl >= 2) printf ("QU.'x=b solve singular\n") ;
1579     }
1580     else if (status != UMFPACK_OK)
1581     {
1582 	dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1583 	error ("QU.'x=b failed\n", 0.) ;
1584     }
1585     else
1586     {
1587         rnorm = resid (n, Up, Ui, Ux, Uz, x, xz, b, bz, r, rz, UMFPACK_Aat, noP, Q, Wx) ;
1588 	if (prl >= 2) printf ("17: rnorm QU.'x=b is %g\n", rnorm) ;
1589         if (check_tol && rnorm > TOL)
1590         {
1591 	    dump_mat ("U", n, n, Up, Ui, CARG(Ux,Uz)) ;
1592 	    error ("QU.'x=b inaccurate %g\n",rnorm) ;
1593         }
1594         maxrnorm = MAX (rnorm, maxrnorm) ;
1595     }
1596 
1597     /* ---------------------------------------------------------------------- */
1598     /* done */
1599     /* ---------------------------------------------------------------------- */
1600 
1601     if (n_row == n_col)
1602     {
1603 	free (Cp) ;
1604 	free (Ci) ;
1605 	free (Cx) ;
1606     }
1607     return (maxrnorm) ;
1608 }
1609 
1610 
1611 /* ========================================================================== */
1612 /* do_symnum:  factor A once, and then test the solves - return if error */
1613 /* ========================================================================== */
1614 
do_symnum(Int n_row,Int n_col,Int Ap[],Int Ai[],double Ax[],double Az[],double b[],double bz[],double Control[],Int Qinit[],double x[],double xz[],double r[],double rz[],double Wx[],Int P[],Int Q[],Int Qtree[],Int Ptree[],Int W[],Int Lp[],Int Up[],Int save_and_load,Int split,Int det_check,double det_x,double det_z)1615 static double do_symnum
1616 (
1617     Int n_row,
1618     Int n_col,
1619     Int Ap [ ],
1620     Int Ai [ ],
1621     double Ax [ ],		double Az [ ],
1622     double b [ ],		double bz [ ],
1623     double Control [ ],
1624     Int Qinit [ ],
1625     double x [ ],		double xz [ ],
1626     double r [ ],		double rz [ ],
1627     double Wx [ ],
1628     Int P [ ],
1629     Int Q [ ],
1630     Int Qtree [ ],
1631     Int Ptree [ ],
1632     Int W [ ],
1633     Int Lp [ ],
1634     Int Up [ ],
1635     Int save_and_load,
1636     Int split,	    /* TRUE if complex variables split, FALSE if merged */
1637     Int det_check, double det_x, double det_z
1638 )
1639 {
1640     void *Symbolic, *Numeric ;
1641     double *Lx, *Ux, *Lz, *Uz, rnorm, *Rs ;
1642     Int *noP = INULL, *noQ = INULL, *Li, *Ui, n, n_inner, n1, do_recip ;
1643     Int lnz, unz, nz, nn, nfr, nchains, nsparse_col, status ;
1644     Int *Front_npivots, *Front_parent, *Chain_start, *Chain_maxrows ;
1645     Int *Chain_maxcols, *Lrowi, *Lrowp, is_singular ;
1646     double Info [UMFPACK_INFO], *Lrowx, *Lrowz, *Dx, *Dz ;
1647     Int nnrow, nncol, nzud, *Front_1strow, *Front_leftmostdesc, prl, i ;
1648     double mind, maxd, rcond ;
1649     Entry d ;
1650     double da, deterr ;
1651     NumericType *Num ;
1652     SymbolicType *Sym ;
1653     double Mx [2], Mz, Exp ;
1654 
1655 #ifdef COMPLEX
1656     if (split)
1657     {
1658 	if (!Az || !bz || !xz) error ("bad split\n", 0.) ;
1659     }
1660     else
1661     {
1662 	if ( Az ||  bz ||  xz) error ("bad merge\n", 0.) ;
1663     }
1664     if (!rz) error ("bad rz\n", 0.) ;
1665 #endif
1666 
1667     /* ---------------------------------------------------------------------- */
1668     /* do the symbolic factorization */
1669     /* ---------------------------------------------------------------------- */
1670 
1671     prl = Control ? Control [UMFPACK_PRL] : UMFPACK_DEFAULT_PRL ;
1672 
1673     n = MAX (n_row, n_col) ;
1674     n = MAX (n,1) ;
1675     n_inner = MIN (n_row, n_col) ;
1676 
1677     if (prl > 2)
1678     {
1679 	printf ("\nA::\n") ;
1680 	status = UMFPACK_report_matrix (n_row, n_col, Ap, Ai, CARG(Ax,Az), 1, Control) ;
1681 	printf ("\nb::\n") ;
1682 	if (n_row == n_col) UMFPACK_report_vector (n, CARG(b,bz), Control) ;
1683     }
1684 
1685     if (Qinit)
1686     {
1687 	/* dump_perm ("Qinit", n_col, Qinit) ; */
1688 	status = UMFPACK_qsymbolic (n_row, n_col, Ap, Ai, CARG(Ax,Az), Qinit,
1689             &Symbolic, Control, Info) ; /* ( */
1690     }
1691     else if (Control != NULL &&
1692         Control [UMFPACK_ORDERING] == UMFPACK_ORDERING_USER)
1693     {
1694         Int params [3] ;
1695         params [0] = UMFPACK_ORDERING_AMD ;
1696         params [1] = prl-1 ;
1697         params [2] = EMPTY ;
1698         status = UMFPACK_fsymbolic (n_row, n_col, Ap, Ai, CARG(Ax,Az),
1699             &my_ordering, (void *) params, &Symbolic, Control, Info) ;
1700     }
1701     else
1702     {
1703 	status = UMFPACK_symbolic (n_row, n_col, Ap, Ai, CARG(Ax,Az),
1704             &Symbolic, Control, Info) ;
1705     }
1706 
1707     UMFPACK_report_status (Control, status) ;
1708     UMFPACK_report_info (Control, Info) ;
1709 
1710     if (!Symbolic)
1711     {
1712 	UMFPACK_report_info (Control, Info) ;
1713 	error ("symbolic invalid\n", 0.) ;
1714     }
1715 
1716     /* ---------------------------------------------------------------------- */
1717     /* test save and load */
1718     /* ---------------------------------------------------------------------- */
1719 
1720     status = UMFPACK_save_symbolic (Symbolic, "s.umf") ;
1721     if (status != UMFPACK_OK)
1722     {
1723 	error ("save symbolic failed\n", 0.) ;
1724     }
1725     UMFPACK_free_symbolic (&Symbolic) ;
1726     status = UMFPACK_load_symbolic (&Symbolic, "s.umf") ;
1727     if (status != UMFPACK_OK)
1728     {
1729 	error ("load symbolic failed\n", 0.) ;
1730     }
1731 
1732     if (n < 15)
1733     {
1734 
1735 	int umf_fail_save [3], memcnt ;
1736 
1737 	status = UMFPACK_save_symbolic (Symbolic, (char *) NULL) ;
1738 	if (status != UMFPACK_OK)
1739 	{
1740 	    error ("save symbolic failed\n", 0.) ;
1741 	}
1742 	UMFPACK_free_symbolic (&Symbolic) ;
1743 	status = UMFPACK_load_symbolic (&Symbolic, (char *) NULL) ;
1744 	if (status != UMFPACK_OK)
1745 	{
1746 	    error ("load symbolic failed\n", 0.) ;
1747 	}
1748 
1749 	/* test memory handling */
1750 	umf_fail_save [0] = umf_fail ;
1751 	umf_fail_save [1] = umf_fail_lo ;
1752 	umf_fail_save [2] = umf_fail_hi ;
1753 
1754 	umf_fail = -1 ;
1755 	umf_fail_lo = 0 ;
1756 	umf_fail_hi = 0 ;
1757 
1758 	UMFPACK_free_symbolic (&Symbolic) ;
1759 	status = UMFPACK_load_symbolic (&Symbolic, (char *) NULL) ;
1760 	if (status != UMFPACK_OK)
1761 	{
1762 	    error ("load symbolic failed\n", 0.) ;
1763 	}
1764 
1765 	Sym = (SymbolicType *) Symbolic ;
1766 
1767 	memcnt = 12 ;
1768 	if (Sym->esize > 0)
1769 	{
1770 	    memcnt++ ;
1771 	}
1772 	if (Sym->prefer_diagonal > 0)
1773 	{
1774 	    memcnt++ ;
1775 	}
1776 
1777 	for (i = 1 ; i <= memcnt ; i++)
1778 	{
1779 	    umf_fail = i ;
1780 	    UMFPACK_free_symbolic (&Symbolic) ;
1781 	    status = UMFPACK_load_symbolic (&Symbolic, (char *) NULL) ;
1782 	    if (status != UMFPACK_ERROR_out_of_memory)
1783 	    {
1784 		error ("load symbolic should have failed\n", 0.) ;
1785 	    }
1786 	}
1787 
1788 	umf_fail = memcnt + 1 ;
1789 
1790 	UMFPACK_free_symbolic (&Symbolic) ;
1791 	status = UMFPACK_load_symbolic (&Symbolic, (char *) NULL) ;
1792 	if (status != UMFPACK_OK)
1793 	{
1794 	    error ("load symbolic failed (edge)\n", 0.) ;
1795 	}
1796 
1797 	umf_fail    = umf_fail_save [0] ;
1798 	umf_fail_lo = umf_fail_save [1] ;
1799 	umf_fail_hi = umf_fail_save [2] ;
1800 
1801 	UMFPACK_free_symbolic (&Symbolic) ;
1802 	status = UMFPACK_load_symbolic (&Symbolic, "s.umf") ;
1803 	if (status != UMFPACK_OK)
1804 	{
1805 	    error ("load symbolic failed\n", 0.) ;
1806 	}
1807 
1808     }
1809 
1810     /* ---------------------------------------------------------------------- */
1811     /* get the symbolic factorization */
1812     /* ---------------------------------------------------------------------- */
1813 
1814     if (prl > 2) printf ("\nSymbolic: ") ;
1815     status = UMFPACK_report_symbolic (Symbolic, Control) ;
1816     if (status != UMFPACK_OK)
1817     {
1818 	UMFPACK_free_symbolic (&Symbolic) ;
1819 	error ("bad symbolic report\n", 0.) ;
1820     }
1821 
1822     Front_npivots = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
1823     Front_parent = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
1824     Front_1strow = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
1825     Front_leftmostdesc = (Int *) malloc ((n+1) * sizeof (Int)) ;	/* [ */
1826     Chain_start = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
1827     Chain_maxrows = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
1828     Chain_maxcols = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
1829 
1830     if (!Front_npivots || !Front_parent || !Chain_start || !Chain_maxrows
1831 	|| !Front_leftmostdesc || !Front_1strow
1832 	|| !Chain_maxcols || !Qtree || !Ptree) error ("out of memory (1)",0.) ;
1833 
1834     status = UMFPACK_get_symbolic (&nnrow, &nncol, &n1, &nz, &nfr, &nchains,
1835 	Ptree, Qtree, Front_npivots, Front_parent, Front_1strow, Front_leftmostdesc,
1836 	Chain_start, Chain_maxrows, Chain_maxcols, Symbolic) ;
1837 
1838     if (status != UMFPACK_OK)
1839     {
1840 	UMFPACK_report_info (Control, Info) ;
1841 	error ("get symbolic failed\n", 0.) ;
1842     }
1843 
1844     free (Chain_maxcols) ;	/* ] */
1845     free (Chain_maxrows) ;	/* ] */
1846     free (Chain_start) ;	/* ] */
1847     free (Front_leftmostdesc) ;	/* ] */
1848     free (Front_1strow) ;	/* ] */
1849     free (Front_parent) ;	/* ] */
1850     free (Front_npivots) ;	/* ] */
1851 
1852     if (!UMF_is_permutation (Qtree, W, n_col, n_col)) { error ("Qtree invalid\n", 0.) ; }
1853     if (!UMF_is_permutation (Ptree, W, n_row, n_row)) { error ("Ptree invalid\n", 0.) ; }
1854 
1855     /* ---------------------------------------------------------------------- */
1856     /* do the numerical factorization */
1857     /* ---------------------------------------------------------------------- */
1858 
1859     status = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Control, Info) ;	/* [ */
1860     if (status != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
1861     is_singular = (status == UMFPACK_WARNING_singular_matrix) ;
1862 
1863     UMFPACK_report_status (Control, status) ;
1864     UMFPACK_report_info (Control, Info) ;
1865 
1866     UMFPACK_free_symbolic (&Symbolic) ;			/* ) */
1867 
1868     if (!Numeric)
1869     {
1870 	/* printf ("numeric bad:  %g\n", Control [UMFPACK_ALLOC_INIT]) ; */
1871 	fflush (stdout) ;
1872 	return (9e10) ;
1873     }
1874 
1875     if (prl > 2) printf ("Numeric: ") ;
1876     status = UMFPACK_report_numeric (Numeric, Control) ;
1877     if (status != UMFPACK_OK)
1878     {
1879 	UMFPACK_free_numeric (&Numeric) ;
1880 	error ("bad numeric report\n", 0.) ;
1881     }
1882 
1883     /* ---------------------------------------------------------------------- */
1884     /* get the determinant */
1885     /* ---------------------------------------------------------------------- */
1886 
1887     Mx [0] = 0. ;
1888     Mx [1] = 0. ;
1889     Mz = 0. ;
1890     Exp = 0. ;
1891 
1892     for (i = 0 ; i <= 3 ; i++)
1893     {
1894 	if (i == 0)
1895 	{
1896 	    status = UMFPACK_get_determinant (CARG (Mx, &Mz), &Exp, Numeric,
1897 		Info) ;
1898 	}
1899 	else if (i == 1)
1900 	{
1901 	    status = UMFPACK_get_determinant (CARG (Mx, &Mz), &Exp, Numeric,
1902 		DNULL) ;
1903 	}
1904 	else if (i == 2)
1905 	{
1906 	    status = UMFPACK_get_determinant (CARG (Mx, &Mz), DNULL, Numeric,
1907 		Info) ;
1908 	}
1909 	else if (i == 3)
1910 	{
1911 	    status = UMFPACK_get_determinant (CARG (Mx, DNULL), DNULL, Numeric,
1912 		Info) ;
1913 	}
1914 	if (n_row == n_col)
1915 	{
1916 	    if (status != UMFPACK_OK)
1917 	    {
1918 		error ("bad det\n", 0.) ;
1919 	    }
1920 	    if (det_check && SCALAR_ABS (det_x < 1e100))
1921 	    {
1922 
1923 		if (i == 0 || i == 1)
1924 		{
1925 		    deterr = SCALAR_ABS (det_x - (Mx [0] * pow (10.0, Exp))) ;
1926 		}
1927 		else if (i == 2 || i == 3)
1928 		{
1929 		    deterr = SCALAR_ABS (det_x - Mx [0]) ;
1930 		}
1931 
1932 		if (deterr > 1e-7)
1933 		{
1934 		    printf ("det: real err %g i: "ID"\n", deterr, i) ;
1935 		    error ("det: bad real part", det_x) ;
1936 		}
1937 
1938 #ifdef COMPLEX
1939 
1940 		if (i == 0 || i == 1)
1941 		{
1942 		    deterr = SCALAR_ABS (det_z - (Mz * pow (10.0, Exp))) ;
1943 		}
1944 		else if (i == 2)
1945 		{
1946 		    deterr = SCALAR_ABS (det_z - Mz) ;
1947 		}
1948 		else if (i == 3)
1949 		{
1950 		    deterr = SCALAR_ABS (det_z - Mx [1]) ;
1951 		}
1952 
1953 		if (deterr > 1e-7)
1954 		{
1955 		    printf ("det: imag err %g\n", deterr) ;
1956 		    error ("det: bad imag part", det_z) ;
1957 		}
1958 #endif
1959 	    }
1960 	}
1961 	else
1962 	{
1963 	    if (status != UMFPACK_ERROR_invalid_system)
1964 	    {
1965 		error ("bad det (rectangluar)\n", 0.) ;
1966 	    }
1967 	}
1968     }
1969 
1970     /* ---------------------------------------------------------------------- */
1971     /* test save and load */
1972     /* ---------------------------------------------------------------------- */
1973 
1974     status = UMFPACK_save_numeric (Numeric, "n.umf") ;
1975     if (status != UMFPACK_OK)
1976     {
1977 	error ("save numeric failed\n", 0.) ;
1978     }
1979     UMFPACK_free_numeric (&Numeric) ;
1980     status = UMFPACK_load_numeric (&Numeric, "n.umf") ;
1981     if (status != UMFPACK_OK)
1982     {
1983 	error ("load numeric failed\n", 0.) ;
1984     }
1985 
1986     if (n < 15)
1987     {
1988 	int umf_fail_save [3], memcnt ;
1989 
1990 	status = UMFPACK_save_numeric (Numeric, (char *) NULL) ;
1991 	if (status != UMFPACK_OK)
1992 	{
1993 	    error ("save numeric failed\n", 0.) ;
1994 	}
1995 	UMFPACK_free_numeric (&Numeric) ;
1996 	status = UMFPACK_load_numeric (&Numeric, (char *) NULL) ;
1997 	if (status != UMFPACK_OK)
1998 	{
1999 	    error ("load numeric failed\n", 0.) ;
2000 	}
2001 
2002 	/* test memory handling */
2003 	umf_fail_save [0] = umf_fail ;
2004 	umf_fail_save [1] = umf_fail_lo ;
2005 	umf_fail_save [2] = umf_fail_hi ;
2006 
2007 	umf_fail = -1 ;
2008 	umf_fail_lo = 0 ;
2009 	umf_fail_hi = 0 ;
2010 
2011 	UMFPACK_free_numeric (&Numeric) ;
2012 	status = UMFPACK_load_numeric (&Numeric, (char *) NULL) ;
2013 	if (status != UMFPACK_OK)
2014 	{
2015 	    error ("load numeric failed\n", 0.) ;
2016 	}
2017 
2018 	Num = (NumericType *) Numeric ;
2019 
2020 	memcnt = 11 ;
2021 	if (Num->scale != UMFPACK_SCALE_NONE)
2022 	{
2023 	    memcnt++ ;
2024 	}
2025 	if (Num->ulen > 0)
2026 	{
2027 	    memcnt++ ;
2028 	}
2029 
2030 	for (i = 1 ; i <= memcnt ; i++)
2031 	{
2032 	    umf_fail = i ;
2033 	    UMFPACK_free_numeric (&Numeric) ;
2034 	    status = UMFPACK_load_numeric (&Numeric, (char *) NULL) ;
2035 	    if (status != UMFPACK_ERROR_out_of_memory)
2036 	    {
2037 		error ("load numeric should have failed\n", 0.) ;
2038 	    }
2039 	}
2040 
2041 	umf_fail = memcnt + 1 ;
2042 
2043 	UMFPACK_free_numeric (&Numeric) ;
2044 	status = UMFPACK_load_numeric (&Numeric, (char *) NULL) ;
2045 	if (status != UMFPACK_OK)
2046 	{
2047 	    printf ("memcnt %d\n", memcnt) ;
2048 	    error ("load numeric failed (edge)\n", 0.) ;
2049 	}
2050 
2051 	umf_fail    = umf_fail_save [0] ;
2052 	umf_fail_lo = umf_fail_save [1] ;
2053 	umf_fail_hi = umf_fail_save [2] ;
2054 
2055 	UMFPACK_free_numeric (&Numeric) ;
2056 	status = UMFPACK_load_numeric (&Numeric, "n.umf") ;
2057 	if (status != UMFPACK_OK)
2058 	{
2059 	    error ("load numeric failed\n", 0.) ;
2060 	}
2061 
2062     }
2063 
2064     /* ---------------------------------------------------------------------- */
2065     /* get the LU factorization */
2066     /* ---------------------------------------------------------------------- */
2067 
2068     status = UMFPACK_get_lunz (&lnz, &unz, &nnrow, &nncol, &nzud, Numeric) ;
2069     if (status != UMFPACK_OK)
2070     {
2071 	UMFPACK_report_info (Control, Info) ;
2072 	error ("get lunz failure\n", 0.) ;
2073 	UMFPACK_free_numeric (&Numeric) ;
2074     }
2075 
2076     /* guard against malloc of zero-sized arrays */
2077     lnz = MAX (lnz,1) ;
2078     unz = MAX (unz,1) ;
2079 
2080     Rs = (double *) malloc ((n+1) * sizeof (double)) ;	/* [ */
2081     Li = (Int *) malloc (lnz * sizeof (Int)) ;		/* [ */
2082     Lx = (double *) calloc (2*lnz , sizeof (double)) ;	/* [ */
2083     Ui = (Int *) malloc (unz * sizeof (Int)) ;		/* [ */
2084     Ux = (double *) calloc (2*unz , sizeof (double)) ;	/* [ */
2085     Dx = (double *) calloc (2*n , sizeof (double)) ;	/* [ */
2086 
2087     Lrowp = (Int *) malloc ((n+1) * sizeof (Int)) ;	/* [ */
2088     Lrowi = (Int *) malloc (lnz * sizeof (Int)) ;	/* [ */
2089     Lrowx = (double *) calloc (2*lnz , sizeof (double)) ;	/* [ */
2090 
2091     if (!Li || !Lx || !Ui || !Ux || !Lrowp || !Lrowi || !Lrowx) error ("out of memory (2)\n",0.) ;
2092 
2093     if (split)
2094     {
2095 	Dz = Dx + n ;
2096 	Lrowz = Lrowx + lnz ;
2097 	Lz = Lx + lnz ;
2098 	Uz = Ux + unz ;
2099     }
2100     else
2101     {
2102 	Dz = DNULL ;
2103 	Lrowz = DNULL ;
2104 	Lz = DNULL ;
2105 	Uz = DNULL ;
2106     }
2107 
2108     status = UMFPACK_get_numeric (Lrowp, Lrowi, CARG(Lrowx,Lrowz), Up, Ui, CARG(Ux,Uz), P, Q, CARG(Dx,Dz), &do_recip, Rs, Numeric) ;
2109     if (status != UMFPACK_OK)
2110     {
2111 	UMFPACK_report_info (Control, Info) ;
2112 	error ("get LU failed\n", 0.) ;
2113     }
2114 
2115     if (!UMF_is_permutation (P, W, n_row, n_row)) { error ("P invalid\n", 0.) ; }
2116     if (!UMF_is_permutation (Q, W, n_col, n_col)) { error ("Q invalid\n", 0.) ; }
2117     if (prl > 2) printf ("\nP: ") ;
2118     status = UMFPACK_report_perm (n_row, P, Control) ;
2119     if (status != UMFPACK_OK) { error ("bad P 1\n", 0.) ; }
2120     if (prl > 2) printf ("\nQ: ") ;
2121     status = UMFPACK_report_perm (n_col, Q, Control) ;
2122     if (status != UMFPACK_OK) { error ("bad Q 1\n", 0.) ; }
2123 
2124     if (prl > 2) printf ("\nL row: ") ;
2125     status = UMFPACK_report_matrix (n_row, n_inner, Lrowp, Lrowi, CARG(Lrowx,Lrowz), 0, Control) ;
2126     if (status != UMFPACK_OK) { error ("bad Lrow\n", 0.) ; }
2127 
2128     if (prl > 2) printf ("\nD, diag of U: ") ;
2129     status = UMFPACK_report_vector (n_inner, CARG(Dx,Dz), Control) ;
2130     if (status != UMFPACK_OK) { error ("bad D\n", 0.) ; }
2131 
2132     /* --- */
2133     /* ASSIGN (d, Dx [0], Dz [0]) ; */
2134     ASSIGN (d, Dx, Dz, 0, SPLIT(Dz)) ;
2135     /* --- */
2136 
2137     ABS (da, d) ;
2138     mind = da ;
2139     maxd = da ;
2140     for (i = 1 ; i < n_inner ; i++)
2141     {
2142 	/* --- */
2143 	/* ASSIGN (d, Dx [i], Dz [i]) ; */
2144 	ASSIGN (d, Dx, Dz, i, SPLIT(Dz)) ;
2145 	/* --- */
2146 
2147 	ABS (da, d) ;
2148 	mind = MIN (mind, da) ;
2149 	maxd = MAX (maxd, da) ;
2150     }
2151     if (maxd == 0.)
2152     {
2153 	rcond = 0. ;
2154     }
2155     else
2156     {
2157 	rcond = mind / maxd ;
2158     }
2159     if (prl > 2) printf ("mind: %g maxd: %g rcond: %g %g\n", mind, maxd, rcond, Info [UMFPACK_RCOND]) ;
2160     if (rcond == 0.0 && Info [UMFPACK_RCOND] != 0.0)
2161     {
2162 	printf ("rcond error %30.20e  %30.20e\n", rcond, Info [UMFPACK_RCOND]) ;
2163 	error ("rcond", 0.) ;
2164     }
2165     if (SCALAR_ABS (rcond - Info [UMFPACK_RCOND]) / rcond > 1e-10)
2166     {
2167 	printf ("rcond error %30.20e  %30.20e\n", rcond, Info [UMFPACK_RCOND]) ;
2168 	error ("rcond", 0.) ;
2169     }
2170 
2171     /* get L = Lrow' */
2172     status = UMFPACK_transpose (n_inner, n_row, Lrowp, Lrowi, CARG(Lrowx,Lrowz), noP, noQ, Lp, Li, CARG(Lx,Lz) C1ARG(0)) ;
2173     if (status != UMFPACK_OK)
2174     {
2175 	error ("L=Lrow' failed\n", 0.) ;
2176     }
2177 
2178     if (prl > 2) printf ("\nL col: ") ;
2179     status = UMFPACK_report_matrix (n_row, n_inner, Lp, Li, CARG(Lx,Lz), 1, Control) ;
2180     if (status != UMFPACK_OK) { error ("bad Lrow\n", 0.) ; }
2181 
2182     if (prl > 2) printf ("\nU col: ") ;
2183     status = UMFPACK_report_matrix (n_inner, n_col, Up, Ui, CARG(Ux,Uz), 1, Control) ;
2184     if (status != UMFPACK_OK) { error ("bad Ucol\n", 0.) ; }
2185 
2186     free (Lrowx) ;	/* ] */
2187     free (Lrowi) ;	/* ] */
2188     free (Lrowp) ;	/* ] */
2189 
2190     rnorm = do_solvers (n_row, n_col, Ap, Ai, Ax,Az, b,bz, Control, Info, Numeric,
2191     	Lp, Li, Lx,Lz, Up, Ui, Ux,Uz, P, Q, x,xz, r,rz, W, Wx, split) ;
2192 
2193     UMFPACK_report_info (Control, Info) ;
2194 
2195     /* ---------------------------------------------------------------------- */
2196     /* free everything */
2197     /* ---------------------------------------------------------------------- */
2198 
2199     free (Dx) ;		/* ] */
2200     free (Ux) ;		/* ] */
2201     free (Ui) ;		/* ] */
2202     free (Lx) ;		/* ] */
2203     free (Li) ;		/* ] */
2204     free (Rs) ;		/* ] */
2205 
2206     UMFPACK_free_numeric (&Numeric) ;	/* ] */
2207 
2208     return (rnorm) ;
2209 }
2210 
2211 
2212 /* ========================================================================== */
2213 /* do_once:  factor A once, and then test the solves - return if error */
2214 /* ========================================================================== */
2215 
2216 /* exit if an error occurs. otherwise, return the largest residual norm seen. */
2217 
do_once(Int n_row,Int n_col,Int Ap[],Int Ai[],double Ax[],double Az[],double b[],double bz[],double Control[],Int Qinit[],Int MemControl[6],Int save_and_load,Int split,Int det_check,double det_x,double det_z)2218 static double do_once
2219 (
2220     Int n_row,
2221     Int n_col,
2222     Int Ap [ ],
2223     Int Ai [ ],
2224     double Ax [ ],		double Az [ ],
2225     double b [ ],		double bz [ ],
2226     double Control [ ],
2227     Int Qinit [ ],
2228     Int MemControl [6],
2229     Int save_and_load,
2230     Int split,	    /* TRUE if complex variables split, FALSE if merged */
2231     Int det_check, double det_x, double det_z
2232 )
2233 {
2234 
2235     double *x, rnorm, *r, *Wx, *xz, *rz ;
2236     Int *P, *Q, *Lp, *Up, *W, *Qtree, *Ptree, n ;
2237 
2238 #ifdef COMPLEX
2239     if (split)
2240     {
2241 	if (!Az || !bz) error ("bad split\n", 0.) ;
2242     }
2243     else
2244     {
2245 	if ( Az ||  bz) error ("bad merge\n", 0.) ;
2246     }
2247 #endif
2248 
2249     /* ---------------------------------------------------------------------- */
2250     /* malloc and realloc failure control */
2251     /* ---------------------------------------------------------------------- */
2252 
2253     umf_fail = MemControl [0] ;
2254     umf_fail_hi = MemControl [1] ;
2255     umf_fail_lo = MemControl [2] ;
2256 
2257     umf_realloc_fail = MemControl [3] ;
2258     umf_realloc_hi = MemControl [4] ;
2259     umf_realloc_lo = MemControl [5] ;
2260 
2261     /* ---------------------------------------------------------------------- */
2262     /* allocate workspace */
2263     /* ---------------------------------------------------------------------- */
2264 
2265     n = MAX (n_row, n_col) ;
2266     n = MAX (n,1) ;
2267 
2268     r = (double *) calloc (2*n , sizeof (double)) ;	/* [ */
2269     x = (double *) calloc (2*n , sizeof (double)) ;	/* [ */
2270     rz = r + n ;
2271 
2272     if (split)
2273     {
2274 	/* real/complex are in r/rz and x/xz */
2275 	xz = x + n ;
2276     }
2277     else
2278     {
2279 	/* r and z are treated as array of size n Entry's */
2280 	xz = DNULL ;
2281     }
2282 
2283     Wx = (double *) malloc (10*n * sizeof (double)) ;	/* [ */
2284     P = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
2285     Q = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
2286     Qtree = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
2287     Ptree = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
2288     W = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
2289     Lp = (Int *) malloc ((n+1) * sizeof (Int)) ;	/* [ */
2290     Up = (Int *) malloc ((n+1) * sizeof (Int)) ;	/* [ */
2291     if (!x || !Wx || !r || !P || !Q || !Qtree || !Ptree || !W || !Lp || !Up) error ("out of memory (3)",0.) ;
2292 
2293     /* ---------------------------------------------------------------------- */
2294     /* report controls */
2295     /* ---------------------------------------------------------------------- */
2296 
2297     if (Control)
2298     {
2299     	if (Control [UMFPACK_PRL] >= 2)
2300 	{
2301 	    UMFPACK_report_control (Control) ;
2302 	}
2303     }
2304 
2305     /* ---------------------------------------------------------------------- */
2306     /* do the symbolic & numeric factorization, and solvers */
2307     /* ---------------------------------------------------------------------- */
2308 
2309     rnorm = do_symnum (n_row, n_col, Ap, Ai, Ax,Az, b,bz, Control, Qinit, x,xz,
2310 		r,rz, Wx, P, Q, Qtree, Ptree, W, Lp, Up, save_and_load, split,
2311 		det_check, det_x, det_z) ;
2312 
2313     /* ---------------------------------------------------------------------- */
2314     /* free workspace */
2315     /* ---------------------------------------------------------------------- */
2316 
2317     free (Up) ;		/* ] */
2318     free (Lp) ;		/* ] */
2319     free (W) ;		/* ] */
2320     free (Ptree) ;	/* ] */
2321     free (Qtree) ;	/* ] */
2322     free (Q) ;		/* ] */
2323     free (P) ;		/* ] */
2324     free (Wx) ;		/* ] */
2325     free (x) ;		/* ] */
2326     free (r) ;		/* ] */
2327 
2328 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
2329     if (UMF_malloc_count != 0) error ("umfpack memory leak!!",0.) ;
2330 #endif
2331 
2332     return (rnorm) ;
2333 }
2334 
2335 /* ========================================================================== */
2336 /* do_many:  factor A once, and then test the solves - return if error */
2337 /* ========================================================================== */
2338 
2339 /* runs do_once with complex variables split, and again with them merged */
2340 
do_many(Int n_row,Int n_col,Int Ap[],Int Ai[],double Ax[],double Az[],double b[],double bz[],double Control[],Int Qinit[],Int MemControl[6],Int save_and_load,Int det_check,double det_x,double det_z)2341 static double do_many
2342 (
2343     Int n_row,
2344     Int n_col,
2345     Int Ap [ ],
2346     Int Ai [ ],
2347     double Ax [ ],		double Az [ ],
2348     double b [ ],		double bz [ ],
2349     double Control [ ],
2350     Int Qinit [ ],
2351     Int MemControl [6],
2352     Int save_and_load,
2353     Int det_check, double det_x, double det_z
2354 )
2355 {
2356     double rnorm, r ;
2357     Entry *A, *B, a ;
2358     Int p, i, nz ;
2359 
2360     rnorm = 0 ;
2361 
2362 #ifdef COMPLEX
2363 
2364     if (!Az || !bz) error ("do_many missing imag parts!\n", 0.) ;
2365 
2366     nz = Ap [n_col] ;
2367     A = (Entry *) malloc ((nz+1) * sizeof (Entry)) ;
2368     B = (Entry *) malloc ((n_col+1) * sizeof (Entry)) ;
2369     if (!A || !B) error ("out of memory (4)",0.) ;
2370 
2371     for (p = 0 ; p < nz ; p++)
2372     {
2373 	ASSIGN (A [p], Ax, Az, p, TRUE) ;
2374     }
2375     for (i = 0 ; i < n_col ; i++)
2376     {
2377 	ASSIGN (B [i], b, bz, i, TRUE) ;
2378     }
2379 
2380     /* with complex variables merged */
2381     r = do_once (n_row, n_col, Ap, Ai, (double *)A,DNULL, (double *)B,DNULL, Control, Qinit, MemControl, save_and_load, FALSE, det_check, det_x, det_z) ;
2382 
2383     free (A) ;
2384     free (B) ;
2385 
2386     rnorm = MAX (r, rnorm) ;
2387 
2388 #endif
2389 
2390     /* with complex variables split */
2391     r = do_once (n_row, n_col, Ap, Ai, Ax,Az, b,bz, Control, Qinit, MemControl, save_and_load, TRUE, det_check, det_x, det_z) ;
2392     rnorm = MAX (r, rnorm) ;
2393     return (rnorm) ;
2394 }
2395 
2396 
2397 /* ========================================================================== */
2398 /* bgen:  b = A*xtrue, where xtrue (i) = 1 + i/n */
2399 /* ========================================================================== */
2400 
bgen(Int n,Int Ap[],Int Ai[],double Ax[],double Az[],double b[],double bz[])2401 static void bgen
2402 (
2403     Int n,
2404     Int Ap [ ],
2405     Int Ai [ ],
2406     double Ax [ ],	double Az [ ],
2407     double b [ ],	double bz [ ]
2408 )
2409 {
2410     Int i, col, p ;
2411     double xtrue, xtruez ;
2412     for (i = 0 ; i < n ; i++)
2413     {
2414 	b [i] = 0.0 ;
2415 	bz[i] = 0.0 ;
2416     }
2417     for (col = 0 ; col < n ; col++)
2418     {
2419 	xtrue = 1.0 + ((double) col) / ((double) n) ;
2420 #ifdef COMPLEX
2421 	xtruez= 1.3 - ((double) col) / ((double) n) ;
2422 #else
2423 	xtruez= 0. ;
2424 #endif
2425 	for (p = Ap [col] ; p < Ap [col+1] ; p++)
2426 	{
2427 	    i = Ai [p] ;
2428 	    b [i] += Ax [p] * xtrue ;
2429 	    b [i] -= Az [p] * xtruez ;
2430 	    bz[i] += Az [p] * xtrue ;
2431 	    bz[i] += Ax [p] * xtruez ;
2432 	}
2433     }
2434 }
2435 
2436 
2437 /* ========================================================================== */
2438 /* do_matrix: process one matrix with lots of options - exit if errors */
2439 /* ========================================================================== */
2440 
2441 /* return the largest residual norm seen, or exit if error occured */
2442 
do_matrix(Int n,Int Ap[],Int Ai[],double Ax[],double Az[],double Controls[UMFPACK_CONTROL][1000],Int Ncontrols[UMFPACK_CONTROL],Int MemControl[6],Int do_dense)2443 static double do_matrix
2444 (
2445     Int n,
2446     Int Ap [ ],
2447     Int Ai [ ],
2448     double Ax [ ],	double Az [ ],
2449 
2450     double Controls [UMFPACK_CONTROL][1000],
2451     Int Ncontrols [UMFPACK_CONTROL],
2452     Int MemControl [6],
2453     Int do_dense
2454 )
2455 {
2456     double Control [UMFPACK_CONTROL], *b, *bz, maxrnorm, rnorm, tol, init,
2457         psave ;
2458     Int *colhist, *rowhist, *rowdeg, *noQinit, *Qinit, *cknob, *rknob,
2459 	c, r, cs, rs, row, col, i, coldeg, p, d, nb, ck, rk, *Head, *Next,
2460 	col1, col2, d1, d2, k, status, n_amd,
2461 	i_tol, i_nb, i_init, n_tol, n_nb, n_init, n_scale, i_scale, scale,
2462 	i_pivot, n_pivot, pivopt, ordering, singletons ;
2463 
2464     /* ---------------------------------------------------------------------- */
2465     /* initializations */
2466     /* ---------------------------------------------------------------------- */
2467 
2468     maxrnorm = 0.0 ;
2469 
2470     /* get the default control parameters */
2471     UMFPACK_defaults (Control) ;
2472 
2473     UMFPACK_report_control (Control) ;
2474 
2475 #ifdef DEBUGGING
2476     Control [UMFPACK_PRL] = 5 ;
2477 #endif
2478 
2479     status = UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Control) ;
2480     if (status != UMFPACK_OK) { error ("bad A do_matrix\n", 0.) ; }
2481 
2482     /* ---------------------------------------------------------------------- */
2483     /* allocate workspace */
2484     /* ---------------------------------------------------------------------- */
2485 
2486     rowdeg = (Int *) malloc ((n+1) * sizeof (Int)) ;	/* ( */
2487     rowhist = (Int *) malloc ((n+1) * sizeof (Int)) ;	/* ( */
2488     colhist = (Int *) malloc ((n+1) * sizeof (Int)) ;	/* ( */
2489     cknob = (Int *) malloc ((n+1) * sizeof (Int)) ;	/* [ */
2490     rknob = (Int *) malloc ((n+1) * sizeof (Int)) ;	/* [ */
2491 
2492     /* ---------------------------------------------------------------------- */
2493     /* count the dense rows and columns */
2494     /* ---------------------------------------------------------------------- */
2495 
2496     for (i = 0 ; i < n ; i++)
2497     {
2498 	colhist [i] = 0 ;
2499 	rowhist [i] = 0 ;
2500 	rowdeg [i] = 0 ;
2501     }
2502 
2503     for (col = 0 ; col < n ; col++)
2504     {
2505 	coldeg = Ap [col+1] - Ap [col] ;
2506 	colhist [coldeg]++ ;
2507 	for (p = Ap [col] ; p < Ap [col+1] ; p++)
2508 	{
2509 	    rowdeg [Ai [p]]++ ;
2510 	}
2511     }
2512 
2513     for (row = 0 ; row < n ; row++)
2514     {
2515 	rowhist [rowdeg [row]]++ ;
2516     }
2517 
2518     rs = 0 ;
2519     if (do_dense)
2520     {
2521         if (n < 16)
2522         {
2523 	    rknob [rs++] = 0 ;  /* all dense rows */
2524         }
2525         for (d = 16 ; d < n ; d++)
2526         {
2527 	    if (rowhist [d] > 0)
2528 	    {
2529 	        rknob [rs++] = d ;
2530 	    }
2531         }
2532     }
2533     rknob [rs++] = n ;	/* no dense rows */
2534 
2535     cs = 0 ;
2536     if (do_dense)
2537     {
2538         if (n < 16)
2539         {
2540 	    cknob [cs++] = 0 ;  /* all dense columns */
2541         }
2542         for (d = 16 ; d < n ; d++)
2543         {
2544 	    if (colhist [d] > 0)
2545 	    {
2546 	        cknob [cs++] = d ;
2547 	    }
2548         }
2549     }
2550     cknob [cs++] = n ;	/* no dense cols */
2551 
2552     free (colhist) ;	/* ) */
2553     free (rowhist) ;	/* ) */
2554 
2555     /* ---------------------------------------------------------------------- */
2556     /* compute b assuming xtrue (i) = 1 + i/n */
2557     /* ---------------------------------------------------------------------- */
2558 
2559     b = (double *) malloc (n * sizeof (double)) ;	/* [ */
2560     bz= (double *) calloc (n , sizeof (double)) ;	/* [ */
2561     if (!b) error ("out of memory (5)",0.) ;
2562     if (!bz) error ("out of memory (6)",0.) ;
2563     bgen (n, Ap, Ai, Ax, Az, b, bz) ;
2564 
2565     /* ---------------------------------------------------------------------- */
2566     /* compute Qinit = sort by colcounts */
2567     /* ---------------------------------------------------------------------- */
2568 
2569     noQinit = INULL ;
2570     Qinit = (Int *) malloc ((n+1) * sizeof (Int)) ;	/* [ */
2571     if (!Qinit) error ("out of memory (7)",0.) ;
2572     Head = (Int *) malloc ((n+1) * sizeof (Int)) ;	/* [ */
2573     Next = (Int *) malloc ((n+1) * sizeof (Int)) ;	/* [ */
2574     for (d = 0 ; d <= n ; d++)
2575     {
2576 	Head [d] = EMPTY ;
2577     }
2578     for (col = n-1 ; col >= 0 ; col--)
2579     {
2580 	d = Ap [col+1] - Ap [col] ;
2581 	Next [col] = Head [d] ;
2582 	Head [d] = col ;
2583     }
2584     k = 0 ;
2585     for (d = 0 ; d <= n ; d++)
2586     {
2587 	for (col = Head [d] ; col != EMPTY ; col = Next [col])
2588 	{
2589 	    Qinit [k++] = col ;
2590 	}
2591     }
2592     free (Next) ;	/* ] */
2593     free (Head) ;	/* ] */
2594 
2595     if (k != n) error ("Qinit error\n",0.) ;
2596 
2597     /* use rowdeg for workspace */
2598     if (!UMF_is_permutation (Qinit, rowdeg, n, n)) error ("Qinit, colsort, not a permutation vector",0.) ;
2599 
2600     for (k = 1 ; k < n ; k++)
2601     {
2602 	col1 = Qinit [k-1] ;
2603 	col2 = Qinit [k] ;
2604 	d1 = Ap [col1+1] - Ap [col1] ;
2605 	d2 = Ap [col2+1] - Ap [col2] ;
2606 	if (d1 > d2) error ("Qinit error = not sorted\n",0.) ;
2607     }
2608 
2609     free (rowdeg) ;					/* ) */
2610 
2611     /* ---------------------------------------------------------------------- */
2612     /* exhaustive test */
2613     /* ---------------------------------------------------------------------- */
2614 
2615     n_tol   = Ncontrols [UMFPACK_PIVOT_TOLERANCE] ;
2616     n_nb    = Ncontrols [UMFPACK_BLOCK_SIZE] ;
2617     n_init  = Ncontrols [UMFPACK_ALLOC_INIT] ;
2618     n_scale = Ncontrols [UMFPACK_SCALE] ;
2619     n_amd   = Ncontrols [UMFPACK_AMD_DENSE] ;
2620 
2621     printf (" cs "ID" rs "ID" : "ID"  ", cs, rs,
2622 	2 + (cs * rs * n_tol * n_nb * n_init )) ;
2623     fflush (stdout) ;
2624 
2625     /* with defaults - null Control array, Qinit */
2626     printf ("with qinit:\n") ;
2627     rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, DNULL, Qinit, MemControl, FALSE, FALSE, 0., 0.) ;
2628     maxrnorm = MAX (rnorm, maxrnorm) ;
2629 
2630     /* with defaults - null Control array */
2631     printf ("with null control array:\n") ;
2632     rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, DNULL, noQinit, MemControl, FALSE, FALSE, 0., 0.) ;
2633     maxrnorm = MAX (rnorm, maxrnorm) ;
2634 
2635     /* with defaults */
2636     printf ("with defaults:\n") ;
2637     rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, Control, noQinit, MemControl, FALSE, FALSE, 0., 0.) ;
2638     maxrnorm = MAX (rnorm, maxrnorm) ;
2639 
2640     printf ("with defaults and qinit:\n") ;
2641     rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, Control, Qinit, MemControl, FALSE, FALSE, 0., 0.) ;
2642     maxrnorm = MAX (rnorm, maxrnorm) ;
2643 
2644     /* with lots of ordering options */
2645     psave = Control [UMFPACK_PRL] ;
2646     if (n < 15) Control [UMFPACK_PRL] = 4 ;
2647     for (singletons = 0 ; singletons <= 1 ; singletons++)
2648     {
2649         for (ordering = EMPTY ; ordering <= UMFPACK_ORDERING_USER ; ordering++)
2650         {
2651             Control [UMFPACK_ORDERING] = ordering ;
2652             Control [UMFPACK_SINGLETONS] = singletons ;
2653             printf ("with ordering method "ID" singletons "ID"\n", ordering,
2654                 singletons) ;
2655             UMFPACK_report_control (Control) ;
2656             rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, Control, noQinit, MemControl, FALSE, FALSE, 0., 0.) ;
2657             maxrnorm = MAX (rnorm, maxrnorm) ;
2658         }
2659     }
2660     Control [UMFPACK_ORDERING] = UMFPACK_DEFAULT_ORDERING ;
2661     Control [UMFPACK_SINGLETONS] = UMFPACK_DEFAULT_SINGLETONS ;
2662     Control [UMFPACK_PRL] = psave ;
2663 
2664     printf ("starting lengthy tests\n") ;
2665 
2666     for (c = 0 ; c <= cs ; c++)
2667     {
2668 	if (c == cs)
2669 	{
2670 	    rs = n_amd ;
2671 	}
2672 
2673 	for (r = 0 ; r < rs ; r++)
2674 	{
2675 	    if (c == cs)
2676 	    {
2677 		Control [UMFPACK_DENSE_COL] = UMFPACK_DEFAULT_DENSE_COL ;
2678 		Control [UMFPACK_DENSE_ROW] = UMFPACK_DEFAULT_DENSE_ROW ;
2679 		Control [UMFPACK_AMD_DENSE] = Controls [UMFPACK_AMD_DENSE][r] ;
2680 	    }
2681 	    else
2682 	    {
2683 		ck = cknob [c] ;
2684 		rk = rknob [r] ;
2685 		/* ignore columns with degree > ck and rows with degree > rk */
2686 		Control [UMFPACK_DENSE_COL] = inv_umfpack_dense (ck, n) ;
2687 		Control [UMFPACK_DENSE_ROW] = inv_umfpack_dense (rk, n) ;
2688 		Control [UMFPACK_AMD_DENSE] = UMFPACK_DEFAULT_AMD_DENSE ;
2689 	    }
2690 
2691 	    for (i_tol = 0 ; i_tol < n_tol ; i_tol++)
2692 	    {
2693 		tol = Controls [UMFPACK_PIVOT_TOLERANCE][i_tol] ;
2694 		Control [UMFPACK_PIVOT_TOLERANCE] = tol ;
2695 
2696 		for (i_nb = 0 ; i_nb < n_nb ; i_nb++)
2697 		{
2698 		    nb = (Int) Controls [UMFPACK_BLOCK_SIZE][i_nb] ;
2699 		    Control [UMFPACK_BLOCK_SIZE] = (double) nb ;
2700 
2701 		    for (i_init = 0 ; i_init < n_init ; i_init++)
2702 		    {
2703 			init = Controls [UMFPACK_ALLOC_INIT][i_init] ;
2704 			Control [UMFPACK_ALLOC_INIT] = init ;
2705 
2706 			for (i_scale = 0 ; i_scale < n_scale ; i_scale++)
2707 			{
2708 			    Int strategy, fixQ ;
2709 			    scale = Controls [UMFPACK_SCALE][i_scale] ;
2710 			    Control [UMFPACK_SCALE] = scale ;
2711 
2712 			    for (strategy = UMFPACK_STRATEGY_AUTO ; strategy <= UMFPACK_STRATEGY_SYMMETRIC ; strategy ++)
2713 			    {
2714                                 if (strategy == UMFPACK_STRATEGY_OBSOLETE)
2715                                 {
2716                                     continue ;
2717                                 }
2718 				Control [UMFPACK_STRATEGY] = strategy ;
2719 				{
2720 				    rnorm = do_once (n, n, Ap, Ai, Ax,Az, b,bz, Control, noQinit, MemControl, FALSE, TRUE, FALSE, 0., 0.) ;
2721 				    maxrnorm = MAX (rnorm, maxrnorm) ;
2722 				    rnorm = do_once (n, n, Ap, Ai, Ax,Az, b,bz, Control, Qinit, MemControl, FALSE, TRUE, FALSE, 0., 0.) ;
2723 				    maxrnorm = MAX (rnorm, maxrnorm) ;
2724 				}
2725 			    }
2726 			}
2727 		    }
2728 		}
2729 	    }
2730 	}
2731     }
2732 
2733     free (Qinit) ;	/* ] */
2734     free (bz) ;		/* ] */
2735     free (b) ;		/* ] */
2736     free (rknob) ;	/* ] */
2737     free (cknob) ;	/* ] */
2738 
2739     return (maxrnorm) ;
2740 }
2741 
2742 
2743 /* ========================================================================== */
2744 /* matgen_dense: generate a dense matrix */
2745 /* ========================================================================== */
2746 
2747 /* allocates Ap, Ai, Ax, and Az */
2748 
matgen_dense(Int n,Int ** Ap,Int ** Ai,double ** Ax,double ** Az)2749 static void matgen_dense
2750 (
2751     Int n,
2752     Int **Ap,
2753     Int **Ai,
2754     double **Ax,	double **Az
2755 )
2756 {
2757     Int nz, *Bp, *Bi, *Ti, *Tj, k, i, j, *P, status ;
2758     double *Bx, *Tx, *Bz, *Tz ;
2759 
2760     nz = n*n + n ;
2761 
2762     /* allocate Bp, Bi, and Bx - but do not free them */
2763     Bp = (Int *) malloc ((n+1) * sizeof (Int)) ;
2764     Bi = (Int *) malloc ((nz+1) * sizeof (Int)) ;
2765     Bx = (double *) malloc ((nz+1) * sizeof (double)) ;
2766     Bz = (double *) calloc ((nz+1) , sizeof (double)) ;
2767 
2768     Ti = (Int *) malloc ((nz+1) * sizeof (Int)) ;		/* [ */
2769     Tj = (Int *) malloc ((nz+1) * sizeof (Int)) ;		/* [ */
2770     Tx = (double *) malloc ((nz+1) * sizeof (double)) ;	/* [ */
2771     Tz = (double *) calloc ((nz+1) , sizeof (double)) ;	/* [ */
2772     P = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
2773 
2774     if (!Bp || !Bi || !Bx || !Ti || !Tj || !Tx || !P) error ("out of memory (8)",0.) ;
2775     if (!Bz || !Tz) error ("outof memory",0.) ;
2776 
2777     k = 0 ;
2778     for (i = 0 ; i < n ; i++)
2779     {
2780 	for (j = 0 ; j < n ; j++)
2781 	{
2782 	    Ti [k] = i ;
2783 	    Tj [k] = j ;
2784 	    Tx [k] = 2.0 * (xrand ( ) - 1.0) ;
2785 #ifdef COMPLEX
2786 	    Tz [k] = 2.0 * (xrand ( ) - 1.0) ;
2787 #else
2788 	    Tz [k] = 0. ;
2789 #endif
2790 	    k++ ;
2791 	}
2792     }
2793 
2794     /* beef up each column and row */
2795     randperm (n, P) ;
2796     for (i = 0 ; i < n ; i++)
2797     {
2798 	Ti [k] = i ;
2799 	Tj [k] = P [i] ;
2800 	Tx [k] = xrand ( ) ;
2801 #ifdef COMPLEX
2802 	Tz [k] = xrand ( ) ;
2803 #else
2804 	Tz [k] = 0. ;
2805 #endif
2806 	k++ ;
2807     }
2808 
2809     if (k != nz) error ("matgen_dense error",0.) ;
2810 
2811     /* convert to column form */
2812     status = UMFPACK_triplet_to_col (n, n, k, Ti, Tj, CARG(Tx,Tz), Bp, Bi, CARG(Bx,Bz), (Int *) NULL) ;
2813     if (status != UMFPACK_OK) error ("matgen_dense triplet_to_col failed 2",0.) ;
2814 
2815     /* return the allocated column-form */
2816     *Ap = Bp ;
2817     *Ai = Bi ;
2818     *Ax = Bx ;
2819     *Az = Bz ;
2820 
2821     free (P) ;		/* ] */
2822     free (Tz) ;		/* ] */
2823     free (Tx) ;		/* ] */
2824     free (Tj) ;		/* ] */
2825     free (Ti) ;		/* ] */
2826 
2827 }
2828 
2829 
2830 /* ========================================================================== */
2831 /* matgen_funky: generate a kind of arrowhead matrix */
2832 /* ========================================================================== */
2833 
2834 /* allocates Ap, Ai, Ax, and Az
2835 
2836    A = speye (n) ;
2837    A (n, 2:3) = rand (1,2) ;
2838    A (3, 3:n) = rand (1, n-2) ;
2839    A (3:n, 1) = rand (n-2, 1) ;
2840 
2841  */
2842 
matgen_funky(Int n,Int ** Ap,Int ** Ai,double ** Ax,double ** Az)2843 static void matgen_funky
2844 (
2845     Int n,
2846     Int **Ap,
2847     Int **Ai,
2848     double **Ax,	double **Az
2849 )
2850 {
2851     Int nz, *Bp, *Bi, *Ti, *Tj, k, i, j, *P, status ;
2852     double *Bx, *Tx, *Bz, *Tz ;
2853 
2854     nz = 4*n + 5 ;
2855 
2856     /* allocate Bp, Bi, and Bx - but do not free them */
2857     Bp = (Int *) malloc ((n+1) * sizeof (Int)) ;
2858     Bi = (Int *) malloc (nz * sizeof (Int)) ;
2859     Bx = (double *) malloc (nz * sizeof (double)) ;
2860     Bz = (double *) calloc (nz , sizeof (double)) ;
2861 
2862     Ti = (Int *) malloc (nz * sizeof (Int)) ;		/* [ */
2863     Tj = (Int *) malloc (nz * sizeof (Int)) ;		/* [ */
2864     Tx = (double *) malloc (nz * sizeof (double)) ;	/* [ */
2865     Tz = (double *) calloc (nz , sizeof (double)) ;	/* [ */
2866     P = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
2867 
2868     if (!Bp || !Bi || !Bx || !Ti || !Tj || !Tx || !P) error ("out of memory (9)",0.) ;
2869     if (!Bz || !Tz) error ("outof memory",0.) ;
2870 
2871     k = 0 ;
2872 
2873     /* A = speye (n) ; */
2874     for (i = 0 ; i < n ; i++)
2875     {
2876 	Ti [k] = i ;
2877 	Tj [k] = i ;
2878 	Tx [k] = 1.0 ;
2879 #ifdef COMPLEX
2880 	Tz [k] = 1.0 ;
2881 #endif
2882 	k++ ;
2883     }
2884 
2885     /* A (n, 2:3) = rand (1,2) ; */
2886     for (j = 1 ; j <= 2 ; j++)
2887     {
2888 	Ti [k] = n-1 ;
2889 	Tj [k] = j ;
2890 	Tx [k] = 1.0 ;
2891 #ifdef COMPLEX
2892 	Tz [k] = 1.0 ;
2893 #endif
2894 	k++ ;
2895     }
2896 
2897     /* A (3, 3:n) = rand (1, n-2) ; */
2898     for (j = 2 ; j < n ; j++)
2899     {
2900 	Ti [k] = 2 ;
2901 	Tj [k] = j ;
2902 	Tx [k] = 1.0 ;
2903 #ifdef COMPLEX
2904 	Tz [k] = 1.0 ;
2905 #endif
2906 	k++ ;
2907     }
2908 
2909     /* A (3:n, 1) = rand (n-2, 1) ; */
2910     for (i = 2 ; i < n ; i++)
2911     {
2912 	Ti [k] = i ;
2913 	Tj [k] = 0 ;
2914 	Tx [k] = 1.0 ;
2915 #ifdef COMPLEX
2916 	Tz [k] = 1.0 ;
2917 #endif
2918 	k++ ;
2919     }
2920 
2921     /* convert to column form */
2922     status = UMFPACK_triplet_to_col (n, n, k, Ti, Tj, CARG(Tx,Tz), Bp, Bi, CARG(Bx,Bz), (Int *) NULL) ;
2923     if (status != UMFPACK_OK) error ("matgen_dense triplet_to_col failed 1",0.) ;
2924 
2925     /* return the allocated column-form */
2926     *Ap = Bp ;
2927     *Ai = Bi ;
2928     *Ax = Bx ;
2929     *Az = Bz ;
2930 
2931     free (P) ;		/* ] */
2932     free (Tz) ;		/* ] */
2933     free (Tx) ;		/* ] */
2934     free (Tj) ;		/* ] */
2935     free (Ti) ;		/* ] */
2936 
2937 }
2938 
2939 
2940 /* ========================================================================== */
2941 /* matgen_band: generate a banded matrix */
2942 /* ========================================================================== */
2943 
2944 /* allocates Ap, Ai, and Ax */
2945 
matgen_band(Int n,Int lo,Int up,Int ndrow,Int rdeg,Int ndcol,Int cdeg,Int ** Ap,Int ** Ai,double ** Ax,double ** Az)2946 static void matgen_band
2947 (
2948     Int n,
2949     Int lo,	/* lo = 0:  upper triangular only */
2950     Int up,	/* up = 0:  lower triangular only */
2951     Int ndrow,	/* plus ndrow dense rows, each of degree rdeg */
2952     Int rdeg,
2953     Int ndcol,	/* plus ndcol dense cols, each of degree cdeg */
2954     Int cdeg,
2955     Int **Ap,
2956     Int **Ai,
2957     double **Ax,	double **Az
2958 )
2959 {
2960     Int nz, *Bp, *Bi, *Ti, *Tj, k, i, j, jlo, jup, j1, i1, k1, status ;
2961     double *Bx, *Bz, *Tx, *Tz ;
2962 
2963     /* an upper bound */
2964     nz = n * (lo + 1 + up) + n + ndrow*rdeg + ndcol*cdeg ;
2965 
2966     /* allocate Bp, Bi, and Bx - but do not free them */
2967     Bp = (Int *) malloc ((n+1) * sizeof (Int)) ;
2968     Bi = (Int *) malloc (nz * sizeof (Int)) ;
2969     Bx = (double *) malloc (nz * sizeof (double)) ;
2970     Bz = (double *) calloc (nz , sizeof (double)) ;
2971 
2972     Ti = (Int *) malloc (nz * sizeof (Int)) ;		/* [ */
2973     Tj = (Int *) malloc (nz * sizeof (Int)) ;		/* [ */
2974     Tx = (double *) malloc (nz * sizeof (double)) ;	/* [ */
2975     Tz = (double *) calloc (nz , sizeof (double)) ;	/* [ */
2976 
2977     if (!Bp || !Bi || !Bx || !Ti || !Tj || !Tx) error ("out of memory (10)",0.) ;
2978     if (!Bz || !Tz) error ("out ofmemory", 0.) ;
2979 
2980     k = 0 ;
2981     for (i = 0 ; i < n ; i++)
2982     {
2983 	jlo = MAX (0,   i - lo) ;
2984 	jup = MIN (n-1, i + up) ;
2985 	for (j = jlo ; j <= jup ; j++)
2986 	{
2987 	    Ti [k] = i ;
2988 	    Tj [k] = j ;
2989 	    Tx [k] = 2.0 * (xrand ( ) - 1.0) ;
2990 #ifdef COMPLEX
2991 	    Tz [k] = 2.0 * (xrand ( ) - 1.0) ;
2992 #else
2993 	    Tz [k] = 0. ;
2994 #endif
2995 	    k++ ;
2996 	}
2997     }
2998 
2999     /* beef up the diagonal */
3000     for (i = 0 ; i < n ; i++)
3001     {
3002 	Ti [k] = i ;
3003 	Tj [k] = i ;
3004 	Tx [k] = xrand ( ) ;
3005 #ifdef COMPLEX
3006 	Tz [k] = xrand ( ) ;
3007 #else
3008 	Tz [k] = 0. ;
3009 #endif
3010 	k++ ;
3011     }
3012 
3013     /* add ndrow rows of degree rdeg */
3014     for (i1 = 0 ; i1 < ndrow ; i1++)
3015     {
3016 	i = irand (n) ;
3017 	for (k1 = 0 ; k1 < rdeg ; k1++)
3018 	{
3019 	    Ti [k] = i ;
3020 	    Tj [k] = irand (n) ;
3021 	    Tx [k] = 0.1 * xrand ( ) ;
3022 #ifdef COMPLEX
3023 	    Tz [k] = 0.1 * xrand ( ) ;
3024 #else
3025 	    Tz [k] = 0. ;
3026 #endif
3027 	    k++ ;
3028 	}
3029     }
3030 
3031     /* add ndcol rows of degree cdeg */
3032     for (j1 = 0 ; j1 < ndcol ; j1++)
3033     {
3034 	j = irand (n) ;
3035 	for (k1 = 0 ; k1 < cdeg ; k1++)
3036 	{
3037 	    Ti [k] = irand (n) ;
3038 	    Tj [k] = j ;
3039 	    Tx [k] = 0.1 * xrand ( ) ;
3040 #ifdef COMPLEX
3041 	    Tz [k] = 0.1 * xrand ( ) ;
3042 #else
3043 	    Tz [k] = 0. ;
3044 #endif
3045 	    k++ ;
3046 	}
3047     }
3048 
3049     if (k > nz) error ("matgen_band error\n",0.) ;
3050 
3051     /* convert to column form */
3052     status = UMFPACK_triplet_to_col (n, n, k, Ti, Tj, CARG(Tx,Tz), Bp, Bi, CARG(Bx,Bz), (Int *) NULL) ;
3053     if (status != UMFPACK_OK) error ("matgen_band triplet_to_col failed\n",0.) ;
3054 
3055     /* return the allocated column-form */
3056     *Ap = Bp ;
3057     *Ai = Bi ;
3058     *Ax = Bx ;
3059     *Az = Bz ;
3060 
3061     free (Tz) ;	    /* ] */
3062     free (Tx) ;	    /* ] */
3063     free (Tj) ;	    /* ] */
3064     free (Ti) ;	    /* ] */
3065 
3066 }
3067 
3068 
3069 /* ========================================================================== */
3070 /* test_col */
3071 /* ========================================================================== */
3072 
test_col(Int n,Int Bp[],Int Bi[],double Bx[],double Bz[],Int prl)3073 static void test_col
3074 (
3075     Int n,
3076     Int Bp [ ],
3077     Int Bi [ ],
3078     double Bx [ ],	double Bz [ ],
3079     Int prl
3080 )
3081 {
3082     Int *Ci, *Cj, *Ep, *Ei, k, s, t, i, j, nz, p, status, *Map, *noMap ;
3083     double *Cx, *Cz, *Ex, *Ez, z, Control [UMFPACK_CONTROL] ;
3084     noMap = (Int *) NULL ;
3085 
3086     printf ("\n\n===== test col -> triplet and triplet -> col\n") ;
3087 
3088     UMFPACK_defaults (Control) ;
3089 
3090     Control [UMFPACK_PRL] = prl ;
3091     UMFPACK_report_control (Control) ;
3092 
3093     nz = Bp [n] ;
3094 
3095     Ci = (Int *) malloc ((2*nz+1) * sizeof (Int)) ;		/* [ */
3096     Cj = (Int *) malloc ((2*nz+1) * sizeof (Int)) ;		/* [ */
3097     Cx = (double *) calloc (2*(2*nz+1) , sizeof (double)) ;	/* [ */
3098     Cz = Cx + (2*nz+1) ;
3099     Ep = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
3100     Ei = (Int *) malloc ((2*nz+1) * sizeof (Int)) ;		/* [ */
3101     Ex = (double *) calloc (2*(2*nz+1) , sizeof (double)) ;	/* [ */
3102     Ez = Ex + (2*nz+1) ;
3103     Map = (Int *) malloc ((2*nz+1) * sizeof (Int)) ;		/* [ */
3104 
3105     if (!Ci || !Cj || !Cx || !Ep || !Ei || !Ex) error ("out of memory (11)",0.) ;
3106 
3107     /* ---------------------------------------------------------------------- */
3108     /* test with split complex values */
3109     /* ---------------------------------------------------------------------- */
3110 
3111     /* convert B (col) to C (triplet) */
3112     status = UMFPACK_col_to_triplet (n, Bp, Cj) ;
3113     if (status != UMFPACK_OK) error ("col->triplet",0.) ;
3114     for (k = 0 ; k < nz ; k++)
3115     {
3116 	Ci [k] = Bi [k] ;
3117 	Cx [k] = Bx [k] ;
3118 	Cz [k] = Bz [k] ;
3119     }
3120 
3121     /* convert C (triplet) to E (col) */
3122     status = UMFPACK_triplet_to_col (n, n, nz, Ci, Cj, CARG(Cx,Cz), Ep, Ei, CARG(Ex,Ez), Map) ;
3123     if (status != UMFPACK_OK) error ("t->col failed (1)",0.) ;
3124 
3125     /* compare E and B, they should be identical */
3126     if (nz != Ep [n]) error ("E nz (1)",0.) ;
3127     for (j = 0 ; j < n ; j++)
3128     {
3129 	if (Bp [j] != Ep [j]) error ("Ep j",0.) ;
3130 	if (Bp [j+1] != Ep [j+1]) error ("Ep j",0.) ;
3131 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3132 	{
3133 	    if (Bi [p] != Ei [p]) error ("Ei",0.) ;
3134 	    if (SCALAR_ABS (Bx [p] - Ex [p]) > 1e-15) error ("Ex",0.) ;
3135 	    if (SCALAR_ABS (Bz [p] - Ez [p]) > 1e-15) error ("Ez (1)",0.) ;
3136 	}
3137     }
3138 
3139     /* convert C (triplet) to E (col), no map */
3140     status = UMFPACK_triplet_to_col (n, n, nz, Ci, Cj, CARG(Cx,Cz), Ep, Ei, CARG(Ex,Ez), noMap) ;
3141     if (status != UMFPACK_OK) error ("t->col failed (1)",0.) ;
3142 
3143     /* compare E and B, they should be identical */
3144     if (nz != Ep [n]) error ("E nz (2)",0.) ;
3145     for (j = 0 ; j < n ; j++)
3146     {
3147 	if (Bp [j] != Ep [j]) error ("Ep j",0.) ;
3148 	if (Bp [j+1] != Ep [j+1]) error ("Ep j",0.) ;
3149 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3150 	{
3151 	    if (Bi [p] != Ei [p]) error ("Ei",0.) ;
3152 	    if (SCALAR_ABS (Bx [p] - Ex [p]) > 1e-15) error ("Ex",0.) ;
3153 	    if (SCALAR_ABS (Bz [p] - Ez [p]) > 1e-15) error ("Ez",0.) ;
3154 	}
3155     }
3156 
3157     /* jumble C a little bit */
3158     for (k = 0 ; k < MIN (nz,4) ; k++)
3159     {
3160 	s = irand (nz) ;
3161 	/* swap positions s and k */
3162 	t = Ci [k] ; Ci [k] = Ci [s] ; Ci [s] = t ;
3163 	t = Cj [k] ; Cj [k] = Cj [s] ; Cj [s] = t ;
3164 	z = Cx [k] ; Cx [k] = Cx [s] ; Cx [s] = z ;
3165 	z = Cz [k] ; Cz [k] = Cz [s] ; Cz [s] = z ;
3166     }
3167 
3168     /* convert C (triplet) to E (col) */
3169     status = UMFPACK_triplet_to_col (n, n, nz, Ci, Cj, CARG(Cx,Cz), Ep, Ei, CARG(Ex,Ez), Map) ;
3170     if (status != UMFPACK_OK) error ("t->col failed (1)",0.) ;
3171 
3172     /* compare E and B, they should be identical */
3173     if (nz != Ep [n]) error ("E nz (3)",0.) ;
3174     for (j = 0 ; j < n ; j++)
3175     {
3176 	if (Bp [j] != Ep [j]) error ("Ep j",0.) ;
3177 	if (Bp [j+1] != Ep [j+1]) error ("Ep j",0.) ;
3178 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3179 	{
3180 	    if (Bi [p] != Ei [p]) error ("Ei",0.) ;
3181 	    if (SCALAR_ABS (Bx [p] - Ex [p]) > 1e-15) error ("Ex",0.) ;
3182 	    if (SCALAR_ABS (Bz [p] - Ez [p]) > 1e-15) error ("Ez",0.) ;
3183 	}
3184     }
3185 
3186     /* convert C (triplet) to E (col), no map */
3187     status = UMFPACK_triplet_to_col (n, n, nz, Ci, Cj, CARG(Cx,Cz), Ep, Ei, CARG(Ex,Ez), noMap) ;
3188     if (status != UMFPACK_OK) error ("t->col failed (1)",0.) ;
3189 
3190     /* compare E and B, they should be identical */
3191     if (nz != Ep [n]) error ("E nz (4)",0.) ;
3192     for (j = 0 ; j < n ; j++)
3193     {
3194 	if (Bp [j] != Ep [j]) error ("Ep j",0.) ;
3195 	if (Bp [j+1] != Ep [j+1]) error ("Ep j",0.) ;
3196 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3197 	{
3198 	    if (Bi [p] != Ei [p]) error ("Ei",0.) ;
3199 	    if (SCALAR_ABS (Bx [p] - Ex [p]) > 1e-15) error ("Ex",0.) ;
3200 	    if (SCALAR_ABS (Bz [p] - Ez [p]) > 1e-15) error ("Ez",0.) ;
3201 	}
3202     }
3203 
3204     /* jumble C a lot */
3205     for (k = 0 ; k < nz ; k++)
3206     {
3207 	s = irand (nz) ;
3208 	/* swap positions s and k */
3209 	t = Ci [k] ; Ci [k] = Ci [s] ; Ci [s] = t ;
3210 	t = Cj [k] ; Cj [k] = Cj [s] ; Cj [s] = t ;
3211 	z = Cx [k] ; Cx [k] = Cx [s] ; Cx [s] = z ;
3212 	z = Cz [k] ; Cz [k] = Cz [s] ; Cz [s] = z ;
3213     }
3214 
3215     /* add duplicates to C, but preserve pattern and values */
3216     for (k = nz ; k < 2*nz ; k++)
3217     {
3218 	/* add a duplicate */
3219 	s = irand (k) ;
3220 	Ci [k] = Ci [s] ;
3221 	Cj [k] = Cj [s] ;
3222 	z = Cx [s] ;
3223 	Cx [s] = z/2 ;
3224 	Cx [k] = z/2 ;
3225 	z = Cz [s] ;
3226 	Cz [s] = z/2 ;
3227 	Cz [k] = z/2 ;
3228     }
3229 
3230     if (prl > 2) printf ("\ntest c->t,t->c: ") ;
3231     status = UMFPACK_report_triplet (n, n, 2*nz, Ci, Cj, CARG(Cx,Cz), Control) ;
3232     if (status != UMFPACK_OK) error ("report col->triplet",0.) ;
3233 
3234     /* convert C (triplet) to E (col), no Map */
3235     status = UMFPACK_triplet_to_col (n, n, 2*nz, Ci, Cj, CARG(Cx,Cz), Ep, Ei, CARG(Ex,Ez), noMap) ;
3236     if (status != UMFPACK_OK) error ("t->col failed",0.) ;
3237 
3238     /* compare E and B, they should be identical */
3239     if (nz != Ep [n]) error ("E nz (5)",0.) ;
3240     for (j = 0 ; j < n ; j++)
3241     {
3242 	if (Bp [j] != Ep [j]) error ("Ep j",0.) ;
3243 	if (Bp [j+1] != Ep [j+1]) error ("Ep j",0.) ;
3244 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3245 	{
3246 	    if (Bi [p] != Ei [p]) error ("Ei",0.) ;
3247 	    if (SCALAR_ABS (Bx [p] - Ex [p]) > 1e-15) error ("Ex",0.) ;
3248 	    if (SCALAR_ABS (Bz [p] - Ez [p]) > 1e-15)
3249 	    {
3250 		printf ("%30.18e %30.18e %g\n", Bz[p], Ez[p], Bz[p]-Ez[p]) ;
3251 		error ("Ez (5)",0.) ;
3252 	    }
3253 	}
3254     }
3255 
3256     /* convert C (triplet) to E (col) */
3257     status = UMFPACK_triplet_to_col (n, n, 2*nz, Ci, Cj, CARG(Cx,Cz), Ep, Ei, CARG(Ex,Ez), Map) ;
3258     if (status != UMFPACK_OK) error ("t->col failed",0.) ;
3259 
3260     /* compare E and B, they should be identical */
3261     if (nz != Ep [n]) error ("E nz (6)",0.) ;
3262     for (j = 0 ; j < n ; j++)
3263     {
3264 	if (Bp [j] != Ep [j]) error ("Ep j",0.) ;
3265 	if (Bp [j+1] != Ep [j+1]) error ("Ep j",0.) ;
3266 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3267 	{
3268 	    if (Bi [p] != Ei [p]) error ("Ei",0.) ;
3269 	    if (SCALAR_ABS (Bx [p] - Ex [p]) > 1e-15) error ("Ex",0.) ;
3270 	    if (SCALAR_ABS (Bz [p] - Ez [p]) > 1e-15) error ("Ez",0.) ;
3271 	}
3272     }
3273 
3274     /* convert C (triplet) to E (col), using Map */
3275     for (p = 0 ; p < Ep [n] ; p++)
3276     {
3277 	Ex [p] = 0. ;
3278 	Ez [p] = 0. ;
3279     }
3280     for (k = 0 ; k < 2*nz ; k++)
3281     {
3282 	p = Map [k] ;
3283 	i = Ci [k] ;
3284 	j = Cj [k] ;
3285 	if (i != Ei [p]) error ("Map", 0.) ;
3286 	if (!(Ep [j] <= p && p < Ep [j+1])) error ("Map Ep", 0.) ;
3287 	Ex [p] += Cx [k] ;
3288 	Ez [p] += Cz [k] ;
3289     }
3290 
3291     /* compare E and B, they should be identical */
3292     for (j = 0 ; j < n ; j++)
3293     {
3294 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3295 	{
3296 	    z = SCALAR_ABS (Bx [p] - Ex [p]) ;
3297 	    if (z > 1e-15) error ("Ex",z) ;
3298 	    z = SCALAR_ABS (Bz [p] - Ez [p]) ;
3299 	    if (z > 1e-15) error ("Ez (7)",z) ;
3300 	}
3301     }
3302 
3303 #ifdef COMPLEX
3304     /* ---------------------------------------------------------------------- */
3305     /* repeat, but with merged complex values */
3306     /* ---------------------------------------------------------------------- */
3307 
3308     /* convert B (col) to C (triplet) */
3309     status = UMFPACK_col_to_triplet (n, Bp, Cj) ;
3310     if (status != UMFPACK_OK) error ("col->triplet",0.) ;
3311     for (k = 0 ; k < nz ; k++)
3312     {
3313 	Ci [k] = Bi [k] ;
3314 	Cx [2*k  ] = Bx [k] ;
3315 	Cx [2*k+1] = Bz [k] ;
3316     }
3317 
3318     /* convert C (triplet) to E (col) */
3319     status = UMFPACK_triplet_to_col (n, n, nz, Ci, Cj, CARG(Cx,DNULL), Ep, Ei, CARG(Ex,DNULL), Map) ;
3320     if (status != UMFPACK_OK) error ("t->col failed (1)",0.) ;
3321 
3322     /* compare E and B, they should be identical */
3323     if (nz != Ep [n]) error ("E nz (7)",0.) ;
3324     for (j = 0 ; j < n ; j++)
3325     {
3326 	if (Bp [j] != Ep [j]) error ("Ep j",0.) ;
3327 	if (Bp [j+1] != Ep [j+1]) error ("Ep j",0.) ;
3328 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3329 	{
3330 	    if (Bi [p] != Ei [p]) error ("Ei",0.) ;
3331 	    if (SCALAR_ABS (Bx [p] - Ex [2*p  ]) > 1e-15) error ("Ex (merge)",0.) ;
3332 	    if (SCALAR_ABS (Bz [p] - Ex [2*p+1]) > 1e-15) error ("Ez (merge)",0.) ;
3333 	}
3334     }
3335 
3336     /* convert C (triplet) to E (col) no Map */
3337     status = UMFPACK_triplet_to_col (n, n, nz, Ci, Cj, CARG(Cx,DNULL), Ep, Ei, CARG(Ex,DNULL), noMap) ;
3338     if (status != UMFPACK_OK) error ("t->col failed (1)",0.) ;
3339 
3340     /* compare E and B, they should be identical */
3341     if (nz != Ep [n]) error ("E nz (8)",0.) ;
3342     for (j = 0 ; j < n ; j++)
3343     {
3344 	if (Bp [j] != Ep [j]) error ("Ep j",0.) ;
3345 	if (Bp [j+1] != Ep [j+1]) error ("Ep j",0.) ;
3346 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3347 	{
3348 	    if (Bi [p] != Ei [p]) error ("Ei",0.) ;
3349 	    if (SCALAR_ABS (Bx [p] - Ex [2*p  ]) > 1e-15) error ("Ex (merge)",0.) ;
3350 	    if (SCALAR_ABS (Bz [p] - Ex [2*p+1]) > 1e-15) error ("Ez (merge)",0.) ;
3351 	}
3352     }
3353 
3354     /* jumble C a little bit */
3355     for (k = 0 ; k < MIN (nz,4) ; k++)
3356     {
3357 	s = irand (nz) ;
3358 	/* swap positions s and k */
3359 	t = Ci [k] ; Ci [k] = Ci [s] ; Ci [s] = t ;
3360 	t = Cj [k] ; Cj [k] = Cj [s] ; Cj [s] = t ;
3361 	z = Cx [2*k  ] ; Cx [2*k  ] = Cx [2*s  ] ; Cx [2*s  ] = z ;
3362 	z = Cx [2*k+1] ; Cx [2*k+1] = Cx [2*s+1] ; Cx [2*s+1] = z ;
3363     }
3364 
3365     /* convert C (triplet) to E (col) */
3366     status = UMFPACK_triplet_to_col (n, n, nz, Ci, Cj, CARG(Cx,DNULL), Ep, Ei, CARG(Ex,DNULL), Map) ;
3367     if (status != UMFPACK_OK) error ("t->col failed (1)",0.) ;
3368 
3369     /* compare E and B, they should be identical */
3370     if (nz != Ep [n]) error ("E nz (9)",0.) ;
3371     for (j = 0 ; j < n ; j++)
3372     {
3373 	if (Bp [j] != Ep [j]) error ("Ep j",0.) ;
3374 	if (Bp [j+1] != Ep [j+1]) error ("Ep j",0.) ;
3375 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3376 	{
3377 	    if (Bi [p] != Ei [p]) error ("Ei",0.) ;
3378 	    if (SCALAR_ABS (Bx [p] - Ex [2*p  ]) > 1e-15) error ("Ex (merge)",0.) ;
3379 	    if (SCALAR_ABS (Bz [p] - Ex [2*p+1]) > 1e-15) error ("Ez (merge)",0.) ;
3380 	}
3381     }
3382 
3383     /* convert C (triplet) to E (col) no Map */
3384     status = UMFPACK_triplet_to_col (n, n, nz, Ci, Cj, CARG(Cx,DNULL), Ep, Ei, CARG(Ex,DNULL), noMap) ;
3385     if (status != UMFPACK_OK) error ("t->col failed (1)",0.) ;
3386 
3387     /* compare E and B, they should be identical */
3388     if (nz != Ep [n]) error ("E nz (10)",0.) ;
3389     for (j = 0 ; j < n ; j++)
3390     {
3391 	if (Bp [j] != Ep [j]) error ("Ep j",0.) ;
3392 	if (Bp [j+1] != Ep [j+1]) error ("Ep j",0.) ;
3393 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3394 	{
3395 	    if (Bi [p] != Ei [p]) error ("Ei",0.) ;
3396 	    if (SCALAR_ABS (Bx [p] - Ex [2*p  ]) > 1e-15) error ("Ex (merge)",0.) ;
3397 	    if (SCALAR_ABS (Bz [p] - Ex [2*p+1]) > 1e-15) error ("Ez (merge)",0.) ;
3398 	}
3399     }
3400 
3401     /* jumble C */
3402     for (k = 0 ; k < nz ; k++)
3403     {
3404 	s = irand (nz) ;
3405 	/* swap positions s and k */
3406 	t = Ci [k] ; Ci [k] = Ci [s] ; Ci [s] = t ;
3407 	t = Cj [k] ; Cj [k] = Cj [s] ; Cj [s] = t ;
3408 	z = Cx [2*k  ] ; Cx [2*k  ] = Cx [2*s  ] ; Cx [2*s  ] = z ;
3409 	z = Cx [2*k+1] ; Cx [2*k+1] = Cx [2*s+1] ; Cx [2*s+1] = z ;
3410     }
3411 
3412     /* add duplicates to C, but preserve pattern and values */
3413     for (k = nz ; k < 2*nz ; k++)
3414     {
3415 	/* add a duplicate */
3416 	s = irand (k) ;
3417 	Ci [k] = Ci [s] ;
3418 	Cj [k] = Cj [s] ;
3419 	z = Cx [2*s] ;
3420 	Cx [2*s] = z/2 ;
3421 	Cx [2*k] = z/2 ;
3422 	z = Cx [2*s+1] ;
3423 	Cx [2*s+1] = z/2 ;
3424 	Cx [2*k+1] = z/2 ;
3425     }
3426 
3427     if (prl > 2) printf ("\ntest c->t,t->c: ") ;
3428     status = UMFPACK_report_triplet (n, n, 2*nz, Ci, Cj, CARG(Cx,DNULL), Control) ;
3429     if (status != UMFPACK_OK) error ("report col->triplet",0.) ;
3430 
3431     /* convert C (triplet) to E (col) */
3432     status = UMFPACK_triplet_to_col (n, n, 2*nz, Ci, Cj, CARG(Cx,DNULL), Ep, Ei, CARG(Ex,DNULL), noMap) ;
3433     if (status != UMFPACK_OK) error ("t->col failed",0.) ;
3434 
3435     /* compare E and B, they should be identical */
3436     if (nz != Ep [n]) error ("E nz (11)",0.) ;
3437     for (j = 0 ; j < n ; j++)
3438     {
3439 	if (Bp [j] != Ep [j]) error ("Ep j",0.) ;
3440 	if (Bp [j+1] != Ep [j+1]) error ("Ep j",0.) ;
3441 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3442 	{
3443 	    if (Bi [p] != Ei [p]) error ("Ei",0.) ;
3444 	    if (SCALAR_ABS (Bx [p] - Ex [2*p  ]) > 1e-15) error ("Ex (merge)",0.) ;
3445 	    if (SCALAR_ABS (Bz [p] - Ex [2*p+1]) > 1e-15) error ("Ez (merge)",0.) ;
3446 	}
3447     }
3448 
3449     /* convert C (triplet) to E (col) */
3450     status = UMFPACK_triplet_to_col (n, n, 2*nz, Ci, Cj, CARG(Cx,DNULL), Ep, Ei, CARG(Ex,DNULL), Map) ;
3451     if (status != UMFPACK_OK) error ("t->col failed",0.) ;
3452 
3453     /* compare E and B, they should be identical */
3454     if (nz != Ep [n]) error ("E nz (12)",0.) ;
3455     for (j = 0 ; j < n ; j++)
3456     {
3457 	if (Bp [j] != Ep [j]) error ("Ep j",0.) ;
3458 	if (Bp [j+1] != Ep [j+1]) error ("Ep j",0.) ;
3459 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3460 	{
3461 	    if (Bi [p] != Ei [p]) error ("Ei",0.) ;
3462 	    if (SCALAR_ABS (Bx [p] - Ex [2*p  ]) > 1e-15) error ("Ex (merge)",0.) ;
3463 	    if (SCALAR_ABS (Bz [p] - Ex [2*p+1]) > 1e-15) error ("Ez (merge)",0.) ;
3464 	}
3465     }
3466 
3467     /* convert C (triplet) to E (col), using Map */
3468     for (p = 0 ; p < Ep [n] ; p++)
3469     {
3470 	Ex [2*p  ] = 0. ;
3471 	Ex [2*p+1] = 0. ;
3472     }
3473     for (k = 0 ; k < 2*nz ; k++)
3474     {
3475 	p = Map [k] ;
3476 	i = Ci [k] ;
3477 	j = Cj [k] ;
3478 	if (i != Ei [p]) error ("Map", 0.) ;
3479 	if (!(Ep [j] <= p && p < Ep [j+1])) error ("Map Ep", 0.) ;
3480 	Ex [2*p  ] += Cx [2*k  ] ;
3481 	Ex [2*p+1] += Cx [2*k+1] ;
3482     }
3483 
3484     /* compare E and B, they should be identical */
3485     for (j = 0 ; j < n ; j++)
3486     {
3487 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3488 	{
3489 	    z = SCALAR_ABS (Bx [p] - Ex [2*p  ]) ;
3490 	    if (z > 1e-15) error ("Ex merged",z) ;
3491 	    z = SCALAR_ABS (Bz [p] - Ex [2*p+1]) ;
3492 	    if (z > 1e-15) error ("Ez merged 7",z) ;
3493 	}
3494     }
3495 
3496 #endif
3497 
3498     printf ("\n =============== test OK\n\n") ;
3499 
3500     free (Map) ;	/* ] */
3501     free (Ex) ;		/* ] */
3502     free (Ei) ;		/* ] */
3503     free (Ep) ;		/* ] */
3504     free (Cx) ;		/* ] */
3505     free (Cj) ;		/* ] */
3506     free (Ci) ;		/* ] */
3507 }
3508 
3509 /* ========================================================================== */
3510 /* matgen_compaction: generate a matrix to test umf_symbolic compaction */
3511 /* ========================================================================== */
3512 
matgen_compaction(Int n,Int ** Ap,Int ** Ai,double ** Ax,double ** Az)3513 static void matgen_compaction
3514 (
3515    Int n,
3516    Int **Ap,
3517    Int **Ai,
3518    double **Ax,		double **Az
3519 )
3520 {
3521     Int nz, *Bp, *Bi, *Ti, *Tj, k, i, j, prl, status ;
3522     double *Bx, *Tx, *Bz, *Tz, Control [UMFPACK_INFO] ;
3523 
3524     prl = Control ? Control [UMFPACK_PRL] : UMFPACK_DEFAULT_PRL ;
3525     UMFPACK_defaults (Control) ;
3526 
3527     UMFPACK_report_control (Control) ;
3528 
3529     nz = 5*n ;
3530 
3531     /* allocate Bp, Bi, and Bx - but do not free them */
3532     Bp = (Int *) malloc ((n+1) * sizeof (Int)) ;
3533     Bi = (Int *) malloc (nz * sizeof (Int)) ;
3534     Bx = (double *) malloc (nz * sizeof (double)) ;
3535     Bz = (double *) calloc (nz , sizeof (double)) ;
3536 
3537     Ti = (Int *) malloc (nz * sizeof (Int)) ;		/* [ */
3538     Tj = (Int *) malloc (nz * sizeof (Int)) ;		/* [ */
3539     Tx = (double *) malloc (nz * sizeof (double)) ;	/* [ */
3540     Tz = (double *) calloc (nz , sizeof (double)) ;	/* [ */
3541     if (!Bp || !Bi || !Bx || !Ti || !Tj || !Tx) error ("out of memory (12)",0.) ;
3542     if (!Bz || !Tz) error ("out of mery",0.) ;
3543 
3544     k = 0 ;
3545     for (i = 0 ; i < n ; i++)
3546     {
3547 	if (i > 0)
3548 	{
3549 	    Ti [k] = i ;
3550 	    Tj [k] = i-1 ;
3551 	    Tx [k] = xrand ( ) ;
3552 #ifdef COMPLEX
3553 	    Tz [k] = xrand ( ) ;
3554 #else
3555 	    Tz [k] = 0. ;
3556 #endif
3557 	    k++ ;
3558 	}
3559 	Ti [k] = i ;
3560 	Tj [k] = i ;
3561 	Tx [k] = xrand ( ) ;
3562 	k++ ;
3563 	if (i < n-1)
3564 	{
3565 	    Ti [k] = i ;
3566 	    Tj [k] = i+1 ;
3567 	    Tx [k] = xrand ( ) ;
3568 #ifdef COMPLEX
3569 	    Tz [k] = xrand ( ) ;
3570 #else
3571 	    Tz [k] = 0. ;
3572 #endif
3573 	    k++ ;
3574 	}
3575     }
3576 
3577     for (j = 0 ; j < n ; j += 2)
3578     {
3579 	Ti [k] = 0 ;
3580 	Tj [k] = j ;
3581 	Tx [k] = xrand ( ) ;
3582 #ifdef COMPLEX
3583 	Tz [k] = xrand ( ) ;
3584 #else
3585 	Tz [k] = 0. ;
3586 #endif
3587 	k++ ;
3588     }
3589 
3590     for (j = 1 ; j < n ; j += 2)
3591     {
3592 	Ti [k] = 1 ;
3593 	Tj [k] = j ;
3594 	Tx [k] = xrand ( ) ;
3595 #ifdef COMPLEX
3596 	Tz [k] = xrand ( ) ;
3597 #else
3598 	Tz [k] = 0. ;
3599 #endif
3600 	k++ ;
3601     }
3602 
3603 
3604     if (prl > 2) printf ("\nmatgen_compact: ") ;
3605     status = UMFPACK_report_triplet (n, n, k, Ti, Tj, CARG(Tx,Tz), Control) ;
3606     if (status != UMFPACK_OK) error ("bad triplet report",0.) ;
3607 
3608     /* convert to column form */
3609     status = UMFPACK_triplet_to_col (n, n, k, Ti, Tj, CARG(Tx,Tz), Bp, Bi, CARG(Bx,Bz), (Int *) NULL) ;
3610     if (status != UMFPACK_OK) error ("matgen_compact triplet_to_col failed",0.) ;
3611 
3612     if (prl > 2) printf ("\nmatgen_compact: ") ;
3613     status = UMFPACK_report_matrix (n, n, Bp, Bi, CARG(Bx,Bz), 1, Control) ;
3614     if (status != UMFPACK_OK) error ("bad A matget sparse",0.) ;
3615 
3616     /* return the allocated column-form */
3617     *Ap = Bp ;
3618     *Ai = Bi ;
3619     *Ax = Bx ;
3620     *Az = Bz ;
3621 
3622     free (Tz) ;	/* ] */
3623     free (Tx) ;	/* ] */
3624     free (Tj) ;	/* ] */
3625     free (Ti) ;	/* ] */
3626 }
3627 
3628 
3629 /* ========================================================================== */
3630 /* matgen_sparse: generate a matrix with random pattern */
3631 /* ========================================================================== */
3632 
3633 /* allocates Ap, Ai, Ax, and Az */
3634 
matgen_sparse(Int n,Int s,Int ndrow,Int rdeg,Int ndcol,Int cdeg,Int ** Ap,Int ** Ai,double ** Ax,double ** Az,Int prl,Int has_nans)3635 static void matgen_sparse
3636 (
3637     Int n,
3638     Int s,	/* s random entries, and one more in each row and column */
3639     Int ndrow,	/* plus ndrow dense rows, each of degree rdeg */
3640     Int rdeg,
3641     Int ndcol,	/* plus ndcol dense cols, each of degree cdeg */
3642     Int cdeg,
3643     Int **Ap,
3644     Int **Ai,
3645     double **Ax,	double **Az,
3646     Int prl,
3647     Int has_nans
3648 )
3649 {
3650     Int nz, *Bp, *Bi, *Ti, *Tj, k, i, j, j1, i1, k1, *P, status, *Map, p, *Cp, *Ci, *noMap ;
3651     double *Bx, *Tx, *Bz, *Tz, Control [UMFPACK_CONTROL], xnan, xinf, x, *Txx, *Cx ;
3652     noMap = (Int *) NULL ;
3653 
3654     if (has_nans)
3655     {
3656 	xnan = divide (0., 0.) ;
3657 	xinf = divide (1., 0.) ;
3658     }
3659 
3660     UMFPACK_defaults (Control) ;
3661     Control [UMFPACK_PRL] = prl ;
3662     UMFPACK_report_control (Control) ;
3663 
3664     nz = s + n + rdeg*ndrow + cdeg*ndcol ;
3665     if (nz == 0) nz++ ;
3666 
3667     /* allocate Bp, Bi, and Bx - but do not free them */
3668     Bp = (Int *) malloc ((n+1) * sizeof (Int)) ;
3669     Bi = (Int *) malloc ((nz+1) * sizeof (Int)) ;
3670     Bx = (double *) malloc ((nz+1) * sizeof (double)) ;
3671     Bz = (double *) calloc ((nz+1) , sizeof (double)) ;
3672 
3673     Ti = (Int *) malloc (nz * sizeof (Int)) ;		/* [ */
3674     Tj = (Int *) malloc (nz * sizeof (Int)) ;		/* [ */
3675     Tx = (double *) malloc (nz * sizeof (double)) ;	/* [ */
3676     Tz = (double *) calloc (nz , sizeof (double)) ;	/* [ */
3677     P = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
3678     Map = (Int *) malloc (nz * sizeof (Int)) ;		/* [ */
3679 
3680     Txx = (double *) calloc (2*(nz+1) , sizeof (double)) ;	/* [ */
3681     Cp = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
3682     Ci = (Int *) malloc ((nz+1) * sizeof (Int)) ;		/* [ */
3683     Cx = (double *) calloc (2*(nz+1) , sizeof (double)) ;	/* [ */
3684 
3685     if (!Bp || !Bi || !Bx || !Ti || !Tj || !Tx || !P) error ("out of memory (13)",0.) ;
3686     if (!Bz || !Tz) error ("out of m",0.) ;
3687     if (!Txx || !Cx || !Cp || !Ci) error ("out of mem xx",0.) ;
3688 
3689     for (k = 0 ; k < s ; k++)
3690     {
3691 	Ti [k] = irand (n) ;
3692 	Tj [k] = irand (n) ;
3693 	if (has_nans)
3694 	{
3695 	    x = xrand ( ) ;
3696 	    Tx [k] = (x > 0.8) ? ((x > 0.9) ? xnan : xinf) : (2*x-1) ;
3697 #ifdef COMPLEX
3698 	    x = xrand ( ) ;
3699 	    Tz [k] = (x > 0.8) ? ((x > 0.9) ? xnan : xinf) : (2*x-1) ;
3700 #else
3701 	    Tz [k] = 0. ;
3702 #endif
3703 	}
3704 	else
3705 	{
3706 	    Tx [k] = 2.0 * (xrand ( ) - 1.0) ;
3707 #ifdef COMPLEX
3708 	    Tz [k] = 2.0 * (xrand ( ) - 1.0) ;
3709 #else
3710 	    Tz [k] = 0. ;
3711 #endif
3712 	}
3713     }
3714 
3715     /* beef up each column and row */
3716     randperm (n, P) ;
3717     for (i = 0 ; i < n ; i++)
3718     {
3719 	Ti [k] = i ;
3720 	Tj [k] = P [i] ;
3721 	Tx [k] = xrand ( ) ;
3722 #ifdef COMPLEX
3723 	Tz [k] = xrand ( ) ;
3724 #else
3725 	Tz [k] = 0. ;
3726 #endif
3727 	k++ ;
3728     }
3729 
3730     /* add ndrow rows of degree rdeg */
3731     for (i1 = 0 ; i1 < ndrow ; i1++)
3732     {
3733 	i = irand (n) ;
3734 	for (k1 = 0 ; k1 < rdeg ; k1++)
3735 	{
3736 	    Ti [k] = i ;
3737 	    Tj [k] = irand (n) ;
3738 	    Tx [k] = 0.1 * xrand ( ) ;
3739 #ifdef COMPLEX
3740 	    Tz [k] = 0.1 * xrand ( ) ;
3741 #else
3742 	    Tz [k] = 0. ;
3743 #endif
3744 	    k++ ;
3745 	}
3746     }
3747 
3748     /* add ndcol rows of degree cdeg */
3749     for (j1 = 0 ; j1 < ndcol ; j1++)
3750     {
3751 	j = irand (n) ;
3752 	for (k1 = 0 ; k1 < cdeg ; k1++)
3753 	{
3754 	    Ti [k] = irand (n) ;
3755 	    Tj [k] = j ;
3756 	    Tx [k] = 0.1 * xrand ( ) ;
3757 #ifdef COMPLEX
3758 	    Tz [k] = 0.1 * xrand ( ) ;
3759 #else
3760 	    Tz [k] = 0. ;
3761 #endif
3762 	    k++ ;
3763 	}
3764     }
3765 
3766     if (k != nz) error ("matgen_sparse error",0.) ;
3767 
3768     if (prl > 2) printf ("\nmatgen_sparse: ") ;
3769     status = UMFPACK_report_triplet (n, n, k, Ti, Tj, CARG(Tx,Tz), Control) ;
3770     if (status != UMFPACK_OK) error ("bad triplet report",0.) ;
3771 
3772     /* convert to column form */
3773     status = UMFPACK_triplet_to_col (n, n, k, Ti, Tj, CARG(Tx,Tz), Bp, Bi, CARG(Bx,Bz), Map) ;
3774     if (status != UMFPACK_OK) error ("matgen_sparse triplet_to_col failed",0.) ;
3775 
3776     /* convert to column form, no values and no map */
3777     status = UMFPACK_triplet_to_col (n, n, k, Ti, Tj, CARG(DNULL,DNULL), Cp, Ci, CARG(DNULL,DNULL), noMap) ;
3778     if (status != UMFPACK_OK) error ("matgen_sparse triplet_to_col failed",0.) ;
3779 
3780     /* compare C and B, they should be identical */
3781     for (j = 0 ; j < n ; j++)
3782     {
3783 	if (Bp [j] != Cp [j]) error ("Cp j",0.) ;
3784 	if (Bp [j+1] != Cp [j+1]) error ("Cp j",0.) ;
3785 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3786 	{
3787 	    if (Bi [p] != Ci [p]) error ("Ci",0.) ;
3788 	}
3789     }
3790 
3791     /* convert to column form, no values and with map */
3792     status = UMFPACK_triplet_to_col (n, n, k, Ti, Tj, CARG(DNULL,DNULL), Cp, Ci, CARG(DNULL,DNULL), Map) ;
3793     if (status != UMFPACK_OK) error ("matgen_sparse triplet_to_col failed",0.) ;
3794 
3795     /* compare C and B, they should be identical */
3796     for (j = 0 ; j < n ; j++)
3797     {
3798 	if (Bp [j] != Cp [j]) error ("Cp j",0.) ;
3799 	if (Bp [j+1] != Cp [j+1]) error ("Cp j",0.) ;
3800 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3801 	{
3802 	    if (Bi [p] != Ci [p]) error ("Ci",0.) ;
3803 	}
3804     }
3805 
3806 #ifdef COMPLEX
3807     /* test with merged case too */
3808     for (p = 0 ; p < k ; p++)
3809     {
3810 	Txx [2*p  ] = Tx [p] ;
3811 	Txx [2*p+1] = Tz [p] ;
3812     }
3813 
3814     /* convert to column form, no map */
3815     status = UMFPACK_triplet_to_col (n, n, k, Ti, Tj, CARG(Txx,DNULL), Cp, Ci, CARG(Cx,DNULL), noMap) ;
3816     if (status != UMFPACK_OK) error ("matgen_sparse triplet_to_col failed",0.) ;
3817 
3818     /* compare C and B, they should be identical */
3819     for (j = 0 ; j < n ; j++)
3820     {
3821 	if (Bp [j] != Cp [j]) error ("Cp j",0.) ;
3822 	if (Bp [j+1] != Cp [j+1]) error ("Cp j",0.) ;
3823 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3824 	{
3825 	    if (Bi [p] != Ci [p]) error ("Ci",0.) ;
3826 	    if (SCALAR_ABS (Bx [p] - Cx [2*p  ]) > 1e-15) error ("Cx",0.) ;
3827 	    if (SCALAR_ABS (Bz [p] - Cx [2*p+1]) > 1e-15) error ("Cz (1)",0.) ;
3828 	}
3829     }
3830 
3831     /* convert to column form */
3832     status = UMFPACK_triplet_to_col (n, n, k, Ti, Tj, CARG(Txx,DNULL), Cp, Ci, CARG(Cx,DNULL), Map) ;
3833     if (status != UMFPACK_OK) error ("matgen_sparse triplet_to_col failed",0.) ;
3834 
3835     /* compare C and B, they should be identical */
3836     for (j = 0 ; j < n ; j++)
3837     {
3838 	if (Bp [j] != Cp [j]) error ("Cp j",0.) ;
3839 	if (Bp [j+1] != Cp [j+1]) error ("Cp j",0.) ;
3840 	for (p = Bp [j] ; p < Bp [j+1] ; p++)
3841 	{
3842 	    if (Bi [p] != Ci [p]) error ("Ci",0.) ;
3843 	    if (SCALAR_ABS (Bx [p] - Cx [2*p  ]) > 1e-15) error ("Cx",0.) ;
3844 	    if (SCALAR_ABS (Bz [p] - Cx [2*p+1]) > 1e-15) error ("Cz (1)",0.) ;
3845 	}
3846     }
3847 
3848 #endif
3849 
3850     if (prl > 2) printf ("\nmatgen_sparse: ") ;
3851     status = UMFPACK_report_matrix (n, n, Bp, Bi, CARG(Bx,Bz), 1, Control) ;
3852     if (status != UMFPACK_OK) error ("bad A matgen sparse",0.) ;
3853 
3854     /* check the Map */
3855     for (k = 0 ; k < nz ; k++)
3856     {
3857 	p = Map [k] ;
3858 	i = Ti [k] ;
3859 	j = Tj [k] ;
3860 	if (i != Bi [p]) error ("Map Bi", 0.) ;
3861 	if (!(Bp [j] <= p && p < Bp [j+1])) error ("Map Bp", 0.) ;
3862     }
3863 
3864     /* test triplet->col and col->triplet */
3865     test_col (n, Bp, Bi, Bx,Bz, prl) ;
3866 
3867     /* return the allocated column-form */
3868     *Ap = Bp ;
3869     *Ai = Bi ;
3870     *Ax = Bx ;
3871     *Az = Bz ;
3872 
3873     free (Cx) ;    /* ] */
3874     free (Ci) ;    /* ] */
3875     free (Cp) ;    /* ] */
3876     free (Txx) ;    /* ] */
3877 
3878     free (Map) ;    /* ] */
3879     free (P) ;	    /* ] */
3880     free (Tz) ;	    /* ] */
3881     free (Tx) ;	    /* ] */
3882     free (Tj) ;	    /* ] */
3883     free (Ti) ;	    /* ] */
3884 
3885 }
3886 
3887 /* ========================================================================== */
3888 /* matgen_transpose:  B = A(P,Q)', where P and Q are random */
3889 /* ========================================================================== */
3890 
matgen_transpose(Int n,Int Ap[],Int Ai[],double Ax[],double Az[],Int ** Bp,Int ** Bi,double ** Bx,double ** Bz)3891 static void matgen_transpose
3892 (
3893     Int n,
3894     Int Ap [ ],
3895     Int Ai [ ],
3896     double Ax [ ],	double Az [ ],
3897     Int **Bp,
3898     Int **Bi,
3899     double **Bx,	double **Bz
3900 )
3901 {
3902     Int nz, *P, *Q, *Cp, *Ci, status ;
3903     double *Cx, *Cz ;
3904 
3905 #ifdef DEBUGGING
3906     double Control [UMFPACK_CONTROL] ;
3907 #endif
3908 
3909     nz = Ap [n] ;
3910     P = (Int *) malloc (n * sizeof (Int)) ;	/* [ */
3911     Q = (Int *) malloc (n * sizeof (Int)) ;	/* [ */
3912 
3913     Cp = (Int *) malloc ((n+1) * sizeof (Int)) ;
3914     Ci = (Int *) malloc ((nz+1) * sizeof (Int)) ;
3915     Cx = (double *) malloc ((nz+1) * sizeof (double)) ;
3916     Cz = (double *) calloc ((nz+1) , sizeof (double)) ;
3917 
3918     if (!P || !Q || !Bp || !Bi || !Bx) error ("out of memory (14)",0.) ;
3919     if (!Cz) error ("out mem", 0.) ;
3920 
3921     randperm (n, P) ;
3922     randperm (n, Q) ;
3923 
3924 #ifdef DEBUGGING
3925     UMFPACK_defaults (Control) ;
3926     Control [UMFPACK_PRL] = 5 ;
3927     printf ("\nA: ") ;
3928     status = UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Control) ;
3929     if (status != UMFPACK_OK) error ("bad A",0.) ;
3930     printf ("Random P: ") ;
3931     UMFPACK_report_perm (n, P, Control) ;
3932     if (status != UMFPACK_OK) error ("bad random P",0.) ;
3933     printf ("Random Q: ") ;
3934     status = UMFPACK_report_perm (n, Q, Control) ;
3935     if (status != UMFPACK_OK) error ("bad random Q",0.) ;
3936 #endif
3937 
3938     /* do complex conjugate transpose */
3939     status = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), P, Q, Cp, Ci, CARG(Cx,Cz) C1ARG(1)) ;
3940     if (status != UMFPACK_OK) error ("transpose failed",0.) ;
3941 
3942 #ifdef DEBUGGING
3943     printf ("\nC: ") ;
3944     status = UMFPACK_report_matrix (n, n, Cp, Ci, CARG(Cx,Cz), 1, Control) ;
3945     if (status != UMFPACK_OK) error ("bad C",0.) ;
3946 #endif
3947 
3948     /* do not free Cp, Ci, and Cx */
3949     *Bp = Cp ;
3950     *Bi = Ci ;
3951     *Bx = Cx ;
3952     *Bz = Cz ;
3953 
3954     free (P) ;	/* ] */
3955     free (Q) ;	/* ] */
3956 }
3957 
3958 
3959 /* ========================================================================== */
3960 /* matgen_file:  read a (1-based) matrix and a Qinit from a file */
3961 /* ========================================================================== */
3962 
3963 /* File syntax:
3964  *	1st line:	    nrows ncols nnz isreal
3965  *	next nnz lines:	    i j x   ... or  ...  i j xreal ximag
3966  *	next ncols lines:   Qk
3967  *	one line            determinant (real and imag. part if A is complex)
3968  *	last line	    determinant of real part of A only
3969  */
3970 
matgen_file(char * filename,Int * n_row,Int * n_col,Int ** Ap,Int ** Ai,double ** Ax,double ** Az,Int ** Qinit,Int prl,double * det_x,double * det_z)3971 static void matgen_file
3972 (
3973     char *filename,
3974     Int *n_row,
3975     Int *n_col,
3976     Int **Ap,
3977     Int **Ai,
3978     double **Ax,	double **Az,
3979     Int **Qinit,
3980     Int prl,
3981     double *det_x,
3982     double *det_z
3983 )
3984 {
3985     FILE *f ;
3986     Int i, j, k, *Ti, *Tj, nr, nc, nz, *Bp, *Bi, *Q, status, isreal, nz1, n ;
3987     double x, *Tx, *Bx, *Tz, *Bz, ximag, Control [UMFPACK_CONTROL],
3988 	    d_x, d_z, d_real ;
3989     int ioerr ;
3990 
3991     printf ("\nFile: %s\n", filename) ;
3992     f = fopen (filename, "r") ;
3993     if (!f) error ("bad file", 0.) ;
3994 
3995     ioerr = fscanf (f, ""ID" "ID" "ID" "ID"\n", &nr, &nc, &nz, &isreal) ;
3996     if (ioerr == EOF) error ("bad file", 0.) ;
3997     n = MAX (nr, nc) ;
3998     n = MAX (n,1) ;
3999 
4000     nz1 = MAX (nz,1) ;
4001     Ti = (Int *) malloc (nz1 * sizeof (Int)) ;		/* [ */
4002     Tj = (Int *) malloc (nz1 * sizeof (Int)) ;		/* [ */
4003     Tx = (double *) malloc (nz1 * sizeof (double)) ;	/* [ */
4004     Tz = (double *) calloc (nz1 , sizeof (double)) ;	/* [ */
4005 
4006     /* allocate Bp, Bi, Bx, and Q - but do not free them */
4007     Bp = (Int *) malloc ((n+1) * sizeof (Int)) ;
4008     Bi = (Int *) malloc (nz1 * sizeof (Int)) ;
4009     Bx = (double *) malloc (nz1 * sizeof (double)) ;
4010     Q = (Int *) malloc (n * sizeof (Int)) ;
4011     Bz = (double *) calloc (nz1 , sizeof (double)) ;
4012 
4013     for (k = 0 ; k < nz ; k++)
4014     {
4015 	if (isreal)
4016 	{
4017 	     ioerr = fscanf (f, ""ID" "ID" %lg\n", &i, &j, &x) ;
4018 	     ximag = 0. ;
4019 	}
4020 	else
4021 	{
4022 	     ioerr = fscanf (f, ""ID" "ID" %lg %lg\n", &i, &j, &x, &ximag) ;
4023 	}
4024         if (ioerr == EOF) error ("bad file", 0.) ;
4025 	Ti [k] = i-1 ;	/* convert to 0-based */
4026 	Tj [k] = j-1 ;
4027 	Tx [k] = x ;
4028 #ifdef COMPLEX
4029 	Tz [k] = ximag ;
4030 #else
4031 	/* the file may have a complex part, but set it to zero */
4032 	Tz [k] = 0. ;
4033 #endif
4034     }
4035 
4036     for (k = 0 ; k < nc ; k++)
4037     {
4038 	ioerr = fscanf (f, ""ID"\n", &i) ;
4039         if (ioerr == EOF) error ("bad file", 0.) ;
4040 	Q [k] = i-1 ;	/* convert to 0-based */
4041     }
4042 
4043     if (isreal)
4044     {
4045 	ioerr = fscanf (f, "%lg\n", &d_x) ;
4046 	d_z = 0 ;
4047     }
4048     else
4049     {
4050 	ioerr = fscanf (f, "%lg %lg\n", &d_x, &d_z) ;
4051     }
4052     if (ioerr == EOF) error ("bad file", 0.) ;
4053     ioerr = fscanf (f, "%lg\n", &d_real) ;
4054     if (ioerr == EOF) error ("bad file", 0.) ;
4055     printf ("%s det: %g + (%g)i, real(A): %g\n", filename, d_x, d_z, d_real) ;
4056 
4057 #ifdef COMPLEX
4058     *det_x = d_x ;
4059     *det_z = d_z ;
4060 #else
4061     /* imaginary part of matrix is ignored */
4062     *det_x = d_real ;
4063     *det_z = 0 ;
4064 #endif
4065 
4066     UMFPACK_defaults (Control) ;
4067     Control [UMFPACK_PRL] = prl ;
4068     if (prl > 2) printf ("\nmatgen_file: ") ;
4069     status = UMFPACK_report_triplet (nr, nc, nz, Ti, Tj, CARG(Tx,Tz), Control) ;
4070     if (status != UMFPACK_OK) error ("bad triplet report",0.) ;
4071 
4072     /* convert to column form */
4073     status = UMFPACK_triplet_to_col (nr, nc, nz, Ti, Tj, CARG(Tx,Tz), Bp, Bi, CARG(Bx,Bz), (Int *) NULL) ;
4074     if (status != UMFPACK_OK) error ("matgen_file triplet_to_col failed",0.) ;
4075 
4076     if (prl > 2) printf ("\nmatgen_file: ") ;
4077     status = UMFPACK_report_matrix (nr, nc, Bp, Bi, CARG(Bx,Bz), 1, Control) ;
4078     if (status != UMFPACK_OK) error ("bad A matgen_file",0.) ;
4079 
4080     /* return the allocated column-form */
4081     *n_row = nr ;
4082     *n_col = nc ;
4083     *Ap = Bp ;
4084     *Ai = Bi ;
4085     *Ax = Bx ;
4086     *Az = Bz ;
4087     *Qinit = Q ;
4088 
4089     free (Tz) ;	/* ] */
4090     free (Tx) ;	/* ] */
4091     free (Tj) ;	/* ] */
4092     free (Ti) ;	/* ] */
4093 
4094     fclose (f) ;
4095 }
4096 
4097 /* ========================================================================== */
4098 /* matgen_arrow:  create an arrowhead matrix */
4099 /* ========================================================================== */
4100 
matgen_arrow(Int n,Int ** Ap,Int ** Ai,Int ** Q)4101 static Int matgen_arrow
4102 (
4103     Int n,
4104     Int **Ap,
4105     Int **Ai,
4106     Int **Q
4107 )
4108 {
4109     Int nz, *Bp, *Bi, i, j, p, *Qp ;
4110 
4111     nz = n + 2*(n-1) ;
4112     printf ("matgen_arrow: n = "ID" nz = "ID"\n", n, nz) ;
4113 
4114     Bp = (Int *) malloc ((n+1) * sizeof (Int)) ;
4115     Bi = (Int *) malloc (nz * sizeof (Int)) ;
4116     Qp = (Int *) malloc (n * sizeof (Int)) ;
4117 
4118     if (!Bp || !Bi || !Qp)
4119     {
4120 	free (Bp) ;
4121 	free (Bi) ;
4122 	free (Qp) ;
4123 	printf ("arrow failed\n") ;
4124     	return (FALSE) ;
4125     }
4126 
4127     /* row and column 0, and diagonal, are dense */
4128 
4129     /* column 0 */
4130     p = 0 ;
4131     Bp [0] = p ;
4132     for (i = 0 ; i < n ; i++)
4133     {
4134 	Bi [p] = i ;
4135 	Qp [p] = i ;
4136 	p++ ;
4137     }
4138 
4139     /* columns 1 to n-1 */
4140     for (j = 1 ; j < n ; j++)
4141     {
4142 	Bp [j] = p ;
4143 	Bi [p] = 0 ;		/* row 0 */
4144 	p++ ;
4145 	Bi [p] = j ;		/* row j (diagonal) */
4146     }
4147 
4148     Bp [n] = p ;
4149 
4150     *Ap = Bp ;
4151     *Ai = Bi ;
4152     *Q = Qp ;
4153 
4154     printf ("matgen_arrow: n = "ID" nz = "ID" done.\n", n, nz) ;
4155     return (TRUE) ;
4156 
4157 }
4158 
4159 
4160 /* ========================================================================== */
4161 /* do_and_free: do a matrix, its random transpose, and then free it */
4162 /* ========================================================================== */
4163 
do_and_free(Int n,Int Ap[],Int Ai[],double Ax[],double Az[],double Controls[UMFPACK_CONTROL][1000],Int Ncontrols[UMFPACK_CONTROL],Int MemControl[6],Int do_dense)4164 static double do_and_free
4165 (
4166     Int n,
4167     Int Ap [ ],
4168     Int Ai [ ],
4169     double Ax [ ],	double Az [ ],
4170 
4171     double Controls [UMFPACK_CONTROL][1000],
4172     Int Ncontrols [UMFPACK_CONTROL],
4173     Int MemControl [6],
4174     Int do_dense
4175 )
4176 {
4177     Int *Bp, *Bi ;
4178     double *Bx, *Bz, rnorm1, rnorm2 ;
4179 
4180     /* A */
4181     rnorm1 = do_matrix (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemControl, do_dense) ;
4182 
4183     /* B = A (P,Q), P and Q random */
4184     matgen_transpose (n, Ap, Ai, Ax, Az, &Bp, &Bi, &Bx, &Bz) ;
4185 
4186     free (Ap) ;
4187     free (Ai) ;
4188     free (Ax) ;
4189     free (Az) ;
4190 
4191     rnorm2 = do_matrix (n, Bp, Bi, Bx, Bz, Controls, Ncontrols, MemControl, do_dense) ;
4192 
4193     free (Bp) ;
4194     free (Bi) ;
4195     free (Bx) ;
4196     free (Bz) ;
4197 
4198     return (MAX (rnorm1, rnorm2)) ;
4199 }
4200 
4201 /* ========================================================================== */
4202 /* AMD */
4203 /* ========================================================================== */
4204 
do_amd(Int n,Int Ap[],Int Ai[],Int P[])4205 static int do_amd
4206 (
4207     Int n,
4208     Int Ap [],
4209     Int Ai [],
4210     Int P []
4211 )
4212 {
4213 
4214 #if 0
4215 #ifndef NDEBUG
4216 
4217     FILE *f ;
4218     f = fopen ("apx.m", "w") ;
4219     Int j, p, nz ;
4220     if (Ap && Ai && P)
4221     {
4222 	nz = Ap [n] ;
4223 	fprintf (f, "ApX = [ ") ;
4224 	for (j = 0 ; j <= n ; j++) fprintf (f, ID" ", Ap [j]) ;
4225 	fprintf (f, "] ; \n nzx = "ID" ;\n Ax = [\n", nz) ;
4226 	for (j = 0 ; j < n ; j++)
4227 	{
4228 	    for (p = Ap [j] ; p < Ap [j+1] ; p++)
4229 	    {
4230 		fprintf (f, ID" "ID" 1\n", 1+j, 1+Ai [p]) ;
4231 	    }
4232 	}
4233 	fprintf (f, ID" "ID" 0] ;\n", n, n) ;
4234 	fclose (f) ;
4235     }
4236 
4237 #endif
4238 #endif
4239 
4240 #if (defined (DINT) || defined (ZINT))
4241     return (amd_order   (n, Ap, Ai, P, DNULL, DNULL)) ;
4242 #else
4243     return (amd_l_order (n, Ap, Ai, P, DNULL, DNULL)) ;
4244 #endif
4245 }
4246 
4247 
do_amd_transpose(Int n,Int Ap[],Int Ai[],Int Rp[],Int Ri[])4248 static int do_amd_transpose
4249 (
4250     Int n,
4251     Int Ap [],
4252     Int Ai [],
4253     Int Rp [],
4254     Int Ri []
4255 )
4256 {
4257     Int *W, *Flag ;
4258 
4259 #if (defined (DINT) || defined (ZINT))
4260     if (amd_valid (n, n, Ap, Ai) < AMD_OK || !Ri || !Rp)
4261     {
4262 	return (AMD_INVALID) ;
4263     }
4264 #else
4265     if (amd_l_valid (n, n, Ap, Ai) < AMD_OK || !Ri || !Rp)
4266     {
4267 	return (AMD_INVALID) ;
4268     }
4269 #endif
4270 
4271     W = SuiteSparse_malloc (n, sizeof (Int)) ;
4272     Flag = SuiteSparse_malloc (n, sizeof (Int)) ;
4273     if (!W || !Flag)
4274     {
4275 	SuiteSparse_free (W) ;
4276 	SuiteSparse_free (Flag) ;
4277 	return (AMD_OUT_OF_MEMORY) ;
4278     }
4279 
4280 #if (defined (DINT) || defined (ZINT))
4281     amd_preprocess (n, Ap, Ai, Rp, Ri, W, Flag) ;
4282 #else
4283     amd_l_preprocess (n, Ap, Ai, Rp, Ri, W, Flag) ;
4284 #endif
4285 
4286     SuiteSparse_free (W) ;
4287     SuiteSparse_free (Flag) ;
4288     return (AMD_OK) ;
4289 
4290 }
4291 
4292 
4293 
4294 /* ========================================================================== */
4295 /* do_file:  read a matrix from a matrix and call do_many */
4296 /* ========================================================================== */
4297 
do_file(char * filename,Int prl,Int MemControl[6])4298 static double do_file
4299 (
4300     char *filename,
4301     Int prl,
4302     Int MemControl [6]
4303 )
4304 {
4305     Int n_row, n_col, *Ap, *Ai, *Qinit, n, *P, s, *W, scale, row, col, p,
4306 	strategy, fixQ ;
4307     double *Ax, *Az, Control [UMFPACK_CONTROL], *b, rnorm, *bz, maxrnorm, bad,
4308 	det_x, det_z ;
4309 
4310     UMFPACK_defaults (Control) ;
4311     Control [UMFPACK_PRL] = prl ;
4312     maxrnorm = 0 ;
4313 
4314     /* get the matrix A and preordering Qinit */
4315     matgen_file (filename, &n_row, &n_col, &Ap, &Ai, &Ax, &Az, &Qinit, prl,
4316 	    &det_x, &det_z) ;	/* [[[[[ */
4317 
4318     check_tol = SCALAR_ABS (det_x < 1e100) ;
4319 
4320     /* test amd, on A and A transpose */
4321     if (n_row == n_col)
4322     {
4323 	Int k, *Rp, *Ri ;
4324 	P = (Int *) malloc (n_row * sizeof (Int)) ;	/* [ */
4325 	W = (Int *) malloc (n_row * sizeof (Int)) ;	/* [ */
4326 	Rp = (Int *) malloc ((n_row+1) * sizeof (Int)) ;	/* [ */
4327 	Ri = (Int *) malloc ((Ap [n_row]) * sizeof (Int)) ;	/* [ */
4328 	s = do_amd (n_row, Ap, Ai, P) ;
4329 	if (s != AMD_OK) error ("amd2", (double) s) ;
4330 	s = UMF_report_perm (n_row, P, W, 3, 0) ;
4331 	if (s != UMFPACK_OK) error ("amd3", (double) s) ;
4332 	s = do_amd_transpose (n_row, Ap, Ai, Rp, Ri) ;
4333 	if (s != AMD_OK) error ("amd4", (double) s) ;
4334 	s = do_amd (n_row, Rp, Ri, P) ;
4335 	if (s != AMD_OK) error ("amd5", (double) s) ;
4336 	s = UMF_report_perm (n_row, P, W, 3, 0) ;
4337 	if (s != UMFPACK_OK) error ("amd6", (double) s) ;
4338 	free (Ri) ;  /* ] */
4339 	free (Rp) ;  /* ] */
4340 	free (W) ;  /* ] */
4341 	free (P) ;  /* ] */
4342     }
4343 
4344     /* do the matrix */
4345     n = MAX (n_row, n_col) ;
4346     n = MAX (n,1) ;
4347     b = (double *) calloc (n, sizeof (double)) ;	/* [ */
4348     bz= (double *) calloc (n, sizeof (double)) ;	/* [ */
4349 
4350     if (n_row == n_col)
4351     {
4352 	bgen (n, Ap, Ai, Ax,Az, b,bz) ;
4353     }
4354 
4355     if (prl == 5 && MAX (n_row, n_col) > 600)
4356     {
4357 	/* do nothing */
4358 	;
4359     }
4360     else if (prl >= 3 || MAX (n_row, n_col) > 15)
4361     {
4362 
4363 	/* quick test */
4364 	printf ("Control strategy auto Q prl "ID"\n", prl) ;
4365 	printf ("quick test..\n") ;
4366 	rnorm = do_many (n_row, n_col, Ap, Ai, Ax,Az, b,bz, Control, Qinit, MemControl, TRUE, TRUE, det_x, det_z) ;
4367 	printf ("quick test.. done\n") ;
4368 	printf ("Control strategy auto Q prl "ID" :: rnorm %g\n", prl, rnorm) ;
4369 	if (check_tol)
4370 	{
4371 	    if (rnorm >= TOL) error ("bad do_file", rnorm) ;
4372 	    maxrnorm = rnorm ;
4373 	}
4374 
4375 	/* quick test - no aggressive absorption */
4376 	printf ("Control strategy auto Q prl "ID" no aggressive\n", prl) ;
4377 	Control [UMFPACK_AGGRESSIVE] = 0 ;
4378 	rnorm = do_many (n_row, n_col, Ap, Ai, Ax,Az, b,bz, Control, Qinit, MemControl, TRUE, TRUE, det_x, det_z) ;
4379 	printf ("Control strategy auto Q prl "ID" no aggressive:: rnorm %g\n", prl, rnorm) ;
4380 	if (check_tol)
4381 	{
4382 	    if (rnorm >= TOL) error ("bad do_file", rnorm) ;
4383 	    maxrnorm = rnorm ;
4384 	}
4385 
4386 	/* quick test - symmetric strategy, no aggressive absorption */
4387 	printf ("Control strategy auto Q prl "ID" no aggressive, symmetric\n", prl) ;
4388 	Control [UMFPACK_STRATEGY] = UMFPACK_STRATEGY_SYMMETRIC ;
4389 	UMFPACK_report_control (Control) ;
4390 	rnorm = do_many (n_row, n_col, Ap, Ai, Ax,Az, b,bz, Control, Qinit, MemControl, TRUE, TRUE, det_x, det_z) ;
4391 	printf ("Control strategy auto Q prl "ID" no aggressive, symmetric:: rnorm %g\n", prl, rnorm) ;
4392 	if (check_tol)
4393 	{
4394 	    if (rnorm >= TOL) error ("bad do_file", rnorm) ;
4395 	    maxrnorm = rnorm ;
4396 	}
4397 
4398     }
4399     else
4400     {
4401 	/* full test */
4402 	for (strategy=-1 ; strategy <= UMFPACK_STRATEGY_SYMMETRIC ; strategy++)
4403 	{
4404             if (strategy == UMFPACK_STRATEGY_OBSOLETE) continue ;
4405 	    Control [UMFPACK_STRATEGY] = strategy ;
4406 	    if (strategy == UMFPACK_STRATEGY_SYMMETRIC)
4407 	    {
4408 		if (n < 5) UMFPACK_report_control (Control) ;
4409 
4410 		for (fixQ = -1 ; fixQ <= 1 ; fixQ++)
4411 		{
4412 		    Control [UMFPACK_FIXQ] = fixQ ;
4413 
4414 
4415 		    for (scale = -1 ; scale <= UMFPACK_SCALE_MAX ; scale++)
4416 		    {
4417 			Control [UMFPACK_SCALE] = scale ;
4418 			printf ("Control strategy "ID" "ID" noQ prl "ID" scale "ID"\n",
4419 			    strategy, fixQ, prl, scale) ;
4420 			rnorm = do_many (n_row, n_col, Ap, Ai, Ax,Az, b,bz, Control, INULL, MemControl, TRUE, TRUE, det_x, det_z) ;
4421 			printf ("Control strategy "ID" "ID" noQ prl "ID" scale "ID" :: rnorm %g\n",
4422 			    strategy, fixQ, prl, scale, rnorm) ;
4423 			if (check_tol)
4424 			{
4425 			    maxrnorm = MAX (maxrnorm, rnorm) ;
4426 			    if (rnorm >= TOL) error ("bad do_file", rnorm) ;
4427 			}
4428 		    }
4429 
4430 		    printf ("Control strategy "ID" "ID" Q\n", strategy, fixQ) ;
4431 		    rnorm = do_many (n_row, n_col, Ap, Ai, Ax,Az, b,bz, Control, Qinit, MemControl, TRUE, TRUE, det_x, det_z) ;
4432 		    printf ("Control strategy "ID" "ID" Q :: rnorm %g\n",
4433 			strategy, fixQ, rnorm) ;
4434 		    if (check_tol)
4435 		    {
4436 			maxrnorm = MAX (maxrnorm, rnorm) ;
4437 			if (rnorm >= TOL) error ("bad do_file", rnorm) ;
4438 		    }
4439 		}
4440 		Control [UMFPACK_FIXQ] = UMFPACK_DEFAULT_FIXQ ;
4441 	    }
4442 	    else
4443 	    {
4444 		printf ("Control strategy "ID" Q prl "ID"\n", strategy, prl) ;
4445 		rnorm = do_many (n_row, n_col, Ap, Ai, Ax,Az, b,bz, Control, Qinit, MemControl, TRUE, TRUE, det_x, det_z) ;
4446 		printf ("Control strategy "ID" Q prl "ID" :: rnorm %g\n", strategy, prl, rnorm) ;
4447 		if (check_tol)
4448 		{
4449 		    maxrnorm = MAX (maxrnorm, rnorm) ;
4450 		    if (rnorm >= TOL) error ("bad do_file", rnorm) ;
4451 		}
4452 
4453 		printf ("Control strategy "ID" noQ\n", strategy) ;
4454 		rnorm = do_many (n_row, n_col, Ap, Ai, Ax,Az, b,bz, Control, INULL, MemControl, TRUE, TRUE, det_x, det_z) ;
4455 		printf ("Control strategy "ID" noQ :: rnorm %g\n", strategy, rnorm) ;
4456 		if (check_tol)
4457 		{
4458 		    maxrnorm = MAX (maxrnorm, rnorm) ;
4459 		    if (rnorm >= TOL) error ("bad do_file", rnorm) ;
4460 		}
4461 
4462 #ifdef UMFPACK_DROPTOL
4463 		Control [UMFPACK_DROPTOL] = 1e-25 ;
4464 		printf ("Control strategy "ID" noQ droptol 1e-25\n", strategy) ;
4465 		rnorm = do_many (n_row, n_col, Ap, Ai, Ax,Az, b,bz, Control, INULL, MemControl, TRUE, TRUE, det_x, det_z) ;
4466 		printf ("Control strategy "ID" noQ droptol 1e-25 :: rnorm %g\n", strategy, rnorm) ;
4467 		if (check_tol)
4468 		{
4469 		    maxrnorm = MAX (maxrnorm, rnorm) ;
4470 		    if (rnorm >= TOL) error ("bad do_file", rnorm) ;
4471 		}
4472 		Control [UMFPACK_DROPTOL] = 0 ;
4473 #endif
4474 
4475 	    }
4476 	}
4477     }
4478 
4479     UMFPACK_defaults (Control) ;
4480     Control [UMFPACK_PRL] = 3 ;
4481 
4482     /* scale row 0 */
4483     for (col = 0 ; col < n_col ; col++)
4484     {
4485 	for (p = Ap [col] ; p < Ap [col+1] ; p++)
4486 	{
4487 	    row = Ai [p] ;
4488 	    if (row == 0)
4489 	    {
4490 		Ax [p] *= 1e-20 ;
4491 		Az [p] *= 1e-20 ;
4492 	    }
4493 	}
4494     }
4495     b  [0] *= 1e-20 ;
4496     bz [0] *= 1e-20 ;
4497 
4498     printf ("Control defaults noQ tiny row 0\n") ;
4499     rnorm = do_many (n_row, n_col, Ap, Ai, Ax,Az, b,bz, Control, INULL, MemControl, TRUE, TRUE, 1e-20*det_x, 1e-20*det_z) ;
4500     printf ("Control defaults noQ  tiny row 0:: rnorm %g\n", rnorm) ;
4501     if (check_tol)
4502     {
4503 	maxrnorm = MAX (maxrnorm, rnorm) ;
4504 	if (rnorm >= TOL) error ("bad do_file", rnorm) ;
4505     }
4506 
4507     free (bz) ;		/* ] */
4508     free (b) ;		/* ] */
4509     free (Ap) ;		/* ] */
4510     free (Ai) ;		/* ] */
4511     free (Ax) ;		/* ] */
4512     free (Az) ;		/* ] */
4513     free (Qinit) ;	/* ] */
4514 
4515     check_tol = TRUE ;
4516 
4517     return (maxrnorm) ;
4518 }
4519 
4520 /* ========================================================================== */
4521 /* main */
4522 /* ========================================================================== */
4523 
4524 
4525 #if 0
4526 /* compile with -lefence and -DEFENCE */
4527 #ifndef EXTERN
4528 #define EXTERN extern
4529 #endif
4530 EXTERN int EF_PROTECT_FREE ;
4531 EXTERN int EF_PROTECT_BELOW  ;
4532 #endif
4533 
4534 
main(int argc,char ** argv)4535 int main (int argc, char **argv)
4536 {
4537     double *Lx, *Ux, *x,  *Cx, *Bx, *Ax, *b, *Ax2,
4538 	   *Lz, *Uz, *xz, *Cz, *Bz, *Az, *bz,*Az2,
4539 	rnorm, maxrnorm, *Con, Info [UMFPACK_INFO], *Wx, *Rs, xnan, xinf, ttt,
4540 	Controls [UMFPACK_CONTROL][1000], Control [UMFPACK_CONTROL],
4541 	alphas [ ] = {-1.0, 0.0, 0.1, 0.5, 10.}, *info, maxrnorm_shl0,
4542 	rnorm_omega2, maxrnorm_arc130, det_x, det_z, Mx, Mz, Exp ;
4543     Int Ncontrols [UMFPACK_CONTROL], c, i, n, prl, *Qinit, *Qinit2, n1,
4544 	*Ap, *Ai, *Aj, nz, *Ap2, *Ai2, p, j, d, s, s2, *Pinit, k, n2, *Map,
4545 	*Lp, *Li, *P, *Q, *Up, *Ui, lnz, unz, nn, *Cp, *Ci, *Cj, *Bi, *Bp, *Bj,
4546 	*Pa, *Front_npivots, *Front_parent, *Chain_start, *Chain_maxrows, *ip,
4547 	*Chain_maxcols, nfr, nchains, nsparse_col, *Qtree, *Ptree, nnz,
4548 	MemOK [6], MemBad [6], nnrow, nncol, nzud, n_row, n_col, n_row2,
4549 	n_col2, scale, *Front_1strow, *Front_leftmostdesc, strategy,
4550 	t, aggressive, *Pamd, mem1, mem2, do_recip ;
4551     int ok ;
4552     void *Symbolic, *Numeric ;
4553     SymbolicType *Sym ;
4554     NumericType *Num ;
4555     DIR *dir ;
4556     struct dirent *direntp ;
4557     char filename [400] ;
4558     FILE *f ;
4559     Int my_params [3], csave ;
4560     double my_info [3] ;
4561 
4562     /* turn off debugging */
4563     { f = fopen ("debug.umf", "w") ; fprintf (f, "-45\n") ; fclose (f) ; }
4564     { f = fopen ("debug.amd", "w") ; fprintf (f, "-45\n") ; fclose (f) ; }
4565 
4566 #if 0
4567     /* compile with -lefence */
4568     EF_PROTECT_FREE = 0 ;   /* 1 to test modifications to free'd memory */
4569     EF_PROTECT_BELOW = 0 ;  /* 1 to test modifications above an obj. */
4570 #endif
4571 
4572     c = UMFPACK_PIVOT_TOLERANCE ;
4573     Controls [c][0] = UMFPACK_DEFAULT_PIVOT_TOLERANCE ;
4574     Ncontrols [c] = 1 ;
4575 
4576     c = UMFPACK_SCALE ;
4577     Controls [c][0] = UMFPACK_SCALE_SUM ;   /* also the default */
4578     Ncontrols [c] = 1 ;
4579 
4580     c = UMFPACK_BLOCK_SIZE ;
4581     Controls [c][0] = 32 ;
4582     Ncontrols [c] = 1 ;
4583 
4584     c = UMFPACK_ALLOC_INIT ;
4585     Controls [c][0] = 1.0 ;
4586     Ncontrols [c] = 1 ;
4587 
4588     c = UMFPACK_AMD_DENSE ;
4589     Controls [c][0] = UMFPACK_DEFAULT_AMD_DENSE ;
4590     Ncontrols [c] = 1 ;
4591 
4592     /* ---------------------------------------------------------------------- */
4593     /* test malloc, realloc, and free */
4594     /* ---------------------------------------------------------------------- */
4595 
4596     /*
4597     P = (Int *) UMF_malloc (Int_MAX, 2) ;
4598     if (P) error ("large malloc should have failed\n", 0.) ;
4599 
4600     printf ("reallocing...\n") ;
4601     P = (Int *) UMF_realloc (P, 1, 4) ;
4602     if (!P) error ("should have succeeded\n", 0.) ;
4603 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
4604     if (UMF_malloc_count != 1) error ("should be 1", 0.) ;
4605 #endif
4606     printf ("ok here...\n") ;
4607 
4608     P = UMF_free (P) ;
4609     if (P) error ("should have free'd it\n", 0.) ;
4610 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
4611     if (UMF_malloc_count != 0) error ("should be 0", 0.) ;
4612 #endif
4613     */
4614 
4615     xnan = divide (0., 0.) ;
4616     xinf = divide (1., 0.) ;
4617 
4618     /* ---------------------------------------------------------------------- */
4619     /* malloc and realloc control */
4620     /* ---------------------------------------------------------------------- */
4621 
4622     MemOK [0] = -1 ;
4623     MemOK [1] = 0 ;
4624     MemOK [2] = 0 ;
4625 
4626     MemOK [3] = -1 ;
4627     MemOK [4] = 0 ;
4628     MemOK [5] = 0 ;
4629 
4630     /* malloc always succeeds */
4631     umf_fail = -1 ;
4632     umf_fail_lo = 0 ;
4633     umf_fail_hi = 0 ;
4634 
4635     /* realloc always succeeds */
4636     umf_realloc_fail = -1 ;
4637     umf_realloc_lo = 0 ;
4638     umf_realloc_hi = 0 ;
4639 
4640     UMFPACK_defaults (Control) ;
4641 
4642     maxrnorm_shl0 = 0.0 ;	/* for shl0 only */
4643     maxrnorm = 0.0 ;	/* for all other matrices */
4644     check_tol = TRUE ;
4645 
4646     /* ---------------------------------------------------------------------- */
4647 
4648     printf ("load/save error handling tests:\n") ;
4649 
4650     /* load a bad symbolic object */
4651     s = UMFPACK_load_symbolic (&Symbolic, "badsym.umf") ;
4652     if (s == UMFPACK_OK)
4653     {
4654 	error ("load symbolic failed\n", 0.) ;
4655     }
4656     s = UMFPACK_load_symbolic (&Symbolic, "badsym2.umf") ;
4657     if (s == UMFPACK_OK)
4658     {
4659 	error ("load symbolic failed (2)\n", 0.) ;
4660     }
4661 
4662     /* load a bad numeric object */
4663     s = UMFPACK_load_numeric (&Numeric, "badnum.umf") ;
4664     if (s == UMFPACK_OK)
4665     {
4666 	error ("load numeric failed\n", 0.) ;
4667     }
4668     s = UMFPACK_load_numeric (&Numeric, "badnum2.umf") ;
4669     if (s == UMFPACK_OK)
4670     {
4671 	error ("load numeric failed (2)\n", 0.) ;
4672     }
4673 
4674     /* ---------------------------------------------------------------------- */
4675     /* reset rand ( ) */
4676     /* ---------------------------------------------------------------------- */
4677 
4678     srand (1) ;
4679 
4680     /* ---------------------------------------------------------------------- */
4681     /* test a tiny matrix */
4682     /* ---------------------------------------------------------------------- */
4683 
4684     n = 2 ;
4685     printf ("\n tiny\n") ;
4686     check_tol = TRUE ;
4687     matgen_dense (n, &Ap, &Ai, &Ax, &Az) ;
4688     rnorm = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemOK, 0) ;
4689     printf ("rnorm tiny %g\n", rnorm) ;
4690     if (rnorm > 1e-12)
4691     {
4692 	error ("bad rnorm for tiny matrix", rnorm) ;
4693     }
4694 
4695     /* ---------------------------------------------------------------------- */
4696     /* test a tiny matrix with a NaN in it */
4697     /* ---------------------------------------------------------------------- */
4698 
4699     c = UMFPACK_SCALE ;
4700     Controls [c][0] = UMFPACK_SCALE_SUM ;   /* also the default */
4701     Controls [c][1] = UMFPACK_SCALE_NONE ;
4702     Ncontrols [c] = 2 ;
4703 
4704     n = 2 ;
4705     printf ("\n tiny\n") ;
4706     check_tol = TRUE ;
4707     matgen_dense (n, &Ap, &Ai, &Ax, &Az) ;
4708     Ax [0] = xnan ;
4709     Az [0] = 0 ;
4710     rnorm = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemOK, 0) ;
4711     printf ("rnorm tiny %g with NaN\n", rnorm) ;
4712 
4713     n = 2 ;
4714     printf ("\n tiny\n") ;
4715     check_tol = TRUE ;
4716     matgen_dense (n, &Ap, &Ai, &Ax, &Az) ;
4717     Ax [1] = 1e-20 ;
4718     Az [1] = 0 ;
4719     Ax [2] = 2e-20 ;
4720     Az [2] = 0 ;
4721     Ax [3] = 3e-20 ;
4722     Az [3] = 0 ;
4723     rnorm = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemOK, 0) ;
4724     printf ("rnorm tiny %g with NaN and small row\n", rnorm) ;
4725 
4726     n = 2 ;
4727     printf ("\n tiny\n") ;
4728     check_tol = TRUE ;
4729     matgen_dense (n, &Ap, &Ai, &Ax, &Az) ;
4730     Ax [0] = 0 ;
4731     rnorm = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemOK, 0) ;
4732     printf ("rnorm tiny %g with small row\n", rnorm) ;
4733 
4734     c = UMFPACK_SCALE ;
4735     Controls [c][0] = UMFPACK_SCALE_SUM ;   /* also the default */
4736     Ncontrols [c] = 1 ;
4737 
4738     /* ---------------------------------------------------------------------- */
4739     /* test omega2 */
4740     /* ---------------------------------------------------------------------- */
4741 
4742     srand (1) ;
4743 
4744     n = 500 ;
4745     printf ("\n omega 2 test\n") ;
4746     matgen_sparse (n, 2*n, 0, 0, 0, 0, &Ap, &Ai, &Ax, &Az, 0, 0) ;
4747 
4748     f = fopen ("A500", "w") ;
4749     fprintf (f, ID" "ID" 0 0\n", n, n) ;
4750     for (j = 0 ; j < n ; j++)
4751     {
4752 	for (p = Ap [j] ; p < Ap [j+1] ; p++)
4753 	{
4754 	    fprintf (f, ID" "ID" %40.25e %40.25e\n", Ai [p], j, Ax [p], Az [p]) ;
4755 	}
4756     }
4757     fclose (f) ;
4758 
4759     rnorm_omega2 = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemOK, 0) ;
4760     printf ("rnorm %g omega-2 test\n", rnorm_omega2) ;
4761 
4762     /* ---------------------------------------------------------------------- */
4763     /* reset rand ( ) */
4764     /* ---------------------------------------------------------------------- */
4765 
4766     srand (1) ;
4767 
4768     /* this is not solved very accurately (about 1e-7) */
4769     maxrnorm_shl0 = do_file ("TestMat/shl0", 4, MemOK) ;
4770     printf ("rnorm shl0 %10.4e\n", maxrnorm_shl0) ;
4771 
4772     /* this is not solved very accurately (about 1e-5, because of U'x=b) */
4773     maxrnorm_arc130 = do_file ("TestMat/arc130", 4, MemOK) ;
4774     printf ("rnorm arc130 %10.4e\n", maxrnorm_arc130) ;
4775 
4776     /* ---------------------------------------------------------------------- */
4777     /* test random sparse matrices */
4778     /* ---------------------------------------------------------------------- */
4779 
4780     n = 30 ;
4781 
4782 	printf ("sparse "ID" 4*n nz's", n) ;
4783 	matgen_sparse (n, 4*n, 0, 0, 0, 0, &Ap, &Ai, &Ax, &Az, 1, 0) ;	/* [[[[ */
4784 	rnorm = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemOK, 1) ; /* ]]]] */
4785 	maxrnorm = MAX (rnorm, maxrnorm) ;
4786 	printf ("rnorm  %10.4e %10.4e\n", rnorm, maxrnorm) ;
4787 
4788     /* ---------------------------------------------------------------------- */
4789     /* reset rand ( ) */
4790     /* ---------------------------------------------------------------------- */
4791 
4792     srand (1) ;
4793 
4794     rnorm = do_file ("TestMat/matrix5", 5, MemOK) ;
4795     maxrnorm = MAX (rnorm, maxrnorm) ;
4796     printf ("rnorm matrix 5 %10.4e %10.4e\n", rnorm, maxrnorm) ;
4797 
4798     /* malloc always succeeds */
4799     umf_fail = -1 ;
4800     umf_fail_lo = 0 ;
4801     umf_fail_hi = 0 ;
4802 
4803     /* realloc always fails */
4804     umf_realloc_fail = 0 ;
4805     umf_realloc_lo = -9999999 ;
4806     umf_realloc_hi = 0 ;
4807 
4808     /* ---------------------------------------------------------------------- */
4809     /* do all test matrices from TestMat directory */
4810     /* ---------------------------------------------------------------------- */
4811 
4812     /* quick tests */
4813     prl = 1 ;
4814 
4815     matgen_file ("TestMat/matrix1", &n_row, &n_col, &Ap, &Ai, &Ax, &Az, &Qinit,
4816 	    prl, &det_x, &det_z) ;	/* [[[[[ */
4817 
4818 	Control [UMFPACK_ALLOC_INIT] = -211 ;
4819 
4820 	/* with no Qinit, out of memory in extend front */
4821 	s = UMFPACK_symbolic (n_row, n_col, Ap, Ai, CARG(Ax,Az), &Symbolic, Control, Info) ;	/* [ */
4822 	if (s != UMFPACK_OK) error ("TestMat matrix1 sym", (double) s) ;
4823 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Control, Info) ; /* [ */
4824 	if (s != UMFPACK_ERROR_out_of_memory) error ("TestMat matrix1 num", (double) s) ;
4825 	UMFPACK_free_numeric (&Numeric) ;	/* ] */
4826 	UMFPACK_free_symbolic (&Symbolic) ;	/* ] */
4827 
4828 	free (Ax) ;	    /* ] */
4829 	free (Ap) ;	    /* ] */
4830 	free (Ai) ;	    /* ] */
4831 	free (Az) ;	    /* ] */
4832 	free (Qinit) ;  /* ] */
4833 
4834     matgen_file ("TestMat/matrix10", &n_row, &n_col, &Ap, &Ai, &Ax, &Az, &Qinit, prl, &det_x, &det_z) ;	/* [[[[[ */
4835 
4836 	Control [UMFPACK_ALLOC_INIT] = -1321 ;
4837 
4838 	/* with Qinit, out of memory in create front (2) */
4839 	s = UMFPACK_qsymbolic (n_row, n_col, Ap, Ai, CARG(Ax,Az), Qinit, &Symbolic, Control, Info) ;	/* [ */
4840 	if (s != UMFPACK_OK) error ("TestMat matrix10 qsym1", (double) s) ;
4841 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Control, Info) ; /* [ */
4842 	if (s != UMFPACK_ERROR_out_of_memory) error ("TestMat matrix10 qnum1", (double) s) ;
4843 	UMFPACK_free_numeric (&Numeric) ;	/* ] */
4844 	UMFPACK_free_symbolic (&Symbolic) ;	/* ] */
4845 
4846 	Control [UMFPACK_ALLOC_INIT] = -1326 ;
4847 
4848 	/* with Qinit, out of memory in init front */
4849 	s = UMFPACK_qsymbolic (n_row, n_col, Ap, Ai, CARG(Ax,Az), Qinit, &Symbolic, Control, Info) ;	/* [ */
4850 	if (s != UMFPACK_OK) error ("TestMat matrix10 qsym", (double) s) ;
4851 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Control, Info) ; /* [ */
4852 	if (s != UMFPACK_ERROR_out_of_memory) error ("TestMat matrix10 qnum", (double) s) ;
4853 	UMFPACK_free_numeric (&Numeric) ;	/* ] */
4854 	UMFPACK_free_symbolic (&Symbolic) ;	/* ] */
4855 
4856 	free (Ax) ;	    /* ] */
4857 	free (Ap) ;	    /* ] */
4858 	free (Ai) ;	    /* ] */
4859 	free (Az) ;	    /* ] */
4860 	free (Qinit) ;  /* ] */
4861 
4862     printf ("\ndone with TestMat memory sizes.\n\n") ;
4863     UMFPACK_defaults (Control) ;
4864 
4865     /* ---------------------------------------------------------------------- */
4866     /* reset rand ( ) */
4867     /* ---------------------------------------------------------------------- */
4868 
4869     srand (1) ;
4870 
4871     /* ---------------------------------------------------------------------- */
4872     /* test amd */
4873     /* ---------------------------------------------------------------------- */
4874 
4875     n = 50 ;
4876     P = (Int *) malloc (n * sizeof (Int)) ; /* [ */
4877     for (k = 0 ; k < 10 ; k++)
4878     {
4879 	matgen_sparse (n, 4*n, 3, 2*n, 0, 0, &Ap, &Ai, &Ax, &Az, 0, 0) ; /* [[[[ */
4880 	for (aggressive = 0 ; aggressive <= 2 ; aggressive++)
4881 	{
4882 	    for (i = 0 ; i < 3 ; i++)
4883 	    {
4884 
4885 #if (defined (DINT) || defined (ZINT))
4886 
4887 		amd_defaults (Control) ;
4888 		Control [AMD_AGGRESSIVE] = aggressive ;
4889 		Control [AMD_DENSE] = alphas [i] ;
4890 		Con = (aggressive == 2) ? DNULL : Control ;
4891 		info = (aggressive == 2) ? DNULL : Info ;
4892 		amd_control (Con) ;
4893 		s = amd_order (n, Ap, Ai, P, Con, info) ;
4894 		if (s != AMD_OK) error ("amd", (double) s) ;
4895 		amd_info (info) ;
4896 
4897 #else
4898 
4899 		amd_l_defaults (Control) ;
4900 		Control [AMD_AGGRESSIVE] = aggressive ;
4901 		Control [AMD_DENSE] = alphas [i] ;
4902 		Con = (aggressive == 2) ? DNULL : Control ;
4903 		info = (aggressive == 2) ? DNULL : Info ;
4904 		amd_l_control (Con) ;
4905 		s = amd_l_order (n, Ap, Ai, P, Con, info) ;
4906 		if (s != AMD_OK) error ("amd", (double) s) ;
4907 		amd_l_info (info) ;
4908 
4909 #endif
4910 
4911 		UMFPACK_defaults (Control) ;
4912 		Control [UMFPACK_PRL] = 3 ;
4913 		UMFPACK_report_perm (n, P, Control) ;
4914 	    }
4915 	}
4916 	free (Ap) ; /* ] */
4917 	free (Ai) ; /* ] */
4918 	free (Ax) ; /* ] */
4919 	free (Az) ; /* ] */
4920     }
4921     free (P) ;	/* ] */
4922 
4923     if (AMD_valid (-1, -1, INULL, INULL) >= AMD_OK) error ("amd error", 0.) ;
4924     Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ;
4925     AMD_info (Info) ;
4926     Info [AMD_STATUS] = AMD_INVALID ;
4927     AMD_info (Info) ;
4928     Info [AMD_STATUS] = -911 ;
4929     AMD_info (Info) ;
4930 
4931     /* ---------------------------------------------------------------------- */
4932     /* malloc and realloc control */
4933     /* ---------------------------------------------------------------------- */
4934 
4935     MemOK [0] = -1 ;
4936     MemOK [1] = 0 ;
4937     MemOK [2] = 0 ;
4938 
4939     MemOK [3] = -1 ;
4940     MemOK [4] = 0 ;
4941     MemOK [5] = 0 ;
4942 
4943     umf_fail = -1 ;
4944     umf_fail_lo = 0 ;
4945     umf_fail_hi = 0 ;
4946 
4947     umf_realloc_fail = -1 ;
4948     umf_realloc_lo = 0 ;
4949     umf_realloc_hi = 0 ;
4950 
4951     for (i = 0 ; i < UMFPACK_CONTROL ; i++)
4952     {
4953 	Ncontrols [i] = 0 ;
4954     }
4955 
4956     UMFPACK_defaults (Control) ;
4957 
4958     /* ---------------------------------------------------------------------- */
4959     /* do three funky sizes to test int overflow cases */
4960     /* ---------------------------------------------------------------------- */
4961 
4962     {
4963 	/* Int funky_sizes [ ] = { 14402, 16400, 600000 } ; */
4964 	Int funky_sizes [ ] = { 144, 164, 600 } ;
4965 
4966 	UMFPACK_defaults (Control) ;
4967 	Control [UMFPACK_PRL] = 1 ;
4968 	Control [UMFPACK_STRATEGY] = 3 ;
4969 	Control [UMFPACK_FRONT_ALLOC_INIT] = 1 ;
4970 
4971 	for (k = 0 ; k < 3 ; k++)
4972 	{
4973 	    n = funky_sizes [k] ;
4974 
4975 	    printf ("funky matrix, n = "ID"\n", n) ;
4976 	    matgen_funky (n, &Ap, &Ai, &Ax, &Az) ;	/* [[[[ */
4977 
4978 	    b = (double *) malloc (n * sizeof (double)) ;	/* [ */
4979 	    bz= (double *) calloc (n , sizeof (double)) ;	/* [ */
4980 	    Qinit = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
4981 	    if (!b) error ("out of memory (15)",0.) ;
4982 	    if (!bz) error ("out of memory (16)",0.) ;
4983 	    if (!Qinit) error ("out of memory (17)",0.) ;
4984 	    bgen (n, Ap, Ai, Ax, Az, b, bz) ;
4985 
4986 	    for (i = 0 ; i < n ; i++) Qinit [i] = i ;
4987 	    fflush (stdout) ;
4988 
4989 	    Control [UMFPACK_FIXQ] = 1 ;
4990 	    rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, Control, Qinit, MemOK, FALSE, FALSE, 0., 0.) ;
4991 	    printf ("funky matrix rnorm (fixQ): %g\n", rnorm) ;
4992 	    fflush (stdout) ;
4993 	    maxrnorm = MAX (rnorm, maxrnorm) ;
4994 
4995 	    Control [UMFPACK_FIXQ] = 0 ;
4996 	    rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, Control, Qinit, MemOK, FALSE, FALSE, 0., 0.) ;
4997 	    printf ("funky matrix rnorm (no fixQ): %g\n", rnorm) ;
4998 	    fflush (stdout) ;
4999 	    maxrnorm = MAX (rnorm, maxrnorm) ;
5000 
5001 	    free (Qinit) ;  /* ] */
5002 	    free (bz) ;	    /* ] */
5003 	    free (b) ;	    /* ] */
5004 	    free (Ap) ;	    /* ] */
5005 	    free (Ai) ;	    /* ] */
5006 	    free (Ax) ;	    /* ] */
5007 	    free (Az) ;	    /* ] */
5008 	}
5009     }
5010     /* maxrnorm = 0 ; */
5011 
5012     /* ---------------------------------------------------------------------- */
5013     /* reset rand ( ) */
5014     /* ---------------------------------------------------------------------- */
5015 
5016     srand (1) ;
5017 
5018     /* ---------------------------------------------------------------------- */
5019     /* tight controls */
5020     /* ---------------------------------------------------------------------- */
5021 
5022     c = UMFPACK_PIVOT_TOLERANCE ;
5023     Controls [c][0] = UMFPACK_DEFAULT_PIVOT_TOLERANCE ;
5024     Ncontrols [c] = 1 ;
5025 
5026     c = UMFPACK_SCALE ;
5027     Controls [c][1] = UMFPACK_DEFAULT_SCALE ;
5028     Ncontrols [c] = 1 ;
5029 
5030     c = UMFPACK_BLOCK_SIZE ;
5031     Controls [c][0] = UMFPACK_DEFAULT_BLOCK_SIZE ;
5032     Ncontrols [c] = 1 ;
5033 
5034     c = UMFPACK_ALLOC_INIT ;
5035     Controls [c][0] = UMFPACK_DEFAULT_ALLOC_INIT ;
5036     Ncontrols [c] = 1 ;
5037 
5038     c = UMFPACK_AMD_DENSE ;
5039     Controls [c][0] = UMFPACK_DEFAULT_AMD_DENSE ;
5040     Ncontrols [c] = 1 ;
5041 
5042     /* ---------------------------------------------------------------------- */
5043     /* license */
5044     /* ---------------------------------------------------------------------- */
5045 
5046     Control [UMFPACK_PRL] = 6 ;
5047     UMFPACK_report_status (Control, UMFPACK_OK) ;
5048 
5049     /* ---------------------------------------------------------------------- */
5050     /* do all test matrices from TestMat directory */
5051     /* ---------------------------------------------------------------------- */
5052 
5053     printf ("\nStarting TestMat:\n") ;
5054     for (prl = 5 ; prl >= 0 ; prl--)
5055     {
5056 	printf ("=====================TestMat PRL "ID"\n", prl) ;
5057         dir = opendir ("TestMat") ;
5058         if (!dir) { printf ("opendir TestMat failed\n") ; exit (1) ; }
5059         while (TRUE)
5060         {
5061 	    errno = 0 ;
5062 	    if ((direntp = readdir (dir)) != NULL)
5063 	    {
5064 	        /* skip this */
5065 	        if (direntp->d_name [0] == '.') continue ;
5066 	        sprintf (filename, "TestMat/%s", direntp->d_name) ;
5067 	        rnorm = do_file (filename, prl, MemOK) ;
5068 
5069 		if (strcmp (filename, "TestMat/shl0") == 0)
5070 		{
5071 		    printf ("shl0 rnorm: %g\n", rnorm) ;
5072 		    maxrnorm_shl0 = MAX (maxrnorm_shl0, rnorm) ;
5073 		}
5074 		else if (strcmp (filename, "TestMat/arc130") == 0)
5075 		{
5076 		    printf ("arc130 rnorm: %g\n", rnorm) ;
5077 		    maxrnorm_arc130 = MAX (maxrnorm_arc130, rnorm) ;
5078 		}
5079 		else
5080 		{
5081 		    printf ("other testmat rnorm: %g\n", rnorm) ;
5082 		    maxrnorm = MAX (maxrnorm, rnorm) ;
5083 		}
5084 	    }
5085 	    else
5086 	    {
5087 	        if (errno != 0) { printf ("read error\n") ; exit (1) ; }
5088 	        closedir (dir) ;
5089 	        break ;
5090 	    }
5091         }
5092         printf ("\n\n@@@@@@ Largest TestMat do_file rnorm: %g shl0: %g @@@@@@ arc130: %g\n\n", maxrnorm, maxrnorm_shl0, maxrnorm_arc130) ;
5093     }
5094 
5095     printf ("\ndone with TestMat.\n\n") ;
5096 
5097     /* ---------------------------------------------------------------------- */
5098     /* reset rand ( ) */
5099     /* ---------------------------------------------------------------------- */
5100 
5101     srand (1) ;
5102 
5103     /* ---------------------------------------------------------------------- */
5104     /* test change of pattern */
5105     /* ---------------------------------------------------------------------- */
5106 
5107     Control [UMFPACK_PRL] = 5 ;
5108     Control [UMFPACK_ALLOC_INIT] = 0. ;
5109 
5110     matgen_file ("TestMat/matrix1", &n_row, &n_col, &Ap, &Ai, &Ax, &Az, &Qinit, 5, &det_x, &det_z) ;	/* [[[[[ */
5111     s = UMFPACK_qsymbolic (n_row, n_col, Ap, Ai, CARG(Ax,Az), Qinit, &Symbolic, Control, Info) ;
5112     if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5113     UMFPACK_report_status (Control, s) ;
5114     UMFPACK_report_info (Control, Info) ;
5115     if (!Symbolic || Info [UMFPACK_STATUS] != UMFPACK_OK) error ("p1",0.) ;
5116     printf ("\nGood symbolic, pattern test: ") ;
5117     s = UMFPACK_report_symbolic (Symbolic, Control) ;
5118     UMFPACK_report_status (Control, s) ;
5119     if (s != UMFPACK_OK) error ("p1c",0.) ;
5120     UMFPACK_report_control (Control) ;
5121 
5122     s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Control, Info) ;
5123     if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5124     UMFPACK_report_status (Control, s) ;
5125     UMFPACK_report_info (Control, Info) ;
5126     printf ("p1b status: "ID" Numeric handle bad %d\n", s, !Numeric) ;
5127     s2 = UMFPACK_report_numeric (Numeric, Control) ;
5128     if (!Numeric || s != UMFPACK_OK) error ("p1b",0.) ;
5129     printf ("Good numeric, pattern test: ") ;
5130     UMFPACK_report_status (Control, s) ;
5131     UMFPACK_report_info (Control, Info) ;
5132     UMFPACK_report_status (Control, s) ;
5133     if (s2 != UMFPACK_OK) error ("p1d",0.) ;
5134     UMFPACK_free_numeric (&Numeric) ;
5135 
5136     /* corrupted Ap (negative degree) */
5137     c = Ap [1] ;
5138     Ap [1] = -1 ;
5139     printf ("Bad Ap [1] = -1: \n") ;
5140     s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Control, Info) ;
5141     if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5142     UMFPACK_report_status (Control, s) ;
5143     UMFPACK_report_info (Control, Info) ;
5144     if (Numeric || s != UMFPACK_ERROR_different_pattern) error ("zzz1",0.) ;
5145     Ap [1] = c ;
5146 
5147     /* corrupted Ai (out of bounds) */
5148     c = Ai [1] ;
5149     Ai [1] = -1 ;
5150     printf ("Bad Ai [1] = -1: \n") ;
5151     s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Control, Info) ;
5152     if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5153     UMFPACK_report_status (Control, s) ;
5154     UMFPACK_report_info (Control, Info) ;
5155     if (Numeric || s != UMFPACK_ERROR_different_pattern) error ("zzz2",0.) ;
5156     Ai [1] = c ;
5157 
5158     /* corrupted Ai (out of bounds) */
5159     c = Ai [1] ;
5160     Ai [1] = n_row ;
5161     printf ("Bad Ai [1] = "ID": \n", n_row) ;
5162     s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Control, Info) ;
5163     if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5164     UMFPACK_report_status (Control, s) ;
5165     UMFPACK_report_info (Control, Info) ;
5166     if (Numeric || s != UMFPACK_ERROR_different_pattern) error ("zzz3",0.) ;
5167     Ai [1] = c ;
5168 
5169     free (Ap) ;		/* ] */
5170     free (Ai) ;		/* ] */
5171     free (Ax) ;		/* ] */
5172     free (Az) ;		/* ] */
5173     free (Qinit) ;	/* ] */
5174 
5175     /* one more entry */
5176     printf ("one more entry\n") ;
5177     matgen_file ("TestMat/matrix2", &n_row2, &n_col2, &Ap2, &Ai2, &Ax2, &Az2, &Qinit2, 5, &det_x, &det_z) ;	/* [[[[[ */
5178     s = UMFPACK_numeric (Ap2, Ai2, CARG(Ax2,Az2), Symbolic, &Numeric, Control, Info) ;
5179     if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5180     UMFPACK_report_status (Control, s) ;
5181     UMFPACK_report_info (Control, Info) ;
5182     if (Numeric || s != UMFPACK_ERROR_different_pattern) error ("p2",0.) ;
5183     free (Ap2) ;		/* ] */
5184     free (Ai2) ;		/* ] */
5185     free (Ax2) ;		/* ] */
5186     free (Az2) ;		/* ] */
5187     free (Qinit2) ;		/* ] */
5188     printf ("one more entry done\n") ;
5189 
5190     /* one less entry */
5191     matgen_file ("TestMat/matrix3", &n_row2, &n_col2, &Ap2, &Ai2, &Ax2, &Az2, &Qinit2, 5, &det_x, &det_z) ;	/* [[[[[ */
5192     s = UMFPACK_numeric (Ap2, Ai2, CARG(Ax2,Az2), Symbolic, &Numeric, Control, Info) ;
5193     if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5194     UMFPACK_report_status (Control, s) ;
5195     UMFPACK_report_info (Control, Info) ;
5196     if (Numeric || s != UMFPACK_ERROR_different_pattern) error ("p3",0.) ;
5197     free (Ap2) ;		/* ] */
5198     free (Ai2) ;		/* ] */
5199     free (Ax2) ;		/* ] */
5200     free (Az2) ;		/* ] */
5201     free (Qinit2) ;		/* ] */
5202 
5203     /* many more entries */
5204     matgen_file ("TestMat/matrix4", &n_row2, &n_col2, &Ap2, &Ai2, &Ax2, &Az2, &Qinit2, 5, &det_x, &det_z) ;	/* [[[[[ */
5205     s = UMFPACK_numeric (Ap2, Ai2, CARG(Ax2,Ax2), Symbolic, &Numeric, Control, Info) ;
5206     if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5207     UMFPACK_report_status (Control, s) ;
5208     UMFPACK_report_info (Control, Info) ;
5209     if (Numeric || s != UMFPACK_ERROR_different_pattern) error ("p4",0.) ;
5210     free (Ap2) ;		/* ] */
5211     free (Ai2) ;		/* ] */
5212     free (Ax2) ;		/* ] */
5213     free (Az2) ;		/* ] */
5214     free (Qinit2) ;		/* ] */
5215 
5216     /* some more entries */
5217     matgen_file ("TestMat/matrix5", &n_row2, &n_col2, &Ap2, &Ai2, &Ax2, &Az2, &Qinit2, 5, &det_x, &det_z) ;	/* [[[[[ */
5218     s = UMFPACK_numeric (Ap2, Ai2, CARG(Ax2,Az2), Symbolic, &Numeric, Control, Info) ;
5219     if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5220     UMFPACK_report_status (Control, s) ;
5221     UMFPACK_report_info (Control, Info) ;
5222     if (Numeric || s != UMFPACK_ERROR_different_pattern) error ("p5",0.) ;
5223     free (Ap2) ;		/* ] */
5224     free (Ai2) ;		/* ] */
5225     free (Ax2) ;		/* ] */
5226     free (Az2) ;		/* ] */
5227     free (Qinit2) ;		/* ] */
5228 
5229     /* same entries - but different pattern */
5230     matgen_file ("TestMat/matrix6", &n_row2, &n_col2, &Ap2, &Ai2, &Ax2, &Az2, &Qinit2, 5, &det_x, &det_z) ;	/* [[[[[ */
5231     s = UMFPACK_numeric (Ap2, Ai2, CARG(Ax2,Az2), Symbolic, &Numeric, Control, Info) ;
5232     if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5233     UMFPACK_report_status (Control, s) ;
5234     UMFPACK_report_info (Control, Info) ;
5235     if (Numeric || s != UMFPACK_ERROR_different_pattern) error ("p6",0.) ;
5236     free (Ap2) ;		/* ] */
5237     free (Ai2) ;		/* ] */
5238     free (Ax2) ;		/* ] */
5239     free (Az2) ;		/* ] */
5240     free (Qinit2) ;		/* ] */
5241 
5242     /* same entries - but different pattern */
5243     matgen_file ("TestMat/matrix7", &n_row2, &n_col2, &Ap2, &Ai2, &Ax2, &Az2, &Qinit2, 5, &det_x, &det_z) ;	/* [[[[[ */
5244     s = UMFPACK_numeric (Ap2, Ai2, CARG(Ax2,Az2), Symbolic, &Numeric, Control, Info) ;
5245     if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5246     UMFPACK_report_status (Control, s) ;
5247     UMFPACK_report_info (Control, Info) ;
5248     if (Numeric || s != UMFPACK_ERROR_different_pattern) error ("p7",0.) ;
5249     free (Ap2) ;		/* ] */
5250     free (Ai2) ;		/* ] */
5251     free (Ax2) ;		/* ] */
5252     free (Az2) ;		/* ] */
5253     free (Qinit2) ;		/* ] */
5254 
5255     /* same entries - but different pattern */
5256     matgen_file ("TestMat/matrix8", &n_row2, &n_col2, &Ap2, &Ai2, &Ax2, &Az2, &Qinit2, 5, &det_x, &det_z) ;	/* [[[[[ */
5257     s = UMFPACK_numeric (Ap2, Ai2, CARG(Ax2,Az2), Symbolic, &Numeric, Control, Info) ;
5258     if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5259     UMFPACK_report_status (Control, s) ;
5260     UMFPACK_report_info (Control, Info) ;
5261     if (Numeric || s != UMFPACK_ERROR_different_pattern) error ("p8",0.) ;
5262     free (Ap2) ;		/* ] */
5263     free (Ai2) ;		/* ] */
5264     free (Ax2) ;		/* ] */
5265     free (Az2) ;		/* ] */
5266     free (Qinit2) ;		/* ] */
5267 
5268     UMFPACK_free_symbolic (&Symbolic) ;
5269 
5270     /* start over, use a bigger matrix */
5271     matgen_file ("TestMat/matrix10", &n_row, &n_col, &Ap, &Ai, &Ax, &Az, &Qinit, 5, &det_x, &det_z) ;	/* [[[[[ */
5272     s = UMFPACK_qsymbolic (n_row, n_col, Ap, Ai, CARG(Ax,Az), Qinit, &Symbolic, Control, Info) ;
5273     if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5274     UMFPACK_report_status (Control, s) ;
5275     UMFPACK_report_info (Control, Info) ;
5276     if (prl > 2) printf ("\nGood matrix10 symbolic, pattern test: ") ;
5277     s = UMFPACK_report_symbolic (Symbolic, Control) ;
5278     if (!Symbolic || Info [UMFPACK_STATUS] != UMFPACK_OK) error ("p10",0.) ;
5279     if (s != UMFPACK_OK) error ("p10",0.) ;
5280     s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Control, Info) ;
5281     if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5282     if (!Numeric || s != UMFPACK_OK) error ("p10b",0.) ;
5283     printf ("Good matrix10matrix10  numeric, pattern test:") ;
5284     s = UMFPACK_report_numeric (Numeric, Control) ;
5285     if (s != UMFPACK_OK) error ("p10b",0.) ;
5286     UMFPACK_report_status (Control, s) ;
5287     UMFPACK_report_info (Control, Info) ;
5288     UMFPACK_free_numeric (&Numeric) ;
5289 
5290     /* kludge Symbolic to force a huge dmax */
5291     printf ("\nKludge symbolic to force dmax int overflow:\n") ;
5292     Control [UMFPACK_PRL] = 3 ;
5293     Sym = (SymbolicType *) Symbolic ;
5294     Sym->amd_dmax = 16400 ;
5295     s = UMFPACK_report_symbolic (Symbolic, Control) ;
5296     if (!Symbolic || Info [UMFPACK_STATUS] != UMFPACK_OK) error ("p10e",0.) ;
5297     s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Control, Info) ;
5298     if (!Numeric || s != UMFPACK_OK) error ("p10c",0.) ;
5299     UMFPACK_report_status (Control, s) ;
5300     UMFPACK_report_info (Control, Info) ;
5301     UMFPACK_free_numeric (&Numeric) ;
5302 
5303     free (Ap) ;		/* ] */
5304     free (Ai) ;		/* ] */
5305     free (Ax) ;		/* ] */
5306     free (Az) ;		/* ] */
5307     free (Qinit) ;	/* ] */
5308 
5309     UMFPACK_free_symbolic (&Symbolic) ;
5310 
5311     /* ---------------------------------------------------------------------- */
5312     /* reset controls */
5313     /* ---------------------------------------------------------------------- */
5314 
5315     UMFPACK_defaults (Control) ;
5316 
5317     /* ---------------------------------------------------------------------- */
5318     /* reset rand ( ) */
5319     /* ---------------------------------------------------------------------- */
5320 
5321     srand (1) ;
5322 
5323     /* ---------------------------------------------------------------------- */
5324     /* test realloc */
5325     /* ---------------------------------------------------------------------- */
5326 
5327     /* malloc always succeeds */
5328     MemBad [0] = -1 ;
5329     MemBad [1] = 0 ;
5330     MemBad [2] = 0 ;
5331 
5332     /* realloc always fails */
5333     MemBad [3] = 0 ;
5334     MemBad [4] = 0 ;
5335     MemBad [5] = -99999 ;
5336 
5337     c = UMFPACK_ALLOC_INIT ;
5338     Ncontrols [c] = 1 ;
5339     Controls [c][0] = 0.001 ;
5340 
5341 #ifdef DINT
5342     printf ("\n all realloc fails sparse + dense rows %7d 4*n nz's\n", n) ;
5343     matgen_sparse (n, 4*n, 3, 2*n, 0, 0, &Ap, &Ai, &Ax, &Az, 0, 0) ;
5344     rnorm = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemBad, 0) ;
5345     printf ("rnorm %g should be 9e10\n", rnorm) ;
5346     if (rnorm != 9e10) error ("MemBad 1 failure", rnorm) ;
5347 
5348     printf ("\n all realloc fails sparse %7d 30*n nz's\n", n) ;
5349     matgen_sparse (n, 30*n, 0, 0, 0, 0, &Ap, &Ai, &Ax, &Az, 0, 0) ;
5350     rnorm = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemBad, 0) ;
5351     printf ("rnorm %g should be 9e10\n", rnorm) ;
5352     if (rnorm != 9e10) error ("MemBad 2 failure", rnorm) ;
5353 #endif
5354 
5355     /* ---------------------------------------------------------------------- */
5356     /* reset rand ( ) */
5357     /* ---------------------------------------------------------------------- */
5358 
5359     srand (1) ;
5360 
5361     /* ---------------------------------------------------------------------- */
5362     /* umf_symbolic compaction test */
5363     /* ---------------------------------------------------------------------- */
5364 
5365     n = 100 ;
5366     Control [UMFPACK_PRL] = 4 ;
5367     Qinit = (Int *) malloc (n * sizeof (Int)) ;			/* [ */
5368     b = (double *) malloc (n * sizeof (double)) ;		/* [ */
5369     bz= (double *) calloc (n , sizeof (double)) ;		/* [ */
5370     for (i = 0 ; i < n ; i++) Qinit [i] = i ;
5371     matgen_compaction (n, &Ap, &Ai, &Ax, &Az) ;					/* [[[[ */
5372     bgen (n, Ap, Ai, Ax, Az, b, bz) ;
5373     printf ("\nA compaction: ") ;
5374     s = UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Control) ;
5375     if (s != UMFPACK_OK) error ("219", 0.) ;
5376     rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, Control, Qinit, MemOK, FALSE, FALSE, 0., 0.) ;
5377     printf ("rnorm %g A compaction\n", rnorm) ;
5378     Control [UMFPACK_PRL] = 1 ;
5379 
5380     printf ("do_and_free for compacted matrix:\n") ;
5381     rnorm = do_and_free (n, Ap, Ai, Ax,Az, Controls, Ncontrols, MemOK, 0) ;	/* ]]]] */
5382     printf ("rnorm for compacted matrix %g\n", rnorm) ;
5383     free (b) ; /* ] */
5384     free (bz) ; /* ] */
5385     free (Qinit) ; /* ] */
5386 
5387     /* ---------------------------------------------------------------------- */
5388     /* umf_symbolic compaction test, again (read a file)  */
5389     /* ---------------------------------------------------------------------- */
5390 
5391     matgen_file ("TestMat/shl0", &n_row, &n_col, &Ap, &Ai, &Ax, &Az, &Qinit, 5, &det_x, &det_z) ;	/* [[[[[ */
5392     n = n_row ;
5393     b = (double *) malloc (n * sizeof (double)) ;	/* [ */
5394     bz= (double *) calloc (n , sizeof (double)) ;	/* [ */
5395     bgen (n, Ap, Ai, Ax, Az, b, bz) ;
5396     Control [UMFPACK_PRL] = 5 ;
5397     Control [UMFPACK_DENSE_ROW] = 0.1 ;
5398     Control [UMFPACK_DENSE_COL] = 2.0 ;
5399     printf ("\nshl0 b: ") ;
5400     UMFPACK_report_vector (n, CARG(b,bz), Control) ;
5401     printf ("\nshl0 A: ") ;
5402     UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Control) ;
5403     rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, Control, Qinit, MemOK, FALSE, FALSE, 0., 0.) ;
5404     printf ("rnorm %g for shl0", rnorm) ;
5405     maxrnorm_shl0 = MAX (maxrnorm_shl0, rnorm) ;
5406     free (bz) ;		/* ] */
5407     free (b) ;		/* ] */
5408     free (Ap) ;		/* ] */
5409     free (Ai) ;		/* ] */
5410     free (Az) ;		/* ] */
5411     free (Ax) ;		/* ] */
5412     free (Qinit) ;	/* ] */
5413 
5414     /* ---------------------------------------------------------------------- */
5415     /* normal Controls */
5416     /* ---------------------------------------------------------------------- */
5417 
5418     c = UMFPACK_PIVOT_TOLERANCE ;
5419     Controls [c][0] = UMFPACK_DEFAULT_PIVOT_TOLERANCE ;
5420     Controls [c][1] = 0.5 ;
5421     Controls [c][2] = 1.0 ;
5422     Ncontrols [c] = 3 ;
5423 
5424     c = UMFPACK_SCALE ;
5425     Controls [c][0] = UMFPACK_SCALE_SUM ;   /* also the default */
5426     Controls [c][1] = UMFPACK_SCALE_NONE ;
5427     Controls [c][2] = UMFPACK_SCALE_MAX ;
5428     Ncontrols [c] = 3 ;
5429 
5430     c = UMFPACK_BLOCK_SIZE ;
5431     Controls [c][0] = 1 ;
5432     Controls [c][1] = 8 ;
5433     Controls [c][2] = 16 ;	/* not the default */
5434     Ncontrols [c] = 3 ;
5435 
5436     c = UMFPACK_ALLOC_INIT ;
5437     Controls [c][0] = 0.0 ;
5438     Controls [c][1] = 0.5 ;
5439     Controls [c][2] = 1.0 ;	/* not the default */
5440     Controls [c][3] = -10000 ;
5441     Ncontrols [c] = 4 ;
5442 
5443     c = UMFPACK_AMD_DENSE ;
5444     Controls [c][0] = -1 ;
5445     Controls [c][1] = 0.5 ;
5446     Controls [c][2] = UMFPACK_DEFAULT_AMD_DENSE ;
5447     Ncontrols [c] = 3 ;
5448 
5449     UMFPACK_defaults (Control) ;
5450 
5451     /* ---------------------------------------------------------------------- */
5452     /* reset rand ( ) */
5453     /* ---------------------------------------------------------------------- */
5454 
5455     srand (1) ;
5456 
5457     /* ---------------------------------------------------------------------- */
5458     /* test realloc */
5459     /* ---------------------------------------------------------------------- */
5460 
5461     /* malloc always succeeds */
5462     MemBad [0] = -1 ;
5463     MemBad [1] = 0 ;
5464     MemBad [2] = 0 ;
5465 
5466     /* realloc always fails */
5467     MemBad [3] = 0 ;
5468     MemBad [4] = 0 ;
5469     MemBad [5] = -99999 ;
5470 
5471     n = 10 ;
5472 
5473     printf ("\n all realloc fails sparse "ID" 4*n nz's\n", n) ;
5474     matgen_sparse (n, 4*n, 0, 0, 0, 0, &Ap, &Ai, &Ax, &Az, 1, 0) ;
5475     rnorm = do_and_free (n, Ap, Ai, Ax,Az, Controls, Ncontrols, MemBad, 1) ;
5476     printf ("rnorm %g for all-realloc-fails\n", rnorm) ;
5477 
5478     /* ---------------------------------------------------------------------- */
5479     /* reset rand ( ) */
5480     /* ---------------------------------------------------------------------- */
5481 
5482     srand (1) ;
5483 
5484     /* ---------------------------------------------------------------------- */
5485     /* reset malloc and realloc failure */
5486     /* ---------------------------------------------------------------------- */
5487 
5488     umf_fail = -1 ;
5489     umf_fail_lo = 0 ;
5490     umf_fail_hi = 0 ;
5491 
5492     umf_realloc_fail = -1 ;
5493     umf_realloc_lo = 0 ;
5494     umf_realloc_hi = 0 ;
5495 
5496     /* ---------------------------------------------------------------------- */
5497     /* test errors */
5498     /* ---------------------------------------------------------------------- */
5499 
5500     n = 32 ;
5501 
5502     Pamd = (Int *) malloc (2*n * sizeof (Int)) ;		/* [ */
5503     Qinit = (Int *) malloc (2*n * sizeof (Int)) ;		/* [ */
5504     Pinit = (Int *) malloc (2*n * sizeof (Int)) ;		/* [ */
5505     Qinit2 = (Int *) malloc (2*n * sizeof (Int)) ;		/* [ */
5506     b = (double *) malloc (2*n * sizeof (double)) ;		/* [ */
5507     bz= (double *) calloc (2*n , sizeof (double)) ;		/* [ */
5508     x = (double *) malloc (2*n * sizeof (double)) ;		/* [ */
5509     xz= (double *) calloc (2*n , sizeof (double)) ;		/* [ */
5510     Ap2 = (Int *) malloc ((2*n+1) * sizeof (Int)) ;		/* [ */
5511 
5512     if (!Qinit || !b || !Ap2 || !Qinit2 || !Pinit)  error ("out of memory (18)",0.) ;
5513     if (!xz || !bz) error ("memr again",0.) ;
5514 
5515     UMFPACK_defaults (DNULL) ;
5516     UMFPACK_defaults (Control) ;
5517 
5518     randperm (n, Pinit) ;
5519 
5520     for (prl = 5 ; prl >= -1 ; prl--)
5521     {
5522       for (strategy = UMFPACK_STRATEGY_AUTO ; strategy <= UMFPACK_STRATEGY_SYMMETRIC ; strategy++)
5523       {
5524         Int *Rp, *Ri ;
5525         if (strategy == UMFPACK_STRATEGY_OBSOLETE) continue ;
5526 
5527 	printf ("\n[[[[ PRL = "ID" strategy = "ID"\n", prl, strategy) ;
5528 	for (k = 0 ; k < n ; k++) Pamd [k] = EMPTY ;
5529 	Control [UMFPACK_PRL] = prl ;
5530 	Control [UMFPACK_STRATEGY] = strategy ;
5531 	UMFPACK_report_control (Control) ;
5532 	i = UMFPACK_DENSE_DEGREE_THRESHOLD (0.2, n) ;
5533 	printf ("(default) dense row/col degree threshold: "ID"\n", i) ;
5534 
5535 	/* ------------------------------------------------------------------ */
5536 
5537 	matgen_sparse (n, 4*n, 10, 2*n, 10, 2*n, &Ap, &Ai, &Ax, &Az, prl, 0) ;  /* [[[[ */
5538 	bgen (n, Ap, Ai, Ax,Az, b,bz) ;
5539 
5540 	nz = Ap [n] ;
5541 	Aj = (Int *) malloc ((nz+n+1) * sizeof (Int)) ;		/* [ */
5542 	Ai2 = (Int *) malloc ((nz+n) * sizeof (Int)) ;		/* [ */
5543 	Ax2 = (double *) malloc ((nz+n) * sizeof (double)) ;	/* [ */
5544 	Az2 = (double *) calloc ((nz+n) , sizeof (double)) ;	/* [ */
5545 	if (!Aj || !Ai2 || !Ax2 || !Az2)  error ("out of memory (19)",0.) ;
5546 	Rp = Aj ;
5547 	Ri = Ai2 ;
5548 
5549 	/* ------------------------------------------------------------------ */
5550 
5551 	Con = (prl == -1) ? (DNULL) : Control ;
5552 	UMFPACK_report_control (Con) ;
5553 
5554 	/* ------------------------------------------------------------------ */
5555 
5556 	randperm (n, Qinit) ;
5557 	if (prl > 2) printf ("Qinit OK: ") ;
5558 	s = UMFPACK_report_perm (n, Qinit, Con) ;
5559 	if (s != UMFPACK_OK) error ("Qinit OK", 0.) ;
5560 
5561 	randperm (2*n, Qinit2) ;
5562 	if (prl > 2) printf ("Qinit2 OK: ") ;
5563 	s = UMFPACK_report_perm (2*n, Qinit2, Con) ;
5564 	if (s != UMFPACK_OK) error ("Qinit2 OK", 0.) ;
5565 
5566 	/* ------------------------------------------------------------------ */
5567 
5568 	if (prl > 2) printf ("\nb OK: ") ;
5569 	s = UMFPACK_report_vector (n, CARG(b,bz), Con) ;
5570 	if (s != UMFPACK_OK) error ("0",0.) ;
5571 
5572 	/* ------------------------------------------------------------------ */
5573 
5574 	if (prl > 2) printf ("\nn=-1: ") ;
5575 	s = UMFPACK_report_vector (-1, CARG(b,bz), Con) ;
5576 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_n_nonpositive)) error ("2",0.) ;
5577 
5578 	/* ------------------------------------------------------------------ */
5579 
5580 	if (prl > 2) printf ("\nb null: ") ;
5581 	s = UMFPACK_report_vector (n, CARG(DNULL,DNULL), Con) ;
5582 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_argument_missing)) error ("2",0.) ;
5583 
5584 	/* ------------------------------------------------------------------ */
5585 
5586 
5587 	if (prl > 2) printf ("\nA OK: ") ;
5588 	s = UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Con) ;
5589 	if (s != UMFPACK_OK) error ("2a",0.) ;
5590 
5591 	/* ------------------------------------------------------------------ */
5592 
5593 	if (prl > 2) printf ("\nA pattern OK: ") ;
5594 	s = UMFPACK_report_matrix (n, n, Ap, Ai, CARG(DNULL,DNULL), 1, Con) ;
5595 	if (s != UMFPACK_OK) error ("2c",0.) ;
5596 
5597 	/* ------------------------------------------------------------------ */
5598 
5599 	if (prl > 2) printf ("\nA OK row: ") ;
5600 	s = UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 0, Con) ;
5601 	if (s != UMFPACK_OK) error ("2b",0.) ;
5602 
5603 	/* ------------------------------------------------------------------ */
5604 
5605 	if (prl > 2) printf ("\nn=zero: ") ;
5606 	s = UMFPACK_report_matrix (0, 0, Ap, Ai, CARG(Ax,Az), 1, Con) ;
5607 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_n_nonpositive)) error ("2",0.) ;
5608 	s = UMFPACK_symbolic (0, 0, Ap, Ai, CARG(Ax,Az), &Symbolic, Con, Info) ;
5609 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5610         UMFPACK_report_status (Con, s) ;
5611 	UMFPACK_report_info (Con, Info) ;
5612 	if (Symbolic || s != UMFPACK_ERROR_n_nonpositive) error ("2b",0.) ;
5613 	s = UMFPACK_qsymbolic (0, 0, Ap, Ai, CARG(Ax,Az), Qinit, &Symbolic, Con, Info) ;
5614 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5615 	UMFPACK_report_info (Con, Info) ;
5616 	if (Symbolic || s != UMFPACK_ERROR_n_nonpositive) error ("2c",0.) ;
5617 
5618 	/* ------------------------------------------------------------------ */
5619 
5620 	s = do_amd (-1, Ap, Ai, Pamd) ;
5621 	if (s != AMD_INVALID) error ("amd 1", (double) s) ;
5622 
5623 	s = do_amd (n, INULL, Ai, Pamd) ;
5624 	if (s != AMD_INVALID) error ("amd 2", (double) s) ;
5625 
5626 	s = do_amd (n, Ap, INULL, Pamd) ;
5627 	if (s != AMD_INVALID) error ("amd 3", (double) s) ;
5628 
5629 	s = do_amd (n, Ap, Ai, INULL) ;
5630 	if (s != AMD_INVALID) error ("amd 4", (double) s) ;
5631 
5632 	s = do_amd (0, Ap, Ai, Pamd) ;
5633 	if (s != AMD_OK) error ("amd 5", (double) s) ;
5634 
5635 	s = do_amd_transpose (-1, Ap, Ai, Rp, Ri) ;
5636 	if (s != AMD_INVALID) error ("amd 1t", (double) s) ;
5637 
5638 	s = do_amd_transpose (n, INULL, Ai, Rp, Ri) ;
5639 	if (s != AMD_INVALID) error ("amd 2t", (double) s) ;
5640 
5641 	s = do_amd_transpose (n, Ap, INULL, Rp, Ri) ;
5642 	if (s != AMD_INVALID) error ("amd 3t", (double) s) ;
5643 
5644 	s = do_amd_transpose (n, Ap, Ai, INULL, Ri) ;
5645 	if (s != AMD_INVALID) error ("amd 7t", (double) s) ;
5646 
5647 	s = do_amd_transpose (n, Ap, Ai, Rp, INULL) ;
5648 	if (s != AMD_INVALID) error ("amd 8t", (double) s) ;
5649 
5650 	s = do_amd_transpose (0, Ap, Ai, Rp, Ri) ;
5651 	if (s != AMD_OK) error ("amd 5t", (double) s) ;
5652 
5653 #if 0
5654 { f = fopen ("debug.amd", "w") ; fprintf (f, "999\n") ; fclose (f) ; }
5655 #endif
5656 
5657 	/* ------------------------------------------------------------------ */
5658 
5659 	if (prl > 2) printf ("\nAp null: ") ;
5660 	s = UMFPACK_report_matrix (n, n, INULL, Ai, CARG(Ax,Az), 1, Con) ;
5661 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_argument_missing)) error ("3",0.) ;
5662 	s = UMFPACK_symbolic (n, n, INULL, Ai, CARG(Ax,Az), &Symbolic, Con, Info) ;
5663 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5664         UMFPACK_report_status (Con, s) ;
5665 	UMFPACK_report_info (Con, Info) ;
5666 	if (Symbolic || s != UMFPACK_ERROR_argument_missing) error ("3b",0.) ;
5667 	s = UMFPACK_qsymbolic (n, n, INULL, Ai, CARG(Ax,Az), Qinit, &Symbolic, Con, Info) ;
5668 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5669         UMFPACK_report_status (Con, s) ;
5670 	UMFPACK_report_info (Con, Info) ;
5671 	if (Symbolic || s != UMFPACK_ERROR_argument_missing) error ("3c",0.) ;
5672 	s = UMFPACK_transpose (n, n, INULL, Ai, CARG(Ax,Az), Pinit, Qinit, Ap2, Ai2, CARG(Ax2,Az2) C1ARG(0)) ;
5673 	UMFPACK_report_status (Con, s) ;
5674 	if (s != UMFPACK_ERROR_argument_missing) error ("52",0.);
5675 
5676 	s = do_amd (n, Ap, Ai, Pamd) ;
5677 	if (s != AMD_OK) error ("amd 6b", (double) s) ;
5678 
5679 	/* ------------------------------------------------------------------ */
5680 
5681 	if (prl > 2) printf ("\nAi null: ") ;
5682 	s = UMFPACK_report_matrix (n, n, Ap, INULL, CARG(Ax,Az), 1, Con) ;
5683 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_argument_missing)) error ("4",0.) ;
5684 	s = UMFPACK_symbolic (n, n, Ap, INULL, CARG(Ax,Az), &Symbolic, Con, Info) ;
5685 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5686         UMFPACK_report_status (Con, s) ;
5687 	UMFPACK_report_info (Con, Info) ;
5688 	if (Symbolic || s != UMFPACK_ERROR_argument_missing) error ("4b",0.) ;
5689 	s = UMFPACK_qsymbolic (n, n, Ap, INULL, CARG(Ax,Az), Qinit, &Symbolic, Con, Info) ;
5690 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5691         UMFPACK_report_status (Con, s) ;
5692 	UMFPACK_report_info (Con, Info) ;
5693 	if (Symbolic || s != UMFPACK_ERROR_argument_missing) error ("4c",0.) ;
5694 
5695 	/* ------------------------------------------------------------------ */
5696 
5697         if (prl >= 0)
5698         {
5699 
5700             csave = Con [UMFPACK_ORDERING] ;
5701             my_params [0] = 1 ;
5702             Con [UMFPACK_ORDERING] = UMFPACK_ORDERING_USER ;
5703 	    s = UMFPACK_fsymbolic (n, n, Ap, Ai, CARG(Ax,Az),
5704                 &my_bad_ordering, my_params, &Symbolic, Con, Info) ;
5705             if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5706             UMFPACK_report_status (Con, s) ;
5707             UMFPACK_report_info (Con, Info) ;
5708             if (Symbolic || s != UMFPACK_ERROR_ordering_failed)error ("6d",0.) ;
5709 
5710             my_params [0] = 0 ;
5711 	    s = UMFPACK_fsymbolic (n, n, Ap, Ai, CARG(Ax,Az),
5712                 &my_bad_ordering, my_params, &Symbolic, Con, Info) ;
5713             if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5714             UMFPACK_report_status (Con, s) ;
5715             UMFPACK_report_info (Con, Info) ;
5716             if (Symbolic || s != UMFPACK_ERROR_ordering_failed)error ("6e",0.) ;
5717 
5718             Con [UMFPACK_ORDERING] = csave ;
5719 
5720         }
5721 
5722 	/* ------------------------------------------------------------------ */
5723 
5724         my_params [0] = UMFPACK_ORDERING_AMD ;
5725         my_params [1] = prl ;
5726         my_params [2] = EMPTY ;
5727         my_info [0] = EMPTY ;
5728         my_info [1] = EMPTY ;
5729         my_info [2] = EMPTY ;
5730 
5731         ok = UMF_cholmod (n, n, TRUE, Ap, Ai, Pamd, my_params, my_info) ;
5732         if (!ok) error ("6f", 0.) ;
5733 
5734         ok = UMF_cholmod (n+1, n, TRUE, Ap, Ai, Pamd, my_params, my_info) ;
5735         if (!ok) error ("6g", 0.) ;
5736 
5737         ok = UMF_cholmod (n, n, TRUE, NULL, Ai, Pamd, my_params, my_info) ;
5738         if (ok) error ("6h", 0.) ;
5739 
5740 	/* ------------------------------------------------------------------ */
5741 
5742 	Ap [0] = 1 ;	/* Ap broken [ */
5743 	if (prl > 2) printf ("\nAp [0] != 0: ") ;
5744 	s = UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Con) ;
5745 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_matrix)) error ("5",0.) ;
5746 	s = UMFPACK_symbolic (n, n, Ap, Ai, CARG(Ax,Az), &Symbolic, Con, Info) ;
5747 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5748         UMFPACK_report_status (Con, s) ;
5749 	UMFPACK_report_info (Con, Info) ;
5750 	if (Symbolic || s != UMFPACK_ERROR_invalid_matrix) error ("5b",0.) ;
5751 	s = UMFPACK_qsymbolic (n, n, Ap, Ai, CARG(Ax,Az), Qinit, &Symbolic, Con, Info) ;
5752 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5753         UMFPACK_report_status (Con, s) ;
5754 	UMFPACK_report_info (Con, Info) ;
5755 	if (Symbolic || s != UMFPACK_ERROR_invalid_matrix) error ("5c",0.) ;
5756 	if (prl > 2) printf ("\nCalling umfpack_transpose:\n") ;
5757 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), Pinit, Qinit, Ap2, Ai2, CARG(Ax2,Az2) C1ARG(0)) ;
5758 	UMFPACK_report_status (Con, s) ;
5759 	if (s != UMFPACK_ERROR_invalid_matrix) error ("53",0.);
5760 
5761 	s = do_amd (n, Ap, Ai, Pamd) ;
5762 	if (s != AMD_INVALID) error ("amd 6", (double) s) ;
5763 
5764 	Ap [0] = 0 ;	/* Ap fixed ] */
5765 
5766 	/* ------------------------------------------------------------------ */
5767 
5768 	Ap [n] = -1 ;	/* Ap broken [ */
5769 	if (prl > 2) printf ("\nnz < 0: ") ;
5770 	s = UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Con) ;
5771 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_matrix)) error ("6",0.) ;
5772 	s = UMFPACK_symbolic (n, n, Ap, Ai, CARG(Ax,Az), &Symbolic, Con, Info) ;
5773 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5774         UMFPACK_report_status (Con, s) ;
5775 	UMFPACK_report_info (Con, Info) ;
5776 	if (Symbolic || s != UMFPACK_ERROR_invalid_matrix) error ("6b",0.) ;
5777 	s = UMFPACK_qsymbolic (n, n, Ap, Ai, CARG(Ax,Az), Qinit, &Symbolic, Con, Info) ;
5778 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5779 	if (Symbolic || s != UMFPACK_ERROR_invalid_matrix) error ("6c",0.) ;
5780 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), Pinit, Qinit, Ap2, Ai2, CARG(Ax2,Az2) C1ARG(0)) ;
5781 	UMFPACK_report_status (Con, s) ;
5782 	if (s != UMFPACK_ERROR_invalid_matrix) error ("51h",0.);
5783 	s = UMFPACK_col_to_triplet (n, Ap, Aj) ;
5784 	if (s != UMFPACK_ERROR_invalid_matrix) error ("52j",0.);
5785 
5786 	s = do_amd (n, Ap, Ai, Pamd) ;
5787 	if (s != AMD_INVALID) error ("amd 6b", (double) s) ;
5788 
5789 	Ap [n] = nz ;	/* Ap fixed ] */
5790 
5791 	/* ------------------------------------------------------------------ */
5792 #if 0
5793 	Ap [n] = Int_MAX ;
5794 	s = UMFPACK_qsymbolic (n, n, Ap, Ai, CARG(Ax,Az), Qinit, &Symbolic, Con, Info) ;
5795 	if (s != UMFPACK_ERROR_problem_too_large) error ("177a",0.);
5796 	Ap [n] = nz ;
5797 #endif
5798 	/* ------------------------------------------------------------------ */
5799 
5800 	printf ("Ap [2] negative:\n") ;
5801 	UMFPACK_report_control (Con) ;
5802 	c = Ap [2] ;	/* Ap broken [ */
5803 	Ap [2] = -1 ;
5804 	if (prl > 2) printf ("\nAp[2]<0: ") ;
5805 	s = UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Con) ;
5806 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_matrix)) error ("8",0.) ;
5807 	s = UMFPACK_symbolic (n, n, Ap, Ai, CARG(Ax,Az), &Symbolic, Con, Info) ;
5808 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5809         UMFPACK_report_status (Con, s) ;
5810 	UMFPACK_report_info (Con, Info) ;
5811 	if (Symbolic || s != UMFPACK_ERROR_invalid_matrix) error ("8b",0.) ;
5812 	s = UMFPACK_qsymbolic (n, n, Ap, Ai, CARG(Ax,Az), Qinit, &Symbolic, Con, Info) ;
5813 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5814         UMFPACK_report_status (Con, s) ;
5815 	UMFPACK_report_info (Con, Info) ;
5816 	if (Symbolic || s != UMFPACK_ERROR_invalid_matrix) error ("8c",0.) ;
5817 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), Pinit, Qinit, Ap2, Ai2, CARG(Ax2,Az2) C1ARG(0)) ;
5818 	UMFPACK_report_status (Con, s) ;
5819 	if (s != UMFPACK_ERROR_invalid_matrix) error ("55",0.);
5820 
5821 	s = do_amd (n, Ap, Ai, Pamd) ;
5822 	if (s != AMD_INVALID) error ("amd 7", (double) s) ;
5823 
5824 	Ap [2] = c ;	/* Ap fixed ] */
5825 
5826 	/* ------------------------------------------------------------------ */
5827 
5828 	c = Ap [2] ;	/* Ap broken [ */
5829 	Ap [2] = nz+1 ;
5830 	if (prl > 2) printf ("\nAp [2] > nz: ") ;
5831 	s = UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Con) ;
5832 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_matrix)) error ("9",0.) ;
5833 	s = UMFPACK_symbolic (n, n, Ap, Ai, CARG(Ax,Az), &Symbolic, Con, Info) ;
5834 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5835 	s = Info [UMFPACK_STATUS] ;
5836         UMFPACK_report_status (Con, s) ;
5837 	UMFPACK_report_info (Con, Info) ;
5838 	if (Symbolic || s != UMFPACK_ERROR_invalid_matrix) error ("9b",0.) ;
5839 	s = UMFPACK_qsymbolic (n, n, Ap, Ai, CARG(Ax,Az), Qinit, &Symbolic, Con, Info) ;
5840 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5841         UMFPACK_report_status (Con, s) ;
5842 	UMFPACK_report_info (Con, Info) ;
5843 	if (Symbolic || s != UMFPACK_ERROR_invalid_matrix) error ("9c",0.) ;
5844 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), Pinit, Qinit, Ap2, Ai2, CARG(Ax2,Az2) C1ARG(0)) ;
5845 	UMFPACK_report_status (Con, s) ;
5846 	if (s != UMFPACK_ERROR_invalid_matrix) error ("51i",0.);
5847 
5848 	s = do_amd (n, Ap, Ai, Pamd) ;
5849 	if (s != AMD_INVALID) error ("amd 8", (double) s) ;
5850 
5851 	Ap [2] = c ;	/* Ap fixed ] */
5852 
5853 	/* ------------------------------------------------------------------ */
5854 
5855 	c = Ap [4] ;	/* Ap broken [ */
5856 	Ap [4] = Ap [3]-1 ;
5857 	if (prl > 2) printf ("\nAp [4] < Ap [3]-1: ") ;
5858 	s = UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Con) ;
5859 	if (s != ((prl <= 2) ? UMFPACK_OK  : UMFPACK_ERROR_invalid_matrix)) error ("10",0.) ;
5860 	s = UMFPACK_symbolic (n, n, Ap, Ai, CARG(Ax,Az), &Symbolic, Con, Info) ;
5861 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5862         UMFPACK_report_status (Con, s) ;
5863 	UMFPACK_report_info (Con, Info) ;
5864 	if (Symbolic || s != UMFPACK_ERROR_invalid_matrix) error ("8b",0.) ;
5865 	s = UMFPACK_qsymbolic (n, n, Ap, Ai, CARG(Ax,Az), Qinit, &Symbolic, Con, Info) ;
5866 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5867         UMFPACK_report_status (Con, s) ;
5868 	UMFPACK_report_info (Con, Info) ;
5869 	if (Symbolic || s != UMFPACK_ERROR_invalid_matrix) error ("8c",0.) ;
5870 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), Pinit, Qinit, Ap2, Ai2, CARG(Ax2,Az2) C1ARG(0)) ;
5871 	UMFPACK_report_status (Con, s) ;
5872 	if (s != UMFPACK_ERROR_invalid_matrix) error ("51j",0.);
5873 
5874 	s = do_amd (n, Ap, Ai, Pamd) ;
5875 	if (s != AMD_INVALID) error ("amd 9", (double) s) ;
5876 
5877 	Ap [4] = c ;	/* Ap fixed ] */
5878 
5879 	/* ------------------------------------------------------------------ */
5880 
5881 	c = Ai [4] ;	/* Ai broken [ */
5882 	Ai [4] = -1 ;
5883 	if (prl > 2) printf ("\nAi [4] = -1: ") ;
5884 	s = UMFPACK_report_matrix (n , n, Ap, Ai, CARG(Ax,Az), 1, Con) ;
5885 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_matrix)) error ("12",0.) ;
5886 	s = UMFPACK_symbolic (n, n, Ap, Ai, CARG(Ax,Az), &Symbolic, Con, Info) ;
5887 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5888         UMFPACK_report_status (Con, s) ;
5889 	UMFPACK_report_info (Con, Info) ;
5890 	if (Symbolic || s != UMFPACK_ERROR_invalid_matrix) error ("12b",0.) ;
5891 	s = UMFPACK_qsymbolic (n, n, Ap, Ai, CARG(Ax,Az), Qinit, &Symbolic, Con, Info) ;
5892 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5893         UMFPACK_report_status (Con, s) ;
5894 	UMFPACK_report_info (Con, Info) ;
5895 	if (Symbolic || s != UMFPACK_ERROR_invalid_matrix) error ("12c",0.) ;
5896 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), Pinit, Qinit, Ap2, Ai2, CARG(Ax2,Az2) C1ARG(0)) ;
5897 	UMFPACK_report_status (Con, s) ;
5898 	if (s != UMFPACK_ERROR_invalid_matrix) error ("51k",0.);
5899 
5900 	s = do_amd (n, Ap, Ai, Pamd) ;
5901 	if (s != AMD_INVALID) error ("amd 10", (double) s) ;
5902 
5903 	Ai [4] = c ;	/* Ai fixed ] */
5904 
5905 	/* ------------------------------------------------------------------ */
5906 
5907 	if (Ap [4] - Ap [3] < 3) error ("col 3 too short",0.) ;
5908 	c = Ai [Ap [3] + 1] ;	/* Ai broken [ */
5909 	Ai [Ap [3] + 1] = 0 ;
5910 	if (prl > 2) printf ("\ncol 3 jumbled: ") ;
5911 	s = UMFPACK_report_matrix (n , n, Ap, Ai, CARG(Ax,Az), 1, Con) ;
5912 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_matrix)) error ("13",0.) ;
5913 	s = UMFPACK_symbolic (n, n, Ap, Ai, CARG(Ax,Az), &Symbolic, Con, Info) ;
5914 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5915         UMFPACK_report_status (Con, s) ;
5916 	UMFPACK_report_info (Con, Info) ;
5917 	if (Symbolic || s != UMFPACK_ERROR_invalid_matrix) error ("13b",0.) ;
5918 	s = UMFPACK_qsymbolic (n, n, Ap, Ai, CARG(Ax,Az), Qinit, &Symbolic, Con, Info) ;
5919 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5920         UMFPACK_report_status (Con, s) ;
5921 	UMFPACK_report_info (Con, Info) ;
5922 	if (Symbolic || s != UMFPACK_ERROR_invalid_matrix) error ("13c",0.) ;
5923 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), Pinit, Qinit, Ap2, Ai2, CARG(Ax2,Az2) C1ARG(0)) ;
5924 	UMFPACK_report_status (Con, s) ;
5925 	if (s != UMFPACK_ERROR_invalid_matrix) error ("51k",0.);
5926 
5927 	s = do_amd (n, Ap, Ai, Pamd) ;
5928 	printf ("amd jumbled: "ID"\n", s) ;
5929 	if (s != AMD_OK_BUT_JUMBLED) error ("amd 11", (double) s) ;
5930 
5931 	Ai [Ap [3] + 1] = c ;	/* Ai fixed ] */
5932 
5933 	/* ------------------------------------------------------------------ */
5934 
5935 #if 0
5936 	{ f = fopen ("debug.amd", "w") ; fprintf (f, "999\n") ; fclose (f) ; }
5937 #endif
5938 
5939 	for (i = 0 ; i < n   ; i++) Ap2 [i] = Ap [i] ;
5940 	for (i = n ; i <= 2*n ; i++) Ap2 [i] = nz ;
5941 
5942 	s = do_amd (2*n, Ap2, Ai, Pamd) ;
5943 	if (s != AMD_OK) error ("amd 12a", (double) s) ;
5944 
5945 	if (prl > 2) printf ("\nhalf empty: ") ;
5946 	s = UMFPACK_report_matrix (2*n, 2*n, Ap2, Ai, CARG(Ax,Az), 1, Con) ;
5947 	if (s != UMFPACK_OK) error ("14",0.) ;
5948 	s = UMFPACK_symbolic (2*n, 2*n, Ap2, Ai, CARG(DNULL,DNULL), &Symbolic, Con, Info) ;
5949 
5950 	if (!Symbolic || s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5951         UMFPACK_report_status (Con, s) ;
5952 	UMFPACK_report_info (Con, Info) ;
5953 	if (!Symbolic || s != UMFPACK_OK) error ("14b",0.) ;
5954 	UMFPACK_free_symbolic (&Symbolic) ;
5955 
5956 	s = UMFPACK_symbolic (2*n, 2*n, Ap2, Ai, CARG(DNULL,DNULL), &Symbolic, Con, DNULL) ;
5957 	if (s != UMFPACK_OK) error ("13d2", 0.) ;
5958 	if (!Symbolic) error ("13d",0.) ;
5959 
5960 	UMFPACK_free_symbolic (&Symbolic) ;
5961 
5962 	s = UMFPACK_qsymbolic (2*n, 2*n, Ap2, Ai, CARG(DNULL,DNULL), Qinit2, &Symbolic, Con, Info) ;
5963 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5964 
5965         UMFPACK_report_status (Con, s) ;
5966 	UMFPACK_report_info (Con, Info) ;
5967 	if (!Symbolic || s != UMFPACK_OK) error ("14c",0.) ;
5968 	UMFPACK_free_symbolic (&Symbolic) ;
5969 
5970 	s = do_amd (2*n, Ap2, Ai, Pamd) ;
5971 	if (s != AMD_OK) error ("amd 12", (double) s) ;
5972 
5973 	/* ------------------------------------------------------------------ */
5974 
5975 	for (i = 0 ; i <= n   ; i++) Ap2 [i] = 0 ;
5976 	if (prl > 2) printf ("\nall empty: ") ;
5977 	s = UMFPACK_report_matrix (n, n, Ap2, Ai, CARG(Ax,Az), 1, Con) ;
5978 	if (s != UMFPACK_OK) error ("141",0.) ;
5979 
5980 	s = UMFPACK_col_to_triplet (n, Ap, Aj) ;
5981 	if (s != UMFPACK_OK) error ("151",0.) ;
5982 
5983 	s = UMFPACK_symbolic (n, n, Ap2, Ai, CARG(DNULL,DNULL), &Symbolic, Con, Info) ;
5984 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5985         UMFPACK_report_status (Con, s) ;
5986 	UMFPACK_report_info (Con, Info) ;
5987 	if (!Symbolic || s != UMFPACK_OK) error ("142",0.) ;
5988 	UMFPACK_free_symbolic (&Symbolic) ;
5989 
5990 	s = UMFPACK_symbolic (n, n, Ap2, Ai, CARG(DNULL,DNULL), &Symbolic, Con, DNULL) ;
5991 	if (s != UMFPACK_OK) error ("142b", 0.) ;
5992 	if (!Symbolic) error ("143",0.) ;
5993 	UMFPACK_free_symbolic (&Symbolic) ;
5994 
5995 	s = UMFPACK_qsymbolic (n, n, Ap2, Ai, CARG(DNULL,DNULL), Qinit, &Symbolic, Con, Info) ;
5996 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
5997         UMFPACK_report_status (Con, s) ;
5998 	UMFPACK_report_info (Con, Info) ;
5999 	if (!Symbolic || s != UMFPACK_OK) error ("144",0.) ;
6000 	UMFPACK_free_symbolic (&Symbolic) ;
6001 
6002 	s = do_amd (n, Ap, Ai, Pamd) ;
6003 	if (s != AMD_OK) error ("amd 13", (double) s) ;
6004 
6005 	/* ------------------------------------------------------------------ */
6006 
6007 	for (i = 0 ; i <= n ; i++) Ap2 [i] = Ap [i] ;
6008 	for (p = 0 ; p < nz ; p++)
6009 	{
6010 	    Ai2 [p] = Ai [p] ;
6011 	    Ax2 [p] = Ax [p] ;
6012 	}
6013 	for (i = n ; i < 2*n ; i++)
6014 	{
6015 	    Ap2 [i] = p ;	/* add a dense row 0 */
6016 	    Ai2 [p] = 0 ;
6017 	    Ax2 [p] = 1.0 ;
6018 	    p++ ;
6019 	}
6020 	Ap2 [2*n] = p ;
6021 	if (prl > 2) printf ("\nhalf empty rows: ") ;
6022 	s = UMFPACK_report_matrix (2*n, 2*n, Ap2, Ai2, CARG(Ax2,Az2), 1, Con) ;
6023 	if (s != UMFPACK_OK) error ("30",0.) ;
6024 	s = UMFPACK_symbolic (2*n, 2*n, Ap2, Ai2, CARG(Ax2,Az2), &Symbolic, Con, Info) ;
6025 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6026         UMFPACK_report_status (Con, s) ;
6027 	UMFPACK_report_info (Con, Info) ;
6028 	if (!Symbolic || s != UMFPACK_OK) error ("30b",0.) ;
6029 	UMFPACK_free_symbolic (&Symbolic) ;
6030 
6031 	s = UMFPACK_qsymbolic (2*n, 2*n, Ap2, Ai2, CARG(Ax2,Az2), Qinit2, &Symbolic, Con, Info) ;
6032 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6033         UMFPACK_report_status (Con, s) ;
6034 	UMFPACK_report_info (Con, Info) ;
6035 	if (!Symbolic || s != UMFPACK_OK) error ("30c",0.) ;
6036 	UMFPACK_free_symbolic (&Symbolic) ;
6037 
6038 	s = do_amd (2*n, Ap2, Ai2, Pamd) ;
6039 	if (s != AMD_OK) error ("amd 14", (double) s) ;
6040 
6041 	/* ------------------------------------------------------------------ */
6042 
6043 	for (i = 0 ; i <= 2*n ; i++) Ap2 [i] = 0 ;
6044 	if (prl > 2) printf ("\nall empty: ") ;
6045 	s = UMFPACK_report_matrix (2*n, 2*n, Ap2, Ai, CARG(Ax,Az), 1, Con) ;
6046 	if (s != UMFPACK_OK) error ("15",0.) ;
6047 
6048 	s = do_amd (2*n, Ap2, Ai2, Pamd) ;
6049 	if (s != AMD_OK) error ("amd 14b", (double) s) ;
6050 
6051 	/* ------------------------------------------------------------------ */
6052 
6053 	if (prl > 2) printf ("\nold null form was same as col_form: ") ;
6054 	s = UMFPACK_report_matrix (n, n, Ap, Ai, CARG(Ax,Az), 1, Con) ;
6055 	if (s != UMFPACK_OK) error ("16",0.) ;
6056 
6057 	/* ================================================================== */
6058 	/* test Numeric [ */
6059 	/* ================================================================== */
6060 
6061 	s = UMFPACK_symbolic (n, n, Ap, Ai, CARG(Ax,Az), &Symbolic, Con, Info) ;	/* [ */
6062 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6063         UMFPACK_report_status (Con, s) ;
6064 	UMFPACK_report_info (Con, Info) ;
6065 	if (!Symbolic || s != UMFPACK_OK) error ("16a",0.) ;
6066 
6067 	/* ------------------------------------------------------------------ */
6068 
6069 	for (scale = UMFPACK_SCALE_NONE ; scale <= UMFPACK_SCALE_MAX ; scale++)
6070 	{
6071 	    if (Con) Con [UMFPACK_SCALE] = scale ;
6072 
6073 	    s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Con, Info) ;	/* [ */
6074 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6075 	    UMFPACK_report_status (Con, s) ;
6076 	    UMFPACK_report_info (Con, Info) ;
6077 	    Info [UMFPACK_FLOPS_ESTIMATE] = -1 ;
6078 	    UMFPACK_report_info (Con, Info) ;
6079 	    if (!Numeric || s != UMFPACK_OK) error ("31",0.) ;
6080 
6081 	    if (prl > 2) printf ("good Numeric: ") ;
6082 	    s = UMFPACK_report_numeric ( Numeric, Con) ;
6083 	    if (s != UMFPACK_OK) error ("90",0.) ;
6084 
6085 	    /* ------------------------------------------------------------------ */
6086 
6087 	    s = UMFPACK_get_lunz (INULL, &unz, &nnrow, &nncol, &nzud, Numeric) ;
6088 	    if (s != UMFPACK_ERROR_argument_missing) error ("57",0.) ;
6089 
6090 	    /* ------------------------------------------------------------------ */
6091 
6092 	    s = UMFPACK_get_lunz (&lnz, &unz, &nnrow, &nncol, &nzud, Numeric) ;
6093 	    printf ("lnz "ID" unz "ID" nn "ID"\n", lnz, unz, nn) ;
6094 	    if (s != UMFPACK_OK) error ("58",0.) ;
6095 
6096 	    /* ------------------------------------------------------------------ */
6097 
6098 	    Lp = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
6099 	    Li = (Int *) malloc ((lnz+1) * sizeof (Int)) ;		/* [ */
6100 	    Lx = (double *) malloc ((lnz+1) * sizeof (double)) ;	/* [ */
6101 	    Lz = (double *) calloc (lnz , sizeof (double)) ;	/* [ */
6102 	    Up = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
6103 	    Ui = (Int *) malloc ((unz+1) * sizeof (Int)) ;		/* [ */
6104 	    Ux = (double *) malloc ((unz+1) * sizeof (double)) ;	/* [ */
6105 	    Uz = (double *) calloc ((unz+1) , sizeof (double)) ;	/* [ */
6106 	    P = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
6107 	    Q = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
6108 	    Pa = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
6109 	    Wx = (double *) malloc ((10*n) * sizeof (double)) ;	/* [ */
6110 	    Rs = (double *) malloc ((n+1) * sizeof (double)) ;	/* [ */
6111 	    if (!Lp || !Li || !Lx || !Up || !Ui || !Ux || !P || !Q) error ("out of memory (20)",0.) ;
6112 	    if (!Pa || !Wx || !Rs) error ("out of memory (20)",0.) ;
6113 	    if (!Uz || !Lz) error ("out of memory (21)",0.) ;
6114 
6115 	    if (prl > 2) printf ("good Numeric again: ") ;
6116 	    s = UMFPACK_report_numeric ( Numeric, Con) ;
6117 	    if (s != UMFPACK_OK) error ("77",0.) ;
6118 
6119 	    s = UMFPACK_get_numeric (Lp, Li, CARG(Lx,Lz), Up, Ui, CARG(Ux,Uz), P, Q, CARG(DNULL,DNULL), &do_recip, Rs, Numeric) ;
6120 	    if (s != UMFPACK_OK) error ("59", 0.) ;
6121 
6122 	    s = UMFPACK_get_numeric (Lp, Li, CARG(Lx,Lz), Up, Ui, CARG(Ux,Uz), P, Q, CARG(DNULL,DNULL), &do_recip, DNULL, Numeric) ;
6123 	    if (s != UMFPACK_OK) error ("59b", 0.) ;
6124 
6125 	    s = UMFPACK_get_numeric (Lp, Li, CARG(Lx,Lz), Up, Ui, CARG(Ux,Uz), P, Q, CARG(DNULL,DNULL), INULL, DNULL, Numeric) ;
6126 	    if (s != UMFPACK_OK) error ("59r", 0.) ;
6127 
6128 	    if (prl > 2) printf ("good Numeric yet again: ") ;
6129 	    s = UMFPACK_report_numeric ( Numeric, Con) ;
6130 	    if (s != UMFPACK_OK) error ("75",0.) ;
6131 	    dump_perm ("goodP1", n, Pamd) ;
6132 	    if (prl > 2) printf ("\nL test: ") ;
6133 	    s = UMFPACK_report_matrix (n, n, Lp, Li, CARG(Lx,Lz), 0, Con) ;
6134 	    if (s != UMFPACK_OK) error ("60",0.) ;
6135 	    if (prl > 2) printf ("\nU test: ") ;
6136 	    s = UMFPACK_report_matrix (n, n, Up, Ui, CARG(Ux,Uz), 1, Con) ;
6137 	    if (s != UMFPACK_OK) error ("61",0.) ;
6138 	    dump_perm ("goodP", n, Pamd) ;
6139 	    if (prl > 2) printf ("P test: ") ;
6140 	    s = UMFPACK_report_perm (n, P, Con) ;
6141 	    if (s != UMFPACK_OK) error ("62",0.) ;
6142 	    if (prl > 2) printf ("Q test: ") ;
6143 	    s = UMFPACK_report_perm (n, Q, Con) ;
6144 	    if (s != UMFPACK_OK) error ("63",0.) ;
6145 
6146 	    s = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Con, Info) ;
6147 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6148 	    if (s != UMFPACK_OK) error ("64",0.) ;
6149 
6150 	    s = UMFPACK_scale (CARG(DNULL,xz), CARG(b,bz), Numeric) ;
6151 	    if (s != UMFPACK_ERROR_argument_missing) error ("64z",0.) ;
6152 
6153 	    s = UMFPACK_scale (CARG(x,xz), CARG(DNULL,bz), Numeric) ;
6154 	    if (s != UMFPACK_ERROR_argument_missing) error ("64y",0.) ;
6155 
6156 	    s = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(DNULL,xz), CARG(b,bz), Numeric, Con, Info) ;
6157 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6158 	    if (s != UMFPACK_ERROR_argument_missing) error ("64e",0.) ;
6159 
6160 	    s = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(DNULL,bz), Numeric, Con, Info) ;
6161 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6162 	    if (s != UMFPACK_ERROR_argument_missing) error ("64f",0.) ;
6163 
6164 	    s = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(DNULL,Az), CARG(x,xz), CARG(DNULL,bz), Numeric, Con, Info) ;
6165 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6166 	    if (s != UMFPACK_ERROR_argument_missing) error ("64g",0.) ;
6167 
6168 	    s = UMFPACK_wsolve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Con, Info, Pa, Wx) ;
6169 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6170 	    if (s != UMFPACK_OK) error ("64a",0.) ;
6171 
6172 	    s = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Con, DNULL) ;
6173 	    if (s != UMFPACK_OK) error ("64b",0.) ;
6174 
6175 	    s = UMFPACK_wsolve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Con, DNULL, Pa, Wx) ;
6176 	    if (s != UMFPACK_OK) error ("64c",0.) ;
6177 
6178 	    s = UMFPACK_solve (UMFPACK_A, INULL, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Con, Info) ;
6179 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6180 	    UMFPACK_report_control (Con) ;
6181 	    UMFPACK_report_status (Con, s) ;
6182 	    UMFPACK_report_info (Con, Info) ;
6183 	    if (s != UMFPACK_ERROR_argument_missing) error ("65a",0.) ;
6184 
6185 	    s = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(DNULL,xz), CARG(b,bz), Numeric, Con, Info) ;
6186 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6187 	    if (s != UMFPACK_ERROR_argument_missing) error ("65a",0.) ;
6188 
6189 	    s = UMFPACK_wsolve (UMFPACK_A, INULL, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Con, Info, Pa, Wx) ;
6190 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6191 	    if (s != UMFPACK_ERROR_argument_missing) error ("65b",0.) ;
6192 
6193 	    s = UMFPACK_solve (UMFPACK_At, INULL, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Con, Info) ;
6194 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6195 	    if (s != UMFPACK_ERROR_argument_missing) error ("65c",0.) ;
6196 
6197 	    s = UMFPACK_wsolve (UMFPACK_At, INULL, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Con, Info, Pa, Wx) ;
6198 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6199 	    if (s != UMFPACK_ERROR_argument_missing) error ("66",0.) ;
6200 
6201 	    s = UMFPACK_wsolve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Con, Info, INULL, Wx) ;
6202 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6203 	    if (s != UMFPACK_ERROR_argument_missing) error ("67",0.) ;
6204 
6205 	    s = UMFPACK_wsolve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Con, Info, Pa, DNULL) ;
6206 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6207 	    if (s != UMFPACK_ERROR_argument_missing) error ("68",0.) ;
6208 
6209 	    if (prl > 2) printf ("erroroneous sys arg for umfpack_solve:\n") ;
6210 	    s = UMFPACK_solve (-1, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Con, Info) ;
6211 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6212 	    UMFPACK_report_status (Con, s) ;
6213 	    UMFPACK_report_info (Con, Info) ;
6214 	    if (s != UMFPACK_ERROR_invalid_system) error ("65d",0.) ;
6215 
6216 	    /* check internal error message */
6217 	    UMFPACK_report_status (Con, UMFPACK_ERROR_internal_error) ;
6218 
6219 	    /* check unrecognized error code */
6220 	    UMFPACK_report_status (Con, 123123999) ;
6221 
6222 	    s = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), (void *) NULL, Con, Info) ;
6223 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6224 	    UMFPACK_report_status (Con, s) ;
6225 	    UMFPACK_report_info (Con, Info) ;
6226 	    if (s != UMFPACK_ERROR_invalid_Numeric_object) error ("70",0.) ;
6227 
6228 	    s = UMFPACK_wsolve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), (void *) NULL, Con, Info, Pa, Wx) ;
6229 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6230 	    if (s != UMFPACK_ERROR_invalid_Numeric_object) error ("71",0.) ;
6231 
6232 	    s = UMFPACK_get_determinant (CARG (&Mx, &Mz), &Exp, (void *) NULL, Info) ;
6233 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6234 	    if (s != UMFPACK_ERROR_invalid_Numeric_object) error ("71det",0.) ;
6235 
6236 	    s = UMFPACK_get_determinant (CARG (DNULL, &Mz), &Exp, Numeric, Info) ;
6237 	    if (s != Info [UMFPACK_STATUS]) error ("huh??", (double) __LINE__)  ;
6238 	    if (s != UMFPACK_ERROR_argument_missing) error ("72det",0.) ;
6239 
6240 	    /* corrupt Numeric */
6241 	    Num = (NumericType *) Numeric ;
6242 	    Num->valid = 4909284 ;
6243 
6244 	    s = UMFPACK_get_numeric (Lp, Li, CARG(Lx,Lz), Up, Ui, CARG(Ux,Uz), P, Q, CARG(DNULL,DNULL), &do_recip, Rs, Numeric) ;
6245 	    if (s != UMFPACK_ERROR_invalid_Numeric_object) error ("91",0.) ;
6246 
6247 	    s = UMFPACK_save_numeric (Numeric, "nbad.umf") ;
6248 	    if (s != UMFPACK_ERROR_invalid_Numeric_object) error ("70num",0.) ;
6249 
6250 	    s = UMFPACK_get_lunz (&lnz, &unz, &nnrow, &nncol, &nzud, Numeric) ;
6251 	    printf ("s "ID"\n", s) ;
6252 	    if (s != UMFPACK_ERROR_invalid_Numeric_object) error ("70b",0.) ;
6253 
6254 	    s = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), (void *) NULL, Con, Info) ;
6255 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6256 	    if (s != UMFPACK_ERROR_invalid_Numeric_object) error ("70",0.) ;
6257 
6258 	    s = UMFPACK_wsolve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), (void *) NULL, Con, Info, Pa, Wx) ;
6259 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6260 	    if (s != UMFPACK_ERROR_invalid_Numeric_object) error ("71",0.) ;
6261 
6262 	    if (prl > 2) printf ("bad Numeric: ") ;
6263 	    s = UMFPACK_report_numeric ( Numeric, Con) ;
6264 	    if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_Numeric_object)) error ("82",0.) ;
6265 
6266 	    /* fix numeric */
6267 	    Num->valid = NUMERIC_VALID ;
6268 	    if (prl > 2) printf ("fixed Numeric: ") ;
6269 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6270 	    if (s != UMFPACK_OK) error ("82",0.) ;
6271 
6272 	    /* valid Numeric, but no permissions */
6273 	    s = UMFPACK_save_numeric (Numeric, "/root/nbad.umf") ;
6274 	    if (s != UMFPACK_ERROR_file_IO) error ("72num",0.) ;
6275 
6276 	    /* corrupt Numeric again */
6277 	    Num->n_row = -1 ;
6278 
6279 	    s = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), (void *) NULL, Con, Info) ;
6280 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6281 	    if (s != UMFPACK_ERROR_invalid_Numeric_object) error ("72",0.) ;
6282 
6283 	    s = UMFPACK_wsolve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), (void *) NULL, Con, Info, Pa, Wx) ;
6284 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6285 	    if (s != UMFPACK_ERROR_invalid_Numeric_object) error ("73",0.) ;
6286 
6287 	    s = UMFPACK_scale (CARG(x,xz), CARG(b,bz), (void *) NULL) ;
6288 	    if (s != UMFPACK_ERROR_invalid_Numeric_object) error ("72f",0.) ;
6289 
6290 	    /* fix numeric */
6291 	    if (prl > 2) printf ("bad Numeric again: ") ;
6292 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6293 	    if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_Numeric_object)) error ("81",0.) ;
6294 	    Num->n_row = n ;
6295 	    if (prl > 2) printf ("fixed Numeric again: ") ;
6296 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6297 	    if (s != UMFPACK_OK) error ("80",0.) ;
6298 
6299 	    /* corrupt Numeric again (bad P), then fix it */
6300 	    c = Num->Rperm [0] ;
6301 	    Num->Rperm [0] = -1 ;
6302 	    if (prl > 2) printf ("bad Numeric (P): ") ;
6303 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6304 	    if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_Numeric_object)) error ("200",0.) ;
6305 	    Num->Rperm [0] = c ;
6306 	    if (prl > 2) printf ("fixed Numeric again: ") ;
6307 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6308 	    if (s != UMFPACK_OK) error ("200b",0.) ;
6309 
6310 	    /* corrupt Numeric again (bad Q), then fix it */
6311 	    c = Num->Cperm [0] ;
6312 	    Num->Cperm [0] = -1 ;
6313 	    if (prl > 2) printf ("bad Numeric (Q): ") ;
6314 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6315 	    if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_Numeric_object)) error ("201",0.) ;
6316 	    Num->Cperm [0] = c ;
6317 	    if (prl > 2) printf ("fixed Numeric again: ") ;
6318 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6319 	    if (s != UMFPACK_OK) error ("201b",0.) ;
6320 
6321 	    /* corrupt Numeric again (bad Lpos), then fix it */
6322 	    for (k = 0 ; k < n ; k++)
6323 	    {
6324 		if (Num->Lpos [k] != EMPTY) break ;
6325 	    }
6326 	    c = Num->Lpos [k] ;
6327 	    Num->Lpos [k] = c + 1 ;
6328 	    if (prl > 2) printf ("bad Numeric (Lpos [k]): ") ;
6329 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6330 	    if (s  != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_Numeric_object)) error ("204",0.) ;
6331 	    Num->Lpos [k] = c ;
6332 	    if (prl > 2) printf ("fixed Numeric again: ") ;
6333 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6334 	    if (s != UMFPACK_OK) error ("204b",0.) ;
6335 
6336 	    /* corrupt Numeric again (bad Upos), then fix it */
6337 	    for (k = 0 ; k < n ; k++)
6338 	    {
6339 		if (Num->Upos [k] != EMPTY) break ;
6340 	    }
6341 	    c = Num->Upos [k] ;
6342 	    Num->Upos [k] = 9999999 ;
6343 	    if (prl > 2) printf ("bad Numeric (Upos [0]): ") ;
6344 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6345 	    if (s  != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_Numeric_object)) error ("204c",0.) ;
6346 	    Num->Upos [k] = c ;
6347 	    if (prl > 2) printf ("fixed Numeric again: ") ;
6348 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6349 	    if (s != UMFPACK_OK) error ("204d",0.) ;
6350 
6351 	    /* corrupt Numeric again (bad Lilen), then fix it */
6352 	    c = Num->Lilen [0] ;
6353 	    Num->Lilen [0] = -1 ;
6354 	    if (prl > 2) printf ("bad Numeric (Lilen [0]): ") ;
6355 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6356 	    if (s  != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_Numeric_object)) error ("205",0.) ;
6357 	    Num->Lilen [0] = c ;
6358 	    if (prl > 2) printf ("fixed Numeric again: ") ;
6359 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6360 	    if (s != UMFPACK_OK) error ("205b",0.) ;
6361 
6362 	    /* corrupt Numeric again (bad Lip), then fix it */
6363 	    c = Num->Lip [0] ;
6364 	    Num->Lip [0] = -9999999 ;
6365 	    printf ("Bad numeric (Lip [0])\n") ;
6366 	    fflush (stdout) ;
6367 	    if (prl > 2) printf ("bad Numeric (Lip [0]): ") ;
6368 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6369 	    fflush (stdout) ;
6370 	    if (s  != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_Numeric_object)) error ("206",0.) ;
6371 	    Num->Lip [0] = c ;
6372 	    printf ("Fixed numeric (Lip [0])\n") ;
6373 	    fflush (stdout) ;
6374 	    if (prl > 2) printf ("fixed Numeric again: ") ;
6375 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6376 	    if (s != UMFPACK_OK) error ("206b",0.) ;
6377 	    fflush (stdout) ;
6378 
6379 	    /* corrupt Numeric again (bad LPattern), then fix it */
6380 	    c = Num->Memory [1].header.size ;
6381 	    Num->Memory [1].header.size = -1 ;
6382 	    if (prl > 2) printf ("bad Numeric (Pattern): ") ;
6383 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6384 	    if (s  != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_Numeric_object)) error ("208",0.) ;
6385 	    Num->Memory [1].header.size = c ;
6386 	    if (prl > 2) printf ("fixed Numeric again: ") ;
6387 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6388 	    if (s != UMFPACK_OK) error ("208b",0.) ;
6389 
6390 	    /* corrupt Numeric again (bad UPattern), then fix it */
6391 	    printf ("test 208d:\n") ;
6392 	    for (k = n-1 ; k >= 0 ; k--)
6393 	    {
6394 		if (Num->Uilen [k] > 0) break ;
6395 	    }
6396 	    ip = (Int *) (Num->Memory + SCALAR_ABS (Num->Uip [k])) ;
6397 	    c = *ip ;
6398 	    printf ("Corrupting Num->Uip [k="ID"] = "ID"\n", k, c) ;
6399 	    *ip = -1 ;
6400 	    if (prl > 2) printf ("bad Numeric (UPattern): ") ;
6401 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6402 	    if (s  != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_Numeric_object)) error ("208c",0.) ;
6403 	    *ip = c ;
6404 	    if (prl > 2) printf ("fixed Numeric again: ") ;
6405 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6406 	    if (s != UMFPACK_OK) error ("208d",0.) ;
6407 
6408 	    /* corrupt Numeric again (bad Uilen), then fix it */
6409 	    c = Num->Uilen [k] ;
6410 	    printf ("Corrupting Num->Uilen [k="ID"] = "ID"\n", k, c) ;
6411 	    Num->Uilen [k] = -1 ;
6412 	    if (prl > 2) printf ("bad Numeric (Uilen [k]): ") ;
6413 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6414 	    if (s  != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_Numeric_object)) error ("205c",0.) ;
6415 	    Num->Uilen [k] = c ;
6416 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6417 	    if (prl > 2) printf ("fixed Numeric again: ") ;
6418 	    if (s != UMFPACK_OK) error ("205d",0.) ;
6419 
6420 	    /* corrupt Numeric again (bad Uilen), then fix it */
6421 	    c = Num->Uilen [k-1] ;
6422 	    Num->Uilen [k-1] = 99999 ;
6423 	    if (prl > 2) printf ("bad Numeric (Uilen [k-1]): ") ;
6424 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6425 	    if (s  != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_Numeric_object)) error ("210",0.) ;
6426 	    Num->Uilen [k-1] = c ;
6427 	    if (prl > 2) printf ("fixed Numeric again: ") ;
6428 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6429 	    if (s != UMFPACK_OK) error ("210b",0.) ;
6430 
6431 	    /* corrupt Numeric again (bad Uip), then fix it */
6432 	    c = Num->Uip [k] ;
6433 	    Num->Uip [k] = -999999 ;
6434 	    printf ("Bad numeric Uip [k]\n") ;
6435 	    fflush (stdout) ;
6436 	    if (prl > 2) printf ("bad Numeric (Uip [k]): ") ;
6437 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6438 	    fflush (stdout) ;
6439 	    if (s  != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_Numeric_object)) error ("206c",0.) ;
6440 	    Num->Uip [k] = c ;
6441 	    printf ("Fixed numeric Uip [k]\n") ;
6442 	    fflush (stdout) ;
6443 	    s = UMFPACK_report_numeric (Numeric, Con) ;
6444 	    if (prl > 2) printf ("fixed Numeric again: ") ;
6445 	    fflush (stdout) ;
6446 	    if (s != UMFPACK_OK) error ("206d",0.) ;
6447 
6448 	    free (Rs) ;		/* ] */
6449 	    free (Wx) ;		/* ] */
6450 	    free (Pa) ;		/* ] */
6451 	    free (Q) ;		/* ] */
6452 	    free (P) ;		/* ] */
6453 	    free (Uz) ;		/* ] */
6454 	    free (Ux) ;		/* ] */
6455 	    free (Ui) ;		/* ] */
6456 	    free (Up) ;		/* ] */
6457 	    free (Lz) ;		/* ] */
6458 	    free (Lx) ;		/* ] */
6459 	    free (Li) ;		/* ] */
6460 	    free (Lp) ;		/* ] */
6461 
6462 	    UMFPACK_free_numeric (&Numeric) ;	/* ] */
6463 
6464 	    if (prl > 2) printf ("Numeric file not found:\n") ;
6465 	    s = UMFPACK_load_numeric (&Numeric, "file_not_found") ;
6466 	    if (s != UMFPACK_ERROR_file_IO) error ("71num",0.) ;
6467 
6468 	}
6469 
6470 	/* ------------------------------------------------------------------ */
6471 
6472 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Con, DNULL) ;
6473 	if (!Numeric || s != UMFPACK_OK) error ("31b",0.) ;
6474 	UMFPACK_free_numeric (&Numeric) ;
6475 
6476 	/* ------------------------------------------------------------------ */
6477 
6478 	/* change the pattern */
6479 	if (Con)
6480 	{
6481 	    Con [UMFPACK_SCALE] = UMFPACK_SCALE_NONE ;
6482 	}
6483 
6484 	printf ("change of pattern between symbolic and numeric:\n") ;
6485 	c = Ap [2] ;
6486 	Ap [2] = -1 ;
6487 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Con, DNULL) ;
6488 	if (s != UMFPACK_ERROR_different_pattern) error ("97a", (double) s) ;
6489 	Ap [2] = c ;
6490 
6491 	c = Ai [2] ;
6492 	Ai [2] = -1 ;
6493 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Con, DNULL) ;
6494 	if (s != UMFPACK_ERROR_different_pattern) error ("97b", (double) s) ;
6495 	Ai [2] = c ;
6496 
6497 	c = Ai [2] ;
6498 	Ai [2] = 9990099 ;
6499 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Con, DNULL) ;
6500 	if (s != UMFPACK_ERROR_different_pattern) error ("97c", (double) s) ;
6501 	Ai [2] = c ;
6502 
6503 	c = Ap [n] ;
6504 	Ai [Ap [n]++] = n-1 ;
6505 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Con, DNULL) ;
6506 	if (s != UMFPACK_ERROR_different_pattern) error ("97d", (double) s) ;
6507 	Ap [n] = c ;
6508 	printf ("done testing change of pattern between symbolic and numeric.\n") ;
6509 
6510 	if (Con)
6511 	{
6512 	    Con [UMFPACK_SCALE] = UMFPACK_DEFAULT_SCALE ;
6513 	}
6514 
6515 	/* ------------------------------------------------------------------ */
6516 
6517 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Con, DNULL) ;
6518 	if (!Numeric || s != UMFPACK_OK) error ("31c",0.) ;
6519 	UMFPACK_free_numeric (&Numeric) ;
6520 
6521 	/* ------------------------------------------------------------------ */
6522 
6523 	printf ("free nothing:\n") ;
6524 	UMFPACK_free_numeric ((void **) NULL) ;
6525 	UMFPACK_free_symbolic ((void **) NULL) ;
6526 	printf ("free nothing OK\n") ;
6527 
6528 	/* ------------------------------------------------------------------ */
6529 
6530 	/* test for singular matrix (IN_IN case) */
6531 	for (j = 0 ; j < n ; j++)
6532 	{
6533 	    for (p = 0 ; p < nz ; p++) Ax2 [p] = Ax [p] ;
6534 	    for (p = 0 ; p < nz ; p++) Az2 [p] = Az [p] ;
6535 	    printf ("lastcol = "ID"\n", j) ;
6536 	    for (p = Ap [j] ; p < Ap [j+1] ; p++)
6537 	    {
6538 		Ax2 [p] = 0.0 ;
6539 		Az2 [p] = 0.0 ;
6540 	    }
6541 	    s = UMFPACK_numeric (Ap, Ai, CARG(Ax2,Az2), Symbolic, &Numeric, Con, Info) ;
6542             UMFPACK_report_status (Con, s) ;
6543 	    UMFPACK_report_info (Con, Info) ;
6544 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6545 	    if (!Numeric || s != UMFPACK_WARNING_singular_matrix) error ("120",0.) ;
6546 	    UMFPACK_free_numeric (&Numeric) ;
6547 	}
6548 
6549 	/* ------------------------------------------------------------------ */
6550 
6551 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), (void *) NULL, &Numeric, Con, Info) ;
6552 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6553 	UMFPACK_report_status (Con, s) ;
6554 	UMFPACK_report_info (Con, Info) ;
6555 	if (Numeric || s != UMFPACK_ERROR_invalid_Symbolic_object) error ("32",0.) ;
6556 
6557 	/* ------------------------------------------------------------------ */
6558 
6559 	s = UMFPACK_numeric (INULL, Ai, CARG(Ax,Az), Symbolic, &Numeric, Con, Info) ;
6560 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6561 	UMFPACK_report_status (Con, s) ;
6562 	UMFPACK_report_info (Con, Info) ;
6563 	if (Numeric || s != UMFPACK_ERROR_argument_missing) error ("32b",0.) ;
6564 
6565 	/* ------------------------------------------------------------------ */
6566 
6567 	for (p = 0 ; p < nz ; p++) Ax2 [p] = 0.0 ;
6568 	for (p = 0 ; p < nz ; p++) Az2 [p] = 0.0 ;
6569 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax2,Az2), Symbolic, &Numeric, Con, Info) ;
6570 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6571 	UMFPACK_report_status (Con, s) ;
6572 	UMFPACK_report_info (Con, Info) ;
6573 	if (!Numeric || s != UMFPACK_WARNING_singular_matrix) error ("33",0.) ;
6574 	UMFPACK_free_numeric (&Numeric) ;
6575 
6576 	/* ------------------------------------------------------------------ */
6577 
6578 	for (p = 0 ; p < nz ; p++) Ax2 [p] = Ax [p] ;
6579 	for (p = 0 ; p < nz ; p++) Az2 [p] = Ax [p] ;
6580 	i = UMFPACK_DENSE_DEGREE_THRESHOLD (0.2, n) ;
6581 	for (j = 0 ; j < n ; j++)
6582 	{
6583 	    d = Ap [j+1] - Ap [j] ;
6584 	    if (d > i)
6585 	    {
6586 	    	for (p = Ap [j] ; p < Ap [j+1] ; p++)
6587 		{
6588 		    Ax2 [p] = 0.0 ;
6589 		    Az2 [p] = 0.0 ;
6590 		}
6591 	    }
6592 	}
6593 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax2,Az2), Symbolic, &Numeric, Con, Info) ;
6594 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6595 	UMFPACK_report_status (Con, s) ;
6596 	UMFPACK_report_info (Con, Info) ;
6597 	if (!Numeric || s != UMFPACK_WARNING_singular_matrix) error ("33",0.) ;
6598 	UMFPACK_free_numeric (&Numeric) ;
6599 
6600 	/* ------------------------------------------------------------------ */
6601 
6602 	/* corrupt the Symbolic object */
6603 
6604 	Sym = (SymbolicType *) Symbolic ;
6605 	printf ("32c:\n") ;
6606 	fflush (stdout) ;
6607 
6608 	Sym->valid = 4040404 ;
6609 	if (prl > 2) printf ("\nSymbolic busted: ") ;
6610 	s = UMFPACK_report_symbolic ((void *) Sym, Con) ;
6611 	if (s  != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_Symbolic_object)) error ("79",0.) ;
6612 
6613 	Front_leftmostdesc = (Int *) malloc (n * sizeof (Int)) ;	/* [ */
6614 	Front_1strow = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
6615 	Front_npivots = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
6616 	Front_parent = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
6617 	Chain_start = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
6618 	Chain_maxrows = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
6619 	Chain_maxcols = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
6620 	Qtree = (Int *) malloc (n * sizeof (Int)) ;			/* [ */
6621 	Ptree = (Int *) malloc (n * sizeof (Int)) ;			/* [ */
6622 	if (!Front_npivots || !Front_parent || !Chain_start || !Chain_maxrows
6623 	    || !Chain_maxcols || !Qtree) error ("out of memory (22)",0.) ;
6624 
6625 	s = UMFPACK_get_symbolic (&nnrow, &nncol, &n1, &nnz, &nfr, &nchains,
6626 	    Ptree, Qtree, Front_npivots, Front_parent, Front_1strow, Front_leftmostdesc,
6627 	    Chain_start, Chain_maxrows, Chain_maxcols, Symbolic) ;
6628 	if (s != UMFPACK_ERROR_invalid_Symbolic_object) error ("93", 0.) ;
6629 
6630 	free (Ptree) ;		/* ] */
6631 	free (Qtree) ;		/* ] */
6632 	free (Chain_maxcols) ;	/* ] */
6633 	free (Chain_maxrows) ;	/* ] */
6634 	free (Chain_start) ;	/* ] */
6635 	free (Front_parent) ;	/* ] */
6636 	free (Front_npivots) ;	/* ] */
6637 	free (Front_1strow) ;	/* ] */
6638 	free (Front_leftmostdesc) ;	/* ] */
6639 
6640 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Con, Info) ;
6641 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6642 	UMFPACK_report_status (Con, s) ;
6643 	UMFPACK_report_info (Con, Info) ;
6644 	printf ("32c s: "ID"\n", s) ;
6645 	if (Numeric || s != UMFPACK_ERROR_invalid_Symbolic_object) error ("32c",0.) ;
6646 
6647 	Sym->valid = SYMBOLIC_VALID ;
6648 	if (prl > 2) printf ("\nSymbolic fixed: ") ;
6649 	s = UMFPACK_report_symbolic (Symbolic, Con) ;
6650 	if (s != UMFPACK_OK) error ("78",0.) ;
6651 
6652 	/* valid Symbolic, but no permissions */
6653 	s = UMFPACK_save_symbolic (Symbolic, "/root/sbad.umf") ;
6654 	if (s != UMFPACK_ERROR_file_IO) error ("72sym",0.) ;
6655 
6656 	/* corrupt Symbolic again (bad Qinit) and then fix it */
6657 	c = Sym->Cperm_init [0] ;
6658 	Sym->Cperm_init [0] = -1 ;
6659 	if (prl > 2) printf ("\nSymbolic busted (bad Qinit): ") ;
6660 	s = UMFPACK_report_symbolic (Symbolic, Con) ;
6661 	Sym->Cperm_init [0] = c ;
6662 
6663 	/* ------------------------------------------------------------------ */
6664 
6665 	/* corrupt the Symbolic object again */
6666 
6667 	printf ("32d:\n") ;
6668 	fflush (stdout) ;
6669 	Sym->Cperm_init = (Int *) UMF_free ((void *) Sym->Cperm_init) ;
6670 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Con, Info) ;
6671 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6672 	UMFPACK_report_status (Con, s) ;
6673 	UMFPACK_report_info (Con, Info) ;
6674 	if (Numeric || s != UMFPACK_ERROR_invalid_Symbolic_object) error ("32d",0.) ;
6675 
6676 	s = UMFPACK_save_symbolic (Symbolic, "sbad.umf") ;
6677 	if (s != UMFPACK_ERROR_invalid_Symbolic_object) error ("70sym",0.) ;
6678 
6679 	/* ------------------------------------------------------------------ */
6680 
6681 	UMFPACK_free_symbolic (&Symbolic) ;		/* ] */
6682 
6683 	printf ("Symbolic file not found:\n") ;
6684 	s = UMFPACK_load_symbolic (&Symbolic, "file_not_found") ;
6685 	if (s != UMFPACK_ERROR_file_IO) error ("71sym",0.) ;
6686 
6687 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
6688 	if (UMF_malloc_count != 0) error ("umfpack memory leak!!",0.) ;
6689 #endif
6690 
6691 	/* printf (" made it here "ID"\n", umf_fail) ; */
6692 	fflush (stdout) ;
6693 
6694 	/* == done ] ======================================================== */
6695 
6696 	/* ------------------------------------------------------------------ */
6697 
6698 	s = UMFPACK_qsymbolic (n, n, Ap, Ai, CARG(DNULL,DNULL), Qinit, &Symbolic, Con, Info) ;
6699 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6700 	/* printf (" made it here 3 "ID"\n", umf_fail) ; */
6701 	fflush (stdout) ;
6702 	s = Info [UMFPACK_STATUS] ;
6703 	UMFPACK_report_status (Con, s) ;
6704 	UMFPACK_report_info (Con, Info) ;
6705 	if (!Symbolic || s != UMFPACK_OK) error ("16b",0.) ;
6706 	/* printf (" made it here too "ID"\n", umf_fail) ; */
6707 	UMFPACK_free_symbolic (&Symbolic) ;
6708 
6709 	/* ------------------------------------------------------------------ */
6710 
6711 	if (prl > 2) printf ("Qinit missing: ") ;
6712 	s = UMFPACK_report_perm (n, INULL, Con) ;
6713 	if (s != UMFPACK_OK) error ("17",0.) ;
6714 	s = UMFPACK_qsymbolic (n, n, Ap, Ai, CARG(DNULL,DNULL), INULL, &Symbolic, Con, Info) ;
6715 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6716 	UMFPACK_report_status (Con, s) ;
6717 	UMFPACK_report_info (Con, Info) ;
6718 	if (!Symbolic || s != UMFPACK_OK) error ("17b",0.) ;
6719 	UMFPACK_free_symbolic (&Symbolic) ;
6720 
6721 	/* ------------------------------------------------------------------ */
6722 
6723 	if (prl > 2) printf ("Qinit n=0: ") ;
6724 	s = UMFPACK_report_perm (0, Qinit, Con) ;
6725 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_n_nonpositive)) error ("18",0.) ;
6726 
6727 	/* ------------------------------------------------------------------ */
6728 
6729 	c = Qinit [5] ;
6730 	Qinit [5]++ ;
6731 	if (prl > 2) printf ("Qinit bad: ") ;
6732 	s = UMFPACK_report_perm (n, Qinit, Con) ;
6733 	if (s != ((prl <= 2) ? UMFPACK_OK  : UMFPACK_ERROR_invalid_permutation)) error ("19",0.) ;
6734 	s = UMFPACK_qsymbolic (n, n, Ap, Ai, CARG(DNULL,DNULL), Qinit, &Symbolic, Con, Info) ;
6735 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6736 	UMFPACK_report_status (Con, s) ;
6737 	UMFPACK_report_info (Con, Info) ;
6738 	if (Symbolic || s != UMFPACK_ERROR_invalid_permutation) error ("19b",0.) ;
6739 	Qinit [5] = c ;
6740 
6741 	/* ------------------------------------------------------------------ */
6742 
6743 	c = Qinit [5] ;
6744 	Qinit [5] = -1 ;
6745 	if (prl > 2) printf ("Qinit bad (out of range): ") ;
6746 	s = UMFPACK_report_perm (n, Qinit, Con) ;
6747 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_permutation)) error ("19c",0.) ;
6748 	s = UMFPACK_qsymbolic (n, n, Ap, Ai, CARG(DNULL,DNULL), Qinit, &Symbolic, Con, Info) ;
6749 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
6750 	UMFPACK_report_status (Con, s) ;
6751 	UMFPACK_report_info (Con, Info) ;
6752 	if (Symbolic || s != UMFPACK_ERROR_invalid_permutation) error ("19d",0.) ;
6753 	Qinit [5] = c ;
6754 
6755 	/* ------------------------------------------------------------------ */
6756 
6757 	s = UMFPACK_col_to_triplet (n, Ap, INULL) ;
6758 	if (s != UMFPACK_ERROR_argument_missing) error ("20a",0.) ;
6759 
6760 	/* ------------------------------------------------------------------ */
6761 
6762 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), Pinit, Qinit, Ap2, Ai2, CARG (Ax2,Az2) C1ARG(0)) ;
6763 	if (s != UMFPACK_OK) error ("50",0.);
6764 
6765 	/* ------------------------------------------------------------------ */
6766 
6767 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(DNULL,DNULL), Pinit, Qinit, Ap2, Ai2, CARG (DNULL,DNULL) C1ARG(0)) ;
6768 	if (s != UMFPACK_OK) error ("50e",0.);
6769 
6770 	/* ------------------------------------------------------------------ */
6771 
6772 	if (prl > 2) printf ("UMFPACK transpose test R = A(P,:)'\n") ;
6773 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), Pinit, INULL, Ap2, Ai2, CARG (Ax2,Az2) C1ARG(1)) ;
6774 	UMFPACK_report_status (Con, s) ;
6775 	UMFPACK_report_info (Con, Info) ;
6776 	if (s != UMFPACK_OK) error ("50",0.);
6777 	if (prl > 2) printf ("\nPinit: ") ;
6778 	s = UMFPACK_report_perm (n, Pinit, Con) ;
6779 	if (prl > 2) printf ("\nR: ") ;
6780 	s = UMFPACK_report_matrix (n , n, Ap2, Ai2, CARG (Ax2,Az2), 1, Con) ;
6781 	if (s != UMFPACK_OK) error ("50e",0.);
6782 	s = UMFPACK_col_to_triplet (n, Ap2, Aj) ;
6783 	if (s != UMFPACK_OK) error ("50i",0.);
6784 	if (prl > 2) printf ("\nR, triplet form: ") ;
6785 	s = UMFPACK_report_triplet (n, n, nz, Ai2, Aj, CARG(Ax2,Az2), Con) ;
6786 	if (s != UMFPACK_OK) error ("50y",0.);
6787 
6788 	/* ------------------------------------------------------------------ */
6789 
6790 	if (prl > 2) printf ("UMFPACK transpose test R = pattern of A(P,:).'\n") ;
6791 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(DNULL,DNULL), Pinit, INULL, Ap2, Ai2, CARG (DNULL,DNULL) C1ARG(0)) ;
6792 	UMFPACK_report_status (Con, s) ;
6793 	UMFPACK_report_info (Con, Info) ;
6794 	if (s != UMFPACK_OK) error ("50f",0.);
6795 	if (prl > 2) printf ("\npattern of R: ") ;
6796 	s = UMFPACK_report_matrix (n , n, Ap2, Ai2, CARG (DNULL,DNULL), 1, Con) ;
6797 	if (s != UMFPACK_OK) error ("50g",0.);
6798 	s = UMFPACK_col_to_triplet (n, Ap2, Aj) ;
6799 	if (s != UMFPACK_OK) error ("50k",0.);
6800 	if (prl > 2) printf ("\npattern of R, triplet form: ") ;
6801 	s = UMFPACK_report_triplet (n, n, nz, Ai2, Aj, CARG (DNULL,DNULL), Con) ;
6802 	if (s != UMFPACK_OK) error ("50z",0.);
6803 
6804 	/* ------------------------------------------------------------------ */
6805 
6806 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), INULL, INULL, Ap2, Ai2, CARG (Ax2,Az2) C1ARG(0)) ;
6807 	UMFPACK_report_status (Con, s) ;
6808 	if (s != UMFPACK_OK) error ("51a",0.);
6809 
6810 	/* ------------------------------------------------------------------ */
6811 
6812 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), Pinit, INULL, Ap2, Ai2, CARG (Ax2,Az2) C1ARG(0)) ;
6813 	UMFPACK_report_status (Con, s) ;
6814 	if (s != UMFPACK_OK) error ("51b",0.);
6815 
6816 	/* ------------------------------------------------------------------ */
6817 
6818 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), INULL, Qinit, Ap2, Ai2, CARG (Ax2,Az2) C1ARG(0)) ;
6819 	UMFPACK_report_status (Con, s) ;
6820 	if (s != UMFPACK_OK) error ("51c",0.);
6821 
6822 	/* ------------------------------------------------------------------ */
6823 
6824 	s = UMFPACK_transpose (0, 0, Ap, Ai, CARG(Ax,Az), Pinit, Qinit, Ap2, Ai2, CARG (Ax2,Az2) C1ARG(0)) ;
6825 	UMFPACK_report_status (Con, s) ;
6826 	if (s != UMFPACK_ERROR_n_nonpositive) error ("54",0.);
6827 
6828 	/* ------------------------------------------------------------------ */
6829 
6830 	c = Pinit [5] ;
6831 	Pinit [5] = n-1 ;
6832 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), Pinit, Qinit, Ap2, Ai2, CARG (Ax2,Az2) C1ARG(0)) ;
6833 	UMFPACK_report_status (Con, s) ;
6834 	if (s != UMFPACK_ERROR_invalid_permutation) error ("51e",0.);
6835 	Pinit [5] = c ;
6836 
6837 	/* ------------------------------------------------------------------ */
6838 
6839 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), Pinit, Qinit, Ap2, Ai2, CARG (Ax2,Az2) C1ARG(0)) ;
6840 	UMFPACK_report_status (Con, s) ;
6841 	if (s != UMFPACK_OK) error ("51d",0.);
6842 
6843 	/* ------------------------------------------------------------------ */
6844 
6845 	c = Pinit [5] ;
6846 	Pinit [5] = -1 ;
6847 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), Pinit, Qinit, Ap2, Ai2, CARG (Ax2,Az2) C1ARG(0)) ;
6848 	UMFPACK_report_status (Con, s) ;
6849 	if (s != UMFPACK_ERROR_invalid_permutation) error ("56",0.);
6850 	Pinit [5] = c ;
6851 
6852 	/* ------------------------------------------------------------------ */
6853 
6854 	s = UMFPACK_col_to_triplet (n, INULL, Aj) ;
6855 	if (s != UMFPACK_ERROR_argument_missing) error ("20b",0.) ;
6856 
6857 	/* ------------------------------------------------------------------ */
6858 
6859 	s = UMFPACK_col_to_triplet (0, Ap, Aj) ;
6860 	if (s != UMFPACK_ERROR_n_nonpositive) error ("20c",0.) ;
6861 
6862 	/* ------------------------------------------------------------------ */
6863 
6864 	Ap [0] = 99 ;
6865 	s = UMFPACK_col_to_triplet (n, Ap, Aj) ;
6866 	if (s != UMFPACK_ERROR_invalid_matrix) error ("20d",0.) ;
6867 	s = do_amd_transpose (n, Ap, Aj, Ap2, Ai2) ;
6868 	if (s != AMD_INVALID) error ("20d_amd",0.) ;
6869 	Ap [0] = 0 ;
6870 
6871 	/* ------------------------------------------------------------------ */
6872 
6873 	Ap [n] = 0 ;
6874 	s = UMFPACK_col_to_triplet (n, Ap, Aj) ;
6875 	if (s != UMFPACK_ERROR_invalid_matrix) error ("20e",0.) ;
6876 	Ap [n] = nz ;
6877 
6878 	/* ------------------------------------------------------------------ */
6879 
6880 	c = Ap [3] ;
6881 	Ap [3] = nz+1 ;
6882 	s = UMFPACK_col_to_triplet (n, Ap, Aj) ;
6883 	if (s != UMFPACK_ERROR_invalid_matrix) error ("20f",0.) ;
6884 	s = do_amd_transpose (n, Ap, Aj, Ap2, Ai2) ;
6885 	if (s != AMD_INVALID) error ("20f_amd",0.) ;
6886 	Ap [3] = c ;
6887 
6888 	/* ------------------------------------------------------------------ */
6889 
6890 	c = Aj [0] ;
6891 	Aj [0] = -1 ;
6892 	s = do_amd_transpose (n, Ap, Aj, Ap2, Ai2) ;
6893 	if (s != AMD_INVALID) error ("20z_amd",0.) ;
6894 	Aj [0] = c ;
6895 
6896 	/* ------------------------------------------------------------------ */
6897 
6898 	c = Ap [4] ;
6899 	Ap [4] = Ap [3]-1 ;
6900 	s = UMFPACK_col_to_triplet (n, Ap, Aj) ;
6901 	if (s != UMFPACK_ERROR_invalid_matrix) error ("20i",0.) ;
6902 	Ap [4] = c ;
6903 
6904 	/* ------------------------------------------------------------------ */
6905 
6906 	s = UMFPACK_col_to_triplet (n, Ap, Aj) ;
6907 	if (s != UMFPACK_OK) error ("20",0.) ;
6908 
6909 	/* ------------------------------------------------------------------ */
6910 
6911 	if (prl > 2) printf ("\nTriples OK: ") ;
6912 	s = UMFPACK_report_triplet (n, n, nz, Ai, Aj, CARG(Ax,Az), Con) ;
6913 	if (s != UMFPACK_OK) error ("21",0.) ;
6914 
6915 	/* ------------------------------------------------------------------ */
6916 
6917 	if (prl > 2) printf ("\nTriples pattern OK: ") ;
6918 	s = UMFPACK_report_triplet (n, n, nz, Ai, Aj, CARG(DNULL,DNULL), Con) ;
6919 	if (s != UMFPACK_OK) error ("21b",0.) ;
6920 
6921 	/* ------------------------------------------------------------------ */
6922 
6923 	if (prl > 2) printf ("\nTriples, Ai null: ") ;
6924 	s = UMFPACK_report_triplet (n, n, nz, INULL, Aj, CARG(Ax,Az), Con) ;
6925 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_argument_missing)) error ("22",0.) ;
6926 
6927 	/* ------------------------------------------------------------------ */
6928 
6929 	if (prl > 2) printf ("\nTriples, nz=0: ") ;
6930 	s = UMFPACK_report_triplet (n, n, 0, Ai, Aj, CARG(Ax,Az), Con) ;
6931 	if (s != UMFPACK_OK) error ("23a",0.) ;
6932 
6933 	if (prl > 2) printf ("\nTriples, nz=-1: ") ;
6934 	s = UMFPACK_report_triplet (n, n, -1, Ai, Aj, CARG(Ax,Az), Con) ;
6935 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_matrix)) error ("23",0.) ;
6936 
6937 	/* ------------------------------------------------------------------ */
6938 
6939 	if (prl > 2) printf ("\nTriples, n=0: ") ;
6940 	s = UMFPACK_report_triplet (0, 0, nz, Ai, Aj, CARG(Ax,Az), Con) ;
6941 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_n_nonpositive)) error ("24",0.) ;
6942 
6943 	/* ------------------------------------------------------------------ */
6944 
6945 	Map = (Int *) malloc (nz * sizeof (Int)) ;	/* [ */
6946 
6947 	c = Aj [1] ;
6948 	Aj [1] = -1 ;
6949 	if (prl > 2) printf ("\nTriples, Aj bad: ") ;
6950 	s = UMFPACK_report_triplet (n, n, nz, Ai, Aj, CARG(Ax,Az), Con) ;
6951 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_invalid_matrix)) error ("41",0.) ;
6952 
6953 	s = UMFPACK_triplet_to_col (n, n, nz, Ai, Aj, CARG(Ax,Az), Ap2, Ai2, CARG (Ax2,Az2), (Int *) NULL) ;
6954 	UMFPACK_report_status (Con, s) ;
6955 	if (s != UMFPACK_ERROR_invalid_matrix) error ("41",0.) ;
6956 
6957 	s = UMFPACK_triplet_to_col (n, n, nz, Ai, Aj, CARG(Ax,Az), Ap2, Ai2, CARG (Ax2,Az2), (Int *) NULL) ;
6958 	UMFPACK_report_status (Con, s) ;
6959 	if (s != UMFPACK_ERROR_invalid_matrix) error ("42",0.);
6960 
6961 	s = UMFPACK_triplet_to_col (n, n, nz, Ai, Aj, CARG(DNULL,DNULL), Ap2, Ai2, CARG (DNULL,DNULL), Map) ;
6962 	UMFPACK_report_status (Con, s) ;
6963 	if (s != UMFPACK_ERROR_invalid_matrix) error ("42cc",0.);
6964 
6965 	s = UMFPACK_triplet_to_col (n, n, nz, Ai, Aj, CARG(DNULL,DNULL), Ap2, Ai2, CARG (Ax2,Az2), (Int *) NULL) ;
6966 	UMFPACK_report_status (Con, s) ;
6967 	if (s != UMFPACK_ERROR_invalid_matrix) error ("42b",0.);
6968 	Aj [1] = c ;
6969 
6970 	/* ------------------------------------------------------------------ */
6971 
6972 	s = UMFPACK_triplet_to_col (n, n, nz, Ai, Aj, CARG(Ax,Az), Ap2, Ai2, CARG (Ax2,Az2), (Int *) NULL) ;
6973 	UMFPACK_report_status (Con, s) ;
6974 	if (s != UMFPACK_OK) error ("42c",0.);
6975 
6976 	s = UMFPACK_triplet_to_col (n, n, nz, Ai, Aj, CARG(Ax,Az), Ap2, Ai2, CARG (Ax2,Az2), Map) ;
6977 	UMFPACK_report_status (Con, s) ;
6978 	if (s != UMFPACK_OK) error ("42c.2",0.);
6979 
6980 	/* check the Map */
6981 	for (k = 0 ; k < nz ; k++)
6982 	{
6983 	    p = Map [k] ;
6984 	    i = Ai [k] ;
6985 	    j = Aj [k] ;
6986 	    if (i != Ai2 [p]) error ("Map Ai2.2", 0.) ;
6987 	    if (!(Ap2 [j] <= p && p < Ap2 [j+1])) error ("Map Ap2.2", 0.) ;
6988 	}
6989 
6990 	/* ------------------------------------------------------------------ */
6991 
6992 	s = UMFPACK_triplet_to_col (n, n, nz, Ai, Aj, CARG(DNULL,DNULL), Ap2, Ai2, CARG (Ax2,Az2), (Int *) NULL) ;
6993 	UMFPACK_report_status (Con, s) ;
6994 	if (s != UMFPACK_OK) error ("42d",0.);
6995 
6996 	s = UMFPACK_triplet_to_col (n, n, nz, Ai, Aj, CARG(DNULL,DNULL), Ap2, Ai2, CARG (Ax2,Az2), Map) ;
6997 	UMFPACK_report_status (Con, s) ;
6998 	if (s != UMFPACK_OK) error ("42d.1",0.);
6999 
7000 	/* check the Map */
7001 	for (k = 0 ; k < nz ; k++)
7002 	{
7003 	    p = Map [k] ;
7004 	    i = Ai [k] ;
7005 	    j = Aj [k] ;
7006 	    if (i != Ai2 [p]) error ("Map Ai2.1", 0.) ;
7007 	    if (!(Ap2 [j] <= p && p < Ap2 [j+1])) error ("Map Ap2.1", 0.) ;
7008 	}
7009 
7010 	c = Aj [1] ;
7011 	Aj [1] = -1 ;
7012 	s = UMFPACK_triplet_to_col (n, n, nz, Ai, Aj, CARG(Ax,Az), Ap2, Ai2, CARG (Ax2,Az2), Map) ;
7013 	UMFPACK_report_status (Con, s) ;
7014 	if (s != UMFPACK_ERROR_invalid_matrix) error ("42c.3",0.);
7015 	Aj [1] = c ;
7016 
7017 	free (Map) ;	/* ] */
7018 
7019 	/* ------------------------------------------------------------------ */
7020 
7021 	s = UMFPACK_triplet_to_col (0, 0, nz, Ai, Aj, CARG(Ax,Az), Ap2, Ai2, CARG (Ax2,Az2), (Int *) NULL) ;
7022 	UMFPACK_report_status (Con, s) ;
7023 	if (s != UMFPACK_ERROR_n_nonpositive) error ("44",0.);
7024 
7025 	/* ------------------------------------------------------------------ */
7026 
7027 	s = UMFPACK_triplet_to_col (n, n, 0, Ai, Aj, CARG(Ax,Az), Ap2, Ai2, CARG (Ax2,Az2), (Int *) NULL) ;
7028 	UMFPACK_report_status (Con, s) ;
7029 	if (s != UMFPACK_OK) error ("45a",0.);
7030 
7031 	if (prl > 2) printf ("\nall empty A2: ") ;
7032 	s = UMFPACK_report_matrix (n , n, Ap2, Ai2, CARG (Ax2,Az2), 1, Con) ;
7033 	if (s != UMFPACK_OK) error ("45c",0.) ;
7034 
7035 	/* ------------------------------------------------------------------ */
7036 
7037 	s = UMFPACK_triplet_to_col (n, n, -1, Ai, Aj, CARG(Ax,Az), Ap2, Ai2, CARG (Ax2,Az2), (Int *) NULL) ;
7038 	UMFPACK_report_status (Con, s) ;
7039 	if (s != UMFPACK_ERROR_invalid_matrix) error ("45",0.);
7040 
7041 	/* ------------------------------------------------------------------ */
7042 
7043 	s = UMFPACK_triplet_to_col (n, n, nz, INULL, Aj, CARG(Ax,Az), Ap2, Ai2, CARG (Ax2,Az2), (Int *) NULL) ;
7044 	UMFPACK_report_status (Con, s) ;
7045 	if (s != UMFPACK_ERROR_argument_missing) error ("46",0.);
7046 
7047 	/* ------------------------------------------------------------------ */
7048 
7049 	free (Az2) ;	/* ] */
7050 	free (Ax2) ;	/* ] */
7051 	free (Ai2) ;	/* ] */
7052 	free (Aj) ;	/* ] */
7053 
7054 	free (Az) ;	/* ] */
7055 	free (Ax) ;	/* ] */
7056 	free (Ai) ;	/* ] */
7057 	free (Ap) ;	/* ] */
7058 
7059 
7060 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
7061 	if (UMF_malloc_count != 0) error ("umfpack memory leak!!",0.) ;
7062 #endif
7063 
7064 	printf ("\n]]]]\n\n\n") ;
7065 
7066       }
7067     }
7068 
7069     free (Ap2) ;	/* ] */
7070     free (xz) ;		/* ] */
7071     free (x) ;		/* ] */
7072     free (bz) ;		/* ] */
7073     free (b) ;		/* ] */
7074     free (Qinit2) ;	/* ] */
7075     free (Pinit) ;	/* ] */
7076     free (Qinit) ;	/* ] */
7077     free (Pamd) ;	/* ] */
7078 
7079     /* ---------------------------------------------------------------------- */
7080     /* reset rand ( ) */
7081     /* ---------------------------------------------------------------------- */
7082 
7083     srand (1) ;
7084 
7085     /* ---------------------------------------------------------------------- */
7086     /* test memory allocation */
7087     /* ---------------------------------------------------------------------- */
7088 
7089     n = 200 ;
7090 
7091     printf ("memory test\n") ;
7092 
7093 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
7094     if (UMF_malloc_count != 0) error ("umfpack mem test starts memory leak!!\n",0.) ;
7095 #endif
7096 
7097     matgen_sparse (n, 8*n, 0, 0, 4, 2*n, &Ap, &Ai, &Ax, &Az, 1, 0) ;	/* [[[[ */
7098     Qinit = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
7099     b = (double *) malloc (n * sizeof (double)) ;	/* [ */
7100     bz= (double *) calloc (n , sizeof (double)) ;	/* [ */
7101     x = (double *) malloc (n * sizeof (double)) ;	/* [ */
7102     xz= (double *) calloc (n , sizeof (double)) ;	/* [ */
7103     bgen (n, Ap, Ai, Ax,Az, b,bz) ;
7104 
7105     nz = Ap [n] ;
7106 
7107     randperm (n, Qinit) ;
7108 
7109     UMFPACK_defaults (Control) ;
7110 
7111     for (prl = 5 ; prl >= -1 ; prl--)
7112     {
7113 
7114 	printf ("prl "ID" memtest\n", prl) ;
7115 	fflush (stdout) ;
7116 
7117 	umf_realloc_fail = -1 ;
7118 	umf_realloc_hi = 0 ;
7119 	umf_realloc_lo = 0 ;
7120 
7121 	umf_fail_hi = 0 ;
7122 	umf_fail_lo = 0 ;
7123 	Control [UMFPACK_PRL] = (Int) prl ;
7124 
7125 	umf_fail = 1 ;
7126 	if (prl > 2) printf ("Memfail Qinit: ") ;
7127 	s = UMFPACK_report_perm (n, Qinit, Control) ;
7128 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_out_of_memory)) error ("101",0.) ;
7129 
7130 	Cp = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
7131 	Cj = (Int *) malloc (nz * sizeof (Int)) ;		/* [ */
7132 	Ci = (Int *) malloc (nz * sizeof (Int)) ;		/* [ */
7133 	Cx = (double *) malloc (nz * sizeof (double)) ;		/* [ */
7134 	Cz = (double *) calloc (nz , sizeof (double)) ;		/* [ */
7135 	Bp = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
7136 	Bj = (Int *) malloc (nz * sizeof (Int)) ;		/* [ */
7137 	Bi = (Int *) malloc (nz * sizeof (Int)) ;		/* [ */
7138 	Bx = (double *) malloc (nz * sizeof (double)) ;		/* [ */
7139 	Bz = (double *) calloc (nz , sizeof (double)) ;		/* [ */
7140 	Map = (Int *) malloc (nz * sizeof (Int)) ;		/* [ */
7141 	if (!Cp || !Ci || !Cx || !Cj) error ("out of memory (23)",0.) ;
7142 	if (!Bp || !Bi || !Bx || !Bj) error ("out of memory (24)",0.) ;
7143 	if (!Bz || !Cz) error ("out of memory (25)",0.) ;
7144 
7145 	umf_fail = 1 ;
7146 	s = UMFPACK_transpose (n, n, Ap, Ai, CARG(Ax,Az), INULL, INULL, Cp, Ci, CARG(Cx,Cz) C1ARG(0)) ;
7147 	if (s != UMFPACK_ERROR_out_of_memory) error ("113", 0.) ;
7148 
7149 	for (k = 0 ; k < nz ; k++)
7150 	{
7151 	    Ci [k] = irand (n) ;
7152 	    Cj [k] = irand (n) ;
7153 	    Cx [k] = 2.0 * (xrand ( ) - 1.0) ;
7154 #ifdef COMPLEX
7155 	    Cx [k] = 2.0 * (xrand ( ) - 1.0) ;
7156 #else
7157 	    Cx [k] = 0. ;
7158 #endif
7159 	}
7160 
7161 	for (i = 1 ; i <= 4 ; i++)
7162 	{
7163 	    umf_fail = i ;
7164 	    s = UMFPACK_triplet_to_col (n, n, nz, Ci, Cj, CARG(DNULL,DNULL), Bp, Bi, CARG(DNULL,DNULL), (Int *) NULL) ;
7165 	    UMFPACK_report_status (Con, s) ;
7166 	    if (s != UMFPACK_ERROR_out_of_memory) error ("114", (double) i) ;
7167 	}
7168 
7169 
7170 	for (i = 1 ; i <= 5 ; i++)
7171 	{
7172 	    umf_fail = i ;
7173 	    s = UMFPACK_triplet_to_col (n, n, nz, Ci, Cj, CARG(Cx,Cz), Bp, Bi, CARG(Bx,Bz), (Int *) NULL) ;
7174 	    UMFPACK_report_status (Con, s) ;
7175 	    if (s != UMFPACK_ERROR_out_of_memory) error ("115", (double) i) ;
7176 	}
7177 
7178 	for (i = 1 ; i <= 5 ; i++)
7179 	{
7180 	    umf_fail = i ;
7181 	    s = UMFPACK_triplet_to_col (n, n, nz, Ci, Cj, CARG(DNULL,DNULL), Bp, Bi, CARG(DNULL,DNULL), Map) ;
7182 	    UMFPACK_report_status (Con, s) ;
7183 	    if (s != UMFPACK_ERROR_out_of_memory) error ("114", (double) i) ;
7184 	}
7185 
7186 
7187 	for (i = 1 ; i <= 6 ; i++)
7188 	{
7189 	    umf_fail = i ;
7190 	    s = UMFPACK_triplet_to_col (n, n, nz, Ci, Cj, CARG(Cx,Cz), Bp, Bi, CARG(Bx,Bz), Map) ;
7191 	    UMFPACK_report_status (Con, s) ;
7192 	    if (s != UMFPACK_ERROR_out_of_memory) error ("115", (double) i) ;
7193 	}
7194 
7195 	free (Map) ;	/* ] */
7196 	free (Bz) ;	/* ] */
7197 	free (Bx) ;	/* ] */
7198 	free (Bi) ;	/* ] */
7199 	free (Bj) ;	/* ] */
7200 	free (Bp) ;	/* ] */
7201 	free (Cz) ;	/* ] */
7202 	free (Cx) ;	/* ] */
7203 	free (Ci) ;	/* ] */
7204 	free (Cj) ;	/* ] */
7205 	free (Cp) ;	/* ] */
7206 
7207 	for (i = 1 ; i <= 24 ; i++)
7208 	{
7209 	    umf_fail = i ;
7210 	    printf ("umf_fail starts at %d\n", umf_fail) ;
7211 	    fflush (stdout) ;
7212 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
7213 	    if (UMF_malloc_count != 0) error ("umfpack mem test starts memory leak!!\n",0.) ;
7214 #endif
7215 	    s = UMFPACK_symbolic (n, n, Ap, Ai, CARG(Ax,Az), &Symbolic, Control, Info) ;
7216 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
7217 	    UMFPACK_report_status (Control, s) ;
7218 	    UMFPACK_report_info (Control, Info) ;
7219 	    if (Symbolic || Info [UMFPACK_STATUS] != UMFPACK_ERROR_out_of_memory) error ("104", (double) i) ;
7220 	}
7221 
7222 	umf_fail = 25 ;
7223 	s = UMFPACK_qsymbolic (n, n, Ap, Ai, CARG(Ax,Az), Qinit, &Symbolic, Control, Info) ;	/* [ */
7224 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
7225 	UMFPACK_report_status (Control, s) ;
7226 	UMFPACK_report_info (Control, Info) ;
7227 	if (!Symbolic || s != UMFPACK_OK) error ("105", 0.) ;
7228 
7229 	umf_fail = 1 ;
7230 	if (prl > 2) printf ("\nMemfail Symbolic: ") ;
7231 	s = UMFPACK_report_symbolic (Symbolic, Control) ;
7232 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_out_of_memory)) error ("102",0.) ;
7233 
7234 	/* alloc reallocs succeed */
7235 	umf_realloc_fail = -1 ;
7236 	umf_realloc_hi = 0 ;
7237 	umf_realloc_lo = 0 ;
7238 
7239 	/* Initial Numeric->Memory allocation fails when umf_fail is 28, and never succeeds.
7240 	 * All mallocs succeed if umf_fail is 16 + 11 + 1 */
7241 	umf_fail_lo = -9999999 ;
7242 	for (i = 1 ; i <= 29 ; i++)
7243 	{
7244 	    umf_fail = i ;
7245 	    printf ("\nDoing numeric, umf_fail = %d\n", umf_fail) ;
7246 	    s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Control, Info) ;
7247 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
7248 	    UMFPACK_report_status (Control, s) ;
7249 	    UMFPACK_report_info (Control, Info) ;
7250 	    if (i < 29)
7251 	    {
7252 		if (Numeric || s != UMFPACK_ERROR_out_of_memory) error ("106", (double) i) ;
7253 	    }
7254 	    else
7255 	    {
7256 		if (!Numeric || s != UMFPACK_OK) error ("106z", (double) umf_fail) ;
7257 		UMFPACK_free_numeric (&Numeric) ;
7258 	    }
7259 	}
7260 
7261 
7262 	/* everything succeeds, use a small alloc_init */
7263 	printf ("106y:\n") ;
7264 	Control [UMFPACK_ALLOC_INIT] = -30000 ;
7265 	UMFPACK_report_control (Control) ;
7266 	umf_fail = 29 ;
7267 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Control, Info) ;
7268 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
7269 	UMFPACK_report_status (Control, s) ;
7270 	UMFPACK_report_info (Control, Info) ;
7271 	if (!Numeric || s != UMFPACK_OK) error ("106y", (double) umf_fail) ;
7272 	UMFPACK_free_numeric (&Numeric) ;
7273 
7274 	/* all malloc's succeed - no realloc during factorization */
7275 	umf_fail = -1 ;
7276 	umf_fail_lo = 0 ;
7277 	umf_fail_hi = 0 ;
7278 	umf_realloc_fail = 1 ;
7279 	umf_realloc_hi = 0 ;
7280 	umf_realloc_lo = -9999999 ;
7281 
7282 	/* restore Control */
7283 	UMFPACK_defaults (Control) ;
7284 	Control [UMFPACK_PRL] = (Int) prl ;
7285 
7286 	/* alloc init the smallest size */
7287 	Control [UMFPACK_ALLOC_INIT] = 0.0 ;
7288 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Control, Info) ;
7289 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
7290 	UMFPACK_report_status (Control, s) ;
7291 	UMFPACK_report_info (Control, Info) ;
7292 
7293 	if (Numeric)
7294 	{
7295 	    UMFPACK_free_numeric (&Numeric) ;
7296 	    printf ("107 succeeded\n") ;
7297 	}
7298 
7299 	/* initial allocation fails once, retry succeeds */
7300 	umf_realloc_fail = 1 ;
7301 	umf_realloc_hi = 0 ;
7302 	umf_realloc_lo = -2 ;
7303 	s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Control, Info) ;	/* ( */
7304 	if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
7305 	UMFPACK_report_status (Control, s) ;
7306 	UMFPACK_report_info (Control, Info) ;
7307 	if (!Numeric || s != UMFPACK_OK) error ("110", (double) umf_fail) ;
7308 
7309 	/* all reallocs succeed */
7310 	umf_realloc_fail = -1 ;
7311 	umf_realloc_hi = 0 ;
7312 	umf_realloc_lo = 0 ;
7313 
7314 	UMFPACK_free_symbolic (&Symbolic) ;		/* ] */
7315 
7316 	umf_fail = 1 ;
7317 	if (prl > 2) printf ("Memfail Numeric: ") ;
7318 	s = UMFPACK_report_numeric (Numeric, Control) ;
7319 	if (s != ((prl <= 2) ? UMFPACK_OK : UMFPACK_ERROR_out_of_memory)) error ("108",0.) ;
7320 
7321 	for (i = 1 ; i <= 2 ; i++)
7322 	{
7323 	    umf_fail = i ;
7324 	    printf ("\nTest 109, %d\n", umf_fail) ;
7325 	    s = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info) ;
7326 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
7327 	    UMFPACK_report_status (Control, s) ;
7328 	    UMFPACK_report_info (Control, Info) ;
7329 	    if (s != UMFPACK_ERROR_out_of_memory) error ("109", (double) i) ;
7330 	}
7331 
7332 	for (i = 1 ; i <= 2 ; i++)
7333 	{
7334 	    umf_fail = i ;
7335 	    s = UMFPACK_solve (UMFPACK_L, Ap, Ai, CARG(Ax,Az), CARG(x,xz), CARG(b,bz), Numeric, Control, Info) ;
7336 	    if (s != Info [UMFPACK_STATUS]) error ("huh", (double) __LINE__)  ;
7337 	    UMFPACK_report_status (Control, s) ;
7338 	    UMFPACK_report_info (Control, Info) ;
7339 	    if (s != UMFPACK_ERROR_out_of_memory) error ("109b", (double) i) ;
7340 	}
7341 
7342 	s = UMFPACK_get_lunz (&lnz, &unz, &nnrow, &nncol, &nzud, Numeric) ;
7343 	if (s != UMFPACK_OK) error ("111", 0.) ;
7344 
7345 	Rs = (double *) malloc ((n+1) * sizeof (double)) ;	/* [ */
7346 	Lp = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
7347 	Li = (Int *) malloc ((lnz+1) * sizeof (Int)) ;		/* [ */
7348 	Lx = (double *) malloc ((lnz+1) * sizeof (double)) ;	/* [ */
7349 	Lz = (double *) calloc ((lnz+1) , sizeof (double)) ;	/* [ */
7350 	Up = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
7351 	Ui = (Int *) malloc ((unz+1) * sizeof (Int)) ;		/* [ */
7352 	Ux = (double *) malloc ((unz+1) * sizeof (double)) ;	/* [ */
7353 	Uz = (double *) calloc ((unz+1) , sizeof (double)) ;	/* [ */
7354 	P = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
7355 	Q = (Int *) malloc ((n+1) * sizeof (Int)) ;		/* [ */
7356 	if (!Lp || !Li || !Lx || !Up || !Ui || !Ux || !P || !Q) error ("out of memory (26)",0.) ;
7357 	if (!Lz || !Uz) error ("out of memory (27)",0.) ;
7358 
7359 	for (i = 1 ; i <= 2 ; i++)
7360 	{
7361 	    umf_fail = i ;
7362 	    s = UMFPACK_get_numeric (Lp, Li, CARG(Lx,Lz), Up, Ui, CARG(Ux,Uz), P, Q, CARG(DNULL,DNULL), &do_recip, Rs, Numeric) ;
7363 	    if (s != UMFPACK_ERROR_out_of_memory) error ("112", (double) i) ;
7364 	}
7365 
7366 	umf_fail = 1 ;
7367 	s = UMFPACK_get_determinant (CARG (&Mx, &Mz), &Exp, Numeric, Info) ;
7368 	if (s != Info [UMFPACK_STATUS])
7369 	{
7370 	    printf ("s "ID" %g\n", s, Info [UMFPACK_STATUS]) ;
7371 	    error ("huh", (double) __LINE__)  ;
7372 	}
7373 	if (s != UMFPACK_ERROR_out_of_memory) error ("73det",0.) ;
7374 
7375 	UMFPACK_free_numeric (&Numeric) ;		/* ) */
7376 
7377 	free (Q) ;		/* ] */
7378 	free (P) ;		/* ] */
7379 	free (Uz) ;		/* ] */
7380 	free (Ux) ;		/* ] */
7381 	free (Ui) ;		/* ] */
7382 	free (Up) ;		/* ] */
7383 	free (Lz) ;		/* ] */
7384 	free (Lx) ;		/* ] */
7385 	free (Li) ;		/* ] */
7386 	free (Lp) ;		/* ] */
7387 	free (Rs) ;		/* ] */
7388 
7389 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
7390 	if (UMF_malloc_count != 0) error ("umfpack memory test leak!!\n",0.) ;
7391 #endif
7392 
7393     }
7394 
7395     free (xz) ;		/* ] */
7396     free (x) ;		/* ] */
7397     free (bz) ;		/* ] */
7398     free (b) ;		/* ] */
7399     free (Qinit) ;	/* ] */
7400     free (Ap) ;		/* ] */
7401     free (Ai) ;		/* ] */
7402     free (Ax) ;		/* ] */
7403     free (Az) ;		/* ] */
7404 
7405     /* ---------------------------------------------------------------------- */
7406     /* NaN/Inf */
7407     /* ---------------------------------------------------------------------- */
7408 
7409     umf_fail = -1 ;
7410     umf_fail_lo = 0 ;
7411     umf_fail_hi = 0 ;
7412     umf_realloc_fail = -1 ;
7413     umf_realloc_lo = 0 ;
7414     umf_realloc_hi = 0 ;
7415 
7416     printf ("matrices with NaN/Infs:\n") ;
7417     n = 100 ;
7418     for (k = 0 ; k <= 100 ; k++)
7419     {
7420 	printf ("NaN/Inf "ID" 4*n nz's, k= "ID"\n", n, k) ;
7421 	matgen_sparse (n, 4*n, 0, 0, 0, 0, &Ap, &Ai, &Ax, &Az, 1, 1) ; /* [[[[  */
7422 	if (k == 100)
7423 	{
7424 	    /* make a matrix of all NaN's */
7425 	    for (i = 0 ; i < Ap [n] ; i++)
7426 	    {
7427 		Ax [i] = xnan ;
7428 #ifdef COMPLEX
7429 		Az [i] = xnan ;
7430 #endif
7431 	    }
7432 	}
7433 	b  = (double *) malloc (n * sizeof (double)) ;	/* [ */
7434 	bz = (double *) malloc (n * sizeof (double)) ;	/* [ */
7435 	bgen (n, Ap, Ai, Ax, Az, b, bz) ;
7436 	x  = (double *) malloc (n * sizeof (double)) ;	/* [ */
7437 	xz = (double *) malloc (n * sizeof (double)) ;	/* [ */
7438 	for (prl = 2 ; prl >= -1 ; prl--)
7439 	{
7440 	    printf ("NaN / Inf matrix: \n") ;
7441 	    UMFPACK_defaults (Control) ;
7442 	    Control [UMFPACK_PRL] = prl ;
7443 	    for (scale = UMFPACK_SCALE_NONE ; scale <= UMFPACK_SCALE_MAX ; scale++)
7444 	    {
7445 		Control [UMFPACK_SCALE] = scale ;
7446 		Con = (prl == -1) ? (DNULL) : Control ;
7447 		UMFPACK_report_control (Con) ;
7448 
7449 		s = UMFPACK_symbolic (n, n, Ap, Ai, CARG(Ax,Az), &Symbolic, Con, Info) ;	/* [ */
7450 		UMFPACK_report_status (Con, s) ;
7451 		UMFPACK_report_info (Con, Info) ;
7452 		if (!(s == UMFPACK_OK || s == UMFPACK_WARNING_singular_matrix)) error ("887", 0.) ;
7453 
7454 		s = UMFPACK_numeric (Ap, Ai, CARG(Ax,Az), Symbolic, &Numeric, Con, Info) ;	/* [ */
7455 		UMFPACK_report_status (Con, s) ;
7456 		UMFPACK_report_info (Con, Info) ;
7457 		if (!(s == UMFPACK_OK || s == UMFPACK_WARNING_singular_matrix)) error ("888", 0.) ;
7458 
7459 		s = UMFPACK_solve (UMFPACK_A, Ap, Ai, CARG(Ax,Az) , CARG(x,xz), CARG(b,bz), Numeric, Con, Info) ;
7460 		UMFPACK_report_status (Con, s) ;
7461 		UMFPACK_report_info (Con, Info) ;
7462 		if (!(s == UMFPACK_OK || s == UMFPACK_WARNING_singular_matrix)) error ("889", 0.) ;
7463 
7464 		UMFPACK_free_numeric (&Numeric) ;	/* ] */
7465 		UMFPACK_free_symbolic (&Symbolic) ;	/* ] */
7466 	    }
7467 	}
7468 	free (xz) ;	/* ] */
7469 	free (x) ;	/* ] */
7470 	free (bz) ;	/* ] */
7471 	free (b) ;	/* ] */
7472 	free (Az) ;	/* ] */
7473 	free (Ax) ;	/* ] */
7474 	free (Ai) ;	/* ] */
7475 	free (Ap) ;	/* ] */
7476     }
7477 
7478 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
7479     if (UMF_malloc_count != 0) error ("umfpack memory leak!!\n",0.) ;
7480 #endif
7481 
7482 
7483     /* ---------------------------------------------------------------------- */
7484     /* reset rand ( ) */
7485     /* ---------------------------------------------------------------------- */
7486 
7487     srand (1) ;
7488 
7489     /* ---------------------------------------------------------------------- */
7490     /* test report routines */
7491     /* ---------------------------------------------------------------------- */
7492 
7493     n = 32 ;
7494     printf ("\n so far: rnorm %10.4e %10.4e\n", rnorm, maxrnorm) ;
7495 
7496     Qinit = (Int *) malloc (n * sizeof (Int)) ;		/* [ */
7497     b = (double *) malloc (n * sizeof (double)) ;	/* [ */
7498     bz= (double *) calloc (n , sizeof (double)) ;	/* [ */
7499     if (!Qinit || !b || !bz) error ("out of memory (28)",0.) ;
7500     UMFPACK_defaults (Control) ;
7501 
7502     for (prl = 5 ; prl >= 0 ; prl--)
7503     {
7504 	printf ("\n[[[[ PRL = "ID"\n", prl) ;
7505 	Control [UMFPACK_PRL] = prl ;
7506 
7507 	i = UMFPACK_DENSE_DEGREE_THRESHOLD (0.2, n) ;
7508 	printf ("(default) dense row/col degree threshold: "ID"\n", i) ;
7509 
7510 	matgen_sparse (n, 12*n, 0, 0, 0, 0, &Ap, &Ai, &Ax, &Az, prl, 0) ; /* [[[[ */
7511 	bgen (n, Ap, Ai, Ax,Az, b,bz) ;
7512 
7513 	/* also test NaN/Inf handling in solvers */
7514 	b [16] = xnan ;
7515 	b [15] = xinf ;
7516 
7517 	/* test col->triplet and triplet->col */
7518 	test_col (n, Ap, Ai, Ax,Az, prl) ;
7519 	rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, Control, INULL, MemOK, FALSE, FALSE, 0., 0.) ;
7520 	printf ("\nrnorm %10.4e %10.4e\n", rnorm, maxrnorm) ;
7521 	randperm (n, Qinit) ;
7522 	rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, Control, Qinit, MemOK, FALSE, FALSE, 0., 0.) ;
7523 	printf ("\nrnorm %10.4e %10.4e\n", rnorm, maxrnorm) ;
7524 	free (Ap) ;	/* ] */
7525 	free (Ai) ;	/* ] */
7526 	free (Ax) ;	/* ] */
7527 	free (Az) ;	/* ] */
7528 	printf ("\n]]]]\n\n\n") ;
7529     }
7530 
7531     /* ---------------------------------------------------------------------- */
7532     /* reset rand ( ) */
7533     /* ---------------------------------------------------------------------- */
7534 
7535     srand (1) ;
7536 
7537     /* test report with more than 10 dense columns */
7538     UMFPACK_defaults (Control) ;
7539 
7540     printf ("\nrnorm %10.4e %10.4e\n", rnorm, maxrnorm) ;
7541     Control [UMFPACK_PRL] = 4 ;
7542     printf ("\nreport dense matrix with n = "ID"\n", n) ;
7543     matgen_dense (n, &Ap, &Ai, &Ax, &Az) ; /* [[[[ */
7544     bgen (n, Ap, Ai, Ax,Az, b,bz) ;
7545     rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, Control, Qinit, MemOK, FALSE, FALSE, 0., 0.) ;
7546     maxrnorm = MAX (rnorm, maxrnorm) ;
7547     printf ("\nrnorm %10.4e %10.4e\n", rnorm, maxrnorm) ;
7548     free (Ap) ;	/* ] */
7549     free (Ai) ;	/* ] */
7550     free (Ax) ;	/* ] */
7551     free (Az) ;	/* ] */
7552 
7553     free (bz) ;		/* ] */
7554     free (b) ;		/* ] */
7555     free (Qinit) ;	/* ] */
7556 
7557     Control [UMFPACK_PRL] = 5 ;
7558 
7559     /* ---------------------------------------------------------------------- */
7560     /* reset rand ( ) */
7561     /* ---------------------------------------------------------------------- */
7562 
7563     srand (1) ;
7564 
7565     /* ---------------------------------------------------------------------- */
7566     /* test random sparse matrices */
7567     /* ---------------------------------------------------------------------- */
7568 
7569     n = 30 ;
7570 
7571 	printf ("sparse "ID" 4*n nz's", n) ;
7572 	matgen_sparse (n, 4*n, 0, 0, 0, 0, &Ap, &Ai, &Ax, &Az, 1, 0) ;	/* [[[[ */
7573 	rnorm = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemOK, 1) ; /* ]]]] */
7574 	maxrnorm = MAX (rnorm, maxrnorm) ;
7575 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7576 
7577     n = 200 ;
7578 
7579 	printf ("sparse "ID" 4*n nz's", n) ;
7580 	matgen_sparse (n, 4*n, 0, 0, 0, 0, &Ap, &Ai, &Ax, &Az, 1, 0) ;	/* [[[[ */
7581 
7582 	/*
7583 	rnorm = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemOK, 1) ;
7584 	*/
7585 
7586 	UMFPACK_defaults (Control) ;
7587 	Control [UMFPACK_DENSE_COL] = 0.883883 ;
7588 	Control [UMFPACK_DENSE_ROW] = 0.883883 ;
7589 	Control [UMFPACK_AMD_DENSE] = 10 ;
7590 	Control [UMFPACK_PIVOT_TOLERANCE] = 0.5 ;
7591 	Control [UMFPACK_BLOCK_SIZE] = 1 ;
7592 	Control [UMFPACK_ALLOC_INIT] = 0 ;
7593 	Control [UMFPACK_SCALE] = 0 ;
7594 	Control [UMFPACK_STRATEGY] = 3 ;
7595 	Control [UMFPACK_FIXQ] = 1 ;
7596 
7597 	b = (double *) malloc (n * sizeof (double)) ;	/* [ */
7598 	bz= (double *) calloc (n , sizeof (double)) ;	/* [ */
7599 	if (!b || !bz) error ("out of memory (29)",0.) ;
7600 	bgen (n, Ap, Ai, Ax, Az, b, bz) ;
7601 
7602 	rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, Control, INULL, MemOK, FALSE, FALSE, 0., 0.) ;
7603 
7604 	UMFPACK_defaults (Control) ;
7605 	Control [UMFPACK_FRONT_ALLOC_INIT] = -10 ;
7606 	Control [UMFPACK_PRL] = 2 ;
7607 
7608 	printf ("negative front alloc init\n") ;
7609 	rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, Control, INULL, MemOK, FALSE, FALSE, 0., 0.) ;
7610 
7611 	Control [UMFPACK_FRONT_ALLOC_INIT] = -10 ;
7612 	Control [UMFPACK_STRATEGY] = UMFPACK_STRATEGY_SYMMETRIC ;
7613 	Control [UMFPACK_AMD_DENSE] = -1 ;
7614 
7615 	printf ("symmetric strategy, no dense rows/cols\n") ;
7616 	rnorm = do_many (n, n, Ap, Ai, Ax,Az, b,bz, Control, INULL, MemOK, FALSE, FALSE, 0., 0.) ;
7617 
7618 	free (bz) ;	/* ] */
7619 	free (b) ;	/* ] */
7620 	free (Ap) ;	/* ] */
7621 	free (Ai) ;	/* ] */
7622 	free (Ax) ;	/* ] */
7623 	free (Az) ;	/* ] */
7624 
7625 	maxrnorm = MAX (rnorm, maxrnorm) ;
7626 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7627 
7628     /* ---------------------------------------------------------------------- */
7629     /* reset rand ( ) */
7630     /* ---------------------------------------------------------------------- */
7631 
7632     srand (1) ;
7633 
7634 #if 0
7635 
7636 
7637     n = 200 ;
7638 
7639 	printf ("sparse %7d few nz's", n) ;
7640 	matgen_sparse (n, 20, 0, 0, 0, 0, &Ap, &Ai, &Ax, &Az, 1, 0) ;
7641 	rnorm = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemOK, 1) ;
7642 	maxrnorm = MAX (rnorm, maxrnorm) ;
7643 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7644 
7645 
7646     /* ---------------------------------------------------------------------- */
7647     /* test random sparse matrices + 4 dense rows */
7648     /* ---------------------------------------------------------------------- */
7649 
7650     n = 100 ;
7651 
7652 	printf ("sparse+dense rows %7d ", n) ;
7653 	matgen_sparse (n, 4*n, 4, 2*n, 0, 0, &Ap, &Ai, &Ax, &Az, 1, 0) ;
7654 	rnorm = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemOK, 1) ;
7655 	maxrnorm = MAX (rnorm, maxrnorm) ;
7656 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7657 
7658 
7659     /* ---------------------------------------------------------------------- */
7660     /* reset rand ( ) */
7661     /* ---------------------------------------------------------------------- */
7662 
7663     srand (1) ;
7664 
7665     /* ---------------------------------------------------------------------- */
7666     /* test random sparse matrices + 4 dense rows & cols */
7667     /* ---------------------------------------------------------------------- */
7668 
7669     n = 100 ;
7670 
7671     /* reduce the number of controls - otherwise this takes too much time */
7672 
7673     c = UMFPACK_BLOCK_SIZE ;
7674     Controls [c][0] = UMFPACK_DEFAULT_BLOCK_SIZE ;
7675     Ncontrols [c] = 1 ;
7676 
7677     c = UMFPACK_ALLOC_INIT ;
7678     Controls [c][0] = 1.0 ;
7679     Ncontrols [c] = 1 ;
7680 
7681 	printf ("sparse+dense rows and cols %7d ", n) ;
7682 	matgen_sparse (n, 4*n, 4, 2*n, 4, 2*n, &Ap, &Ai, &Ax, &Az, 1, 0) ;
7683 	rnorm = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemOK, 1) ;
7684 	maxrnorm = MAX (rnorm, maxrnorm) ;
7685 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7686 
7687     c = UMFPACK_BLOCK_SIZE ;
7688     Controls [c][0] = 1 ;
7689     Controls [c][1] = 8 ;
7690     Controls [c][2] = UMFPACK_DEFAULT_BLOCK_SIZE ;
7691     Ncontrols [c] = 3 ;
7692 
7693     c = UMFPACK_ALLOC_INIT ;
7694     Controls [c][0] = 0.0 ;
7695     Controls [c][1] = 0.5 ;
7696     Controls [c][2] = 1.0 ;	/* not the default */
7697     Ncontrols [c] = 3 ;
7698 
7699     n = 100 ;
7700 
7701 	printf ("very sparse+dense cols %7d ", n) ;
7702 	matgen_sparse (n, 2, 0, 0, 4, 2*n, &Ap, &Ai, &Ax, &Az, 1, 0) ;
7703 	rnorm = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemOK, 1) ;
7704 	maxrnorm = MAX (rnorm, maxrnorm) ;
7705 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7706 
7707 
7708     /* ---------------------------------------------------------------------- */
7709     /* test all diagonal matrices */
7710     /* ---------------------------------------------------------------------- */
7711 
7712     for (n = 1 ; n < 16 ; n++)
7713     {
7714 	printf ("diagonal %7d ", n) ;
7715 	matgen_band (n, 0, 0, 0, 0, 0, 0, &Ap, &Ai, &Ax, &Az) ;
7716 	rnorm = do_and_free (n, Ap, Ai, Ax, Az, Controls, Ncontrols, MemOK, 1) ;
7717 	maxrnorm = MAX (rnorm, maxrnorm) ;
7718 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7719     }
7720 
7721     for (n = 100 ; n <= 500 ; n += 100)
7722     {
7723 	printf ("diagonal %7d ", n) ;
7724 	matgen_band (n, 0, 0, 0, 0, 0, 0, &Ap, &Ai, &Ax, &Az) ;
7725 	rnorm = do_and_free (n, Ap, Ai, Ax,Az, Controls, Ncontrols, MemOK, 1) ;
7726 	maxrnorm = MAX (rnorm, maxrnorm) ;
7727 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7728     }
7729 
7730     /* ---------------------------------------------------------------------- */
7731     /* test all tri-diagonal matrices */
7732     /* ---------------------------------------------------------------------- */
7733 
7734     for (n = 1 ; n < 16 ; n++)
7735     {
7736 	printf ("tri-diagonal %7d ", n) ;
7737 	matgen_band (n, 1, 1, 0, 0, 0, 0, &Ap, &Ai, &Ax, &Az) ;
7738 	rnorm = do_and_free (n, Ap, Ai, Ax,Az, Controls, Ncontrols, MemOK, 1) ;
7739 	maxrnorm = MAX (rnorm, maxrnorm) ;
7740 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7741     }
7742 
7743     for (n = 100 ; n <= 500 ; n += 100)
7744     {
7745 	printf ("tri-diagonal %7d ", n) ;
7746 	matgen_band (n, 1, 1, 0, 0, 0, 0, &Ap, &Ai, &Ax, &Az) ;
7747 	rnorm = do_and_free (n, Ap, Ai, Ax,Az, Controls, Ncontrols, MemOK, 1) ;
7748 	maxrnorm = MAX (rnorm, maxrnorm) ;
7749 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7750     }
7751 
7752     /* ---------------------------------------------------------------------- */
7753     /* test all tri-diagonal matrices + one "dense" row */
7754     /* ---------------------------------------------------------------------- */
7755 
7756     n = 100 ;
7757 
7758 	printf ("tri-diagonal+dense row %7d ", n) ;
7759 	matgen_band (n, 1, 1, 1, n, 0, 0, &Ap, &Ai, &Ax, &Az) ;
7760 	rnorm = do_and_free (n, Ap, Ai, Ax,Az, Controls, Ncontrols, MemOK, 1) ;
7761 	maxrnorm = MAX (rnorm, maxrnorm) ;
7762 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7763 
7764 
7765     /* ---------------------------------------------------------------------- */
7766     /* test all tri-diagonal matrices + one "dense" row and col  */
7767     /* ---------------------------------------------------------------------- */
7768 
7769     n = 100 ;
7770 
7771 	printf ("tri-diagonal+dense row and col "ID" ", n) ;
7772 	matgen_band (n, 1, 1, 1, n, 1, n, &Ap, &Ai, &Ax, &Az) ;
7773 	rnorm = do_and_free (n, Ap, Ai, Ax,Az, Controls, Ncontrols, MemOK, 1) ;
7774 	maxrnorm = MAX (rnorm, maxrnorm) ;
7775 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7776 
7777 
7778     /* ---------------------------------------------------------------------- */
7779     /* test all small dense matrices */
7780     /* ---------------------------------------------------------------------- */
7781 
7782     for (n = 1 ; n < 16 ; n++)
7783     {
7784 	printf ("dense "ID" ", n) ;
7785 	matgen_dense (n, &Ap, &Ai, &Ax, &Az) ;
7786 	rnorm = do_and_free (n, Ap, Ai, Ax,Az, Controls, Ncontrols, MemOK, 1) ;
7787 	maxrnorm = MAX (rnorm, maxrnorm) ;
7788 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7789     }
7790 
7791     for (n = 20 ; n <= 80 ; n += 20 )
7792     {
7793 	printf ("dense "ID" ", n) ;
7794 	matgen_dense (n, &Ap, &Ai, &Ax, &Az) ;
7795 	rnorm = do_and_free (n, Ap, Ai, Ax,Az, Controls, Ncontrols, MemOK, 1) ;
7796 	maxrnorm = MAX (rnorm, maxrnorm) ;
7797 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7798     }
7799 
7800     n = 130 ;
7801 
7802 	printf ("dense "ID" ", n) ;
7803 	matgen_dense (n, &Ap, &Ai, &Ax, &Az) ;
7804 	rnorm = do_and_free (n, Ap, Ai, Ax,Az, Controls, Ncontrols, MemOK, 1) ;
7805 	maxrnorm = MAX (rnorm, maxrnorm) ;
7806 	printf (" %10.4e %10.4e\n", rnorm, maxrnorm) ;
7807 #endif
7808 
7809     /* ---------------------------------------------------------------------- */
7810     /* done with accurate matrices */
7811     /* ---------------------------------------------------------------------- */
7812 
7813     ttt = umfpack_timer ( ) ;
7814 
7815     fprintf (stderr,
7816         "ALL TESTS PASSED: rnorm %8.2e (%8.2e %8.2e %8.2e )\n",
7817         maxrnorm, maxrnorm_shl0, maxrnorm_arc130, rnorm_omega2) ;
7818 
7819     printf (
7820         "ALL TESTS PASSED: rnorm %8.2e (%8.2e %8.2e %8.2e)\n",
7821         maxrnorm, maxrnorm_shl0, maxrnorm_arc130, rnorm_omega2) ;
7822 
7823 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
7824     if (UMF_malloc_count != 0) error ("umfpack memory leak!!\n",0.) ;
7825 #endif
7826 
7827     return (0) ;
7828 }
7829