Amesos Package Browser (Single Doxygen Collection) Development
amesos_cholmod_check.c
Go to the documentation of this file.
00001 /* ========================================================================== */
00002 /* === Check/cholmod_check ================================================== */
00003 /* ========================================================================== */
00004 
00005 /* -----------------------------------------------------------------------------
00006  * CHOLMOD/Check Module.  Copyright (C) 2005-2006, Timothy A. Davis
00007  * The CHOLMOD/Check Module is licensed under Version 2.1 of the GNU
00008  * Lesser General Public License.  See lesser.txt for a text of the license.
00009  * CHOLMOD is also available under other licenses; contact authors for details.
00010  * http://www.cise.ufl.edu/research/sparse
00011  * -------------------------------------------------------------------------- */
00012 
00013 /* Routines to check and print the contents of the 5 CHOLMOD objects:
00014  *
00015  * No CHOLMOD routine calls the check or print routines.  If a user wants to
00016  * check CHOLMOD's input parameters, a separate call to the appropriate check
00017  * routine should be used before calling other CHOLMOD routines.
00018  *
00019  * cholmod_check_common   check statistics and workspace in Common
00020  * cholmod_check_sparse   check sparse matrix in compressed column form
00021  * cholmod_check_dense    check dense matrix
00022  * cholmod_check_factor   check factorization
00023  * cholmod_check_triplet  check sparse matrix in triplet form
00024  *
00025  * cholmod_print_common   print statistics in Common
00026  * cholmod_print_sparse   print sparse matrix in compressed column form
00027  * cholmod_print_dense    print dense matrix
00028  * cholmod_print_factor   print factorization
00029  * cholmod_print_triplet  print sparse matrix in triplet form
00030  *
00031  * In addition, this file contains routines to check and print three types of
00032  * integer vectors:
00033  * 
00034  * cholmod_check_perm   check a permutation of 0:n-1 (no duplicates)
00035  * cholmod_check_subset   check a subset of 0:n-1 (duplicates OK)
00036  * cholmod_check_parent   check an elimination tree
00037  *
00038  * cholmod_print_perm   print a permutation
00039  * cholmod_print_subset   print a subset
00040  * cholmod_print_parent   print an elimination tree
00041  *
00042  * Each Common->print level prints the items at or below the given level:
00043  *
00044  *  0: print nothing; just check the data structures and return TRUE/FALSE
00045  *  1: error messages
00046  *  2: warning messages
00047  *  3: one-line summary of each object printed
00048  *  4: short summary of each object (first and last few entries)
00049  *  5: entire contents of the object
00050  *
00051  * No CHOLMOD routine calls these routines, so no printing occurs unless
00052  * the user specifically calls a cholmod_print_* routine.  Thus, the default
00053  * print level is 3.
00054  *
00055  * Common->precise controls the # of digits printed for numerical entries
00056  * (5 if FALSE, 15 if TRUE).
00057  *
00058  * If Common->print_function is NULL, then no printing occurs.  The
00059  * cholmod_check_* and cholmod_print_* routines still check their inputs and
00060  * return TRUE/FALSE if the object is valid or not.
00061  *
00062  * This file also includes debugging routines that are enabled only when
00063  * NDEBUG is defined in cholmod_internal.h (cholmod_dump_*).
00064  */
00065 
00066 #ifndef NCHECK
00067 
00068 #include "amesos_cholmod_internal.h"
00069 #include "amesos_cholmod_check.h"
00070 
00071 /* ========================================================================== */
00072 /* === printing definitions ================================================= */
00073 /* ========================================================================== */
00074 
00075 #ifdef LONG
00076 #define I8 "%8ld"
00077 #define I_8 "%-8ld"
00078 #else
00079 #define I8 "%8d"
00080 #define I_8 "%-8d"
00081 #endif
00082 
00083 #define PR(i,format,arg) \
00084 { \
00085     if (print >= i && Common->print_function != NULL) \
00086     { \
00087   (Common->print_function) (format, arg) ; \
00088     } \
00089 }
00090 
00091 #define P1(format,arg) PR(1,format,arg)
00092 #define P2(format,arg) PR(2,format,arg)
00093 #define P3(format,arg) PR(3,format,arg)
00094 #define P4(format,arg) PR(4,format,arg)
00095 
00096 #define ERR(msg) \
00097 { \
00098     P1 ("\nCHOLMOD ERROR: %s: ", type) ; \
00099     if (name != NULL) \
00100     { \
00101   P1 ("%s", name) ; \
00102     } \
00103     P1 (": %s\n", msg) ; \
00104     ERROR (CHOLMOD_INVALID, "invalid") ; \
00105     return (FALSE) ; \
00106 }
00107 
00108 /* print a numerical value */
00109 #define PRINTVALUE(value) \
00110 { \
00111     if (Common->precise) \
00112     { \
00113   P4 (" %23.15e", value) ; \
00114     } \
00115     else \
00116     { \
00117   P4 (" %.5g", value) ; \
00118     } \
00119 }
00120 
00121 /* start printing */
00122 #define ETC_START(count,limit) \
00123 { \
00124     count = (init_print == 4) ? (limit) : (-1) ; \
00125 }
00126 
00127 /* re-enable printing if condition is met */
00128 #define ETC_ENABLE(condition,count,limit) \
00129 { \
00130     if ((condition) && init_print == 4) \
00131     { \
00132   count = limit ; \
00133   print = 4 ; \
00134     } \
00135 }
00136 
00137 /* turn off printing if limit is reached */
00138 #define ETC_DISABLE(count) \
00139 { \
00140     if ((count >= 0) && (count-- == 0) && print == 4) \
00141     { \
00142   P4 ("%s", "    ...\n")  ; \
00143   print = 3 ; \
00144     } \
00145 }
00146 
00147 /* re-enable printing, or turn if off after limit is reached */
00148 #define ETC(condition,count,limit) \
00149 { \
00150     ETC_ENABLE (condition, count, limit) ; \
00151     ETC_DISABLE (count) ; \
00152 }
00153 
00154 #define BOOLSTR(x) ((x) ? "true " : "false")
00155 
00156 /* ========================================================================== */
00157 /* === print_value ========================================================== */
00158 /* ========================================================================== */
00159 
00160 static void amesos_print_value
00161 (
00162     Int print,
00163     Int xtype,
00164     double *Xx,
00165     double *Xz,
00166     Int p,
00167     cholmod_common *Common)
00168 {
00169     if (xtype == CHOLMOD_REAL)
00170     {
00171   PRINTVALUE (Xx [p]) ;
00172     }
00173     else if (xtype == CHOLMOD_COMPLEX)
00174     {
00175   P4 ("%s", "(") ;
00176   PRINTVALUE (Xx [2*p  ]) ;
00177   P4 ("%s", " , ") ;
00178   PRINTVALUE (Xx [2*p+1]) ;
00179   P4 ("%s", ")") ;
00180     }
00181     else if (xtype == CHOLMOD_ZOMPLEX)
00182     {
00183   P4 ("%s", "(") ;
00184   PRINTVALUE (Xx [p]) ;
00185   P4 ("%s", " , ") ;
00186   PRINTVALUE (Xz [p]) ;
00187   P4 ("%s", ")") ;
00188     }
00189 }
00190 
00191 /* ========================================================================== */
00192 /* === cholmod_check_common ================================================= */
00193 /* ========================================================================== */
00194 
00195 /* Print and verify the contents of Common */
00196 
00197 static int check_common
00198 (
00199     Int print,
00200     char *name,
00201     cholmod_common *Common
00202 )
00203 {
00204     double fl, lnz ;
00205     double *Xwork ;
00206     Int *Flag, *Head ;
00207     UF_long mark ;
00208     Int i, nrow, nmethods, ordering, xworksize, amd_printed, init_print ;
00209     char *type = "common" ;
00210 
00211     /* ---------------------------------------------------------------------- */
00212     /* print control parameters and statistics */
00213     /* ---------------------------------------------------------------------- */
00214 
00215     RETURN_IF_NULL_COMMON (FALSE) ;
00216     init_print = print ;
00217 
00218     P2 ("%s", "\n") ;
00219 
00220     P1 ("CHOLMOD version %d", CHOLMOD_MAIN_VERSION) ;
00221     P1 (".%d", CHOLMOD_SUB_VERSION) ;
00222     P1 (".%d", CHOLMOD_SUBSUB_VERSION) ;
00223     P1 (", %s: ", CHOLMOD_DATE) ;
00224 
00225     if (name != NULL)
00226     {
00227   P1 ("%s: ", name) ;
00228     }
00229     switch (Common->status)
00230     {
00231 
00232   case CHOLMOD_OK:
00233       P1 ("%s", "status: OK\n") ;
00234       break ;
00235 
00236   case CHOLMOD_OUT_OF_MEMORY:
00237       P1 ("%s", "status: ERROR, out of memory\n") ;
00238       break ;
00239 
00240   case CHOLMOD_INVALID:
00241       P1 ("%s", "status: ERROR, invalid parameter\n") ;
00242       break ;
00243 
00244   case CHOLMOD_TOO_LARGE:
00245       P1 ("%s", "status: ERROR, problem too large\n") ;
00246       break ;
00247 
00248   case CHOLMOD_NOT_INSTALLED:
00249       P1 ("%s", "status: ERROR, method not installed\n") ;
00250       break ;
00251 
00252   case CHOLMOD_NOT_POSDEF:
00253       P1 ("%s", "status: warning, matrix not positive definite\n") ;
00254       break ;
00255 
00256   case CHOLMOD_DSMALL:
00257       P1 ("%s", "status: warning, diagonal entry has tiny abs. value\n") ;
00258       break ;
00259 
00260   default:
00261       ERR ("unknown status") ;
00262     }
00263 
00264     P2 ("  Architecture: %s\n", CHOLMOD_ARCHITECTURE) ;
00265     P3 ("    sizeof(int):      %d\n", (int) sizeof (int)) ;
00266     P3 ("    sizeof(UF_long):  %d\n", (int) sizeof (UF_long)) ;
00267     P3 ("    sizeof(void *):   %d\n", (int) sizeof (void *)) ;
00268     P3 ("    sizeof(double):   %d\n", (int) sizeof (double)) ;
00269     P3 ("    sizeof(Int):      %d (CHOLMOD's basic integer)\n", (int) sizeof (Int)) ;
00270     P3 ("    sizeof(BLAS_INT): %d (integer used in the BLAS)\n",
00271       (int) sizeof (BLAS_INT)) ;
00272 
00273     if (Common->fl != EMPTY)
00274     {
00275   P2 ("%s", "  Results from most recent analysis:\n") ;
00276   P2 ("    Cholesky flop count: %.5g\n", Common->fl) ;
00277   P2 ("    Nonzeros in L:       %.5g\n", Common->lnz) ;
00278     }
00279     if (Common->modfl != EMPTY)
00280     {
00281   P2 ("    Update/downdate flop count: %.5g\n", Common->modfl) ;
00282     }
00283 
00284     P2 ("  memory blocks in use:    %8.0f\n", (double) (Common->malloc_count)) ;
00285     P2 ("  memory in use (MB):      %8.1f\n", 
00286   (double) (Common->memory_inuse) / 1048576.) ;
00287     P2 ("  peak memory usage (MB):  %8.1f\n", 
00288   (double) (Common->memory_usage) / 1048576.) ;
00289 
00290     /* ---------------------------------------------------------------------- */
00291     /* primary control parameters and related ordering statistics */
00292     /* ---------------------------------------------------------------------- */
00293 
00294     P3 ("  maxrank:    update/downdate rank:   "ID"\n",
00295       (Int) CHOLMOD(maxrank) (0, Common)) ;
00296     P3 ("  supernodal control: %d", Common->supernodal) ;
00297     P3 (" %g ", Common->supernodal_switch) ;
00298     if (Common->supernodal <= CHOLMOD_SIMPLICIAL)
00299     {
00300   P3 ("%s", "(always do simplicial)\n") ;
00301     }
00302     else if (Common->supernodal == CHOLMOD_AUTO)
00303     {
00304   P3 ("(supernodal if flops/lnz >= %g)\n", Common->supernodal_switch) ;
00305     }
00306     else
00307     {
00308   P3 ("%s", "(always do supernodal)\n") ;
00309     }
00310 
00311     nmethods = MIN (Common->nmethods, CHOLMOD_MAXMETHODS) ;
00312     nmethods = MAX (0, nmethods) ;
00313 
00314     if (nmethods > 0)
00315     {
00316   P3 ("%s", "  nmethods:   number of ordering methods to try: ") ;
00317   P3 (""ID"\n", nmethods) ;
00318     }
00319     else
00320     {
00321   P3 ("%s", "  nmethods=0: default strategy:  Try user permutation if "
00322     "given.  Try AMD.\n") ;
00323 #ifndef NPARTITION
00324   if (Common->default_nesdis)
00325   {
00326       P3 ("%s", "    Try NESDIS if AMD reports flops/nnz(L) >= 500 and "
00327     "nnz(L)/nnz(A) >= 5.\n") ;
00328   }
00329   else
00330   {
00331       P3 ("%s", "    Try METIS if AMD reports flops/nnz(L) >= 500 and "
00332     "nnz(L)/nnz(A) >= 5.\n") ;
00333   }
00334 #endif
00335   P3 ("%s", "    Select best ordering tried.\n") ;
00336   Common->method [0].ordering = CHOLMOD_GIVEN ;
00337   Common->method [1].ordering = CHOLMOD_AMD ;
00338   Common->method [2].ordering = CHOLMOD_METIS ;
00339 #ifndef NPARTITION
00340   nmethods = 3 ;
00341 #else
00342   nmethods = 2 ;
00343 #endif
00344     }
00345 
00346     amd_printed = FALSE ;
00347     for (i = 0 ; i < nmethods ; i++)
00348     {
00349   P3 ("    method "ID": ", i) ;
00350   ordering = Common->method [i].ordering ;
00351   fl = Common->method [i].fl ;
00352   lnz = Common->method [i].lnz ;
00353   switch (ordering)
00354   {
00355 
00356       case CHOLMOD_NATURAL:
00357     P3 ("%s", "natural\n") ;
00358     break ;
00359 
00360       case CHOLMOD_GIVEN:
00361     P3 ("%s", "user permutation (if given)\n") ;
00362     break ;
00363 
00364       case CHOLMOD_AMD:
00365     P3 ("%s", "AMD (or COLAMD if factorizing AA')\n") ;
00366     amd_printed = TRUE ;
00367     break ;
00368 
00369       case CHOLMOD_COLAMD:
00370     P3 ("%s", "AMD if factorizing A, COLAMD if factorizing AA')\n");
00371     amd_printed = TRUE ;
00372     break ;
00373 
00374       case CHOLMOD_METIS:
00375     P3 ("%s", "METIS_NodeND nested dissection\n") ;
00376     break ;
00377 
00378       case CHOLMOD_NESDIS:
00379     P3 ("%s", "CHOLMOD nested dissection\n") ;
00380 
00381     P3 ("        nd_small: # nodes in uncut subgraph: "ID"\n",
00382       (Int) (Common->method [i].nd_small)) ;
00383     P3 ("        nd_compress: compress the graph:     %s\n",
00384       BOOLSTR (Common->method [i].nd_compress)) ;
00385     P3 ("        nd_camd: use constrained min degree: %s\n",
00386       BOOLSTR (Common->method [i].nd_camd)) ;
00387     break ;
00388 
00389       default:
00390     P3 (ID, ordering) ;
00391     ERR ("unknown ordering method") ;
00392     break ;
00393 
00394   }
00395 
00396   if (!(ordering == CHOLMOD_NATURAL || ordering == CHOLMOD_GIVEN))
00397   {
00398       if (Common->method [i].prune_dense < 0)
00399       {
00400     P3 ("        prune_dense: for pruning dense nodes:   %s\n",
00401       " none pruned") ;
00402       }
00403       else
00404       {
00405     P3 ("        prune_dense: for pruning dense nodes:   "
00406         "%.5g\n",
00407         Common->method [i].prune_dense) ;
00408     P3 ("        a dense node has degree "
00409       ">= max(16,(%.5g)*sqrt(n))\n",
00410         Common->method [i].prune_dense) ;
00411       }
00412   }
00413 
00414   if (ordering == CHOLMOD_COLAMD || ordering == CHOLMOD_NESDIS)
00415   {
00416       if (Common->method [i].prune_dense2 < 0)
00417       {
00418     P3 ("        prune_dense2: for pruning dense rows for AA':"
00419       "  %s\n", " none pruned") ;
00420       }
00421       else
00422       {
00423     P3 ("        prune_dense2: for pruning dense rows for AA':"
00424         " %.5g\n", Common->method [i].prune_dense2) ;
00425     P3 ("        a dense row has degree "
00426       ">= max(16,(%.5g)*sqrt(ncol))\n",
00427         Common->method [i].prune_dense2) ;
00428       }
00429   }
00430 
00431   if (fl  != EMPTY) P3 ("        flop count: %.5g\n", fl) ;
00432   if (lnz != EMPTY) P3 ("        nnz(L):     %.5g\n", lnz) ;
00433     }
00434 
00435     /* backup AMD results, if any */
00436     if (!amd_printed)
00437     {
00438   P3 ("%s", "    backup method: ") ;
00439   P3 ("%s", "AMD (or COLAMD if factorizing AA')\n") ;
00440   fl = Common->method [nmethods].fl ;
00441   lnz = Common->method [nmethods].lnz ;
00442   if (fl  != EMPTY) P3 ("        AMD flop count: %.5g\n", fl) ;
00443   if (lnz != EMPTY) P3 ("        AMD nnz(L):     %.5g\n", lnz) ;
00444     }
00445 
00446     /* ---------------------------------------------------------------------- */
00447     /* arcane control parameters */
00448     /* ---------------------------------------------------------------------- */
00449 
00450     if (Common->final_asis)
00451     {
00452   P4 ("%s", "  final_asis: TRUE, leave as is\n") ;
00453     }
00454     else
00455     {
00456   P4 ("%s", "  final_asis: FALSE, convert when done\n") ;
00457   if (Common->final_super)
00458   {
00459       P4 ("%s", "  final_super: TRUE, leave in supernodal form\n") ;
00460   }
00461   else
00462   {
00463       P4 ("%s", "  final_super: FALSE, convert to simplicial form\n") ;
00464   }
00465   if (Common->final_ll)
00466   {
00467       P4 ("%s", "  final_ll: TRUE, convert to LL' form\n") ;
00468   }
00469   else
00470   {
00471       P4 ("%s", "  final_ll: FALSE, convert to LDL' form\n") ;
00472   }
00473   if (Common->final_pack)
00474   {
00475       P4 ("%s", "  final_pack: TRUE, pack when done\n") ;
00476   }
00477   else
00478   {
00479       P4 ("%s", "  final_pack: FALSE, do not pack when done\n") ;
00480   }
00481   if (Common->final_monotonic)
00482   {
00483       P4 ("%s", "  final_monotonic: TRUE, ensure L is monotonic\n") ;
00484   }
00485   else
00486   {
00487       P4 ("%s",
00488     "  final_monotonic: FALSE, do not ensure L is monotonic\n") ;
00489   }
00490   P4 ("  final_resymbol: remove zeros from amalgamation: %s\n",
00491     BOOLSTR (Common->final_resymbol)) ;
00492     }
00493 
00494     P4 ("  dbound:  LDL' diagonal threshold: % .5g\n    Entries with abs. value"
00495       " less than dbound are replaced with +/- dbound.\n",
00496       Common->dbound) ;
00497 
00498     P4 ("  grow0: memory reallocation: % .5g\n", Common->grow0) ;
00499     P4 ("  grow1: memory reallocation: % .5g\n", Common->grow1) ;
00500     P4 ("  grow2: memory reallocation: %g\n", (double) (Common->grow2)) ;
00501 
00502     P4 ("%s", "  nrelax, zrelax:  supernodal amalgamation rule:\n") ;
00503     P4 ("%s", "    s = # columns in two adjacent supernodes\n") ;
00504     P4 ("%s", "    z = % of zeros in new supernode if they are merged.\n") ;
00505     P4 ("%s", "    Two supernodes are merged if") ;
00506     P4 (" (s <= %g) or (no new zero entries) or\n",
00507       (double) (Common->nrelax [0])) ;
00508     P4 ("    (s <= %g and ",  (double) (Common->nrelax [1])) ;
00509     P4 ("z < %.5g%%) or",      Common->zrelax [0] * 100) ;
00510     P4 (" (s <= %g and ",     (double) (Common->nrelax [2])) ;
00511     P4 ("z < %.5g%%) or",      Common->zrelax [1] * 100) ;
00512     P4 (" (z < %.5g%%)\n",     Common->zrelax [2] * 100) ;
00513 
00514     /* ---------------------------------------------------------------------- */
00515     /* check workspace */
00516     /* ---------------------------------------------------------------------- */
00517 
00518     mark = Common->mark ;
00519     nrow = Common->nrow ;
00520     Flag = Common->Flag ;
00521     Head = Common->Head ;
00522     if (nrow > 0)
00523     {
00524   if (mark < 0 || Flag == NULL || Head == NULL)
00525   {
00526       ERR ("workspace corrupted (Flag and/or Head missing)") ;
00527   }
00528   for (i = 0 ; i < nrow ; i++)
00529   {
00530       if (Flag [i] >= mark)
00531       {
00532     PRINT0 (("Flag ["ID"]="ID", mark = %ld\n", i, Flag [i], mark)) ;
00533     ERR ("workspace corrupted (Flag)") ;
00534       }
00535   }
00536   for (i = 0 ; i <= nrow ; i++)
00537   {
00538       if (Head [i] != EMPTY)
00539       {
00540     PRINT0 (("Head ["ID"] = "ID",\n", i, Head [i])) ;
00541     ERR ("workspace corrupted (Head)") ;
00542       }
00543   }
00544     }
00545     xworksize = Common->xworksize ;
00546     Xwork = Common->Xwork ;
00547     if (xworksize > 0)
00548     {
00549   if (Xwork == NULL)
00550   {
00551       ERR ("workspace corrupted (Xwork missing)") ;
00552   }
00553   for (i = 0 ; i < xworksize ; i++)
00554   {
00555       if (Xwork [i] != 0.)
00556       {
00557     PRINT0 (("Xwork ["ID"] = %g\n", i, Xwork [i])) ;
00558     ERR ("workspace corrupted (Xwork)") ;
00559       }
00560   }
00561     }
00562 
00563     /* workspace and parameters are valid */
00564     P3 ("%s", "  OK\n") ;
00565     P4 ("%s", "\n") ;
00566     return (TRUE) ;
00567 }
00568 
00569 
00570 int CHOLMOD(check_common)
00571 (
00572     cholmod_common *Common
00573 )
00574 {
00575     return (check_common (0, NULL, Common)) ;
00576 }
00577 
00578 
00579 int CHOLMOD(print_common)
00580 (
00581     /* ---- input ---- */
00582     char *name,   /* printed name of Common object */
00583     /* --------------- */
00584     cholmod_common *Common
00585 )
00586 {
00587     Int print = (Common == NULL) ? 3 : (Common->print) ;
00588     return (check_common (print, name, Common)) ;
00589 }
00590 
00591 
00592 /* ========================================================================== */
00593 /* === cholmod_check_sparse ================================================= */
00594 /* ========================================================================== */
00595 
00596 /* Ensure that a sparse matrix in column-oriented form is valid, and optionally
00597  * print it.  Returns the number of entries on the diagonal or -1 if error.
00598  *
00599  * workspace: Iwork (nrow)
00600  */
00601 
00602 static UF_long check_sparse
00603 (
00604     Int *Wi,
00605     Int print,
00606     char *name,
00607     cholmod_sparse *A,
00608     UF_long *nnzdiag,
00609     cholmod_common *Common
00610 )
00611 {
00612     double *Ax, *Az ;
00613     Int *Ap, *Ai, *Anz ;
00614     Int nrow, ncol, nzmax, sorted, packed, j, p, pend, i, nz, ilast,
00615   space, init_print, dnz, count, xtype ;
00616     char *type = "sparse" ;
00617 
00618     /* ---------------------------------------------------------------------- */
00619     /* print header information */
00620     /* ---------------------------------------------------------------------- */
00621 
00622     P4 ("%s", "\n") ;
00623     P3 ("%s", "CHOLMOD sparse:  ") ;
00624     if (name != NULL)
00625     {
00626   P3 ("%s: ", name) ;
00627     }
00628 
00629     if (A == NULL)
00630     {
00631   ERR ("null") ;
00632     }
00633 
00634     nrow = A->nrow ;
00635     ncol = A->ncol ;
00636     nzmax = A->nzmax ;
00637     sorted = A->sorted ;
00638     packed = A->packed ;
00639     xtype = A->xtype ;
00640     Ap = A->p ;
00641     Ai = A->i ;
00642     Ax = A->x ;
00643     Az = A->z ;
00644     Anz = A->nz ;
00645     nz = CHOLMOD(nnz) (A, Common) ;
00646 
00647     P3 (" "ID"", nrow) ;
00648     P3 ("-by-"ID", ", ncol) ;
00649     P3 ("nz "ID",", nz) ;
00650     if (A->stype > 0)
00651     {
00652   P3 ("%s", " upper.") ;
00653     }
00654     else if (A->stype < 0)
00655     {
00656   P3 ("%s", " lower.") ;
00657     }
00658     else
00659     {
00660   P3 ("%s", " up/lo.") ;
00661     }
00662 
00663     P4 ("\n  nzmax "ID", ", nzmax) ;
00664     if (nz > nzmax)
00665     {
00666   ERR ("nzmax too small") ;
00667     }
00668     if (!sorted)
00669     {
00670   P4 ("%s", "un") ;
00671     }
00672     P4 ("%s", "sorted, ") ;
00673     if (!packed)
00674     {
00675   P4 ("%s", "un") ;
00676     }
00677     P4 ("%s", "packed, ") ;
00678 
00679     switch (A->itype)
00680     {
00681   case CHOLMOD_INT:     P4 ("%s", "\n  scalar types: int, ") ; break ;
00682   case CHOLMOD_INTLONG: ERR ("mixed int/UF_long type unsupported") ;
00683   case CHOLMOD_LONG:    P4 ("%s", "\n  scalar types: UF_long, ") ; break ;
00684   default:        ERR ("unknown itype") ;
00685     }
00686 
00687     switch (A->xtype)
00688     {
00689   case CHOLMOD_PATTERN: P4 ("%s", "pattern") ;  break ;
00690   case CHOLMOD_REAL:    P4 ("%s", "real") ; break ;
00691   case CHOLMOD_COMPLEX: P4 ("%s", "complex") ;  break ;
00692   case CHOLMOD_ZOMPLEX: P4 ("%s", "zomplex") ;  break ;
00693   default:        ERR ("unknown xtype") ;
00694     }
00695 
00696     switch (A->dtype)
00697     {
00698   case CHOLMOD_DOUBLE:  P4 ("%s", ", double\n") ;        break ;
00699   case CHOLMOD_SINGLE:  ERR ("float unsupported") ;
00700   default:        ERR ("unknown dtype") ;
00701     }
00702 
00703     if (A->itype != ITYPE || A->dtype != DTYPE)
00704     {
00705   ERR ("integer and real type must match routine") ;
00706     }
00707 
00708     if (A->stype && nrow != ncol)
00709     {
00710   ERR ("symmetric but not square") ;
00711     }
00712 
00713     /* check for existence of Ap, Ai, Anz, Ax, and Az arrays */
00714     if (Ap == NULL)
00715     {
00716   ERR ("p array not present") ;
00717     }
00718     if (Ai == NULL)
00719     {
00720   ERR ("i array not present") ;
00721     }
00722     if (!packed && Anz == NULL)
00723     {
00724   ERR ("nz array not present") ;
00725     }
00726     if (xtype != CHOLMOD_PATTERN && Ax == NULL)
00727     {
00728   ERR ("x array not present") ;
00729     }
00730     if (xtype == CHOLMOD_ZOMPLEX && Az == NULL)
00731     {
00732   ERR ("z array not present") ;
00733     }
00734 
00735     /* packed matrices must start at Ap [0] = 0 */
00736     if (packed && Ap [0] != 0)
00737     {
00738   ERR ("p [0] must be zero") ;
00739     }
00740     if (packed && (Ap [ncol] < Ap [0] || Ap [ncol] > nzmax))
00741     {
00742   ERR ("p [ncol] invalid") ;
00743     }
00744 
00745     /* ---------------------------------------------------------------------- */
00746     /* allocate workspace if needed */
00747     /* ---------------------------------------------------------------------- */
00748 
00749     if (!sorted)
00750     {
00751   if (Wi == NULL)
00752   {
00753       CHOLMOD(allocate_work) (0, nrow, 0, Common) ;
00754       Wi = Common->Iwork ;  /* size nrow, (i/i/l) */
00755   }
00756   if (Common->status < CHOLMOD_OK)
00757   {
00758       return (FALSE) ;      /* out of memory */
00759   }
00760   for (i = 0 ; i < nrow ; i++)
00761   {
00762       Wi [i] = EMPTY ;
00763   }
00764     }
00765 
00766     /* ---------------------------------------------------------------------- */
00767     /* check and print each column */
00768     /* ---------------------------------------------------------------------- */
00769 
00770     init_print = print ;
00771     dnz = 0 ;
00772     ETC_START (count, 8) ;
00773 
00774     for (j = 0 ; j < ncol ; j++)
00775     {
00776   ETC (j == ncol-1, count, 4) ;
00777   p = Ap [j] ;
00778   if (packed)
00779   {
00780       pend = Ap [j+1] ;
00781       nz = pend - p ;
00782   }
00783   else
00784   {
00785       /* Note that Anz [j] < 0 is treated as zero */
00786       nz = MAX (0, Anz [j]) ;
00787       pend = p + nz ;
00788   }
00789   /* Note that space can be negative if the matrix is non-monotonic */
00790   space = Ap [j+1] - p ;
00791   P4 ("  col "ID":", j) ;
00792   P4 (" nz "ID"", nz) ;
00793   P4 (" start "ID"", p) ;
00794   P4 (" end "ID"", pend) ;
00795   if (!packed)
00796   {
00797       P4 (" space "ID"", space) ;
00798   }
00799   P4 ("%s", ":\n") ;
00800   if (p < 0 || pend > nzmax)
00801   {
00802       ERR ("pointer invalid") ;
00803   }
00804   if (nz < 0 || nz > nrow)
00805   {
00806       ERR ("nz invalid") ;
00807   }
00808   ilast = EMPTY ;
00809 
00810   for ( ; p < pend ; p++)
00811   {
00812       ETC (j == ncol-1 && p >= pend-4, count, -1) ;
00813       i = Ai [p] ;
00814       P4 ("  "I8":", i) ;
00815 
00816       amesos_print_value (print, xtype, Ax, Az, p, Common) ;
00817 
00818       if (i == j)
00819       {
00820     dnz++ ;
00821       }
00822       if (i < 0 || i >= nrow)
00823       {
00824     ERR ("row index out of range") ;
00825       }
00826       if (sorted && i <= ilast)
00827       {
00828     ERR ("row indices out of order") ;
00829       }
00830       if (!sorted && Wi [i] == j)
00831       {
00832     ERR ("duplicate row index") ;
00833       }
00834       P4 ("%s", "\n") ;
00835       ilast = i ;
00836       if (!sorted)
00837       {
00838     Wi [i] = j ;
00839       }
00840   }
00841     }
00842 
00843     /* matrix is valid */
00844     P4 ("  nnz on diagonal: "ID"\n", dnz) ;
00845     P3 ("%s", "  OK\n") ;
00846     P4 ("%s", "\n") ;
00847     *nnzdiag = dnz ;
00848     return (TRUE) ;
00849 }
00850 
00851 
00852 int CHOLMOD(check_sparse)
00853 (
00854     /* ---- input ---- */
00855     cholmod_sparse *A,  /* sparse matrix to check */
00856     /* --------------- */
00857     cholmod_common *Common
00858 )
00859 {
00860     UF_long nnzdiag ;
00861     RETURN_IF_NULL_COMMON (FALSE) ;
00862     Common->status = CHOLMOD_OK ;
00863     return (check_sparse (NULL, 0, NULL, A, &nnzdiag, Common)) ;
00864 }
00865 
00866 
00867 int CHOLMOD(print_sparse)
00868 (
00869     /* ---- input ---- */
00870     cholmod_sparse *A,  /* sparse matrix to print */
00871     char *name,   /* printed name of sparse matrix */
00872     /* --------------- */
00873     cholmod_common *Common
00874 )
00875 {
00876     UF_long nnzdiag ;
00877     RETURN_IF_NULL_COMMON (FALSE) ;
00878     Common->status = CHOLMOD_OK ;
00879     return (check_sparse (NULL, Common->print, name, A, &nnzdiag, Common)) ;
00880 }
00881 
00882 
00883 /* ========================================================================== */
00884 /* === cholmod_check_dense ================================================== */
00885 /* ========================================================================== */
00886 
00887 /* Ensure a dense matrix is valid, and optionally print it. */
00888 
00889 static int check_dense
00890 (
00891     Int print,
00892     char *name,
00893     cholmod_dense *X,
00894     cholmod_common *Common
00895 )
00896 {
00897     double *Xx, *Xz ;
00898     Int i, j, d, nrow, ncol, nzmax, nz, init_print, count, xtype ;
00899     char *type = "dense" ;
00900 
00901     /* ---------------------------------------------------------------------- */
00902     /* print header information */
00903     /* ---------------------------------------------------------------------- */
00904 
00905     P4 ("%s", "\n") ;
00906     P3 ("%s", "CHOLMOD dense:   ") ;
00907     if (name != NULL)
00908     {
00909   P3 ("%s: ", name) ;
00910     }
00911 
00912     if (X == NULL)
00913     {
00914   ERR ("null") ;
00915     }
00916 
00917     nrow = X->nrow ;
00918     ncol = X->ncol ;
00919     nzmax = X->nzmax ;
00920     d = X->d ;
00921     Xx = X->x ;
00922     Xz = X->z ;
00923     xtype = X->xtype ;
00924 
00925     P3 (" "ID"", nrow) ;
00926     P3 ("-by-"ID", ", ncol) ;
00927     P4 ("\n  leading dimension "ID", ", d) ;
00928     P4 ("nzmax "ID", ", nzmax) ;
00929     if (d * ncol > nzmax)
00930     {
00931   ERR ("nzmax too small") ;
00932     }
00933     if (d < nrow)
00934     {
00935   ERR ("leading dimension must be >= # of rows") ;
00936     }
00937     if (Xx == NULL)
00938     {
00939   ERR ("null") ;
00940     }
00941 
00942     switch (X->xtype)
00943     {
00944   case CHOLMOD_PATTERN: ERR ("pattern unsupported") ;  break ;
00945   case CHOLMOD_REAL:    P4 ("%s", "real") ; break ;
00946   case CHOLMOD_COMPLEX: P4 ("%s", "complex") ;  break ;
00947   case CHOLMOD_ZOMPLEX: P4 ("%s", "zomplex") ;  break ;
00948   default:        ERR ("unknown xtype") ;
00949     }
00950 
00951     switch (X->dtype)
00952     {
00953   case CHOLMOD_DOUBLE:  P4 ("%s", ", double\n") ;        break ;
00954   case CHOLMOD_SINGLE:  ERR ("single unsupported") ;
00955   default:        ERR ("unknown dtype") ;
00956     }
00957 
00958     /* ---------------------------------------------------------------------- */
00959     /* check and print each entry */
00960     /* ---------------------------------------------------------------------- */
00961 
00962     if (print >= 4)
00963     {
00964   init_print = print ;
00965   ETC_START (count, 9) ;
00966   nz = nrow * ncol ;
00967   for (j = 0 ; j < ncol ; j++)
00968   {
00969       ETC (j == ncol-1, count, 5) ;
00970       P4 ("  col "ID":\n", j) ;
00971       for (i = 0 ; i < nrow ; i++)
00972       {
00973     ETC (j == ncol-1 && i >= nrow-4, count, -1) ;
00974     P4 ("  "I8":", i) ;
00975 
00976     amesos_print_value (print, xtype, Xx, Xz, i+j*d, Common) ;
00977 
00978     P4 ("%s", "\n") ;
00979       }
00980   }
00981     }
00982 
00983     /* dense  is valid */
00984     P3 ("%s", "  OK\n") ;
00985     P4 ("%s", "\n") ;
00986     return (TRUE) ;
00987 }
00988 
00989 
00990 int CHOLMOD(check_dense)
00991 (
00992     /* ---- input ---- */
00993     cholmod_dense *X, /* dense matrix to check */
00994     /* --------------- */
00995     cholmod_common *Common
00996 )
00997 {
00998     RETURN_IF_NULL_COMMON (FALSE) ;
00999     Common->status = CHOLMOD_OK ;
01000     return (check_dense (0, NULL, X, Common)) ;
01001 }
01002 
01003 
01004 int CHOLMOD(print_dense)
01005 (
01006     /* ---- input ---- */
01007     cholmod_dense *X, /* dense matrix to print */
01008     char *name,   /* printed name of dense matrix */
01009     /* --------------- */
01010     cholmod_common *Common
01011 )
01012 {
01013     RETURN_IF_NULL_COMMON (FALSE) ;
01014     Common->status = CHOLMOD_OK ;
01015     return (check_dense (Common->print, name, X, Common)) ;
01016 }
01017 
01018 
01019 /* ========================================================================== */
01020 /* === cholmod_check_subset ================================================= */
01021 /* ========================================================================== */
01022 
01023 /* Ensure S (0:len-1) is a subset of 0:n-1.  Duplicates are allowed.  S may be
01024  * NULL.  A negative len denotes the set 0:n-1.
01025  *
01026  * To check the rset and cset for A(rset,cset), where nc and nr are the length
01027  * of cset and rset respectively:
01028  *
01029  *  cholmod_check_subset (cset, nc, A->ncol, Common) ;
01030  *  cholmod_check_subset (rset, nr, A->nrow, Common) ;
01031  *
01032  * workspace: none
01033  */
01034 
01035 static int check_subset
01036 (
01037     Int *S,
01038     UF_long len,
01039     size_t n,
01040     Int print,
01041     char *name,
01042     cholmod_common *Common
01043 )
01044 {
01045     Int i, k, init_print, count ;
01046     char *type = "subset" ;
01047 
01048     init_print = print ;
01049 
01050     if (S == NULL)
01051     {
01052   /* zero len denotes S = [ ], negative len denotes S = 0:n-1 */
01053   len = (len < 0) ? (-1) : 0 ;
01054     }
01055 
01056     P4 ("%s", "\n") ;
01057     P3 ("%s", "CHOLMOD subset:  ") ;
01058     if (name != NULL)
01059     {
01060   P3 ("%s: ", name) ;
01061     }
01062 
01063     P3 (" len: %ld ", len) ;
01064     if (len < 0)
01065     {
01066   P3 ("%s", "(denotes 0:n-1) ") ;
01067     }
01068     P3 ("n: "ID"", (Int) n) ;
01069     P4 ("%s", "\n") ;
01070 
01071     if (len <= 0 || S == NULL)
01072     {
01073   P3 ("%s", "  OK\n") ;
01074   P4 ("%s", "\n") ;
01075   return (TRUE) ;
01076     }
01077 
01078     if (print >= 4)
01079     {
01080   ETC_START (count, 8) ;
01081   for (k = 0 ; k < ((Int) len) ; k++)
01082   {
01083       ETC (k == ((Int) len) - 4, count, -1) ;
01084       i = S [k] ;
01085       P4 ("  "I8":", k) ;
01086       P4 (" "ID"\n", i) ;
01087       if (i < 0 || i >= ((Int) n))
01088       {
01089     ERR ("entry out range") ;
01090       }
01091   }
01092     }
01093     else
01094     {
01095   for (k = 0 ; k < ((Int) len) ; k++)
01096   {
01097       i = S [k] ;
01098       if (i < 0 || i >= ((Int) n))
01099       {
01100     ERR ("entry out range") ;
01101       }
01102   }
01103     }
01104     P3 ("%s", "  OK\n") ;
01105     P4 ("%s", "\n") ;
01106     return (TRUE) ;
01107 }
01108 
01109 
01110 int CHOLMOD(check_subset)
01111 (
01112     /* ---- input ---- */
01113     Int *Set,   /* Set [0:len-1] is a subset of 0:n-1.  Duplicates OK */
01114     UF_long len,  /* size of Set (an integer array), or < 0 if 0:n-1 */
01115     size_t n,   /* 0:n-1 is valid range */
01116     /* --------------- */
01117     cholmod_common *Common
01118 )
01119 {
01120     RETURN_IF_NULL_COMMON (FALSE) ;
01121     Common->status = CHOLMOD_OK ;
01122     return (check_subset (Set, len, n, 0, NULL, Common)) ;
01123 }
01124 
01125 
01126 int CHOLMOD(print_subset)
01127 (
01128     /* ---- input ---- */
01129     Int *Set,   /* Set [0:len-1] is a subset of 0:n-1.  Duplicates OK */
01130     UF_long len,  /* size of Set (an integer array), or < 0 if 0:n-1 */
01131     size_t n,   /* 0:n-1 is valid range */
01132     char *name,   /* printed name of Set */
01133     /* --------------- */
01134     cholmod_common *Common
01135 )
01136 {
01137     RETURN_IF_NULL_COMMON (FALSE) ;
01138     Common->status = CHOLMOD_OK ;
01139     return (check_subset (Set, len, n, Common->print, name, Common)) ;
01140 }
01141 
01142 
01143 /* ========================================================================== */
01144 /* === cholmod_check_perm =================================================== */
01145 /* ========================================================================== */
01146 
01147 /* Ensure that Perm [0..len-1] is a permutation of a subset of 0:n-1.  Perm
01148  * may be NULL, which is interpreted as the identity permutation.  There can
01149  * be no duplicate entries (len must be <= n).
01150  *
01151  * If n <= Common->nrow, then this routine takes O(len) time and does not
01152  * allocate any memory, by using Common->Flag.  Otherwise, it takes O(n) time
01153  * and ensures that Common->Iwork is at least n*sizeof(Int) in size.
01154  *
01155  * To check the fset:     cholmod_check_perm (fset, fsize, ncol, Common) ;
01156  * To check a permutation:  cholmod_check_perm (Perm, n, n, Common) ;
01157  *
01158  * workspace:  Flag (n) if n <= Common->nrow, Iwork (n) otherwise.
01159  */
01160 
01161 static int check_perm
01162 (
01163     Int *Wi,
01164     Int print,
01165     char *name,
01166     Int *Perm,
01167     size_t len,
01168     size_t n,
01169     cholmod_common *Common
01170 )
01171 {
01172     Int *Flag ;
01173     Int i, k, mark, init_print, count ;
01174     char *type = "perm" ;
01175 
01176     /* ---------------------------------------------------------------------- */
01177     /* checks that take O(1) time */
01178     /* ---------------------------------------------------------------------- */
01179 
01180     if (Perm == NULL || n == 0)
01181     {
01182   /* Perm is valid implicit identity, or empty */
01183   return (TRUE) ;
01184     }
01185 
01186     /* ---------------------------------------------------------------------- */
01187     /* checks that take O(n) time or require memory allocation */
01188     /* ---------------------------------------------------------------------- */
01189 
01190     init_print = print ;
01191     ETC_START (count, 8) ;
01192 
01193     if (Wi == NULL && n <= Common->nrow)
01194     {
01195   /* use the Common->Flag array if it's big enough */
01196   mark = CHOLMOD(clear_flag) (Common) ;
01197   Flag = Common->Flag ;
01198   ASSERT (CHOLMOD(dump_work) (TRUE, FALSE, 0, Common)) ;
01199   if (print >= 4)
01200   {
01201       for (k = 0 ; k < ((Int) len) ; k++)
01202       {
01203     ETC (k >= ((Int) len) - 4, count, -1) ;
01204     i = Perm [k] ;
01205     P4 ("  "I8":", k) ;
01206     P4 (""ID"\n", i) ;
01207     if (i < 0 || i >= ((Int) n) || Flag [i] == mark)
01208     {
01209         CHOLMOD(clear_flag) (Common) ;
01210         ERR ("invalid permutation") ;
01211     }
01212     Flag [i] = mark ;
01213       }
01214   }
01215   else
01216   {
01217       for (k = 0 ; k < ((Int) len) ; k++)
01218       {
01219     i = Perm [k] ;
01220     if (i < 0 || i >= ((Int) n) || Flag [i] == mark)
01221     {
01222         CHOLMOD(clear_flag) (Common) ;
01223         ERR ("invalid permutation") ;
01224     }
01225     Flag [i] = mark ;
01226       }
01227   }
01228   CHOLMOD(clear_flag) (Common) ;
01229   ASSERT (CHOLMOD(dump_work) (TRUE, FALSE, 0, Common)) ;
01230     }
01231     else
01232     {
01233   if (Wi == NULL)
01234   {
01235       /* use Common->Iwork instead, but initialize it first */
01236       CHOLMOD(allocate_work) (0, n, 0, Common) ;
01237       Wi = Common->Iwork ;        /* size n, (i/i/i) is OK */
01238   }
01239   if (Common->status < CHOLMOD_OK)
01240   {
01241       return (FALSE) ;      /* out of memory */
01242   }
01243   for (i = 0 ; i < ((Int) n) ; i++)
01244   {
01245       Wi [i] = FALSE ;
01246   }
01247   if (print >= 4)
01248   {
01249       for (k = 0 ; k < ((Int) len) ; k++)
01250       {
01251     ETC (k >= ((Int) len) - 4, count, -1) ;
01252     i = Perm [k] ;
01253     P4 ("  "I8":", k) ;
01254     P4 (""ID"\n", i) ;
01255     if (i < 0 || i >= ((Int) n) || Wi [i])
01256     {
01257         ERR ("invalid permutation") ;
01258     }
01259     Wi [i] = TRUE ;
01260       }
01261   }
01262   else
01263   {
01264       for (k = 0 ; k < ((Int) len) ; k++)
01265       {
01266     i = Perm [k] ;
01267     if (i < 0 || i >= ((Int) n) || Wi [i])
01268     {
01269         ERR ("invalid permutation") ;
01270     }
01271     Wi [i] = TRUE ;
01272       }
01273   }
01274     }
01275 
01276     /* perm is valid */
01277     return (TRUE) ;
01278 }
01279 
01280 
01281 int CHOLMOD(check_perm)
01282 (
01283     /* ---- input ---- */
01284     Int *Perm,    /* Perm [0:len-1] is a permutation of subset of 0:n-1 */
01285     size_t len,   /* size of Perm (an integer array) */
01286     size_t n,   /* 0:n-1 is valid range */
01287     /* --------------- */
01288     cholmod_common *Common
01289 )
01290 {
01291     RETURN_IF_NULL_COMMON (FALSE) ;
01292     Common->status = CHOLMOD_OK ;
01293     return (check_perm (NULL, 0, NULL, Perm, len, n, Common)) ;
01294 }
01295 
01296 
01297 int CHOLMOD(print_perm)
01298 (
01299     /* ---- input ---- */
01300     Int *Perm,    /* Perm [0:len-1] is a permutation of subset of 0:n-1 */
01301     size_t len,   /* size of Perm (an integer array) */
01302     size_t n,   /* 0:n-1 is valid range */
01303     char *name,   /* printed name of Perm */
01304     /* --------------- */
01305     cholmod_common *Common
01306 )
01307 {
01308     Int ok, print ;
01309     RETURN_IF_NULL_COMMON (FALSE) ;
01310     Common->status = CHOLMOD_OK ;
01311     print = Common->print ;
01312     P4 ("%s", "\n") ;
01313     P3 ("%s", "CHOLMOD perm:    ") ;
01314     if (name != NULL)
01315     {
01316   P3 ("%s: ", name) ;
01317     }
01318     P3 (" len: "ID"", (Int) len) ;
01319     P3 (" n: "ID"", (Int) n) ;
01320     P4 ("%s", "\n") ;
01321     ok = check_perm (NULL, print, name, Perm, len, n, Common) ;
01322     if (ok)
01323     {
01324   P3 ("%s", "  OK\n") ;
01325   P4 ("%s", "\n") ;
01326     }
01327     return (ok) ;
01328 }
01329 
01330 
01331 /* ========================================================================== */
01332 /* === cholmod_check_parent ================================================= */
01333 /* ========================================================================== */
01334 
01335 /* Ensure that Parent is a valid elimination tree of nodes 0 to n-1.
01336  * If j is a root of the tree then Parent [j] is EMPTY (-1).
01337  *
01338  * NOTE: this check will fail if applied to the component tree (CParent) in
01339  * cholmod_nested_dissection, unless it has been postordered and renumbered.
01340  *
01341  * workspace: none
01342  */
01343 
01344 static int check_parent
01345 (
01346     Int *Parent,
01347     size_t n,
01348     Int print,
01349     char *name,
01350     cholmod_common *Common
01351 )
01352 {
01353     Int j, p, init_print, count ;
01354     char *type = "parent" ;
01355 
01356     init_print = print ;
01357 
01358     P4 ("%s", "\n") ;
01359     P3 ("%s", "CHOLMOD parent:  ") ;
01360     if (name != NULL)
01361     {
01362   P3 ("%s: ", name) ;
01363     }
01364 
01365     P3 (" n: "ID"", (Int) n) ;
01366     P4 ("%s", "\n") ;
01367 
01368     if (Parent == NULL)
01369     {
01370   ERR ("null") ;
01371     }
01372 
01373     /* ---------------------------------------------------------------------- */
01374     /* checks that take O(n) time */
01375     /* ---------------------------------------------------------------------- */
01376 
01377     ETC_START (count, 8) ;
01378     for (j = 0 ; j < ((Int) n) ; j++)
01379     {
01380   ETC (j == ((Int) n) - 4, count, -1) ;
01381   p = Parent [j] ;
01382   P4 ("  "I8":", j) ;
01383   P4 (" "ID"\n", p) ;
01384   if (!(p == EMPTY || p > j))
01385   {
01386       ERR ("invalid") ;
01387   }
01388     }
01389     P3 ("%s", "  OK\n") ;
01390     P4 ("%s", "\n") ;
01391     return (TRUE) ;
01392 }
01393 
01394 
01395 int CHOLMOD(check_parent)
01396 (
01397     /* ---- input ---- */
01398     Int *Parent,  /* Parent [0:n-1] is an elimination tree */
01399     size_t n,   /* size of Parent */
01400     /* --------------- */
01401     cholmod_common *Common
01402 )
01403 {
01404     RETURN_IF_NULL_COMMON (FALSE) ;
01405     Common->status = CHOLMOD_OK ;
01406     return (check_parent (Parent, n, 0, NULL, Common)) ;
01407 }
01408 
01409 
01410 int CHOLMOD(print_parent)
01411 (
01412     /* ---- input ---- */
01413     Int *Parent,  /* Parent [0:n-1] is an elimination tree */
01414     size_t n,   /* size of Parent */
01415     char *name,   /* printed name of Parent */
01416     /* --------------- */
01417     cholmod_common *Common
01418 )
01419 {
01420     RETURN_IF_NULL_COMMON (FALSE) ;
01421     Common->status = CHOLMOD_OK ;
01422     return (check_parent (Parent, n, Common->print, name, Common)) ;
01423 }
01424 
01425 
01426 /* ========================================================================== */
01427 /* === cholmod_check_factor ================================================= */
01428 /* ========================================================================== */
01429 
01430 static int check_factor
01431 (
01432     Int *Wi,
01433     Int print,
01434     char *name,
01435     cholmod_factor *L,
01436     cholmod_common *Common
01437 )
01438 {
01439     double *Lx, *Lz ;
01440     Int *Lp, *Li, *Lnz, *Lnext, *Lprev, *Perm, *ColCount, *Lpi, *Lpx, *Super,
01441   *Ls ;
01442     Int n, nzmax, j, p, pend, i, nz, ordering, space, is_monotonic, minor,
01443   count, precise, init_print, ilast, lnz, head, tail, jprev, plast,
01444   jnext, examine_super, nsuper, s, k1, k2, psi, psend, psx, nsrow, nscol,
01445   ps2, psxend, ssize, xsize, maxcsize, maxesize, nsrow2, jj, ii, xtype ;
01446     char *type = "factor" ;
01447 
01448     /* ---------------------------------------------------------------------- */
01449     /* print header information */
01450     /* ---------------------------------------------------------------------- */
01451 
01452     P4 ("%s", "\n") ;
01453     P3 ("%s", "CHOLMOD factor:  ") ;
01454     if (name != NULL)
01455     {
01456   P3 ("%s: ", name) ;
01457     }
01458 
01459     if (L == NULL)
01460     {
01461   ERR ("null") ;
01462     }
01463 
01464     n = L->n ;
01465     minor = L->minor ;
01466     ordering = L->ordering ;
01467     xtype = L->xtype ;
01468 
01469     Perm = L->Perm ;
01470     ColCount = L->ColCount ;
01471     lnz = 0 ;
01472 
01473     precise = Common->precise ;
01474 
01475     P3 (" "ID"", n) ;
01476     P3 ("-by-"ID"", n) ;
01477 
01478     if (minor < n)
01479     {
01480   P3 (" not positive definite (column "ID")", minor) ;
01481     }
01482 
01483     switch (L->itype)
01484     {
01485   case CHOLMOD_INT:     P4 ("%s", "\n  scalar types: int, ") ; break ;
01486   case CHOLMOD_INTLONG: ERR ("mixed int/UF_long type unsupported") ;
01487   case CHOLMOD_LONG:    P4 ("%s", "\n  scalar types: UF_long, ") ; break ;
01488   default:        ERR ("unknown itype") ;
01489     }
01490 
01491     switch (L->xtype)
01492     {
01493   case CHOLMOD_PATTERN: P4 ("%s", "pattern") ;  break ;
01494   case CHOLMOD_REAL:    P4 ("%s", "real") ; break ;
01495   case CHOLMOD_COMPLEX: P4 ("%s", "complex") ;  break ;
01496   case CHOLMOD_ZOMPLEX: P4 ("%s", "zomplex") ;  break ;
01497   default:        ERR ("unknown xtype") ;
01498     }
01499 
01500     switch (L->dtype)
01501     {
01502   case CHOLMOD_DOUBLE:  P4 ("%s", ", double\n") ;        break ;
01503   case CHOLMOD_SINGLE:  ERR ("single unsupported") ;
01504   default:        ERR ("unknown dtype") ;
01505     }
01506 
01507     if (L->itype != ITYPE || L->dtype != DTYPE)
01508     {
01509   ERR ("integer and real type must match routine") ;
01510     }
01511 
01512     if (L->is_super)
01513     {
01514   P3 ("%s", "  supernodal") ;
01515     }
01516     else
01517     {
01518   P3 ("%s", "  simplicial") ;
01519     }
01520 
01521     if (L->is_ll)
01522     {
01523   P3 ("%s", ", LL'.") ;
01524     }
01525     else
01526     {
01527   P3 ("%s", ", LDL'.") ;
01528     }
01529 
01530     P4 ("%s", "\n  ordering method used: ") ;
01531     switch (L->ordering)
01532     {
01533   case CHOLMOD_POSTORDERED:P4 ("%s", "natural (postordered)") ;  break ;
01534   case CHOLMOD_NATURAL: P4 ("%s", "natural") ;       break ;
01535   case CHOLMOD_GIVEN: P4 ("%s", "user-provided") ;     break ;
01536   case CHOLMOD_AMD: P4 ("%s", "AMD") ;       break ;
01537   case CHOLMOD_COLAMD:  P4 ("%s", "AMD for A, COLAMD for A*A'") ;break ;
01538 #ifndef NPARTITION
01539   case CHOLMOD_METIS: P4 ("%s", "METIS NodeND") ;    break ;
01540   case CHOLMOD_NESDIS:  P4 ("%s", "CHOLMOD nested dissection") ; break ;
01541 #endif
01542   default:    ERR ("unknown ordering") ;
01543     }
01544 
01545     P4 ("%s", "\n") ;
01546 
01547     init_print = print ;
01548 
01549     if (L->is_super && L->xtype == CHOLMOD_ZOMPLEX)
01550     {
01551   ERR ("Supernodal zomplex L not supported") ;
01552     }
01553 
01554     /* ---------------------------------------------------------------------- */
01555     /* check L->Perm */
01556     /* ---------------------------------------------------------------------- */
01557 
01558     if (!check_perm (Wi, print, name, Perm, n, n, Common))
01559     {
01560   return (FALSE) ;
01561     }
01562 
01563     /* ---------------------------------------------------------------------- */
01564     /* check L->ColCount */
01565     /* ---------------------------------------------------------------------- */
01566 
01567     if (ColCount == NULL)
01568     {
01569   ERR ("ColCount vector invalid") ;
01570     }
01571 
01572     ETC_START (count, 8) ;
01573     for (j = 0 ; j < n ; j++)
01574     {
01575   ETC (j >= n-4, count, -1) ;
01576   P4 ("  col: "ID" ", j) ;
01577   nz = ColCount [j] ;
01578   P4 ("colcount: "ID"\n", nz) ;
01579   if (nz < 0 || nz > n-j)
01580   {
01581       ERR ("ColCount out of range") ;
01582   }
01583     }
01584 
01585     /* ---------------------------------------------------------------------- */
01586     /* check factor */
01587     /* ---------------------------------------------------------------------- */
01588 
01589     if (L->xtype == CHOLMOD_PATTERN && !(L->is_super))
01590     {
01591 
01592   /* ------------------------------------------------------------------ */
01593   /* check simplicial symbolic factor */
01594   /* ------------------------------------------------------------------ */
01595 
01596   /* nothing else to do */ ;
01597 
01598     }
01599     else if (L->xtype != CHOLMOD_PATTERN && !(L->is_super))
01600     {
01601 
01602   /* ------------------------------------------------------------------ */
01603   /* check simplicial numerical factor */
01604   /* ------------------------------------------------------------------ */
01605 
01606   P4 ("monotonic: %d\n", L->is_monotonic) ;
01607   nzmax = L->nzmax ;
01608   P3 (" nzmax "ID".", nzmax) ;
01609   P4 ("%s", "\n") ;
01610   Lp = L->p ;
01611   Li = L->i ;
01612   Lx = L->x ;
01613   Lz = L->z ;
01614   Lnz = L->nz ;
01615   Lnext = L->next ;
01616   Lprev = L->prev ;
01617 
01618   /* check for existence of Lp, Li, Lnz, Lnext, Lprev, and Lx arrays */
01619   if (Lp == NULL)
01620   {
01621       ERR ("p array not present") ;
01622   }
01623   if (Li == NULL)
01624   {
01625       ERR ("i array not present") ;
01626   }
01627   if (Lnz == NULL)
01628   {
01629       ERR ("nz array not present") ;
01630   }
01631   if (Lx == NULL)
01632   {
01633       ERR ("x array not present") ;
01634   }
01635   if (xtype == CHOLMOD_ZOMPLEX && Lz == NULL)
01636   {
01637       ERR ("z array not present") ;
01638   }
01639   if (Lnext == NULL)
01640   {
01641       ERR ("next array not present") ;
01642   }
01643   if (Lprev == NULL)
01644   {
01645       ERR ("prev array not present") ;
01646   }
01647 
01648   ETC_START (count, 8) ;
01649 
01650   /* check each column of L */
01651   plast = 0 ;
01652   is_monotonic = TRUE ;
01653   for (j = 0 ; j < n ; j++)
01654   {
01655       ETC (j >= n-3, count, -1) ;
01656       p = Lp [j] ;
01657       nz = Lnz [j] ;
01658       pend = p + nz ;
01659       lnz += nz ;
01660 
01661       P4 ("  col "ID":", j) ;
01662       P4 (" nz "ID"", nz) ;
01663       P4 (" start "ID"", p) ;
01664       P4 (" end "ID"", pend) ;
01665 
01666       if (Lnext [j] < 0 || Lnext [j] > n)
01667       {
01668     ERR ("invalid link list")  ;
01669       }
01670       space = Lp [Lnext [j]] - p ;
01671 
01672       P4 (" space "ID"", space) ;
01673       P4 (" free "ID":\n", space - nz) ;
01674 
01675       if (p < 0 || pend > nzmax || space < 1)
01676       {
01677     ERR ("pointer invalid") ;
01678       }
01679       if (nz < 1 || nz > (n-j) || nz > space)
01680       {
01681     ERR ("nz invalid") ;
01682       }
01683       ilast = j-1 ;
01684 
01685       if (p < plast)
01686       {
01687     is_monotonic = FALSE ;
01688       }
01689       plast = p ;
01690 
01691       i = Li [p] ;
01692       P4 ("  "I8":", i) ;
01693       if (i != j)
01694       {
01695     ERR ("diagonal missing") ;
01696       }
01697 
01698       amesos_print_value (print, xtype, Lx, Lz, p, Common) ;
01699 
01700       P4 ("%s", "\n") ;
01701       ilast = j ;
01702       for (p++ ; p < pend ; p++)
01703       {
01704     ETC_DISABLE (count) ;
01705     i = Li [p] ;
01706     P4 ("  "I8":", i) ;
01707     if (i < j || i >= n)
01708     {
01709         ERR ("row index out of range") ;
01710     }
01711     if (i <= ilast)
01712     {
01713         ERR ("row indices out of order") ;
01714     }
01715 
01716     amesos_print_value (print, xtype, Lx, Lz, p, Common) ;
01717 
01718     P4 ("%s", "\n") ;
01719     ilast = i ;
01720       }
01721   }
01722 
01723   if (L->is_monotonic && !is_monotonic)
01724   {
01725       ERR ("columns not monotonic") ;
01726   }
01727 
01728   /* check the link list */
01729   head = n+1 ;
01730   tail = n ;
01731   j = head ;
01732   jprev = EMPTY ;
01733   count = 0 ;
01734   for ( ; ; )
01735   {
01736       if (j < 0 || j > n+1 || count > n+2)
01737       {
01738     ERR ("invalid link list") ;
01739       }
01740       jnext = Lnext [j] ;
01741       if (j >= 0 && j < n)
01742       {
01743     if (jprev != Lprev [j])
01744     {
01745         ERR ("invalid link list") ;
01746     }
01747       }
01748       count++ ;
01749       if (j == tail)
01750       {
01751     break ;
01752       }
01753       jprev = j ;
01754       j = jnext ;
01755   }
01756   if (Lnext [tail] != EMPTY || count != n+2)
01757   {
01758       ERR ("invalid link list") ;
01759   }
01760 
01761     }
01762     else
01763     {
01764 
01765   /* ------------------------------------------------------------------ */
01766   /* check supernodal numeric or symbolic factor */
01767   /* ------------------------------------------------------------------ */
01768 
01769   nsuper = L->nsuper ;
01770   ssize = L->ssize ;
01771   xsize = L->xsize ;
01772   maxcsize = L->maxcsize ;
01773   maxesize = L->maxesize ;
01774   Ls = L->s ;
01775   Lpi = L->pi ;
01776   Lpx = L->px ;
01777   Super = L->super ;
01778   Lx = L->x ;
01779   ETC_START (count, 8) ;
01780 
01781   P4 ("  ssize "ID" ", ssize) ;
01782   P4 ("xsize "ID" ", xsize) ;
01783   P4 ("maxcsize "ID" ", maxcsize) ;
01784   P4 ("maxesize "ID"\n", maxesize) ;
01785 
01786   if (Ls == NULL)
01787   {
01788       ERR ("invalid: L->s missing") ;
01789   }
01790   if (Lpi == NULL)
01791   {
01792       ERR ("invalid: L->pi missing") ;
01793   }
01794   if (Lpx == NULL)
01795   {
01796       ERR ("invalid: L->px missing") ;
01797   }
01798   if (Super == NULL)
01799   {
01800       ERR ("invalid: L->super missing") ;
01801   }
01802 
01803   if (L->xtype != CHOLMOD_PATTERN)
01804   {
01805       /* numerical supernodal factor */
01806       if (Lx == NULL)
01807       {
01808     ERR ("invalid: L->x missing") ;
01809       }
01810       if (Ls [0] == EMPTY)
01811       {
01812     ERR ("invalid: L->s not defined") ;
01813       }
01814       examine_super = TRUE ;
01815   }
01816   else
01817   {
01818       /* symbolic supernodal factor, but only if it has been computed */
01819       examine_super = (Ls [0] != EMPTY) ;
01820   }
01821 
01822   if (examine_super)
01823   {
01824       if (Lpi [0] != 0 || MAX (1, Lpi [nsuper]) != ssize)
01825       {
01826     PRINT0 (("Lpi [0] "ID", Lpi [nsuper = "ID"] = "ID"\n",
01827       Lpi [0], nsuper, Lpi [nsuper])) ;
01828     ERR ("invalid: L->pi invalid") ;
01829       }
01830       if (Lpx [0] != 0 || MAX (1, Lpx [nsuper]) != xsize)
01831       {
01832     ERR ("invalid: L->px invalid") ;
01833       }
01834 
01835       /* check and print each supernode */
01836       for (s = 0 ; s < nsuper ; s++)
01837       {
01838     k1 = Super [s] ;
01839     k2 = Super [s+1] ;
01840     psi = Lpi [s] ;
01841     psend = Lpi [s+1] ;
01842     psx = Lpx [s] ;
01843     nsrow = psend - psi ;
01844     nscol = k2 - k1 ;
01845     nsrow2 = nsrow - nscol ;
01846     ps2 = psi + nscol ;
01847     psxend = Lpx [s+1] ;
01848 
01849     ETC (s == nsuper-1, count, 4) ;
01850 
01851     P4 ("  supernode "ID", ", s) ;
01852     P4 ("col "ID" ", k1) ;
01853     P4 ("to "ID". ", k2-1) ;
01854     P4 ("nz in first col: "ID".\n", nsrow) ;
01855     P4 ("  values start "ID", ", psx) ;
01856     P4 ("end "ID"\n", psxend) ;
01857 
01858     if (k1 > k2 || k1 < 0 || k2 > n || nsrow < nscol || nsrow2 < 0
01859         || psxend - psx != nsrow * nscol)
01860     {
01861         ERR ("invalid supernode") ;
01862     }
01863 
01864     lnz += nscol * nsrow - (nscol*nscol - nscol)/2 ;
01865 
01866     if (L->xtype != CHOLMOD_PATTERN)
01867     {
01868         /* print each column of the supernode */
01869         for (jj = 0 ; jj < nscol ; jj++)
01870         {
01871       ETC_ENABLE (s == nsuper-1 && jj >= nscol-3, count, -1) ;
01872       j = k1 + jj ;
01873       P4 ("  col "ID"\n", j) ;
01874       ilast = j ;
01875       i = Ls [psi + jj] ;
01876       P4 ("  "I8":", i) ;
01877       if (i != j)
01878       {
01879           ERR ("row index invalid") ;
01880       }
01881 
01882       /* PRINTVALUE (Lx [psx + jj + jj*nsrow]) ; */
01883       amesos_print_value (print, xtype, Lx, NULL,
01884         psx + jj + jj*nsrow, Common) ;
01885 
01886       P4 ("%s", "\n") ;
01887       for (ii = jj + 1 ; ii < nsrow ; ii++)
01888       {
01889           ETC_DISABLE (count) ;
01890           i = Ls [psi + ii] ;
01891           P4 ("  "I8":", i) ;
01892           if (i <= ilast || i > n)
01893           {
01894         ERR ("row index out of range") ;
01895           }
01896 
01897           /* PRINTVALUE (Lx [psx + ii + jj*nsrow]) ; */
01898           amesos_print_value (print, xtype, Lx, NULL,
01899             psx + ii + jj*nsrow, Common) ;
01900 
01901           P4 ("%s", "\n") ;
01902           ilast = i ;
01903       }
01904         }
01905     }
01906     else
01907     {
01908         /* just print the leading column of the supernode */
01909         P4 ("  col "ID"\n", k1) ;
01910         for (jj = 0 ; jj < nscol ; jj++)
01911         {
01912       ETC (s == nsuper-1 && jj >= nscol-3, count, -1) ;
01913       j = k1 + jj ;
01914       i = Ls [psi + jj] ;
01915       P4 ("  "I8"", i) ;
01916       if (i != j)
01917       {
01918           ERR ("row index invalid") ;
01919       }
01920       P4 ("%s", "\n") ;
01921         }
01922         ilast = j ;
01923         for (ii = nscol ; ii < nsrow ; ii++)
01924         {
01925       ETC_DISABLE (count) ;
01926       i = Ls [psi + ii] ;
01927       P4 ("  "I8"", i) ;
01928       if (i <= ilast || i > n)
01929       {
01930           ERR ("row index out of range") ;
01931       }
01932       P4 ("%s", "\n") ;
01933       ilast = i ;
01934         }
01935     }
01936       }
01937   }
01938     }
01939 
01940     /* factor is valid */
01941     P3 ("  nz "ID"", lnz) ;
01942     P3 ("%s", "  OK\n") ;
01943     P4 ("%s", "\n") ;
01944     return (TRUE) ;
01945 }
01946 
01947 
01948 int CHOLMOD(check_factor)
01949 (
01950     /* ---- input ---- */
01951     cholmod_factor *L,  /* factor to check */
01952     /* --------------- */
01953     cholmod_common *Common
01954 )
01955 {
01956     RETURN_IF_NULL_COMMON (FALSE) ;
01957     Common->status = CHOLMOD_OK ;
01958     return (check_factor (NULL, 0, NULL, L, Common)) ;
01959 }
01960 
01961 
01962 int CHOLMOD(print_factor)
01963 (
01964     /* ---- input ---- */
01965     cholmod_factor *L,  /* factor to print */
01966     char *name,   /* printed name of factor */
01967     /* --------------- */
01968     cholmod_common *Common
01969 )
01970 {
01971     RETURN_IF_NULL_COMMON (FALSE) ;
01972     Common->status = CHOLMOD_OK ;
01973     return (check_factor (NULL, Common->print, name, L, Common)) ;
01974 }
01975 
01976 
01977 /* ========================================================================== */
01978 /* === cholmod_check_triplet ================================================ */
01979 /* ========================================================================== */
01980 
01981 /* Ensure a triplet matrix is valid, and optionally print it. */
01982 
01983 static int check_triplet
01984 (
01985     Int print,
01986     char *name,
01987     cholmod_triplet *T,
01988     cholmod_common *Common
01989 )
01990 {
01991     double *Tx, *Tz ;
01992     Int *Ti, *Tj ;
01993     Int i, j, p, nrow, ncol, nzmax, nz, xtype, init_print, count ;
01994     char *type = "triplet" ;
01995 
01996     /* ---------------------------------------------------------------------- */
01997     /* print header information */
01998     /* ---------------------------------------------------------------------- */
01999 
02000     P4 ("%s", "\n") ;
02001     P3 ("%s", "CHOLMOD triplet: ") ;
02002     if (name != NULL)
02003     {
02004   P3 ("%s: ", name) ;
02005     }
02006 
02007     if (T == NULL)
02008     {
02009   ERR ("null") ;
02010     }
02011 
02012     nrow = T->nrow ;
02013     ncol = T->ncol ;
02014     nzmax = T->nzmax ;
02015     nz = T->nnz ;
02016     Ti = T->i ;
02017     Tj = T->j ;
02018     Tx = T->x ;
02019     Tz = T->z ;
02020     xtype = T->xtype ;
02021 
02022 
02023     P3 (" "ID"", nrow) ;
02024     P3 ("-by-"ID", ", ncol) ;
02025     P3 ("nz "ID",", nz) ;
02026     if (T->stype > 0)
02027     {
02028   P3 ("%s", " upper.") ;
02029     }
02030     else if (T->stype < 0)
02031     {
02032   P3 ("%s", " lower.") ;
02033     }
02034     else
02035     {
02036   P3 ("%s", " up/lo.") ;
02037     }
02038 
02039     P4 ("\n  nzmax "ID", ", nzmax) ;
02040     if (nz > nzmax)
02041     {
02042   ERR ("nzmax too small") ;
02043     }
02044 
02045     switch (T->itype)
02046     {
02047   case CHOLMOD_INT:     P4 ("%s", "\n  scalar types: int, ") ; break ;
02048   case CHOLMOD_INTLONG: ERR ("mixed int/UF_long type unsupported") ;
02049   case CHOLMOD_LONG:    P4 ("%s", "\n  scalar types: UF_long, ") ; break ;
02050   default:        ERR ("unknown itype") ;
02051     }
02052 
02053     switch (T->xtype)
02054     {
02055   case CHOLMOD_PATTERN: P4 ("%s", "pattern") ;  break ;
02056   case CHOLMOD_REAL:    P4 ("%s", "real") ; break ;
02057   case CHOLMOD_COMPLEX: P4 ("%s", "complex") ;  break ;
02058   case CHOLMOD_ZOMPLEX: P4 ("%s", "zomplex") ;  break ;
02059   default:        ERR ("unknown xtype") ;
02060     }
02061 
02062     switch (T->dtype)
02063     {
02064   case CHOLMOD_DOUBLE:  P4 ("%s", ", double\n") ;        break ;
02065   case CHOLMOD_SINGLE:  ERR ("single unsupported") ;
02066   default:        ERR ("unknown dtype") ;
02067     }
02068 
02069     if (T->itype != ITYPE || T->dtype != DTYPE)
02070     {
02071   ERR ("integer and real type must match routine") ;
02072     }
02073 
02074     if (T->stype && nrow != ncol)
02075     {
02076   ERR ("symmetric but not square") ;
02077     }
02078 
02079     /* check for existence of Ti, Tj, Tx arrays */
02080     if (Tj == NULL)
02081     {
02082   ERR ("j array not present") ;
02083     }
02084     if (Ti == NULL)
02085     {
02086   ERR ("i array not present") ;
02087     }
02088 
02089     if (xtype != CHOLMOD_PATTERN && Tx == NULL)
02090     {
02091   ERR ("x array not present") ;
02092     }
02093     if (xtype == CHOLMOD_ZOMPLEX && Tz == NULL)
02094     {
02095   ERR ("z array not present") ;
02096     }
02097 
02098     /* ---------------------------------------------------------------------- */
02099     /* check and print each entry */
02100     /* ---------------------------------------------------------------------- */
02101 
02102     init_print = print ;
02103     ETC_START (count, 8) ;
02104 
02105     for (p = 0 ; p < nz ; p++)
02106     {
02107   ETC (p >= nz-4, count, -1) ;
02108   i = Ti [p] ;
02109   P4 ("  "I8":", p) ;
02110   P4 (" "I_8"", i) ;
02111   if (i < 0 || i >= nrow)
02112   {
02113       ERR ("row index out of range") ;
02114   }
02115   j = Tj [p] ;
02116   P4 (" "I_8"", j) ;
02117   if (j < 0 || j >= ncol)
02118   {
02119       ERR ("column index out of range") ;
02120   }
02121 
02122   amesos_print_value (print, xtype, Tx, Tz, p, Common) ;
02123 
02124   P4 ("%s", "\n") ;
02125     }
02126 
02127     /* triplet matrix is valid */
02128     P3 ("%s", "  OK\n") ;
02129     P4 ("%s", "\n") ;
02130     return (TRUE) ;
02131 }
02132 
02133 
02134 
02135 int CHOLMOD(check_triplet)
02136 (
02137     /* ---- input ---- */
02138     cholmod_triplet *T, /* triplet matrix to check */
02139     /* --------------- */
02140     cholmod_common *Common
02141 )
02142 {
02143     RETURN_IF_NULL_COMMON (FALSE) ;
02144     Common->status = CHOLMOD_OK ;
02145     return (check_triplet (0, NULL, T, Common)) ;
02146 }
02147 
02148 
02149 int CHOLMOD(print_triplet)
02150 (
02151     /* ---- input ---- */
02152     cholmod_triplet *T, /* triplet matrix to print */
02153     char *name,   /* printed name of triplet matrix */
02154     /* --------------- */
02155     cholmod_common *Common
02156 )
02157 {
02158     RETURN_IF_NULL_COMMON (FALSE) ;
02159     Common->status = CHOLMOD_OK ;
02160     return (check_triplet (Common->print, name, T, Common)) ;
02161 }
02162 
02163 
02164 
02165 /* ========================================================================== */
02166 /* === CHOLMOD debugging routines =========================================== */
02167 /* ========================================================================== */
02168 
02169 #ifndef NDEBUG
02170 
02171 /* The global variables present only when debugging enabled. */
02172 int CHOLMOD(dump) = 0 ;
02173 int CHOLMOD(dump_malloc) = -1 ;
02174 
02175 /* workspace: no debug routines use workspace in Common */
02176 
02177 /* ========================================================================== */
02178 /* === cholmod_dump_init ==================================================== */
02179 /* ========================================================================== */
02180 
02181 void CHOLMOD(dump_init) (char *s, cholmod_common *Common)
02182 {
02183     FILE *f ;
02184     f = fopen ("debug", "r") ;
02185     if (f == NULL)
02186     {
02187   CHOLMOD(dump) = 0 ;
02188     }
02189     else
02190     {
02191   fscanf (f, "%d", &CHOLMOD(dump)) ;
02192   fclose (f) ;
02193     }
02194     PRINT1 (("%s: cholmod_dump_init, D = %d\n", s, CHOLMOD(dump))) ;
02195 }
02196 
02197 
02198 /* ========================================================================== */
02199 /* === cholmod_dump_sparse ================================================== */
02200 /* ========================================================================== */
02201 
02202 UF_long CHOLMOD(dump_sparse)  /* returns nnz (diag (A)) or EMPTY if error */
02203 (
02204     cholmod_sparse *A,
02205     char *name,
02206     cholmod_common *Common
02207 )
02208 {
02209     Int *Wi ;
02210     UF_long nnzdiag ;
02211     Int ok ;
02212 
02213     if (CHOLMOD(dump) < -1)
02214     {
02215   /* no checks if debug level is -2 or less */
02216   return (0) ;
02217     }
02218 
02219     RETURN_IF_NULL_COMMON (FALSE) ;
02220     RETURN_IF_NULL (A, FALSE) ;
02221     Wi = malloc (MAX (1, A->nrow) * sizeof (Int)) ;
02222     ok = check_sparse (Wi, CHOLMOD(dump), name, A, &nnzdiag, Common) ;
02223     if (Wi != NULL) free (Wi) ;
02224     return (ok ? nnzdiag : EMPTY) ;
02225 }
02226 
02227 
02228 /* ========================================================================== */
02229 /* === cholmod_dump_factor ================================================== */
02230 /* ========================================================================== */
02231 
02232 int CHOLMOD(dump_factor)
02233 (
02234     cholmod_factor *L,
02235     char *name,
02236     cholmod_common *Common
02237 )
02238 {
02239     Int *Wi ;
02240     int ok ;
02241 
02242     if (CHOLMOD(dump) < -1)
02243     {
02244   /* no checks if debug level is -2 or less */
02245   return (TRUE) ;
02246     }
02247     RETURN_IF_NULL_COMMON (FALSE) ;
02248     RETURN_IF_NULL (L, FALSE) ;
02249     Wi = malloc (MAX (1, L->n) * sizeof (Int)) ;
02250     ok = check_factor (Wi, CHOLMOD(dump), name, L, Common) ;
02251     if (Wi != NULL) free (Wi) ;
02252     return (ok) ;
02253 }
02254 
02255 
02256 /* ========================================================================== */
02257 /* === cholmod_dump_perm ==================================================== */
02258 /* ========================================================================== */
02259 
02260 int CHOLMOD(dump_perm)
02261 (
02262     Int *Perm,
02263     size_t len,
02264     size_t n,
02265     char *name,
02266     cholmod_common *Common
02267 )
02268 {
02269     Int *Wi ;
02270     int ok ;
02271 
02272     if (CHOLMOD(dump) < -1)
02273     {
02274   /* no checks if debug level is -2 or less */
02275   return (TRUE) ;
02276     }
02277     RETURN_IF_NULL_COMMON (FALSE) ;
02278     Wi = malloc (MAX (1, n) * sizeof (Int)) ;
02279     ok = check_perm (Wi, CHOLMOD(dump), name, Perm, len, n,Common) ;
02280     if (Wi != NULL) free (Wi) ;
02281     return (ok) ;
02282 }
02283 
02284 
02285 /* ========================================================================== */
02286 /* === cholmod_dump_dense =================================================== */
02287 /* ========================================================================== */
02288 
02289 int CHOLMOD(dump_dense)
02290 (
02291     cholmod_dense *X,
02292     char *name,
02293     cholmod_common *Common
02294 )
02295 {
02296     if (CHOLMOD(dump) < -1)
02297     {
02298   /* no checks if debug level is -2 or less */
02299   return (TRUE) ;
02300     }
02301     RETURN_IF_NULL_COMMON (FALSE) ;
02302     return (check_dense (CHOLMOD(dump), name, X, Common)) ;
02303 }
02304 
02305 
02306 /* ========================================================================== */
02307 /* === cholmod_dump_triplet ================================================= */
02308 /* ========================================================================== */
02309 
02310 int CHOLMOD(dump_triplet)
02311 (
02312     cholmod_triplet *T,
02313     char *name,
02314     cholmod_common *Common
02315 )
02316 {
02317     if (CHOLMOD(dump) < -1)
02318     {
02319   /* no checks if debug level is -2 or less */
02320   return (TRUE) ;
02321     }
02322     RETURN_IF_NULL_COMMON (FALSE) ;
02323     return (check_triplet (CHOLMOD(dump), name, T, Common)) ;
02324 }
02325 
02326 
02327 /* ========================================================================== */
02328 /* === cholmod_dump_subset ================================================== */
02329 /* ========================================================================== */
02330 
02331 int CHOLMOD(dump_subset)
02332 (
02333     Int *S,
02334     size_t len,
02335     size_t n,
02336     char *name,
02337     cholmod_common *Common
02338 )
02339 {
02340     if (CHOLMOD(dump) < -1)
02341     {
02342   /* no checks if debug level is -2 or less */
02343   return (TRUE) ;
02344     }
02345     RETURN_IF_NULL_COMMON (FALSE) ;
02346     return (check_subset (S, len, n, CHOLMOD(dump), name, Common)) ;
02347 }
02348 
02349 
02350 /* ========================================================================== */
02351 /* === cholmod_dump_parent ================================================== */
02352 /* ========================================================================== */
02353 
02354 int CHOLMOD(dump_parent)
02355 (
02356     Int *Parent,
02357     size_t n,
02358     char *name,
02359     cholmod_common *Common
02360 )
02361 {
02362     if (CHOLMOD(dump) < -1)
02363     {
02364   /* no checks if debug level is -2 or less */
02365   return (TRUE) ;
02366     }
02367     RETURN_IF_NULL_COMMON (FALSE) ;
02368     return (check_parent (Parent, n, CHOLMOD(dump), name, Common)) ;
02369 }
02370 
02371 
02372 /* ========================================================================== */
02373 /* === cholmod_dump_real ==================================================== */
02374 /* ========================================================================== */
02375 
02376 void CHOLMOD(dump_real)
02377 (
02378     char *name, Real *X, UF_long nrow, UF_long ncol, int lower, int xentry,
02379     cholmod_common *Common
02380 )
02381 {
02382     /* dump an nrow-by-ncol real dense matrix */
02383     UF_long i, j ;
02384     double x, z ;
02385     if (CHOLMOD(dump) < -1)
02386     {
02387   /* no checks if debug level is -2 or less */
02388   return ;
02389     }
02390     PRINT1 (("%s: dump_real, nrow: %ld ncol: %ld lower: %d\n",
02391     name, nrow, ncol, lower)) ;
02392     for (j = 0 ; j < ncol ; j++)
02393     {
02394   PRINT2 (("    col %ld\n", j)) ;
02395   for (i = 0 ; i < nrow ; i++)
02396   {
02397       /* X is stored in column-major form */
02398       if (lower && i < j)
02399       {
02400     PRINT2 (("        %5ld: -", i)) ;
02401       }
02402       else
02403       {
02404     x = *X ;
02405     PRINT2 (("        %5ld: %e", i, x)) ;
02406     if (xentry == 2)
02407     {
02408         z = *(X+1) ;
02409         PRINT2 ((", %e", z)) ;
02410     }
02411       }
02412       PRINT2 (("\n")) ;
02413       X += xentry ;
02414   }
02415     }
02416 }
02417 
02418 
02419 /* ========================================================================== */
02420 /* === cholmod_dump_super =================================================== */
02421 /* ========================================================================== */
02422 
02423 void CHOLMOD(dump_super)
02424 (
02425     UF_long s,
02426     Int *Super, Int *Lpi, Int *Ls, Int *Lpx, double *Lx,
02427     int xentry,
02428     cholmod_common *Common
02429 )
02430 {
02431     Int k1, k2, do_values, psi, psx, nsrow, nscol, psend, ilast, p, i ;
02432     if (CHOLMOD(dump) < -1)
02433     {
02434   /* no checks if debug level is -2 or less */
02435   return ;
02436     }
02437     k1 = Super [s] ;
02438     k2 = Super [s+1] ;
02439     nscol = k2 - k1 ;
02440     do_values = (Lpx != NULL) && (Lx != NULL) ;
02441     psi = Lpi [s] ;
02442     psend = Lpi [s+1] ;
02443     nsrow = psend - psi ;
02444     PRINT1 (("\nSuper %ld, columns "ID" to "ID", "ID" rows "ID" cols\n",
02445     s, k1, k2-1, nsrow, nscol)) ;
02446     ilast = -1 ;
02447     for (p = psi ; p < psend ; p++)
02448     {
02449   i = Ls [p] ;
02450   PRINT2 (("  "ID" : p-psi "ID"\n", i, p-psi)) ;
02451   ASSERT (IMPLIES (p-psi < nscol, i == k1 + (p-psi))) ;
02452   if (p-psi == nscol-1) PRINT2 (("------\n")) ;
02453   ASSERT (i > ilast) ;
02454   ilast = i ;
02455     }
02456     if (do_values)
02457     {
02458   psx = Lpx [s] ;
02459   CHOLMOD(dump_real) ("Supernode", Lx + xentry*psx, nsrow, nscol, TRUE, 
02460     xentry, Common) ;
02461     }
02462 }
02463 
02464 
02465 /* ========================================================================== */
02466 /* === cholmod_dump_mem ===================================================== */
02467 /* ========================================================================== */
02468 
02469 int CHOLMOD(dump_mem) (char *where, UF_long should, cholmod_common *Common)
02470 {
02471     UF_long diff = should - Common->memory_inuse ;
02472     if (diff != 0)
02473     {
02474   PRINT0 (("mem: %-15s peak %10g inuse %10g should %10g\n",
02475       where, (double) Common->memory_usage, (double) Common->memory_inuse,
02476       (double) should)) ;
02477   PRINT0 (("mem: %s diff %ld !\n", where, diff)) ;
02478     }
02479     return (diff == 0) ;
02480 }
02481 
02482 
02483 /* ========================================================================== */
02484 /* === cholmod_dump_partition =============================================== */
02485 /* ========================================================================== */
02486 
02487 /* make sure we have a proper separator (for debugging only)
02488  *
02489  * workspace: none
02490  */
02491 
02492 int CHOLMOD(dump_partition)
02493 (
02494     UF_long n,
02495     Int *Cp,
02496     Int *Ci,
02497     Int *Cnw,
02498     Int *Part,
02499     UF_long sepsize,
02500     cholmod_common *Common
02501 )
02502 {
02503     Int chek [3], which, ok, i, j, p ;
02504     PRINT1 (("bisect sepsize %ld\n", sepsize)) ;
02505     ok = TRUE ;
02506     chek [0] = 0 ;
02507     chek [1] = 0 ;
02508     chek [2] = 0 ;
02509     for (j = 0 ; j < n ; j++)
02510     {
02511   PRINT2 (("--------j "ID" in part "ID" nw "ID"\n", j, Part [j], Cnw[j]));
02512   which = Part [j] ;
02513   for (p = Cp [j] ; p < Cp [j+1] ; p++)
02514   {
02515       i = Ci [p] ;
02516       PRINT3 (("i "ID", part "ID"\n", i, Part [i])) ;
02517       if (which == 0)
02518       {
02519     if (Part [i] == 1)
02520     {
02521         PRINT0 (("Error! "ID" "ID"\n", i, j)) ;
02522         ok = FALSE ;
02523     }
02524       }
02525       else if (which == 1)
02526       {
02527     if (Part [i] == 0)
02528     {
02529         PRINT0 (("Error! "ID" "ID"\n", i, j)) ;
02530         ok = FALSE ;
02531     }
02532       }
02533   }
02534   if (which < 0 || which > 2)
02535   {
02536       PRINT0 (("Part out of range\n")) ;
02537       ok = FALSE ;
02538   }
02539   chek [which] += Cnw [j] ;
02540     }
02541     PRINT1 (("sepsize %ld check "ID" "ID" "ID"\n",
02542     sepsize, chek[0], chek[1],chek[2]));
02543     if (sepsize != chek[2])
02544     {
02545   PRINT0 (("mismatch!\n")) ;
02546   ok = FALSE ;
02547     }
02548     return (ok) ;
02549 }
02550 
02551 
02552 /* ========================================================================== */
02553 /* === cholmod_dump_work ==================================================== */
02554 /* ========================================================================== */
02555 
02556 int CHOLMOD(dump_work) (int flag, int head, UF_long wsize,
02557     cholmod_common *Common)
02558 {
02559     double *W ;
02560     Int *Flag, *Head ;
02561     Int k, nrow, mark ;
02562 
02563     if (CHOLMOD(dump) < -1)
02564     {
02565   /* no checks if debug level is -2 or less */
02566   return (TRUE) ;
02567     }
02568 
02569     RETURN_IF_NULL_COMMON (FALSE) ;
02570     nrow = Common->nrow ;
02571     Flag = Common->Flag ;
02572     Head = Common->Head ;
02573     W = Common->Xwork ;
02574     mark = Common->mark ;
02575 
02576     if (wsize < 0)
02577     {
02578   /* check all of Xwork */
02579   wsize = Common->xworksize ;
02580     }
02581     else
02582     {
02583   /* check on the first wsize doubles in Xwork */
02584   wsize = MIN (wsize, (Int) (Common->xworksize)) ;
02585     }
02586 
02587     if (flag)
02588     {
02589   for (k = 0 ; k < nrow ; k++)
02590   {
02591       if (Flag [k] >= mark)
02592       {
02593     PRINT0 (("Flag invalid, Flag ["ID"] = "ID", mark = "ID"\n",
02594           k, Flag [k], mark)) ;
02595     ASSERT (0) ;
02596     return (FALSE) ;
02597       }
02598   }
02599     }
02600 
02601     if (head)
02602     {
02603   for (k = 0 ; k < nrow ; k++)
02604   {
02605       if (Head [k] != EMPTY)
02606       {
02607     PRINT0 (("Head invalid, Head ["ID"] = "ID"\n", k, Head [k])) ;
02608     ASSERT (0) ;
02609     return (FALSE) ;
02610       }
02611   }
02612     }
02613 
02614     for (k = 0 ; k < wsize ; k++)
02615     {
02616   if (W [k] != 0.)
02617   {
02618       PRINT0 (("W invalid, W ["ID"] = %g\n", k, W [k])) ;
02619       ASSERT (0) ;
02620       return (FALSE) ;
02621   }
02622     }
02623 
02624     return (TRUE) ;
02625 }
02626 #endif
02627 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines