Amesos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
amesos_cholmod_check.c
Go to the documentation of this file.
1 /* ========================================================================== */
2 /* === Check/cholmod_check ================================================== */
3 /* ========================================================================== */
4 
5 /* -----------------------------------------------------------------------------
6  * CHOLMOD/Check Module. Copyright (C) 2005-2006, Timothy A. Davis
7  * The CHOLMOD/Check Module is licensed under Version 2.1 of the GNU
8  * Lesser General Public License. See lesser.txt for a text of the license.
9  * CHOLMOD is also available under other licenses; contact authors for details.
10  * http://www.cise.ufl.edu/research/sparse
11  * -------------------------------------------------------------------------- */
12 
13 /* Routines to check and print the contents of the 5 CHOLMOD objects:
14  *
15  * No CHOLMOD routine calls the check or print routines. If a user wants to
16  * check CHOLMOD's input parameters, a separate call to the appropriate check
17  * routine should be used before calling other CHOLMOD routines.
18  *
19  * cholmod_check_common check statistics and workspace in Common
20  * cholmod_check_sparse check sparse matrix in compressed column form
21  * cholmod_check_dense check dense matrix
22  * cholmod_check_factor check factorization
23  * cholmod_check_triplet check sparse matrix in triplet form
24  *
25  * cholmod_print_common print statistics in Common
26  * cholmod_print_sparse print sparse matrix in compressed column form
27  * cholmod_print_dense print dense matrix
28  * cholmod_print_factor print factorization
29  * cholmod_print_triplet print sparse matrix in triplet form
30  *
31  * In addition, this file contains routines to check and print three types of
32  * integer vectors:
33  *
34  * cholmod_check_perm check a permutation of 0:n-1 (no duplicates)
35  * cholmod_check_subset check a subset of 0:n-1 (duplicates OK)
36  * cholmod_check_parent check an elimination tree
37  *
38  * cholmod_print_perm print a permutation
39  * cholmod_print_subset print a subset
40  * cholmod_print_parent print an elimination tree
41  *
42  * Each Common->print level prints the items at or below the given level:
43  *
44  * 0: print nothing; just check the data structures and return TRUE/FALSE
45  * 1: error messages
46  * 2: warning messages
47  * 3: one-line summary of each object printed
48  * 4: short summary of each object (first and last few entries)
49  * 5: entire contents of the object
50  *
51  * No CHOLMOD routine calls these routines, so no printing occurs unless
52  * the user specifically calls a cholmod_print_* routine. Thus, the default
53  * print level is 3.
54  *
55  * Common->precise controls the # of digits printed for numerical entries
56  * (5 if FALSE, 15 if TRUE).
57  *
58  * If Common->print_function is NULL, then no printing occurs. The
59  * cholmod_check_* and cholmod_print_* routines still check their inputs and
60  * return TRUE/FALSE if the object is valid or not.
61  *
62  * This file also includes debugging routines that are enabled only when
63  * NDEBUG is defined in cholmod_internal.h (cholmod_dump_*).
64  */
65 
66 #ifndef NCHECK
67 
69 #include "amesos_cholmod_check.h"
70 
71 /* ========================================================================== */
72 /* === printing definitions ================================================= */
73 /* ========================================================================== */
74 
75 #ifdef LONG
76 #define I8 "%8ld"
77 #define I_8 "%-8ld"
78 #else
79 #define I8 "%8d"
80 #define I_8 "%-8d"
81 #endif
82 
83 #define PR(i,format,arg) \
84 { \
85  if (print >= i && Common->print_function != NULL) \
86  { \
87  (Common->print_function) (format, arg) ; \
88  } \
89 }
90 
91 #define P1(format,arg) PR(1,format,arg)
92 #define P2(format,arg) PR(2,format,arg)
93 #define P3(format,arg) PR(3,format,arg)
94 #define P4(format,arg) PR(4,format,arg)
95 
96 #define ERR(msg) \
97 { \
98  P1 ("\nCHOLMOD ERROR: %s: ", type) ; \
99  if (name != NULL) \
100  { \
101  P1 ("%s", name) ; \
102  } \
103  P1 (": %s\n", msg) ; \
104  ERROR (CHOLMOD_INVALID, "invalid") ; \
105  return (FALSE) ; \
106 }
107 
108 /* print a numerical value */
109 #define PRINTVALUE(value) \
110 { \
111  if (Common->precise) \
112  { \
113  P4 (" %23.15e", value) ; \
114  } \
115  else \
116  { \
117  P4 (" %.5g", value) ; \
118  } \
119 }
120 
121 /* start printing */
122 #define ETC_START(count,limit) \
123 { \
124  count = (init_print == 4) ? (limit) : (-1) ; \
125 }
126 
127 /* re-enable printing if condition is met */
128 #define ETC_ENABLE(condition,count,limit) \
129 { \
130  if ((condition) && init_print == 4) \
131  { \
132  count = limit ; \
133  print = 4 ; \
134  } \
135 }
136 
137 /* turn off printing if limit is reached */
138 #define ETC_DISABLE(count) \
139 { \
140  if ((count >= 0) && (count-- == 0) && print == 4) \
141  { \
142  P4 ("%s", " ...\n") ; \
143  print = 3 ; \
144  } \
145 }
146 
147 /* re-enable printing, or turn if off after limit is reached */
148 #define ETC(condition,count,limit) \
149 { \
150  ETC_ENABLE (condition, count, limit) ; \
151  ETC_DISABLE (count) ; \
152 }
153 
154 #define BOOLSTR(x) ((x) ? "true " : "false")
155 
156 /* ========================================================================== */
157 /* === print_value ========================================================== */
158 /* ========================================================================== */
159 
160 static void amesos_print_value
161 (
162  Int print,
163  Int xtype,
164  double *Xx,
165  double *Xz,
166  Int p,
167  cholmod_common *Common)
168 {
169  if (xtype == CHOLMOD_REAL)
170  {
171  PRINTVALUE (Xx [p]) ;
172  }
173  else if (xtype == CHOLMOD_COMPLEX)
174  {
175  P4 ("%s", "(") ;
176  PRINTVALUE (Xx [2*p ]) ;
177  P4 ("%s", " , ") ;
178  PRINTVALUE (Xx [2*p+1]) ;
179  P4 ("%s", ")") ;
180  }
181  else if (xtype == CHOLMOD_ZOMPLEX)
182  {
183  P4 ("%s", "(") ;
184  PRINTVALUE (Xx [p]) ;
185  P4 ("%s", " , ") ;
186  PRINTVALUE (Xz [p]) ;
187  P4 ("%s", ")") ;
188  }
189 }
190 
191 /* ========================================================================== */
192 /* === cholmod_check_common ================================================= */
193 /* ========================================================================== */
194 
195 /* Print and verify the contents of Common */
196 
197 static int check_common
198 (
199  Int print,
200  char *name,
201  cholmod_common *Common
202 )
203 {
204  double fl, lnz ;
205  double *Xwork ;
206  Int *Flag, *Head ;
207  UF_long mark ;
208  Int i, nrow, nmethods, ordering, xworksize, amd_printed, init_print ;
209  char *type = "common" ;
210 
211  /* ---------------------------------------------------------------------- */
212  /* print control parameters and statistics */
213  /* ---------------------------------------------------------------------- */
214 
216  init_print = print ;
217 
218  P2 ("%s", "\n") ;
219 
220  P1 ("CHOLMOD version %d", CHOLMOD_MAIN_VERSION) ;
221  P1 (".%d", CHOLMOD_SUB_VERSION) ;
222  P1 (".%d", CHOLMOD_SUBSUB_VERSION) ;
223  P1 (", %s: ", CHOLMOD_DATE) ;
224 
225  if (name != NULL)
226  {
227  P1 ("%s: ", name) ;
228  }
229  switch (Common->status)
230  {
231 
232  case CHOLMOD_OK:
233  P1 ("%s", "status: OK\n") ;
234  break ;
235 
237  P1 ("%s", "status: ERROR, out of memory\n") ;
238  break ;
239 
240  case CHOLMOD_INVALID:
241  P1 ("%s", "status: ERROR, invalid parameter\n") ;
242  break ;
243 
244  case CHOLMOD_TOO_LARGE:
245  P1 ("%s", "status: ERROR, problem too large\n") ;
246  break ;
247 
249  P1 ("%s", "status: ERROR, method not installed\n") ;
250  break ;
251 
252  case CHOLMOD_NOT_POSDEF:
253  P1 ("%s", "status: warning, matrix not positive definite\n") ;
254  break ;
255 
256  case CHOLMOD_DSMALL:
257  P1 ("%s", "status: warning, diagonal entry has tiny abs. value\n") ;
258  break ;
259 
260  default:
261  ERR ("unknown status") ;
262  }
263 
264  P2 (" Architecture: %s\n", CHOLMOD_ARCHITECTURE) ;
265  P3 (" sizeof(int): %d\n", (int) sizeof (int)) ;
266  P3 (" sizeof(UF_long): %d\n", (int) sizeof (UF_long)) ;
267  P3 (" sizeof(void *): %d\n", (int) sizeof (void *)) ;
268  P3 (" sizeof(double): %d\n", (int) sizeof (double)) ;
269  P3 (" sizeof(Int): %d (CHOLMOD's basic integer)\n", (int) sizeof (Int)) ;
270  P3 (" sizeof(BLAS_INT): %d (integer used in the BLAS)\n",
271  (int) sizeof (BLAS_INT)) ;
272 
273  if (Common->fl != EMPTY)
274  {
275  P2 ("%s", " Results from most recent analysis:\n") ;
276  P2 (" Cholesky flop count: %.5g\n", Common->fl) ;
277  P2 (" Nonzeros in L: %.5g\n", Common->lnz) ;
278  }
279  if (Common->modfl != EMPTY)
280  {
281  P2 (" Update/downdate flop count: %.5g\n", Common->modfl) ;
282  }
283 
284  P2 (" memory blocks in use: %8.0f\n", (double) (Common->malloc_count)) ;
285  P2 (" memory in use (MB): %8.1f\n",
286  (double) (Common->memory_inuse) / 1048576.) ;
287  P2 (" peak memory usage (MB): %8.1f\n",
288  (double) (Common->memory_usage) / 1048576.) ;
289 
290  /* ---------------------------------------------------------------------- */
291  /* primary control parameters and related ordering statistics */
292  /* ---------------------------------------------------------------------- */
293 
294  P3 (" maxrank: update/downdate rank: "ID"\n",
295  (Int) CHOLMOD(maxrank) (0, Common)) ;
296  P3 (" supernodal control: %d", Common->supernodal) ;
297  P3 (" %g ", Common->supernodal_switch) ;
298  if (Common->supernodal <= CHOLMOD_SIMPLICIAL)
299  {
300  P3 ("%s", "(always do simplicial)\n") ;
301  }
302  else if (Common->supernodal == CHOLMOD_AUTO)
303  {
304  P3 ("(supernodal if flops/lnz >= %g)\n", Common->supernodal_switch) ;
305  }
306  else
307  {
308  P3 ("%s", "(always do supernodal)\n") ;
309  }
310 
311  nmethods = MIN (Common->nmethods, CHOLMOD_MAXMETHODS) ;
312  nmethods = MAX (0, nmethods) ;
313 
314  if (nmethods > 0)
315  {
316  P3 ("%s", " nmethods: number of ordering methods to try: ") ;
317  P3 (""ID"\n", nmethods) ;
318  }
319  else
320  {
321  P3 ("%s", " nmethods=0: default strategy: Try user permutation if "
322  "given. Try AMD.\n") ;
323 #ifndef NPARTITION
324  if (Common->default_nesdis)
325  {
326  P3 ("%s", " Try NESDIS if AMD reports flops/nnz(L) >= 500 and "
327  "nnz(L)/nnz(A) >= 5.\n") ;
328  }
329  else
330  {
331  P3 ("%s", " Try METIS if AMD reports flops/nnz(L) >= 500 and "
332  "nnz(L)/nnz(A) >= 5.\n") ;
333  }
334 #endif
335  P3 ("%s", " Select best ordering tried.\n") ;
336  Common->method [0].ordering = CHOLMOD_GIVEN ;
337  Common->method [1].ordering = CHOLMOD_AMD ;
338  Common->method [2].ordering = CHOLMOD_METIS ;
339 #ifndef NPARTITION
340  nmethods = 3 ;
341 #else
342  nmethods = 2 ;
343 #endif
344  }
345 
346  amd_printed = FALSE ;
347  for (i = 0 ; i < nmethods ; i++)
348  {
349  P3 (" method "ID": ", i) ;
350  ordering = Common->method [i].ordering ;
351  fl = Common->method [i].fl ;
352  lnz = Common->method [i].lnz ;
353  switch (ordering)
354  {
355 
356  case CHOLMOD_NATURAL:
357  P3 ("%s", "natural\n") ;
358  break ;
359 
360  case CHOLMOD_GIVEN:
361  P3 ("%s", "user permutation (if given)\n") ;
362  break ;
363 
364  case CHOLMOD_AMD:
365  P3 ("%s", "AMD (or COLAMD if factorizing AA')\n") ;
366  amd_printed = TRUE ;
367  break ;
368 
369  case CHOLMOD_COLAMD:
370  P3 ("%s", "AMD if factorizing A, COLAMD if factorizing AA')\n");
371  amd_printed = TRUE ;
372  break ;
373 
374  case CHOLMOD_METIS:
375  P3 ("%s", "METIS_NodeND nested dissection\n") ;
376  break ;
377 
378  case CHOLMOD_NESDIS:
379  P3 ("%s", "CHOLMOD nested dissection\n") ;
380 
381  P3 (" nd_small: # nodes in uncut subgraph: "ID"\n",
382  (Int) (Common->method [i].nd_small)) ;
383  P3 (" nd_compress: compress the graph: %s\n",
384  BOOLSTR (Common->method [i].nd_compress)) ;
385  P3 (" nd_camd: use constrained min degree: %s\n",
386  BOOLSTR (Common->method [i].nd_camd)) ;
387  break ;
388 
389  default:
390  P3 (ID, ordering) ;
391  ERR ("unknown ordering method") ;
392  break ;
393 
394  }
395 
396  if (!(ordering == CHOLMOD_NATURAL || ordering == CHOLMOD_GIVEN))
397  {
398  if (Common->method [i].prune_dense < 0)
399  {
400  P3 (" prune_dense: for pruning dense nodes: %s\n",
401  " none pruned") ;
402  }
403  else
404  {
405  P3 (" prune_dense: for pruning dense nodes: "
406  "%.5g\n",
407  Common->method [i].prune_dense) ;
408  P3 (" a dense node has degree "
409  ">= max(16,(%.5g)*sqrt(n))\n",
410  Common->method [i].prune_dense) ;
411  }
412  }
413 
414  if (ordering == CHOLMOD_COLAMD || ordering == CHOLMOD_NESDIS)
415  {
416  if (Common->method [i].prune_dense2 < 0)
417  {
418  P3 (" prune_dense2: for pruning dense rows for AA':"
419  " %s\n", " none pruned") ;
420  }
421  else
422  {
423  P3 (" prune_dense2: for pruning dense rows for AA':"
424  " %.5g\n", Common->method [i].prune_dense2) ;
425  P3 (" a dense row has degree "
426  ">= max(16,(%.5g)*sqrt(ncol))\n",
427  Common->method [i].prune_dense2) ;
428  }
429  }
430 
431  if (fl != EMPTY) P3 (" flop count: %.5g\n", fl) ;
432  if (lnz != EMPTY) P3 (" nnz(L): %.5g\n", lnz) ;
433  }
434 
435  /* backup AMD results, if any */
436  if (!amd_printed)
437  {
438  P3 ("%s", " backup method: ") ;
439  P3 ("%s", "AMD (or COLAMD if factorizing AA')\n") ;
440  fl = Common->method [nmethods].fl ;
441  lnz = Common->method [nmethods].lnz ;
442  if (fl != EMPTY) P3 (" AMD flop count: %.5g\n", fl) ;
443  if (lnz != EMPTY) P3 (" AMD nnz(L): %.5g\n", lnz) ;
444  }
445 
446  /* ---------------------------------------------------------------------- */
447  /* arcane control parameters */
448  /* ---------------------------------------------------------------------- */
449 
450  if (Common->final_asis)
451  {
452  P4 ("%s", " final_asis: TRUE, leave as is\n") ;
453  }
454  else
455  {
456  P4 ("%s", " final_asis: FALSE, convert when done\n") ;
457  if (Common->final_super)
458  {
459  P4 ("%s", " final_super: TRUE, leave in supernodal form\n") ;
460  }
461  else
462  {
463  P4 ("%s", " final_super: FALSE, convert to simplicial form\n") ;
464  }
465  if (Common->final_ll)
466  {
467  P4 ("%s", " final_ll: TRUE, convert to LL' form\n") ;
468  }
469  else
470  {
471  P4 ("%s", " final_ll: FALSE, convert to LDL' form\n") ;
472  }
473  if (Common->final_pack)
474  {
475  P4 ("%s", " final_pack: TRUE, pack when done\n") ;
476  }
477  else
478  {
479  P4 ("%s", " final_pack: FALSE, do not pack when done\n") ;
480  }
481  if (Common->final_monotonic)
482  {
483  P4 ("%s", " final_monotonic: TRUE, ensure L is monotonic\n") ;
484  }
485  else
486  {
487  P4 ("%s",
488  " final_monotonic: FALSE, do not ensure L is monotonic\n") ;
489  }
490  P4 (" final_resymbol: remove zeros from amalgamation: %s\n",
491  BOOLSTR (Common->final_resymbol)) ;
492  }
493 
494  P4 (" dbound: LDL' diagonal threshold: % .5g\n Entries with abs. value"
495  " less than dbound are replaced with +/- dbound.\n",
496  Common->dbound) ;
497 
498  P4 (" grow0: memory reallocation: % .5g\n", Common->grow0) ;
499  P4 (" grow1: memory reallocation: % .5g\n", Common->grow1) ;
500  P4 (" grow2: memory reallocation: %g\n", (double) (Common->grow2)) ;
501 
502  P4 ("%s", " nrelax, zrelax: supernodal amalgamation rule:\n") ;
503  P4 ("%s", " s = # columns in two adjacent supernodes\n") ;
504  P4 ("%s", " z = % of zeros in new supernode if they are merged.\n") ;
505  P4 ("%s", " Two supernodes are merged if") ;
506  P4 (" (s <= %g) or (no new zero entries) or\n",
507  (double) (Common->nrelax [0])) ;
508  P4 (" (s <= %g and ", (double) (Common->nrelax [1])) ;
509  P4 ("z < %.5g%%) or", Common->zrelax [0] * 100) ;
510  P4 (" (s <= %g and ", (double) (Common->nrelax [2])) ;
511  P4 ("z < %.5g%%) or", Common->zrelax [1] * 100) ;
512  P4 (" (z < %.5g%%)\n", Common->zrelax [2] * 100) ;
513 
514  /* ---------------------------------------------------------------------- */
515  /* check workspace */
516  /* ---------------------------------------------------------------------- */
517 
518  mark = Common->mark ;
519  nrow = Common->nrow ;
520  Flag = Common->Flag ;
521  Head = Common->Head ;
522  if (nrow > 0)
523  {
524  if (mark < 0 || Flag == NULL || Head == NULL)
525  {
526  ERR ("workspace corrupted (Flag and/or Head missing)") ;
527  }
528  for (i = 0 ; i < nrow ; i++)
529  {
530  if (Flag [i] >= mark)
531  {
532  PRINT0 (("Flag ["ID"]="ID", mark = %ld\n", i, Flag [i], mark)) ;
533  ERR ("workspace corrupted (Flag)") ;
534  }
535  }
536  for (i = 0 ; i <= nrow ; i++)
537  {
538  if (Head [i] != EMPTY)
539  {
540  PRINT0 (("Head ["ID"] = "ID",\n", i, Head [i])) ;
541  ERR ("workspace corrupted (Head)") ;
542  }
543  }
544  }
545  xworksize = Common->xworksize ;
546  Xwork = Common->Xwork ;
547  if (xworksize > 0)
548  {
549  if (Xwork == NULL)
550  {
551  ERR ("workspace corrupted (Xwork missing)") ;
552  }
553  for (i = 0 ; i < xworksize ; i++)
554  {
555  if (Xwork [i] != 0.)
556  {
557  PRINT0 (("Xwork ["ID"] = %g\n", i, Xwork [i])) ;
558  ERR ("workspace corrupted (Xwork)") ;
559  }
560  }
561  }
562 
563  /* workspace and parameters are valid */
564  P3 ("%s", " OK\n") ;
565  P4 ("%s", "\n") ;
566  return (TRUE) ;
567 }
568 
569 
571 (
572  cholmod_common *Common
573 )
574 {
575  return (check_common (0, NULL, Common)) ;
576 }
577 
578 
580 (
581  /* ---- input ---- */
582  char *name, /* printed name of Common object */
583  /* --------------- */
584  cholmod_common *Common
585 )
586 {
587  Int print = (Common == NULL) ? 3 : (Common->print) ;
588  return (check_common (print, name, Common)) ;
589 }
590 
591 
592 /* ========================================================================== */
593 /* === cholmod_check_sparse ================================================= */
594 /* ========================================================================== */
595 
596 /* Ensure that a sparse matrix in column-oriented form is valid, and optionally
597  * print it. Returns the number of entries on the diagonal or -1 if error.
598  *
599  * workspace: Iwork (nrow)
600  */
601 
602 static UF_long check_sparse
603 (
604  Int *Wi,
605  Int print,
606  char *name,
607  cholmod_sparse *A,
608  UF_long *nnzdiag,
609  cholmod_common *Common
610 )
611 {
612  double *Ax, *Az ;
613  Int *Ap, *Ai, *Anz ;
614  Int nrow, ncol, nzmax, sorted, packed, j, p, pend, i, nz, ilast,
615  space, init_print, dnz, count, xtype ;
616  char *type = "sparse" ;
617 
618  /* ---------------------------------------------------------------------- */
619  /* print header information */
620  /* ---------------------------------------------------------------------- */
621 
622  P4 ("%s", "\n") ;
623  P3 ("%s", "CHOLMOD sparse: ") ;
624  if (name != NULL)
625  {
626  P3 ("%s: ", name) ;
627  }
628 
629  if (A == NULL)
630  {
631  ERR ("null") ;
632  }
633 
634  nrow = A->nrow ;
635  ncol = A->ncol ;
636  nzmax = A->nzmax ;
637  sorted = A->sorted ;
638  packed = A->packed ;
639  xtype = A->xtype ;
640  Ap = A->p ;
641  Ai = A->i ;
642  Ax = A->x ;
643  Az = A->z ;
644  Anz = A->nz ;
645  nz = CHOLMOD(nnz) (A, Common) ;
646 
647  P3 (" "ID"", nrow) ;
648  P3 ("-by-"ID", ", ncol) ;
649  P3 ("nz "ID",", nz) ;
650  if (A->stype > 0)
651  {
652  P3 ("%s", " upper.") ;
653  }
654  else if (A->stype < 0)
655  {
656  P3 ("%s", " lower.") ;
657  }
658  else
659  {
660  P3 ("%s", " up/lo.") ;
661  }
662 
663  P4 ("\n nzmax "ID", ", nzmax) ;
664  if (nz > nzmax)
665  {
666  ERR ("nzmax too small") ;
667  }
668  if (!sorted)
669  {
670  P4 ("%s", "un") ;
671  }
672  P4 ("%s", "sorted, ") ;
673  if (!packed)
674  {
675  P4 ("%s", "un") ;
676  }
677  P4 ("%s", "packed, ") ;
678 
679  switch (A->itype)
680  {
681  case CHOLMOD_INT: P4 ("%s", "\n scalar types: int, ") ; break ;
682  case CHOLMOD_INTLONG: ERR ("mixed int/UF_long type unsupported") ;
683  case CHOLMOD_LONG: P4 ("%s", "\n scalar types: UF_long, ") ; break ;
684  default: ERR ("unknown itype") ;
685  }
686 
687  switch (A->xtype)
688  {
689  case CHOLMOD_PATTERN: P4 ("%s", "pattern") ; break ;
690  case CHOLMOD_REAL: P4 ("%s", "real") ; break ;
691  case CHOLMOD_COMPLEX: P4 ("%s", "complex") ; break ;
692  case CHOLMOD_ZOMPLEX: P4 ("%s", "zomplex") ; break ;
693  default: ERR ("unknown xtype") ;
694  }
695 
696  switch (A->dtype)
697  {
698  case CHOLMOD_DOUBLE: P4 ("%s", ", double\n") ; break ;
699  case CHOLMOD_SINGLE: ERR ("float unsupported") ;
700  default: ERR ("unknown dtype") ;
701  }
702 
703  if (A->itype != ITYPE || A->dtype != DTYPE)
704  {
705  ERR ("integer and real type must match routine") ;
706  }
707 
708  if (A->stype && nrow != ncol)
709  {
710  ERR ("symmetric but not square") ;
711  }
712 
713  /* check for existence of Ap, Ai, Anz, Ax, and Az arrays */
714  if (Ap == NULL)
715  {
716  ERR ("p array not present") ;
717  }
718  if (Ai == NULL)
719  {
720  ERR ("i array not present") ;
721  }
722  if (!packed && Anz == NULL)
723  {
724  ERR ("nz array not present") ;
725  }
726  if (xtype != CHOLMOD_PATTERN && Ax == NULL)
727  {
728  ERR ("x array not present") ;
729  }
730  if (xtype == CHOLMOD_ZOMPLEX && Az == NULL)
731  {
732  ERR ("z array not present") ;
733  }
734 
735  /* packed matrices must start at Ap [0] = 0 */
736  if (packed && Ap [0] != 0)
737  {
738  ERR ("p [0] must be zero") ;
739  }
740  if (packed && (Ap [ncol] < Ap [0] || Ap [ncol] > nzmax))
741  {
742  ERR ("p [ncol] invalid") ;
743  }
744 
745  /* ---------------------------------------------------------------------- */
746  /* allocate workspace if needed */
747  /* ---------------------------------------------------------------------- */
748 
749  if (!sorted)
750  {
751  if (Wi == NULL)
752  {
753  CHOLMOD(allocate_work) (0, nrow, 0, Common) ;
754  Wi = Common->Iwork ; /* size nrow, (i/i/l) */
755  }
756  if (Common->status < CHOLMOD_OK)
757  {
758  return (FALSE) ; /* out of memory */
759  }
760  for (i = 0 ; i < nrow ; i++)
761  {
762  Wi [i] = EMPTY ;
763  }
764  }
765 
766  /* ---------------------------------------------------------------------- */
767  /* check and print each column */
768  /* ---------------------------------------------------------------------- */
769 
770  init_print = print ;
771  dnz = 0 ;
772  ETC_START (count, 8) ;
773 
774  for (j = 0 ; j < ncol ; j++)
775  {
776  ETC (j == ncol-1, count, 4) ;
777  p = Ap [j] ;
778  if (packed)
779  {
780  pend = Ap [j+1] ;
781  nz = pend - p ;
782  }
783  else
784  {
785  /* Note that Anz [j] < 0 is treated as zero */
786  nz = MAX (0, Anz [j]) ;
787  pend = p + nz ;
788  }
789  /* Note that space can be negative if the matrix is non-monotonic */
790  space = Ap [j+1] - p ;
791  P4 (" col "ID":", j) ;
792  P4 (" nz "ID"", nz) ;
793  P4 (" start "ID"", p) ;
794  P4 (" end "ID"", pend) ;
795  if (!packed)
796  {
797  P4 (" space "ID"", space) ;
798  }
799  P4 ("%s", ":\n") ;
800  if (p < 0 || pend > nzmax)
801  {
802  ERR ("pointer invalid") ;
803  }
804  if (nz < 0 || nz > nrow)
805  {
806  ERR ("nz invalid") ;
807  }
808  ilast = EMPTY ;
809 
810  for ( ; p < pend ; p++)
811  {
812  ETC (j == ncol-1 && p >= pend-4, count, -1) ;
813  i = Ai [p] ;
814  P4 (" "I8":", i) ;
815 
816  amesos_print_value (print, xtype, Ax, Az, p, Common) ;
817 
818  if (i == j)
819  {
820  dnz++ ;
821  }
822  if (i < 0 || i >= nrow)
823  {
824  ERR ("row index out of range") ;
825  }
826  if (sorted && i <= ilast)
827  {
828  ERR ("row indices out of order") ;
829  }
830  if (!sorted && Wi [i] == j)
831  {
832  ERR ("duplicate row index") ;
833  }
834  P4 ("%s", "\n") ;
835  ilast = i ;
836  if (!sorted)
837  {
838  Wi [i] = j ;
839  }
840  }
841  }
842 
843  /* matrix is valid */
844  P4 (" nnz on diagonal: "ID"\n", dnz) ;
845  P3 ("%s", " OK\n") ;
846  P4 ("%s", "\n") ;
847  *nnzdiag = dnz ;
848  return (TRUE) ;
849 }
850 
851 
853 (
854  /* ---- input ---- */
855  cholmod_sparse *A, /* sparse matrix to check */
856  /* --------------- */
857  cholmod_common *Common
858 )
859 {
860  UF_long nnzdiag ;
862  Common->status = CHOLMOD_OK ;
863  return (check_sparse (NULL, 0, NULL, A, &nnzdiag, Common)) ;
864 }
865 
866 
868 (
869  /* ---- input ---- */
870  cholmod_sparse *A, /* sparse matrix to print */
871  char *name, /* printed name of sparse matrix */
872  /* --------------- */
873  cholmod_common *Common
874 )
875 {
876  UF_long nnzdiag ;
878  Common->status = CHOLMOD_OK ;
879  return (check_sparse (NULL, Common->print, name, A, &nnzdiag, Common)) ;
880 }
881 
882 
883 /* ========================================================================== */
884 /* === cholmod_check_dense ================================================== */
885 /* ========================================================================== */
886 
887 /* Ensure a dense matrix is valid, and optionally print it. */
888 
889 static int check_dense
890 (
891  Int print,
892  char *name,
893  cholmod_dense *X,
894  cholmod_common *Common
895 )
896 {
897  double *Xx, *Xz ;
898  Int i, j, d, nrow, ncol, nzmax, nz, init_print, count, xtype ;
899  char *type = "dense" ;
900 
901  /* ---------------------------------------------------------------------- */
902  /* print header information */
903  /* ---------------------------------------------------------------------- */
904 
905  P4 ("%s", "\n") ;
906  P3 ("%s", "CHOLMOD dense: ") ;
907  if (name != NULL)
908  {
909  P3 ("%s: ", name) ;
910  }
911 
912  if (X == NULL)
913  {
914  ERR ("null") ;
915  }
916 
917  nrow = X->nrow ;
918  ncol = X->ncol ;
919  nzmax = X->nzmax ;
920  d = X->d ;
921  Xx = X->x ;
922  Xz = X->z ;
923  xtype = X->xtype ;
924 
925  P3 (" "ID"", nrow) ;
926  P3 ("-by-"ID", ", ncol) ;
927  P4 ("\n leading dimension "ID", ", d) ;
928  P4 ("nzmax "ID", ", nzmax) ;
929  if (d * ncol > nzmax)
930  {
931  ERR ("nzmax too small") ;
932  }
933  if (d < nrow)
934  {
935  ERR ("leading dimension must be >= # of rows") ;
936  }
937  if (Xx == NULL)
938  {
939  ERR ("null") ;
940  }
941 
942  switch (X->xtype)
943  {
944  case CHOLMOD_PATTERN: ERR ("pattern unsupported") ; break ;
945  case CHOLMOD_REAL: P4 ("%s", "real") ; break ;
946  case CHOLMOD_COMPLEX: P4 ("%s", "complex") ; break ;
947  case CHOLMOD_ZOMPLEX: P4 ("%s", "zomplex") ; break ;
948  default: ERR ("unknown xtype") ;
949  }
950 
951  switch (X->dtype)
952  {
953  case CHOLMOD_DOUBLE: P4 ("%s", ", double\n") ; break ;
954  case CHOLMOD_SINGLE: ERR ("single unsupported") ;
955  default: ERR ("unknown dtype") ;
956  }
957 
958  /* ---------------------------------------------------------------------- */
959  /* check and print each entry */
960  /* ---------------------------------------------------------------------- */
961 
962  if (print >= 4)
963  {
964  init_print = print ;
965  ETC_START (count, 9) ;
966  nz = nrow * ncol ;
967  for (j = 0 ; j < ncol ; j++)
968  {
969  ETC (j == ncol-1, count, 5) ;
970  P4 (" col "ID":\n", j) ;
971  for (i = 0 ; i < nrow ; i++)
972  {
973  ETC (j == ncol-1 && i >= nrow-4, count, -1) ;
974  P4 (" "I8":", i) ;
975 
976  amesos_print_value (print, xtype, Xx, Xz, i+j*d, Common) ;
977 
978  P4 ("%s", "\n") ;
979  }
980  }
981  }
982 
983  /* dense is valid */
984  P3 ("%s", " OK\n") ;
985  P4 ("%s", "\n") ;
986  return (TRUE) ;
987 }
988 
989 
990 int CHOLMOD(check_dense)
991 (
992  /* ---- input ---- */
993  cholmod_dense *X, /* dense matrix to check */
994  /* --------------- */
995  cholmod_common *Common
996 )
997 {
999  Common->status = CHOLMOD_OK ;
1000  return (check_dense (0, NULL, X, Common)) ;
1001 }
1002 
1003 
1004 int CHOLMOD(print_dense)
1006  /* ---- input ---- */
1007  cholmod_dense *X, /* dense matrix to print */
1008  char *name, /* printed name of dense matrix */
1009  /* --------------- */
1010  cholmod_common *Common
1011 )
1012 {
1014  Common->status = CHOLMOD_OK ;
1015  return (check_dense (Common->print, name, X, Common)) ;
1016 }
1017 
1018 
1019 /* ========================================================================== */
1020 /* === cholmod_check_subset ================================================= */
1021 /* ========================================================================== */
1022 
1023 /* Ensure S (0:len-1) is a subset of 0:n-1. Duplicates are allowed. S may be
1024  * NULL. A negative len denotes the set 0:n-1.
1025  *
1026  * To check the rset and cset for A(rset,cset), where nc and nr are the length
1027  * of cset and rset respectively:
1028  *
1029  * cholmod_check_subset (cset, nc, A->ncol, Common) ;
1030  * cholmod_check_subset (rset, nr, A->nrow, Common) ;
1031  *
1032  * workspace: none
1033  */
1034 
1035 static int check_subset
1037  Int *S,
1038  UF_long len,
1039  size_t n,
1040  Int print,
1041  char *name,
1042  cholmod_common *Common
1043 )
1044 {
1045  Int i, k, init_print, count ;
1046  char *type = "subset" ;
1047 
1048  init_print = print ;
1049 
1050  if (S == NULL)
1051  {
1052  /* zero len denotes S = [ ], negative len denotes S = 0:n-1 */
1053  len = (len < 0) ? (-1) : 0 ;
1054  }
1055 
1056  P4 ("%s", "\n") ;
1057  P3 ("%s", "CHOLMOD subset: ") ;
1058  if (name != NULL)
1059  {
1060  P3 ("%s: ", name) ;
1061  }
1062 
1063  P3 (" len: %ld ", len) ;
1064  if (len < 0)
1065  {
1066  P3 ("%s", "(denotes 0:n-1) ") ;
1067  }
1068  P3 ("n: "ID"", (Int) n) ;
1069  P4 ("%s", "\n") ;
1070 
1071  if (len <= 0 || S == NULL)
1072  {
1073  P3 ("%s", " OK\n") ;
1074  P4 ("%s", "\n") ;
1075  return (TRUE) ;
1076  }
1077 
1078  if (print >= 4)
1079  {
1080  ETC_START (count, 8) ;
1081  for (k = 0 ; k < ((Int) len) ; k++)
1082  {
1083  ETC (k == ((Int) len) - 4, count, -1) ;
1084  i = S [k] ;
1085  P4 (" "I8":", k) ;
1086  P4 (" "ID"\n", i) ;
1087  if (i < 0 || i >= ((Int) n))
1088  {
1089  ERR ("entry out range") ;
1090  }
1091  }
1092  }
1093  else
1094  {
1095  for (k = 0 ; k < ((Int) len) ; k++)
1096  {
1097  i = S [k] ;
1098  if (i < 0 || i >= ((Int) n))
1099  {
1100  ERR ("entry out range") ;
1101  }
1102  }
1103  }
1104  P3 ("%s", " OK\n") ;
1105  P4 ("%s", "\n") ;
1106  return (TRUE) ;
1107 }
1108 
1109 
1110 int CHOLMOD(check_subset)
1112  /* ---- input ---- */
1113  Int *Set, /* Set [0:len-1] is a subset of 0:n-1. Duplicates OK */
1114  UF_long len, /* size of Set (an integer array), or < 0 if 0:n-1 */
1115  size_t n, /* 0:n-1 is valid range */
1116  /* --------------- */
1117  cholmod_common *Common
1118 )
1119 {
1121  Common->status = CHOLMOD_OK ;
1122  return (check_subset (Set, len, n, 0, NULL, Common)) ;
1123 }
1124 
1125 
1126 int CHOLMOD(print_subset)
1128  /* ---- input ---- */
1129  Int *Set, /* Set [0:len-1] is a subset of 0:n-1. Duplicates OK */
1130  UF_long len, /* size of Set (an integer array), or < 0 if 0:n-1 */
1131  size_t n, /* 0:n-1 is valid range */
1132  char *name, /* printed name of Set */
1133  /* --------------- */
1134  cholmod_common *Common
1135 )
1136 {
1138  Common->status = CHOLMOD_OK ;
1139  return (check_subset (Set, len, n, Common->print, name, Common)) ;
1140 }
1141 
1142 
1143 /* ========================================================================== */
1144 /* === cholmod_check_perm =================================================== */
1145 /* ========================================================================== */
1146 
1147 /* Ensure that Perm [0..len-1] is a permutation of a subset of 0:n-1. Perm
1148  * may be NULL, which is interpreted as the identity permutation. There can
1149  * be no duplicate entries (len must be <= n).
1150  *
1151  * If n <= Common->nrow, then this routine takes O(len) time and does not
1152  * allocate any memory, by using Common->Flag. Otherwise, it takes O(n) time
1153  * and ensures that Common->Iwork is at least n*sizeof(Int) in size.
1154  *
1155  * To check the fset: cholmod_check_perm (fset, fsize, ncol, Common) ;
1156  * To check a permutation: cholmod_check_perm (Perm, n, n, Common) ;
1157  *
1158  * workspace: Flag (n) if n <= Common->nrow, Iwork (n) otherwise.
1159  */
1160 
1161 static int check_perm
1163  Int *Wi,
1164  Int print,
1165  char *name,
1166  Int *Perm,
1167  size_t len,
1168  size_t n,
1169  cholmod_common *Common
1170 )
1171 {
1172  Int *Flag ;
1173  Int i, k, mark, init_print, count ;
1174  char *type = "perm" ;
1175 
1176  /* ---------------------------------------------------------------------- */
1177  /* checks that take O(1) time */
1178  /* ---------------------------------------------------------------------- */
1179 
1180  if (Perm == NULL || n == 0)
1181  {
1182  /* Perm is valid implicit identity, or empty */
1183  return (TRUE) ;
1184  }
1185 
1186  /* ---------------------------------------------------------------------- */
1187  /* checks that take O(n) time or require memory allocation */
1188  /* ---------------------------------------------------------------------- */
1189 
1190  init_print = print ;
1191  ETC_START (count, 8) ;
1192 
1193  if (Wi == NULL && n <= Common->nrow)
1194  {
1195  /* use the Common->Flag array if it's big enough */
1196  mark = CHOLMOD(clear_flag) (Common) ;
1197  Flag = Common->Flag ;
1198  ASSERT (CHOLMOD(dump_work) (TRUE, FALSE, 0, Common)) ;
1199  if (print >= 4)
1200  {
1201  for (k = 0 ; k < ((Int) len) ; k++)
1202  {
1203  ETC (k >= ((Int) len) - 4, count, -1) ;
1204  i = Perm [k] ;
1205  P4 (" "I8":", k) ;
1206  P4 (""ID"\n", i) ;
1207  if (i < 0 || i >= ((Int) n) || Flag [i] == mark)
1208  {
1209  CHOLMOD(clear_flag) (Common) ;
1210  ERR ("invalid permutation") ;
1211  }
1212  Flag [i] = mark ;
1213  }
1214  }
1215  else
1216  {
1217  for (k = 0 ; k < ((Int) len) ; k++)
1218  {
1219  i = Perm [k] ;
1220  if (i < 0 || i >= ((Int) n) || Flag [i] == mark)
1221  {
1222  CHOLMOD(clear_flag) (Common) ;
1223  ERR ("invalid permutation") ;
1224  }
1225  Flag [i] = mark ;
1226  }
1227  }
1228  CHOLMOD(clear_flag) (Common) ;
1229  ASSERT (CHOLMOD(dump_work) (TRUE, FALSE, 0, Common)) ;
1230  }
1231  else
1232  {
1233  if (Wi == NULL)
1234  {
1235  /* use Common->Iwork instead, but initialize it first */
1236  CHOLMOD(allocate_work) (0, n, 0, Common) ;
1237  Wi = Common->Iwork ; /* size n, (i/i/i) is OK */
1238  }
1239  if (Common->status < CHOLMOD_OK)
1240  {
1241  return (FALSE) ; /* out of memory */
1242  }
1243  for (i = 0 ; i < ((Int) n) ; i++)
1244  {
1245  Wi [i] = FALSE ;
1246  }
1247  if (print >= 4)
1248  {
1249  for (k = 0 ; k < ((Int) len) ; k++)
1250  {
1251  ETC (k >= ((Int) len) - 4, count, -1) ;
1252  i = Perm [k] ;
1253  P4 (" "I8":", k) ;
1254  P4 (""ID"\n", i) ;
1255  if (i < 0 || i >= ((Int) n) || Wi [i])
1256  {
1257  ERR ("invalid permutation") ;
1258  }
1259  Wi [i] = TRUE ;
1260  }
1261  }
1262  else
1263  {
1264  for (k = 0 ; k < ((Int) len) ; k++)
1265  {
1266  i = Perm [k] ;
1267  if (i < 0 || i >= ((Int) n) || Wi [i])
1268  {
1269  ERR ("invalid permutation") ;
1270  }
1271  Wi [i] = TRUE ;
1272  }
1273  }
1274  }
1275 
1276  /* perm is valid */
1277  return (TRUE) ;
1278 }
1279 
1280 
1281 int CHOLMOD(check_perm)
1283  /* ---- input ---- */
1284  Int *Perm, /* Perm [0:len-1] is a permutation of subset of 0:n-1 */
1285  size_t len, /* size of Perm (an integer array) */
1286  size_t n, /* 0:n-1 is valid range */
1287  /* --------------- */
1288  cholmod_common *Common
1289 )
1290 {
1292  Common->status = CHOLMOD_OK ;
1293  return (check_perm (NULL, 0, NULL, Perm, len, n, Common)) ;
1294 }
1295 
1296 
1297 int CHOLMOD(print_perm)
1299  /* ---- input ---- */
1300  Int *Perm, /* Perm [0:len-1] is a permutation of subset of 0:n-1 */
1301  size_t len, /* size of Perm (an integer array) */
1302  size_t n, /* 0:n-1 is valid range */
1303  char *name, /* printed name of Perm */
1304  /* --------------- */
1305  cholmod_common *Common
1306 )
1307 {
1308  Int ok, print ;
1310  Common->status = CHOLMOD_OK ;
1311  print = Common->print ;
1312  P4 ("%s", "\n") ;
1313  P3 ("%s", "CHOLMOD perm: ") ;
1314  if (name != NULL)
1315  {
1316  P3 ("%s: ", name) ;
1317  }
1318  P3 (" len: "ID"", (Int) len) ;
1319  P3 (" n: "ID"", (Int) n) ;
1320  P4 ("%s", "\n") ;
1321  ok = check_perm (NULL, print, name, Perm, len, n, Common) ;
1322  if (ok)
1323  {
1324  P3 ("%s", " OK\n") ;
1325  P4 ("%s", "\n") ;
1326  }
1327  return (ok) ;
1328 }
1329 
1330 
1331 /* ========================================================================== */
1332 /* === cholmod_check_parent ================================================= */
1333 /* ========================================================================== */
1334 
1335 /* Ensure that Parent is a valid elimination tree of nodes 0 to n-1.
1336  * If j is a root of the tree then Parent [j] is EMPTY (-1).
1337  *
1338  * NOTE: this check will fail if applied to the component tree (CParent) in
1339  * cholmod_nested_dissection, unless it has been postordered and renumbered.
1340  *
1341  * workspace: none
1342  */
1343 
1344 static int check_parent
1346  Int *Parent,
1347  size_t n,
1348  Int print,
1349  char *name,
1350  cholmod_common *Common
1351 )
1352 {
1353  Int j, p, init_print, count ;
1354  char *type = "parent" ;
1355 
1356  init_print = print ;
1357 
1358  P4 ("%s", "\n") ;
1359  P3 ("%s", "CHOLMOD parent: ") ;
1360  if (name != NULL)
1361  {
1362  P3 ("%s: ", name) ;
1363  }
1364 
1365  P3 (" n: "ID"", (Int) n) ;
1366  P4 ("%s", "\n") ;
1367 
1368  if (Parent == NULL)
1369  {
1370  ERR ("null") ;
1371  }
1372 
1373  /* ---------------------------------------------------------------------- */
1374  /* checks that take O(n) time */
1375  /* ---------------------------------------------------------------------- */
1376 
1377  ETC_START (count, 8) ;
1378  for (j = 0 ; j < ((Int) n) ; j++)
1379  {
1380  ETC (j == ((Int) n) - 4, count, -1) ;
1381  p = Parent [j] ;
1382  P4 (" "I8":", j) ;
1383  P4 (" "ID"\n", p) ;
1384  if (!(p == EMPTY || p > j))
1385  {
1386  ERR ("invalid") ;
1387  }
1388  }
1389  P3 ("%s", " OK\n") ;
1390  P4 ("%s", "\n") ;
1391  return (TRUE) ;
1392 }
1393 
1394 
1395 int CHOLMOD(check_parent)
1397  /* ---- input ---- */
1398  Int *Parent, /* Parent [0:n-1] is an elimination tree */
1399  size_t n, /* size of Parent */
1400  /* --------------- */
1401  cholmod_common *Common
1402 )
1403 {
1405  Common->status = CHOLMOD_OK ;
1406  return (check_parent (Parent, n, 0, NULL, Common)) ;
1407 }
1408 
1409 
1410 int CHOLMOD(print_parent)
1412  /* ---- input ---- */
1413  Int *Parent, /* Parent [0:n-1] is an elimination tree */
1414  size_t n, /* size of Parent */
1415  char *name, /* printed name of Parent */
1416  /* --------------- */
1417  cholmod_common *Common
1418 )
1419 {
1421  Common->status = CHOLMOD_OK ;
1422  return (check_parent (Parent, n, Common->print, name, Common)) ;
1423 }
1424 
1425 
1426 /* ========================================================================== */
1427 /* === cholmod_check_factor ================================================= */
1428 /* ========================================================================== */
1429 
1430 static int check_factor
1432  Int *Wi,
1433  Int print,
1434  char *name,
1435  cholmod_factor *L,
1436  cholmod_common *Common
1437 )
1438 {
1439  double *Lx, *Lz ;
1440  Int *Lp, *Li, *Lnz, *Lnext, *Lprev, *Perm, *ColCount, *Lpi, *Lpx, *Super,
1441  *Ls ;
1442  Int n, nzmax, j, p, pend, i, nz, ordering, space, is_monotonic, minor,
1443  count, precise, init_print, ilast, lnz, head, tail, jprev, plast,
1444  jnext, examine_super, nsuper, s, k1, k2, psi, psend, psx, nsrow, nscol,
1445  ps2, psxend, ssize, xsize, maxcsize, maxesize, nsrow2, jj, ii, xtype ;
1446  char *type = "factor" ;
1447 
1448  /* ---------------------------------------------------------------------- */
1449  /* print header information */
1450  /* ---------------------------------------------------------------------- */
1451 
1452  P4 ("%s", "\n") ;
1453  P3 ("%s", "CHOLMOD factor: ") ;
1454  if (name != NULL)
1455  {
1456  P3 ("%s: ", name) ;
1457  }
1458 
1459  if (L == NULL)
1460  {
1461  ERR ("null") ;
1462  }
1463 
1464  n = L->n ;
1465  minor = L->minor ;
1466  ordering = L->ordering ;
1467  xtype = L->xtype ;
1468 
1469  Perm = L->Perm ;
1470  ColCount = L->ColCount ;
1471  lnz = 0 ;
1472 
1473  precise = Common->precise ;
1474 
1475  P3 (" "ID"", n) ;
1476  P3 ("-by-"ID"", n) ;
1477 
1478  if (minor < n)
1479  {
1480  P3 (" not positive definite (column "ID")", minor) ;
1481  }
1482 
1483  switch (L->itype)
1484  {
1485  case CHOLMOD_INT: P4 ("%s", "\n scalar types: int, ") ; break ;
1486  case CHOLMOD_INTLONG: ERR ("mixed int/UF_long type unsupported") ;
1487  case CHOLMOD_LONG: P4 ("%s", "\n scalar types: UF_long, ") ; break ;
1488  default: ERR ("unknown itype") ;
1489  }
1490 
1491  switch (L->xtype)
1492  {
1493  case CHOLMOD_PATTERN: P4 ("%s", "pattern") ; break ;
1494  case CHOLMOD_REAL: P4 ("%s", "real") ; break ;
1495  case CHOLMOD_COMPLEX: P4 ("%s", "complex") ; break ;
1496  case CHOLMOD_ZOMPLEX: P4 ("%s", "zomplex") ; break ;
1497  default: ERR ("unknown xtype") ;
1498  }
1499 
1500  switch (L->dtype)
1501  {
1502  case CHOLMOD_DOUBLE: P4 ("%s", ", double\n") ; break ;
1503  case CHOLMOD_SINGLE: ERR ("single unsupported") ;
1504  default: ERR ("unknown dtype") ;
1505  }
1506 
1507  if (L->itype != ITYPE || L->dtype != DTYPE)
1508  {
1509  ERR ("integer and real type must match routine") ;
1510  }
1511 
1512  if (L->is_super)
1513  {
1514  P3 ("%s", " supernodal") ;
1515  }
1516  else
1517  {
1518  P3 ("%s", " simplicial") ;
1519  }
1520 
1521  if (L->is_ll)
1522  {
1523  P3 ("%s", ", LL'.") ;
1524  }
1525  else
1526  {
1527  P3 ("%s", ", LDL'.") ;
1528  }
1529 
1530  P4 ("%s", "\n ordering method used: ") ;
1531  switch (L->ordering)
1532  {
1533  case CHOLMOD_POSTORDERED:P4 ("%s", "natural (postordered)") ; break ;
1534  case CHOLMOD_NATURAL: P4 ("%s", "natural") ; break ;
1535  case CHOLMOD_GIVEN: P4 ("%s", "user-provided") ; break ;
1536  case CHOLMOD_AMD: P4 ("%s", "AMD") ; break ;
1537  case CHOLMOD_COLAMD: P4 ("%s", "AMD for A, COLAMD for A*A'") ;break ;
1538 #ifndef NPARTITION
1539  case CHOLMOD_METIS: P4 ("%s", "METIS NodeND") ; break ;
1540  case CHOLMOD_NESDIS: P4 ("%s", "CHOLMOD nested dissection") ; break ;
1541 #endif
1542  default: ERR ("unknown ordering") ;
1543  }
1544 
1545  P4 ("%s", "\n") ;
1546 
1547  init_print = print ;
1548 
1549  if (L->is_super && L->xtype == CHOLMOD_ZOMPLEX)
1550  {
1551  ERR ("Supernodal zomplex L not supported") ;
1552  }
1553 
1554  /* ---------------------------------------------------------------------- */
1555  /* check L->Perm */
1556  /* ---------------------------------------------------------------------- */
1557 
1558  if (!check_perm (Wi, print, name, Perm, n, n, Common))
1559  {
1560  return (FALSE) ;
1561  }
1562 
1563  /* ---------------------------------------------------------------------- */
1564  /* check L->ColCount */
1565  /* ---------------------------------------------------------------------- */
1566 
1567  if (ColCount == NULL)
1568  {
1569  ERR ("ColCount vector invalid") ;
1570  }
1571 
1572  ETC_START (count, 8) ;
1573  for (j = 0 ; j < n ; j++)
1574  {
1575  ETC (j >= n-4, count, -1) ;
1576  P4 (" col: "ID" ", j) ;
1577  nz = ColCount [j] ;
1578  P4 ("colcount: "ID"\n", nz) ;
1579  if (nz < 0 || nz > n-j)
1580  {
1581  ERR ("ColCount out of range") ;
1582  }
1583  }
1584 
1585  /* ---------------------------------------------------------------------- */
1586  /* check factor */
1587  /* ---------------------------------------------------------------------- */
1588 
1589  if (L->xtype == CHOLMOD_PATTERN && !(L->is_super))
1590  {
1591 
1592  /* ------------------------------------------------------------------ */
1593  /* check simplicial symbolic factor */
1594  /* ------------------------------------------------------------------ */
1595 
1596  /* nothing else to do */ ;
1597 
1598  }
1599  else if (L->xtype != CHOLMOD_PATTERN && !(L->is_super))
1600  {
1601 
1602  /* ------------------------------------------------------------------ */
1603  /* check simplicial numerical factor */
1604  /* ------------------------------------------------------------------ */
1605 
1606  P4 ("monotonic: %d\n", L->is_monotonic) ;
1607  nzmax = L->nzmax ;
1608  P3 (" nzmax "ID".", nzmax) ;
1609  P4 ("%s", "\n") ;
1610  Lp = L->p ;
1611  Li = L->i ;
1612  Lx = L->x ;
1613  Lz = L->z ;
1614  Lnz = L->nz ;
1615  Lnext = L->next ;
1616  Lprev = L->prev ;
1617 
1618  /* check for existence of Lp, Li, Lnz, Lnext, Lprev, and Lx arrays */
1619  if (Lp == NULL)
1620  {
1621  ERR ("p array not present") ;
1622  }
1623  if (Li == NULL)
1624  {
1625  ERR ("i array not present") ;
1626  }
1627  if (Lnz == NULL)
1628  {
1629  ERR ("nz array not present") ;
1630  }
1631  if (Lx == NULL)
1632  {
1633  ERR ("x array not present") ;
1634  }
1635  if (xtype == CHOLMOD_ZOMPLEX && Lz == NULL)
1636  {
1637  ERR ("z array not present") ;
1638  }
1639  if (Lnext == NULL)
1640  {
1641  ERR ("next array not present") ;
1642  }
1643  if (Lprev == NULL)
1644  {
1645  ERR ("prev array not present") ;
1646  }
1647 
1648  ETC_START (count, 8) ;
1649 
1650  /* check each column of L */
1651  plast = 0 ;
1652  is_monotonic = TRUE ;
1653  for (j = 0 ; j < n ; j++)
1654  {
1655  ETC (j >= n-3, count, -1) ;
1656  p = Lp [j] ;
1657  nz = Lnz [j] ;
1658  pend = p + nz ;
1659  lnz += nz ;
1660 
1661  P4 (" col "ID":", j) ;
1662  P4 (" nz "ID"", nz) ;
1663  P4 (" start "ID"", p) ;
1664  P4 (" end "ID"", pend) ;
1665 
1666  if (Lnext [j] < 0 || Lnext [j] > n)
1667  {
1668  ERR ("invalid link list") ;
1669  }
1670  space = Lp [Lnext [j]] - p ;
1671 
1672  P4 (" space "ID"", space) ;
1673  P4 (" free "ID":\n", space - nz) ;
1674 
1675  if (p < 0 || pend > nzmax || space < 1)
1676  {
1677  ERR ("pointer invalid") ;
1678  }
1679  if (nz < 1 || nz > (n-j) || nz > space)
1680  {
1681  ERR ("nz invalid") ;
1682  }
1683  ilast = j-1 ;
1684 
1685  if (p < plast)
1686  {
1687  is_monotonic = FALSE ;
1688  }
1689  plast = p ;
1690 
1691  i = Li [p] ;
1692  P4 (" "I8":", i) ;
1693  if (i != j)
1694  {
1695  ERR ("diagonal missing") ;
1696  }
1697 
1698  amesos_print_value (print, xtype, Lx, Lz, p, Common) ;
1699 
1700  P4 ("%s", "\n") ;
1701  ilast = j ;
1702  for (p++ ; p < pend ; p++)
1703  {
1704  ETC_DISABLE (count) ;
1705  i = Li [p] ;
1706  P4 (" "I8":", i) ;
1707  if (i < j || i >= n)
1708  {
1709  ERR ("row index out of range") ;
1710  }
1711  if (i <= ilast)
1712  {
1713  ERR ("row indices out of order") ;
1714  }
1715 
1716  amesos_print_value (print, xtype, Lx, Lz, p, Common) ;
1717 
1718  P4 ("%s", "\n") ;
1719  ilast = i ;
1720  }
1721  }
1722 
1723  if (L->is_monotonic && !is_monotonic)
1724  {
1725  ERR ("columns not monotonic") ;
1726  }
1727 
1728  /* check the link list */
1729  head = n+1 ;
1730  tail = n ;
1731  j = head ;
1732  jprev = EMPTY ;
1733  count = 0 ;
1734  for ( ; ; )
1735  {
1736  if (j < 0 || j > n+1 || count > n+2)
1737  {
1738  ERR ("invalid link list") ;
1739  }
1740  jnext = Lnext [j] ;
1741  if (j >= 0 && j < n)
1742  {
1743  if (jprev != Lprev [j])
1744  {
1745  ERR ("invalid link list") ;
1746  }
1747  }
1748  count++ ;
1749  if (j == tail)
1750  {
1751  break ;
1752  }
1753  jprev = j ;
1754  j = jnext ;
1755  }
1756  if (Lnext [tail] != EMPTY || count != n+2)
1757  {
1758  ERR ("invalid link list") ;
1759  }
1760 
1761  }
1762  else
1763  {
1764 
1765  /* ------------------------------------------------------------------ */
1766  /* check supernodal numeric or symbolic factor */
1767  /* ------------------------------------------------------------------ */
1768 
1769  nsuper = L->nsuper ;
1770  ssize = L->ssize ;
1771  xsize = L->xsize ;
1772  maxcsize = L->maxcsize ;
1773  maxesize = L->maxesize ;
1774  Ls = L->s ;
1775  Lpi = L->pi ;
1776  Lpx = L->px ;
1777  Super = L->super ;
1778  Lx = L->x ;
1779  ETC_START (count, 8) ;
1780 
1781  P4 (" ssize "ID" ", ssize) ;
1782  P4 ("xsize "ID" ", xsize) ;
1783  P4 ("maxcsize "ID" ", maxcsize) ;
1784  P4 ("maxesize "ID"\n", maxesize) ;
1785 
1786  if (Ls == NULL)
1787  {
1788  ERR ("invalid: L->s missing") ;
1789  }
1790  if (Lpi == NULL)
1791  {
1792  ERR ("invalid: L->pi missing") ;
1793  }
1794  if (Lpx == NULL)
1795  {
1796  ERR ("invalid: L->px missing") ;
1797  }
1798  if (Super == NULL)
1799  {
1800  ERR ("invalid: L->super missing") ;
1801  }
1802 
1803  if (L->xtype != CHOLMOD_PATTERN)
1804  {
1805  /* numerical supernodal factor */
1806  if (Lx == NULL)
1807  {
1808  ERR ("invalid: L->x missing") ;
1809  }
1810  if (Ls [0] == EMPTY)
1811  {
1812  ERR ("invalid: L->s not defined") ;
1813  }
1814  examine_super = TRUE ;
1815  }
1816  else
1817  {
1818  /* symbolic supernodal factor, but only if it has been computed */
1819  examine_super = (Ls [0] != EMPTY) ;
1820  }
1821 
1822  if (examine_super)
1823  {
1824  if (Lpi [0] != 0 || MAX (1, Lpi [nsuper]) != ssize)
1825  {
1826  PRINT0 (("Lpi [0] "ID", Lpi [nsuper = "ID"] = "ID"\n",
1827  Lpi [0], nsuper, Lpi [nsuper])) ;
1828  ERR ("invalid: L->pi invalid") ;
1829  }
1830  if (Lpx [0] != 0 || MAX (1, Lpx [nsuper]) != xsize)
1831  {
1832  ERR ("invalid: L->px invalid") ;
1833  }
1834 
1835  /* check and print each supernode */
1836  for (s = 0 ; s < nsuper ; s++)
1837  {
1838  k1 = Super [s] ;
1839  k2 = Super [s+1] ;
1840  psi = Lpi [s] ;
1841  psend = Lpi [s+1] ;
1842  psx = Lpx [s] ;
1843  nsrow = psend - psi ;
1844  nscol = k2 - k1 ;
1845  nsrow2 = nsrow - nscol ;
1846  ps2 = psi + nscol ;
1847  psxend = Lpx [s+1] ;
1848 
1849  ETC (s == nsuper-1, count, 4) ;
1850 
1851  P4 (" supernode "ID", ", s) ;
1852  P4 ("col "ID" ", k1) ;
1853  P4 ("to "ID". ", k2-1) ;
1854  P4 ("nz in first col: "ID".\n", nsrow) ;
1855  P4 (" values start "ID", ", psx) ;
1856  P4 ("end "ID"\n", psxend) ;
1857 
1858  if (k1 > k2 || k1 < 0 || k2 > n || nsrow < nscol || nsrow2 < 0
1859  || psxend - psx != nsrow * nscol)
1860  {
1861  ERR ("invalid supernode") ;
1862  }
1863 
1864  lnz += nscol * nsrow - (nscol*nscol - nscol)/2 ;
1865 
1866  if (L->xtype != CHOLMOD_PATTERN)
1867  {
1868  /* print each column of the supernode */
1869  for (jj = 0 ; jj < nscol ; jj++)
1870  {
1871  ETC_ENABLE (s == nsuper-1 && jj >= nscol-3, count, -1) ;
1872  j = k1 + jj ;
1873  P4 (" col "ID"\n", j) ;
1874  ilast = j ;
1875  i = Ls [psi + jj] ;
1876  P4 (" "I8":", i) ;
1877  if (i != j)
1878  {
1879  ERR ("row index invalid") ;
1880  }
1881 
1882  /* PRINTVALUE (Lx [psx + jj + jj*nsrow]) ; */
1883  amesos_print_value (print, xtype, Lx, NULL,
1884  psx + jj + jj*nsrow, Common) ;
1885 
1886  P4 ("%s", "\n") ;
1887  for (ii = jj + 1 ; ii < nsrow ; ii++)
1888  {
1889  ETC_DISABLE (count) ;
1890  i = Ls [psi + ii] ;
1891  P4 (" "I8":", i) ;
1892  if (i <= ilast || i > n)
1893  {
1894  ERR ("row index out of range") ;
1895  }
1896 
1897  /* PRINTVALUE (Lx [psx + ii + jj*nsrow]) ; */
1898  amesos_print_value (print, xtype, Lx, NULL,
1899  psx + ii + jj*nsrow, Common) ;
1900 
1901  P4 ("%s", "\n") ;
1902  ilast = i ;
1903  }
1904  }
1905  }
1906  else
1907  {
1908  /* just print the leading column of the supernode */
1909  P4 (" col "ID"\n", k1) ;
1910  for (jj = 0 ; jj < nscol ; jj++)
1911  {
1912  ETC (s == nsuper-1 && jj >= nscol-3, count, -1) ;
1913  j = k1 + jj ;
1914  i = Ls [psi + jj] ;
1915  P4 (" "I8"", i) ;
1916  if (i != j)
1917  {
1918  ERR ("row index invalid") ;
1919  }
1920  P4 ("%s", "\n") ;
1921  }
1922  ilast = j ;
1923  for (ii = nscol ; ii < nsrow ; ii++)
1924  {
1925  ETC_DISABLE (count) ;
1926  i = Ls [psi + ii] ;
1927  P4 (" "I8"", i) ;
1928  if (i <= ilast || i > n)
1929  {
1930  ERR ("row index out of range") ;
1931  }
1932  P4 ("%s", "\n") ;
1933  ilast = i ;
1934  }
1935  }
1936  }
1937  }
1938  }
1939 
1940  /* factor is valid */
1941  P3 (" nz "ID"", lnz) ;
1942  P3 ("%s", " OK\n") ;
1943  P4 ("%s", "\n") ;
1944  return (TRUE) ;
1945 }
1946 
1947 
1948 int CHOLMOD(check_factor)
1950  /* ---- input ---- */
1951  cholmod_factor *L, /* factor to check */
1952  /* --------------- */
1953  cholmod_common *Common
1954 )
1955 {
1957  Common->status = CHOLMOD_OK ;
1958  return (check_factor (NULL, 0, NULL, L, Common)) ;
1959 }
1960 
1961 
1962 int CHOLMOD(print_factor)
1964  /* ---- input ---- */
1965  cholmod_factor *L, /* factor to print */
1966  char *name, /* printed name of factor */
1967  /* --------------- */
1968  cholmod_common *Common
1969 )
1970 {
1972  Common->status = CHOLMOD_OK ;
1973  return (check_factor (NULL, Common->print, name, L, Common)) ;
1974 }
1975 
1976 
1977 /* ========================================================================== */
1978 /* === cholmod_check_triplet ================================================ */
1979 /* ========================================================================== */
1980 
1981 /* Ensure a triplet matrix is valid, and optionally print it. */
1982 
1983 static int check_triplet
1985  Int print,
1986  char *name,
1987  cholmod_triplet *T,
1988  cholmod_common *Common
1989 )
1990 {
1991  double *Tx, *Tz ;
1992  Int *Ti, *Tj ;
1993  Int i, j, p, nrow, ncol, nzmax, nz, xtype, init_print, count ;
1994  char *type = "triplet" ;
1995 
1996  /* ---------------------------------------------------------------------- */
1997  /* print header information */
1998  /* ---------------------------------------------------------------------- */
1999 
2000  P4 ("%s", "\n") ;
2001  P3 ("%s", "CHOLMOD triplet: ") ;
2002  if (name != NULL)
2003  {
2004  P3 ("%s: ", name) ;
2005  }
2006 
2007  if (T == NULL)
2008  {
2009  ERR ("null") ;
2010  }
2011 
2012  nrow = T->nrow ;
2013  ncol = T->ncol ;
2014  nzmax = T->nzmax ;
2015  nz = T->nnz ;
2016  Ti = T->i ;
2017  Tj = T->j ;
2018  Tx = T->x ;
2019  Tz = T->z ;
2020  xtype = T->xtype ;
2021 
2022 
2023  P3 (" "ID"", nrow) ;
2024  P3 ("-by-"ID", ", ncol) ;
2025  P3 ("nz "ID",", nz) ;
2026  if (T->stype > 0)
2027  {
2028  P3 ("%s", " upper.") ;
2029  }
2030  else if (T->stype < 0)
2031  {
2032  P3 ("%s", " lower.") ;
2033  }
2034  else
2035  {
2036  P3 ("%s", " up/lo.") ;
2037  }
2038 
2039  P4 ("\n nzmax "ID", ", nzmax) ;
2040  if (nz > nzmax)
2041  {
2042  ERR ("nzmax too small") ;
2043  }
2044 
2045  switch (T->itype)
2046  {
2047  case CHOLMOD_INT: P4 ("%s", "\n scalar types: int, ") ; break ;
2048  case CHOLMOD_INTLONG: ERR ("mixed int/UF_long type unsupported") ;
2049  case CHOLMOD_LONG: P4 ("%s", "\n scalar types: UF_long, ") ; break ;
2050  default: ERR ("unknown itype") ;
2051  }
2052 
2053  switch (T->xtype)
2054  {
2055  case CHOLMOD_PATTERN: P4 ("%s", "pattern") ; break ;
2056  case CHOLMOD_REAL: P4 ("%s", "real") ; break ;
2057  case CHOLMOD_COMPLEX: P4 ("%s", "complex") ; break ;
2058  case CHOLMOD_ZOMPLEX: P4 ("%s", "zomplex") ; break ;
2059  default: ERR ("unknown xtype") ;
2060  }
2061 
2062  switch (T->dtype)
2063  {
2064  case CHOLMOD_DOUBLE: P4 ("%s", ", double\n") ; break ;
2065  case CHOLMOD_SINGLE: ERR ("single unsupported") ;
2066  default: ERR ("unknown dtype") ;
2067  }
2068 
2069  if (T->itype != ITYPE || T->dtype != DTYPE)
2070  {
2071  ERR ("integer and real type must match routine") ;
2072  }
2073 
2074  if (T->stype && nrow != ncol)
2075  {
2076  ERR ("symmetric but not square") ;
2077  }
2078 
2079  /* check for existence of Ti, Tj, Tx arrays */
2080  if (Tj == NULL)
2081  {
2082  ERR ("j array not present") ;
2083  }
2084  if (Ti == NULL)
2085  {
2086  ERR ("i array not present") ;
2087  }
2088 
2089  if (xtype != CHOLMOD_PATTERN && Tx == NULL)
2090  {
2091  ERR ("x array not present") ;
2092  }
2093  if (xtype == CHOLMOD_ZOMPLEX && Tz == NULL)
2094  {
2095  ERR ("z array not present") ;
2096  }
2097 
2098  /* ---------------------------------------------------------------------- */
2099  /* check and print each entry */
2100  /* ---------------------------------------------------------------------- */
2101 
2102  init_print = print ;
2103  ETC_START (count, 8) ;
2104 
2105  for (p = 0 ; p < nz ; p++)
2106  {
2107  ETC (p >= nz-4, count, -1) ;
2108  i = Ti [p] ;
2109  P4 (" "I8":", p) ;
2110  P4 (" "I_8"", i) ;
2111  if (i < 0 || i >= nrow)
2112  {
2113  ERR ("row index out of range") ;
2114  }
2115  j = Tj [p] ;
2116  P4 (" "I_8"", j) ;
2117  if (j < 0 || j >= ncol)
2118  {
2119  ERR ("column index out of range") ;
2120  }
2121 
2122  amesos_print_value (print, xtype, Tx, Tz, p, Common) ;
2123 
2124  P4 ("%s", "\n") ;
2125  }
2126 
2127  /* triplet matrix is valid */
2128  P3 ("%s", " OK\n") ;
2129  P4 ("%s", "\n") ;
2130  return (TRUE) ;
2131 }
2132 
2133 
2134 
2137  /* ---- input ---- */
2138  cholmod_triplet *T, /* triplet matrix to check */
2139  /* --------------- */
2140  cholmod_common *Common
2141 )
2142 {
2144  Common->status = CHOLMOD_OK ;
2145  return (check_triplet (0, NULL, T, Common)) ;
2146 }
2147 
2148 
2151  /* ---- input ---- */
2152  cholmod_triplet *T, /* triplet matrix to print */
2153  char *name, /* printed name of triplet matrix */
2154  /* --------------- */
2155  cholmod_common *Common
2156 )
2157 {
2159  Common->status = CHOLMOD_OK ;
2160  return (check_triplet (Common->print, name, T, Common)) ;
2161 }
2162 
2163 
2164 
2165 /* ========================================================================== */
2166 /* === CHOLMOD debugging routines =========================================== */
2167 /* ========================================================================== */
2168 
2169 #ifndef NDEBUG
2170 
2171 /* The global variables present only when debugging enabled. */
2172 int CHOLMOD(dump) = 0 ;
2173 int CHOLMOD(dump_malloc) = -1 ;
2174 
2175 /* workspace: no debug routines use workspace in Common */
2176 
2177 /* ========================================================================== */
2178 /* === cholmod_dump_init ==================================================== */
2179 /* ========================================================================== */
2180 
2181 void CHOLMOD(dump_init) (char *s, cholmod_common *Common)
2182 {
2183  FILE *f ;
2184  f = fopen ("debug", "r") ;
2185  if (f == NULL)
2186  {
2187  CHOLMOD(dump) = 0 ;
2188  }
2189  else
2190  {
2191  fscanf (f, "%d", &CHOLMOD(dump)) ;
2192  fclose (f) ;
2193  }
2194  PRINT1 (("%s: cholmod_dump_init, D = %d\n", s, CHOLMOD(dump))) ;
2195 }
2196 
2197 
2198 /* ========================================================================== */
2199 /* === cholmod_dump_sparse ================================================== */
2200 /* ========================================================================== */
2201 
2202 UF_long CHOLMOD(dump_sparse) /* returns nnz (diag (A)) or EMPTY if error */
2203 (
2204  cholmod_sparse *A,
2205  char *name,
2206  cholmod_common *Common
2207 )
2208 {
2209  Int *Wi ;
2210  UF_long nnzdiag ;
2211  Int ok ;
2212 
2213  if (CHOLMOD(dump) < -1)
2214  {
2215  /* no checks if debug level is -2 or less */
2216  return (0) ;
2217  }
2218 
2220  RETURN_IF_NULL (A, FALSE) ;
2221  Wi = malloc (MAX (1, A->nrow) * sizeof (Int)) ;
2222  ok = check_sparse (Wi, CHOLMOD(dump), name, A, &nnzdiag, Common) ;
2223  if (Wi != NULL) free (Wi) ;
2224  return (ok ? nnzdiag : EMPTY) ;
2225 }
2226 
2227 
2228 /* ========================================================================== */
2229 /* === cholmod_dump_factor ================================================== */
2230 /* ========================================================================== */
2231 
2232 int CHOLMOD(dump_factor)
2234  cholmod_factor *L,
2235  char *name,
2236  cholmod_common *Common
2237 )
2238 {
2239  Int *Wi ;
2240  int ok ;
2241 
2242  if (CHOLMOD(dump) < -1)
2243  {
2244  /* no checks if debug level is -2 or less */
2245  return (TRUE) ;
2246  }
2248  RETURN_IF_NULL (L, FALSE) ;
2249  Wi = malloc (MAX (1, L->n) * sizeof (Int)) ;
2250  ok = check_factor (Wi, CHOLMOD(dump), name, L, Common) ;
2251  if (Wi != NULL) free (Wi) ;
2252  return (ok) ;
2253 }
2254 
2255 
2256 /* ========================================================================== */
2257 /* === cholmod_dump_perm ==================================================== */
2258 /* ========================================================================== */
2259 
2260 int CHOLMOD(dump_perm)
2262  Int *Perm,
2263  size_t len,
2264  size_t n,
2265  char *name,
2266  cholmod_common *Common
2267 )
2268 {
2269  Int *Wi ;
2270  int ok ;
2271 
2272  if (CHOLMOD(dump) < -1)
2273  {
2274  /* no checks if debug level is -2 or less */
2275  return (TRUE) ;
2276  }
2278  Wi = malloc (MAX (1, n) * sizeof (Int)) ;
2279  ok = check_perm (Wi, CHOLMOD(dump), name, Perm, len, n,Common) ;
2280  if (Wi != NULL) free (Wi) ;
2281  return (ok) ;
2282 }
2283 
2284 
2285 /* ========================================================================== */
2286 /* === cholmod_dump_dense =================================================== */
2287 /* ========================================================================== */
2288 
2289 int CHOLMOD(dump_dense)
2291  cholmod_dense *X,
2292  char *name,
2293  cholmod_common *Common
2294 )
2295 {
2296  if (CHOLMOD(dump) < -1)
2297  {
2298  /* no checks if debug level is -2 or less */
2299  return (TRUE) ;
2300  }
2302  return (check_dense (CHOLMOD(dump), name, X, Common)) ;
2303 }
2304 
2305 
2306 /* ========================================================================== */
2307 /* === cholmod_dump_triplet ================================================= */
2308 /* ========================================================================== */
2309 
2310 int CHOLMOD(dump_triplet)
2312  cholmod_triplet *T,
2313  char *name,
2314  cholmod_common *Common
2315 )
2316 {
2317  if (CHOLMOD(dump) < -1)
2318  {
2319  /* no checks if debug level is -2 or less */
2320  return (TRUE) ;
2321  }
2323  return (check_triplet (CHOLMOD(dump), name, T, Common)) ;
2324 }
2325 
2326 
2327 /* ========================================================================== */
2328 /* === cholmod_dump_subset ================================================== */
2329 /* ========================================================================== */
2330 
2331 int CHOLMOD(dump_subset)
2333  Int *S,
2334  size_t len,
2335  size_t n,
2336  char *name,
2337  cholmod_common *Common
2338 )
2339 {
2340  if (CHOLMOD(dump) < -1)
2341  {
2342  /* no checks if debug level is -2 or less */
2343  return (TRUE) ;
2344  }
2346  return (check_subset (S, len, n, CHOLMOD(dump), name, Common)) ;
2347 }
2348 
2349 
2350 /* ========================================================================== */
2351 /* === cholmod_dump_parent ================================================== */
2352 /* ========================================================================== */
2353 
2354 int CHOLMOD(dump_parent)
2356  Int *Parent,
2357  size_t n,
2358  char *name,
2359  cholmod_common *Common
2360 )
2361 {
2362  if (CHOLMOD(dump) < -1)
2363  {
2364  /* no checks if debug level is -2 or less */
2365  return (TRUE) ;
2366  }
2368  return (check_parent (Parent, n, CHOLMOD(dump), name, Common)) ;
2369 }
2370 
2371 
2372 /* ========================================================================== */
2373 /* === cholmod_dump_real ==================================================== */
2374 /* ========================================================================== */
2375 
2376 void CHOLMOD(dump_real)
2378  char *name, Real *X, UF_long nrow, UF_long ncol, int lower, int xentry,
2379  cholmod_common *Common
2380 )
2381 {
2382  /* dump an nrow-by-ncol real dense matrix */
2383  UF_long i, j ;
2384  double x, z ;
2385  if (CHOLMOD(dump) < -1)
2386  {
2387  /* no checks if debug level is -2 or less */
2388  return ;
2389  }
2390  PRINT1 (("%s: dump_real, nrow: %ld ncol: %ld lower: %d\n",
2391  name, nrow, ncol, lower)) ;
2392  for (j = 0 ; j < ncol ; j++)
2393  {
2394  PRINT2 ((" col %ld\n", j)) ;
2395  for (i = 0 ; i < nrow ; i++)
2396  {
2397  /* X is stored in column-major form */
2398  if (lower && i < j)
2399  {
2400  PRINT2 ((" %5ld: -", i)) ;
2401  }
2402  else
2403  {
2404  x = *X ;
2405  PRINT2 ((" %5ld: %e", i, x)) ;
2406  if (xentry == 2)
2407  {
2408  z = *(X+1) ;
2409  PRINT2 ((", %e", z)) ;
2410  }
2411  }
2412  PRINT2 (("\n")) ;
2413  X += xentry ;
2414  }
2415  }
2416 }
2417 
2418 
2419 /* ========================================================================== */
2420 /* === cholmod_dump_super =================================================== */
2421 /* ========================================================================== */
2422 
2423 void CHOLMOD(dump_super)
2425  UF_long s,
2426  Int *Super, Int *Lpi, Int *Ls, Int *Lpx, double *Lx,
2427  int xentry,
2428  cholmod_common *Common
2429 )
2430 {
2431  Int k1, k2, do_values, psi, psx, nsrow, nscol, psend, ilast, p, i ;
2432  if (CHOLMOD(dump) < -1)
2433  {
2434  /* no checks if debug level is -2 or less */
2435  return ;
2436  }
2437  k1 = Super [s] ;
2438  k2 = Super [s+1] ;
2439  nscol = k2 - k1 ;
2440  do_values = (Lpx != NULL) && (Lx != NULL) ;
2441  psi = Lpi [s] ;
2442  psend = Lpi [s+1] ;
2443  nsrow = psend - psi ;
2444  PRINT1 (("\nSuper %ld, columns "ID" to "ID", "ID" rows "ID" cols\n",
2445  s, k1, k2-1, nsrow, nscol)) ;
2446  ilast = -1 ;
2447  for (p = psi ; p < psend ; p++)
2448  {
2449  i = Ls [p] ;
2450  PRINT2 ((" "ID" : p-psi "ID"\n", i, p-psi)) ;
2451  ASSERT (IMPLIES (p-psi < nscol, i == k1 + (p-psi))) ;
2452  if (p-psi == nscol-1) PRINT2 (("------\n")) ;
2453  ASSERT (i > ilast) ;
2454  ilast = i ;
2455  }
2456  if (do_values)
2457  {
2458  psx = Lpx [s] ;
2459  CHOLMOD(dump_real) ("Supernode", Lx + xentry*psx, nsrow, nscol, TRUE,
2460  xentry, Common) ;
2461  }
2462 }
2463 
2464 
2465 /* ========================================================================== */
2466 /* === cholmod_dump_mem ===================================================== */
2467 /* ========================================================================== */
2468 
2469 int CHOLMOD(dump_mem) (char *where, UF_long should, cholmod_common *Common)
2470 {
2471  UF_long diff = should - Common->memory_inuse ;
2472  if (diff != 0)
2473  {
2474  PRINT0 (("mem: %-15s peak %10g inuse %10g should %10g\n",
2475  where, (double) Common->memory_usage, (double) Common->memory_inuse,
2476  (double) should)) ;
2477  PRINT0 (("mem: %s diff %ld !\n", where, diff)) ;
2478  }
2479  return (diff == 0) ;
2480 }
2481 
2482 
2483 /* ========================================================================== */
2484 /* === cholmod_dump_partition =============================================== */
2485 /* ========================================================================== */
2486 
2487 /* make sure we have a proper separator (for debugging only)
2488  *
2489  * workspace: none
2490  */
2491 
2494  UF_long n,
2495  Int *Cp,
2496  Int *Ci,
2497  Int *Cnw,
2498  Int *Part,
2499  UF_long sepsize,
2500  cholmod_common *Common
2501 )
2502 {
2503  Int chek [3], which, ok, i, j, p ;
2504  PRINT1 (("bisect sepsize %ld\n", sepsize)) ;
2505  ok = TRUE ;
2506  chek [0] = 0 ;
2507  chek [1] = 0 ;
2508  chek [2] = 0 ;
2509  for (j = 0 ; j < n ; j++)
2510  {
2511  PRINT2 (("--------j "ID" in part "ID" nw "ID"\n", j, Part [j], Cnw[j]));
2512  which = Part [j] ;
2513  for (p = Cp [j] ; p < Cp [j+1] ; p++)
2514  {
2515  i = Ci [p] ;
2516  PRINT3 (("i "ID", part "ID"\n", i, Part [i])) ;
2517  if (which == 0)
2518  {
2519  if (Part [i] == 1)
2520  {
2521  PRINT0 (("Error! "ID" "ID"\n", i, j)) ;
2522  ok = FALSE ;
2523  }
2524  }
2525  else if (which == 1)
2526  {
2527  if (Part [i] == 0)
2528  {
2529  PRINT0 (("Error! "ID" "ID"\n", i, j)) ;
2530  ok = FALSE ;
2531  }
2532  }
2533  }
2534  if (which < 0 || which > 2)
2535  {
2536  PRINT0 (("Part out of range\n")) ;
2537  ok = FALSE ;
2538  }
2539  chek [which] += Cnw [j] ;
2540  }
2541  PRINT1 (("sepsize %ld check "ID" "ID" "ID"\n",
2542  sepsize, chek[0], chek[1],chek[2]));
2543  if (sepsize != chek[2])
2544  {
2545  PRINT0 (("mismatch!\n")) ;
2546  ok = FALSE ;
2547  }
2548  return (ok) ;
2549 }
2550 
2551 
2552 /* ========================================================================== */
2553 /* === cholmod_dump_work ==================================================== */
2554 /* ========================================================================== */
2555 
2556 int CHOLMOD(dump_work) (int flag, int head, UF_long wsize,
2557  cholmod_common *Common)
2558 {
2559  double *W ;
2560  Int *Flag, *Head ;
2561  Int k, nrow, mark ;
2562 
2563  if (CHOLMOD(dump) < -1)
2564  {
2565  /* no checks if debug level is -2 or less */
2566  return (TRUE) ;
2567  }
2568 
2570  nrow = Common->nrow ;
2571  Flag = Common->Flag ;
2572  Head = Common->Head ;
2573  W = Common->Xwork ;
2574  mark = Common->mark ;
2575 
2576  if (wsize < 0)
2577  {
2578  /* check all of Xwork */
2579  wsize = Common->xworksize ;
2580  }
2581  else
2582  {
2583  /* check on the first wsize doubles in Xwork */
2584  wsize = MIN (wsize, (Int) (Common->xworksize)) ;
2585  }
2586 
2587  if (flag)
2588  {
2589  for (k = 0 ; k < nrow ; k++)
2590  {
2591  if (Flag [k] >= mark)
2592  {
2593  PRINT0 (("Flag invalid, Flag ["ID"] = "ID", mark = "ID"\n",
2594  k, Flag [k], mark)) ;
2595  ASSERT (0) ;
2596  return (FALSE) ;
2597  }
2598  }
2599  }
2600 
2601  if (head)
2602  {
2603  for (k = 0 ; k < nrow ; k++)
2604  {
2605  if (Head [k] != EMPTY)
2606  {
2607  PRINT0 (("Head invalid, Head ["ID"] = "ID"\n", k, Head [k])) ;
2608  ASSERT (0) ;
2609  return (FALSE) ;
2610  }
2611  }
2612  }
2613 
2614  for (k = 0 ; k < wsize ; k++)
2615  {
2616  if (W [k] != 0.)
2617  {
2618  PRINT0 (("W invalid, W ["ID"] = %g\n", k, W [k])) ;
2619  ASSERT (0) ;
2620  return (FALSE) ;
2621  }
2622  }
2623 
2624  return (TRUE) ;
2625 }
2626 #endif
2627 #endif
int CHOLMOD(dump)=0
#define BLAS_INT
#define P4(format, arg)
#define CHOLMOD_TOO_LARGE
#define CHOLMOD_SUBSUB_VERSION
void CHOLMOD() dump_init(char *s, cholmod_common *Common)
int CHOLMOD() print_parent(Int *Parent, size_t n, char *name, cholmod_common *Common)
#define CHOLMOD_ARCHITECTURE
void f()
#define CHOLMOD_NOT_INSTALLED
#define CHOLMOD_DOUBLE
#define EMPTY
UF_long CHOLMOD() nnz(cholmod_sparse *A, cholmod_common *Common)
#define ETC(condition, count, limit)
int CHOLMOD() print_triplet(cholmod_triplet *T, char *name, cholmod_common *Common)
#define CHOLMOD_AUTO
int CHOLMOD() dump_triplet(cholmod_triplet *T, char *name, cholmod_common *Common)
#define Int
static int check_triplet(Int print, char *name, cholmod_triplet *T, cholmod_common *Common)
#define CHOLMOD_COMPLEX
#define FALSE
#define PRINT1(params)
int CHOLMOD() dump_subset(Int *S, size_t len, size_t n, char *name, cholmod_common *Common)
#define PRINT3(params)
static int check_common(Int print, char *name, cholmod_common *Common)
#define RETURN_IF_NULL_COMMON(result)
#define BOOLSTR(x)
static int check_factor(Int *Wi, Int print, char *name, cholmod_factor *L, cholmod_common *Common)
static UF_long check_sparse(Int *Wi, Int print, char *name, cholmod_sparse *A, UF_long *nnzdiag, cholmod_common *Common)
#define CHOLMOD_SUB_VERSION
struct cholmod_common_struct::cholmod_method_struct method[CHOLMOD_MAXMETHODS+1]
int CHOLMOD() print_dense(cholmod_dense *X, char *name, cholmod_common *Common)
int CHOLMOD() dump_work(int flag, int head, UF_long wsize, cholmod_common *Common)
#define CHOLMOD_PATTERN
#define MAX(a, b)
#define CHOLMOD_GIVEN
static void amesos_print_value(Int print, Int xtype, double *Xx, double *Xz, Int p, cholmod_common *Common)
int CHOLMOD() print_sparse(cholmod_sparse *A, char *name, cholmod_common *Common)
#define CHOLMOD_AMD
int CHOLMOD() dump_partition(UF_long n, Int *Cp, Int *Ci, Int *Cnw, Int *Part, UF_long sepsize, cholmod_common *Common)
#define P2(format, arg)
#define CHOLMOD_REAL
#define NULL
int CHOLMOD() dump_dense(cholmod_dense *X, char *name, cholmod_common *Common)
#define ASSERT(expression)
#define PRINT2(params)
double Real
#define ERR(msg)
#define ID
#define CHOLMOD_METIS
#define PRINTVALUE(value)
#define P1(format, arg)
#define ETC_START(count, limit)
#define CHOLMOD_INT
#define DTYPE
int CHOLMOD() dump_perm(Int *Perm, size_t len, size_t n, char *name, cholmod_common *Common)
#define CHOLMOD_POSTORDERED
#define ETC_DISABLE(count)
#define CHOLMOD_INVALID
void CHOLMOD() dump_super(UF_long s, Int *Super, Int *Lpi, Int *Ls, Int *Lpx, double *Lx, int xentry, cholmod_common *Common)
static int check_parent(Int *Parent, size_t n, Int print, char *name, cholmod_common *Common)
#define CHOLMOD_NOT_POSDEF
#define CHOLMOD_OK
void CHOLMOD() dump_real(char *name, Real *X, UF_long nrow, UF_long ncol, int lower, int xentry, cholmod_common *Common)
int CHOLMOD() print_perm(Int *Perm, size_t len, size_t n, char *name, cholmod_common *Common)
#define PRINT0(params)
#define CHOLMOD_OUT_OF_MEMORY
static int check_subset(Int *S, UF_long len, size_t n, Int print, char *name, cholmod_common *Common)
#define CHOLMOD_LONG
#define CHOLMOD_INTLONG
int CHOLMOD() dump_mem(char *where, UF_long should, cholmod_common *Common)
int CHOLMOD() allocate_work(size_t nrow, size_t iworksize, size_t xworksize, cholmod_common *Common)
#define CHOLMOD_MAXMETHODS
static int check_dense(Int print, char *name, cholmod_dense *X, cholmod_common *Common)
#define RETURN_IF_NULL(A, result)
#define CHOLMOD_DSMALL
#define I_8
#define CHOLMOD_COLAMD
int CHOLMOD() dump_parent(Int *Parent, size_t n, char *name, cholmod_common *Common)
#define MIN(a, b)
#define CHOLMOD_SINGLE
int CHOLMOD() dump_factor(cholmod_factor *L, char *name, cholmod_common *Common)
#define CHOLMOD_SIMPLICIAL
static int check_perm(Int *Wi, Int print, char *name, Int *Perm, size_t len, size_t n, cholmod_common *Common)
#define P3(format, arg)
UF_long CHOLMOD() clear_flag(cholmod_common *Common)
#define CHOLMOD_NESDIS
int CHOLMOD() print_common(char *name, cholmod_common *Common)
#define UF_long
int CHOLMOD() print_subset(Int *Set, UF_long len, size_t n, char *name, cholmod_common *Common)
#define ETC_ENABLE(condition, count, limit)
#define CHOLMOD_MAIN_VERSION
#define IMPLIES(p, q)
#define I8
#define TRUE
#define CHOLMOD_ZOMPLEX
#define CHOLMOD_NATURAL
int CHOLMOD() print_factor(cholmod_factor *L, char *name, cholmod_common *Common)
#define CHOLMOD_DATE
#define ITYPE