diff --git a/.github/workflows/build-arch-emu.yaml b/.github/workflows/build-arch-emu.yaml index 8011d708c..2ad03cab1 100644 --- a/.github/workflows/build-arch-emu.yaml +++ b/.github/workflows/build-arch-emu.yaml @@ -1,5 +1,6 @@ name: arch-emu on: + workflow_dispatch: push: branches-ignore: - '**/dev2' diff --git a/CHOLMOD/.gitignore b/CHOLMOD/.gitignore index 9ef9289f9..35ad65d69 100644 --- a/CHOLMOD/.gitignore +++ b/CHOLMOD/.gitignore @@ -1 +1,2 @@ timelog.m +_*.tex diff --git a/CHOLMOD/CMakeLists.txt b/CHOLMOD/CMakeLists.txt index 902088cec..670383133 100644 --- a/CHOLMOD/CMakeLists.txt +++ b/CHOLMOD/CMakeLists.txt @@ -12,10 +12,10 @@ # cmake 3.22 is required to find the BLAS/LAPACK cmake_minimum_required ( VERSION 3.22 ) -set ( CHOLMOD_DATE "Oct 15, 2023" ) -set ( CHOLMOD_VERSION_MAJOR 4 ) -set ( CHOLMOD_VERSION_MINOR 2 ) -set ( CHOLMOD_VERSION_SUB 2 ) +set ( CHOLMOD_DATE "Oct 23, 2023" ) +set ( CHOLMOD_VERSION_MAJOR 5 ) +set ( CHOLMOD_VERSION_MINOR 0 ) +set ( CHOLMOD_VERSION_SUB 0 ) message ( STATUS "Building CHOLMOD version: v" ${CHOLMOD_VERSION_MAJOR}. @@ -78,22 +78,22 @@ else ( ) find_package ( OpenMP ) endif ( ) -find_package ( SuiteSparse_config 7.2.0 +find_package ( SuiteSparse_config 7.3.0 PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) - find_package ( SuiteSparse_config 7.2.0 REQUIRED ) + find_package ( SuiteSparse_config 7.3.0 REQUIRED ) endif ( ) -find_package ( COLAMD 3.2.0 +find_package ( COLAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../COLAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::COLAMD ) - find_package ( COLAMD 3.2.0 REQUIRED ) + find_package ( COLAMD 3.2.1 REQUIRED ) endif ( ) -find_package ( AMD 3.2.0 +find_package ( AMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../AMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::AMD ) - find_package ( AMD 3.2.0 REQUIRED ) + find_package ( AMD 3.2.1 REQUIRED ) endif ( ) #------------------------------------------------------------------------------- @@ -196,16 +196,16 @@ endif ( ) if ( NOT NCAMD ) # find CAMD and CCOLAMD - find_package ( CAMD 3.2.0 + find_package ( CAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../CAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CAMD ) - find_package ( CAMD 3.2.0 ) + find_package ( CAMD 3.2.1 ) endif ( ) - find_package ( CCOLAMD 3.2.0 + find_package ( CCOLAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../CCOLAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CCOLAMD ) - find_package ( CCOLAMD 3.2.0 ) + find_package ( CCOLAMD 3.2.1 ) endif ( ) if ( NOT CAMD_FOUND OR NOT CCOLAMD_FOUND ) @@ -290,7 +290,7 @@ configure_file ( "Config/cholmod_version.tex.in" # include directories #------------------------------------------------------------------------------- -include_directories ( Check Cholesky Core MatrixOps Modify Partition +include_directories ( Check Cholesky Utility MatrixOps Modify Partition Supernodal Include ${CMAKE_SOURCE_DIR} ) #------------------------------------------------------------------------------- @@ -298,7 +298,7 @@ include_directories ( Check Cholesky Core MatrixOps Modify Partition #------------------------------------------------------------------------------- file ( GLOB CHOLMOD_SOURCES "Check/cholmod_*.c" "Cholesky/cholmod_*.c" - "Core/cholmod_*.c" "MatrixOps/cholmod_*.c" "Modify/cholmod_*.c" + "Utility/cholmod_*.c" "MatrixOps/cholmod_*.c" "Modify/cholmod_*.c" "Partition/cholmod_*.c" "Supernodal/cholmod_*.c" ) add_library ( CHOLMOD SHARED ${CHOLMOD_SOURCES} ) diff --git a/CHOLMOD/Check/cholmod_check.c b/CHOLMOD/Check/cholmod_check.c index 857163e40..56bc8e9a7 100644 --- a/CHOLMOD/Check/cholmod_check.c +++ b/CHOLMOD/Check/cholmod_check.c @@ -69,7 +69,7 @@ /* === printing definitions ================================================= */ /* ========================================================================== */ -#if ( ITYPE == CHOLMOD_LONG ) +#if defined ( CHOLMOD_INT64 ) #define I8 "%8ld" #define I_8 "%-8ld" #else @@ -204,7 +204,7 @@ static int check_common ) { double fl, lnz ; - double *Xwork ; + uint8_t *Xwork ; Int *Flag, *Head ; int64_t mark ; Int i, nrow, nmethods, ordering, xworksize, amd_backup, init_print ; @@ -502,9 +502,15 @@ static int check_common } P4 (" dbound: LDL' diagonal threshold: % .5g\n Entries with abs. value" - " less than dbound are replaced with +/- dbound.\n", + " less than dbound are replaced with +/- dbound.\n" + " (for double precision case)\n", Common->dbound) ; + P4 (" sbound: LDL' diagonal threshold: % .5g\n Entries with abs. value" + " less than sbound are replaced with +/- sbound.\n" + " (for single precision case)\n", + Common->sbound) ; + P4 (" grow0: memory reallocation: % .5g\n", Common->grow0) ; P4 (" grow1: memory reallocation: % .5g\n", Common->grow1) ; P4 (" grow2: memory reallocation: %g\n", (double) (Common->grow2)) ; @@ -552,7 +558,8 @@ static int check_common } } } - xworksize = Common->xworksize ; + + xworksize = Common->xworkbytes ; Xwork = Common->Xwork ; if (xworksize > 0) { @@ -564,7 +571,7 @@ static int check_common { if (Xwork [i] != 0.) { - PRINT0 (("Xwork ["ID"] = %g\n", i, Xwork [i])) ; + PRINT0 (("Xwork ["ID"] = %d\n", i, Xwork [i])) ; ERR ("workspace corrupted (Xwork)") ; } } @@ -742,7 +749,6 @@ static int64_t check_sparse switch (A->itype) { case CHOLMOD_INT: P4 ("%s", "\n scalar types: int, ") ; break ; - case CHOLMOD_INTLONG: ERR ("mixed int/long type unsupported") ; case CHOLMOD_LONG: P4 ("%s", "\n scalar types: int64_t, "); break ; default: ERR ("unknown itype") ; @@ -760,13 +766,13 @@ static int64_t check_sparse switch (A->dtype) { case CHOLMOD_DOUBLE: P4 ("%s", ", double\n") ; break ; - case CHOLMOD_SINGLE: ERR ("float unsupported") ; + case CHOLMOD_SINGLE: P4 ("%s", ", single\n") ; break ; default: ERR ("unknown dtype") ; } - if (A->itype != ITYPE || A->dtype != DTYPE) + if (A->itype != ITYPE) { - ERR ("integer and real type must match routine") ; + ERR ("integer type must match routine") ; } if (A->stype && nrow != ncol) @@ -1009,7 +1015,7 @@ static int check_dense switch (X->dtype) { case CHOLMOD_DOUBLE: P4 ("%s", ", double\n") ; break ; - case CHOLMOD_SINGLE: ERR ("single unsupported") ; + case CHOLMOD_SINGLE: P4 ("%s", ", single\n") ; break ; default: ERR ("unknown dtype") ; } @@ -1542,7 +1548,6 @@ static int check_factor switch (L->itype) { case CHOLMOD_INT: P4 ("%s", "\n scalar types: int, ") ; break ; - case CHOLMOD_INTLONG: ERR ("mixed int/long type unsupported") ; case CHOLMOD_LONG: P4 ("%s", "\n scalar types: int64_t, "); break ; default: ERR ("unknown itype") ; @@ -1560,13 +1565,13 @@ static int check_factor switch (L->dtype) { case CHOLMOD_DOUBLE: P4 ("%s", ", double\n") ; break ; - case CHOLMOD_SINGLE: ERR ("single unsupported") ; + case CHOLMOD_SINGLE: P4 ("%s", ", single\n") ; break ; default: ERR ("unknown dtype") ; } - if (L->itype != ITYPE || L->dtype != DTYPE) + if (L->itype != ITYPE) { - ERR ("integer and real type must match routine") ; + ERR ("integer type must match routine") ; } if (L->is_super) @@ -2118,7 +2123,6 @@ static int check_triplet switch (T->itype) { case CHOLMOD_INT: P4 ("%s", "\n scalar types: int, ") ; break ; - case CHOLMOD_INTLONG: ERR ("mixed int/long type unsupported") ; case CHOLMOD_LONG: P4 ("%s", "\n scalar types: int64_t, "); break ; default: ERR ("unknown itype") ; @@ -2136,13 +2140,13 @@ static int check_triplet switch (T->dtype) { case CHOLMOD_DOUBLE: P4 ("%s", ", double\n") ; break ; - case CHOLMOD_SINGLE: ERR ("single unsupported") ; + case CHOLMOD_SINGLE: P4 ("%s", ", single\n") ; break ; default: ERR ("unknown dtype") ; } - if (T->itype != ITYPE || T->dtype != DTYPE) + if (T->itype != ITYPE) { - ERR ("integer and real type must match routine") ; + ERR ("integer type must match routine") ; } if (T->stype && nrow != ncol) @@ -2450,7 +2454,7 @@ int CHOLMOD(dump_parent) void CHOLMOD(dump_real) ( const char *name, - Real *X, int64_t nrow, int64_t ncol, int lower, + double *X, int64_t nrow, int64_t ncol, int lower, int xentry, cholmod_common *Common ) { @@ -2654,16 +2658,19 @@ int CHOLMOD(dump_work) (int flag, int head, int64_t wsize, W = Common->Xwork ; mark = Common->mark ; +#if 0 + // FIXME: need float and double if (wsize < 0) { /* check all of Xwork */ - wsize = Common->xworksize ; + wsize = Common->xworkbytes ; } else { /* check on the first wsize doubles in Xwork */ - wsize = MIN (wsize, (Int) (Common->xworksize)) ; + wsize = MIN (wsize, (Int) (Common->xworkbytes)) ; } +#endif if (flag) { @@ -2673,7 +2680,6 @@ int CHOLMOD(dump_work) (int flag, int head, int64_t wsize, { PRINT0 (("Flag invalid, Flag ["ID"] = "ID", mark = "ID"\n", k, Flag [k], mark)) ; - ASSERT (0) ; return (FALSE) ; } } @@ -2686,23 +2692,25 @@ int CHOLMOD(dump_work) (int flag, int head, int64_t wsize, if (Head [k] != EMPTY) { PRINT0 (("Head invalid, Head ["ID"] = "ID"\n", k, Head [k])) ; - ASSERT (0) ; return (FALSE) ; } } } +#if 0 + // FIXME: need float and double for (k = 0 ; k < wsize ; k++) { if (W [k] != 0.) { PRINT0 (("W invalid, W ["ID"] = %g\n", k, W [k])) ; - ASSERT (0) ; return (FALSE) ; } } +#endif return (TRUE) ; } #endif #endif + diff --git a/CHOLMOD/Check/cholmod_l_check.c b/CHOLMOD/Check/cholmod_l_check.c index 5fb51ae16..881ee3479 100644 --- a/CHOLMOD/Check/cholmod_l_check.c +++ b/CHOLMOD/Check/cholmod_l_check.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_check.c" diff --git a/CHOLMOD/Check/cholmod_l_read.c b/CHOLMOD/Check/cholmod_l_read.c index 3af7074e6..d0decedbc 100644 --- a/CHOLMOD/Check/cholmod_l_read.c +++ b/CHOLMOD/Check/cholmod_l_read.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_read.c" diff --git a/CHOLMOD/Check/cholmod_l_write.c b/CHOLMOD/Check/cholmod_l_write.c index a7937d644..6ea5fa088 100644 --- a/CHOLMOD/Check/cholmod_l_write.c +++ b/CHOLMOD/Check/cholmod_l_write.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_write.c" diff --git a/CHOLMOD/Check/cholmod_read.c b/CHOLMOD/Check/cholmod_read.c index e610a8d0c..f1153dd61 100644 --- a/CHOLMOD/Check/cholmod_read.c +++ b/CHOLMOD/Check/cholmod_read.c @@ -48,7 +48,7 @@ * complex symmetric matrices are always returned with both upper and lower * triangular parts present, with an stype of zero, since CHOLMOD does not * have a method for representing skew-symmetric and complex symmetric - * matrices. Real symmetric and complex Hermitian matrices may optionally + * matrices. real symmetric and complex Hermitian matrices may optionally * be returned with both parts present. * * Any other lines starting with "%" are treated as comments, and are ignored. diff --git a/CHOLMOD/Check/cholmod_write.c b/CHOLMOD/Check/cholmod_write.c index f6adc9480..b19f2d030 100644 --- a/CHOLMOD/Check/cholmod_write.c +++ b/CHOLMOD/Check/cholmod_write.c @@ -140,7 +140,7 @@ static int print_value /* ---------------------------------------------------------------------- */ /* change -inf to -HUGE_DOUBLE, and change +inf and nan to +HUGE_DOUBLE */ - if (CHOLMOD_IS_NAN (x) || x >= HUGE_DOUBLE) + if (isnan (x) || x >= HUGE_DOUBLE) { x = HUGE_DOUBLE ; } @@ -341,7 +341,7 @@ static Int ntriplets * as A. * * Returns the symmetry in which the matrix was printed (1 to 7, see the - * CHOLMOD_MM_* codes in CHOLMOD/Include/cholmod_core.h), or -1 on failure. + * CHOLMOD_MM_* codes in CHOLMOD/Include/cholmod.h), or -1 on failure. * * If A and Z are sorted on input, and either unsymmetric (stype = 0) or * symmetric-lower (stype < 0), and if A and Z do not overlap, then the triplets diff --git a/CHOLMOD/Cholesky/cholmod_amd.c b/CHOLMOD/Cholesky/cholmod_amd.c index ef4eff006..6925e0ec3 100644 --- a/CHOLMOD/Cholesky/cholmod_amd.c +++ b/CHOLMOD/Cholesky/cholmod_amd.c @@ -166,7 +166,7 @@ int CHOLMOD(amd) Control [AMD_AGGRESSIVE] = Common->method [Common->current].aggressive ; } -#if ( ITYPE == CHOLMOD_LONG ) +#if defined ( CHOLMOD_INT64 ) amd_l2 (n, C->p, C->i, Len, C->nzmax, cnz, Nv, Next, Perm, Head, Elen, Degree, Wi, Control, Info) ; #else diff --git a/CHOLMOD/Cholesky/cholmod_analyze.c b/CHOLMOD/Cholesky/cholmod_analyze.c index 9f5f0dbb9..f61d8616d 100644 --- a/CHOLMOD/Cholesky/cholmod_analyze.c +++ b/CHOLMOD/Cholesky/cholmod_analyze.c @@ -408,7 +408,7 @@ cholmod_factor *CHOLMOD(analyze_p2) Int *First, *Level, *Work4n, *Cmember, *CParent, *ColCount, *Lperm, *Parent, *Post, *Perm, *Lparent, *Lcolcount ; cholmod_factor *L ; - Int k, n, ordering, method, nmethods, status, default_strategy, ncol, uncol, + Int k, n, method, nmethods, status, default_strategy, ncol, uncol, skip_analysis, skip_best ; Int amd_backup ; size_t s ; @@ -477,7 +477,9 @@ cholmod_factor *CHOLMOD(analyze_p2) * being tried, then enable AMD backup */ amd_backup = (nmethods > 1) || (nmethods == 1 && (Common->method [0].ordering == CHOLMOD_METIS || - Common->method [0].ordering == CHOLMOD_NESDIS)) ; + Common->method [0].ordering == CHOLMOD_NESDIS || + (Common->method [0].ordering == CHOLMOD_GIVEN && + UserPerm == NULL))) ; } #ifdef NSUPERNODAL @@ -565,6 +567,8 @@ cholmod_factor *CHOLMOD(analyze_p2) /* determine the method to try */ /* ------------------------------------------------------------------ */ + Int ordering ; + Common->fl = EMPTY ; Common->lnz = EMPTY ; skip_analysis = FALSE ; @@ -574,7 +578,6 @@ cholmod_factor *CHOLMOD(analyze_p2) /* All methods failed: backup to AMD */ if (Common->selected == EMPTY && amd_backup) { - PRINT1 (("All methods requested failed: backup to AMD\n")) ; ordering = CHOLMOD_AMD ; } else @@ -587,7 +590,6 @@ cholmod_factor *CHOLMOD(analyze_p2) ordering = Common->method [method].ordering ; } Common->current = method ; - PRINT1 (("method "ID": Try method: "ID"\n", method, ordering)) ; /* ------------------------------------------------------------------ */ /* find the fill-reducing permutation */ @@ -616,7 +618,6 @@ cholmod_factor *CHOLMOD(analyze_p2) if (UserPerm == NULL) { /* this is not an error condition */ - PRINT1 (("skip, no user perm given\n")) ; continue ; } for (k = 0 ; k < n ; k++) @@ -652,9 +653,6 @@ cholmod_factor *CHOLMOD(analyze_p2) } else { - /* Alternative: - CHOLMOD(ccolamd) (A, fset, fsize, NULL, Perm, Common) ; - */ /* do not postorder, it is done later, below */ /* workspace: Iwork (4*nrow+uncol), Flag (nrow), Head (nrow+1)*/ CHOLMOD(colamd) (A, fset, fsize, FALSE, Perm, Common) ; @@ -707,7 +705,6 @@ cholmod_factor *CHOLMOD(analyze_p2) /* -------------------------------------------------------------- */ Common->status = CHOLMOD_INVALID ; - PRINT1 (("No such ordering: "ID"\n", ordering)) ; } ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; @@ -739,7 +736,6 @@ cholmod_factor *CHOLMOD(analyze_p2) ASSERT (Common->fl >= 0 && Common->lnz >= 0) ; Common->method [method].fl = Common->fl ; Common->method [method].lnz = Common->lnz ; - PRINT1 (("lnz %g fl %g\n", Common->lnz, Common->fl)) ; /* ------------------------------------------------------------------ */ /* pick the best method */ @@ -749,7 +745,6 @@ cholmod_factor *CHOLMOD(analyze_p2) if (Common->selected == EMPTY || Common->lnz < lnz_best) { Common->selected = method ; - PRINT1 (("this is best so far, method "ID"\n", method)) ; L->ordering = ordering ; lnz_best = Common->lnz ; for (k = 0 ; k < n ; k++) @@ -915,8 +910,6 @@ cholmod_factor *CHOLMOD(analyze_p2) /* workspace: Flag (nrow), Head (nrow), Iwork (5*nrow) */ CHOLMOD(super_symbolic2) (for_whom, S, F, Lparent, L, Common) ; - PRINT1 (("status %d\n", Common->status)) ; - CHOLMOD(free_sparse) (&A1, Common) ; CHOLMOD(free_sparse) (&A2, Common) ; } diff --git a/CHOLMOD/Cholesky/cholmod_colamd.c b/CHOLMOD/Cholesky/cholmod_colamd.c index c14b7d0d3..3653d7d3b 100644 --- a/CHOLMOD/Cholesky/cholmod_colamd.c +++ b/CHOLMOD/Cholesky/cholmod_colamd.c @@ -92,7 +92,7 @@ int CHOLMOD(colamd) s = CHOLMOD(mult_size_t) (nrow, 4, &ok) ; s = CHOLMOD(add_size_t) (s, ncol, &ok) ; -#if ( ITYPE == CHOLMOD_LONG ) +#if defined ( CHOLMOD_INT64 ) alen = colamd_l_recommended (A->nzmax, ncol, nrow) ; colamd_l_set_defaults (knobs) ; #else @@ -151,7 +151,7 @@ int CHOLMOD(colamd) Int stats [COLAMD_STATS] ; Cp = C->p ; -#if ( ITYPE == CHOLMOD_LONG ) +#if defined ( CHOLMOD_INT64 ) colamd_l (ncol, nrow, alen, C->i, Cp, knobs, stats) ; #else colamd (ncol, nrow, alen, C->i, Cp, knobs, stats) ; diff --git a/CHOLMOD/Cholesky/cholmod_factorize.c b/CHOLMOD/Cholesky/cholmod_factorize.c index 2d4782c03..491dd8400 100644 --- a/CHOLMOD/Cholesky/cholmod_factorize.c +++ b/CHOLMOD/Cholesky/cholmod_factorize.c @@ -386,7 +386,7 @@ int CHOLMOD(factorize_p) if (Common->status == CHOLMOD_OK) { grow2 = Common->grow2 ; - L->is_ll = BOOLEAN (Common->final_ll) ; + L->is_ll = (Common->final_ll) ? 1 : 0 ; if (L->xtype == CHOLMOD_PATTERN && Common->final_pack) { /* allocate a factor with exactly the space required */ diff --git a/CHOLMOD/Cholesky/cholmod_l_amd.c b/CHOLMOD/Cholesky/cholmod_l_amd.c index 297f41050..8cdd7ca0e 100644 --- a/CHOLMOD/Cholesky/cholmod_l_amd.c +++ b/CHOLMOD/Cholesky/cholmod_l_amd.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_amd.c" diff --git a/CHOLMOD/Cholesky/cholmod_l_analyze.c b/CHOLMOD/Cholesky/cholmod_l_analyze.c index ef3ba5c30..0a7d87d0f 100644 --- a/CHOLMOD/Cholesky/cholmod_l_analyze.c +++ b/CHOLMOD/Cholesky/cholmod_l_analyze.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_analyze.c" diff --git a/CHOLMOD/Cholesky/cholmod_l_colamd.c b/CHOLMOD/Cholesky/cholmod_l_colamd.c index 58d4a2b50..990fab3d5 100644 --- a/CHOLMOD/Cholesky/cholmod_l_colamd.c +++ b/CHOLMOD/Cholesky/cholmod_l_colamd.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_colamd.c" diff --git a/CHOLMOD/Cholesky/cholmod_l_etree.c b/CHOLMOD/Cholesky/cholmod_l_etree.c index 057b544fa..9c30c27cb 100644 --- a/CHOLMOD/Cholesky/cholmod_l_etree.c +++ b/CHOLMOD/Cholesky/cholmod_l_etree.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_etree.c" diff --git a/CHOLMOD/Cholesky/cholmod_l_factorize.c b/CHOLMOD/Cholesky/cholmod_l_factorize.c index 177ddf61b..b7572779b 100644 --- a/CHOLMOD/Cholesky/cholmod_l_factorize.c +++ b/CHOLMOD/Cholesky/cholmod_l_factorize.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_factorize.c" diff --git a/CHOLMOD/Cholesky/cholmod_l_postorder.c b/CHOLMOD/Cholesky/cholmod_l_postorder.c index 207b1381e..ebf4b2cbb 100644 --- a/CHOLMOD/Cholesky/cholmod_l_postorder.c +++ b/CHOLMOD/Cholesky/cholmod_l_postorder.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_postorder.c" diff --git a/CHOLMOD/Cholesky/cholmod_l_rcond.c b/CHOLMOD/Cholesky/cholmod_l_rcond.c index 4ad8a08b6..63bb7b2d0 100644 --- a/CHOLMOD/Cholesky/cholmod_l_rcond.c +++ b/CHOLMOD/Cholesky/cholmod_l_rcond.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_rcond.c" diff --git a/CHOLMOD/Cholesky/cholmod_l_resymbol.c b/CHOLMOD/Cholesky/cholmod_l_resymbol.c index 8425f8335..8b5f15c75 100644 --- a/CHOLMOD/Cholesky/cholmod_l_resymbol.c +++ b/CHOLMOD/Cholesky/cholmod_l_resymbol.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_resymbol.c" diff --git a/CHOLMOD/Cholesky/cholmod_l_rowcolcounts.c b/CHOLMOD/Cholesky/cholmod_l_rowcolcounts.c index 10536d045..884ab3fb0 100644 --- a/CHOLMOD/Cholesky/cholmod_l_rowcolcounts.c +++ b/CHOLMOD/Cholesky/cholmod_l_rowcolcounts.c @@ -9,6 +9,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_rowcolcounts.c" diff --git a/CHOLMOD/Cholesky/cholmod_l_rowfac.c b/CHOLMOD/Cholesky/cholmod_l_rowfac.c index fb55f7221..5aa9253e0 100644 --- a/CHOLMOD/Cholesky/cholmod_l_rowfac.c +++ b/CHOLMOD/Cholesky/cholmod_l_rowfac.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_rowfac.c" diff --git a/CHOLMOD/Cholesky/cholmod_l_solve.c b/CHOLMOD/Cholesky/cholmod_l_solve.c index 7d2e14e30..01de1758e 100644 --- a/CHOLMOD/Cholesky/cholmod_l_solve.c +++ b/CHOLMOD/Cholesky/cholmod_l_solve.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_solve.c" diff --git a/CHOLMOD/Cholesky/cholmod_l_spsolve.c b/CHOLMOD/Cholesky/cholmod_l_spsolve.c index 1d43a57c9..7c510d836 100644 --- a/CHOLMOD/Cholesky/cholmod_l_spsolve.c +++ b/CHOLMOD/Cholesky/cholmod_l_spsolve.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_spsolve.c" diff --git a/CHOLMOD/Cholesky/cholmod_rcond.c b/CHOLMOD/Cholesky/cholmod_rcond.c index c0ebb6974..ae69bfbda 100644 --- a/CHOLMOD/Cholesky/cholmod_rcond.c +++ b/CHOLMOD/Cholesky/cholmod_rcond.c @@ -33,7 +33,7 @@ #define FIRST_LMINMAX(Ljj,lmin,lmax) \ { \ double ljj = Ljj ; \ - if (IS_NAN (ljj)) \ + if (isnan (ljj)) \ { \ return (0) ; \ } \ @@ -44,7 +44,7 @@ #define LMINMAX(Ljj,lmin,lmax) \ { \ double ljj = Ljj ; \ - if (IS_NAN (ljj)) \ + if (isnan (ljj)) \ { \ return (0) ; \ } \ diff --git a/CHOLMOD/Cholesky/cholmod_resymbol.c b/CHOLMOD/Cholesky/cholmod_resymbol.c index 7ecf85c15..cc142a5b7 100644 --- a/CHOLMOD/Cholesky/cholmod_resymbol.c +++ b/CHOLMOD/Cholesky/cholmod_resymbol.c @@ -440,7 +440,7 @@ int CHOLMOD(resymbol_noperm) /* flag the diagonal entry */ /* mark = CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; mark = Common->mark ; Flag [k] = mark ; @@ -597,8 +597,8 @@ int CHOLMOD(resymbol_noperm) /* ---------------------------------------------------------------------- */ /* CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; - + CLEAR_FLAG (Common) ; + ASSERT (check_flag (Common)) ; DEBUG (CHOLMOD(dump_factor) (L, "ReSymbol final L (i, x):", Common)) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; return (TRUE) ; diff --git a/CHOLMOD/Cholesky/cholmod_rowcolcounts.c b/CHOLMOD/Cholesky/cholmod_rowcolcounts.c index 57ffcf373..f98002ae5 100644 --- a/CHOLMOD/Cholesky/cholmod_rowcolcounts.c +++ b/CHOLMOD/Cholesky/cholmod_rowcolcounts.c @@ -507,8 +507,8 @@ int CHOLMOD(rowcolcounts) Common->mark = EMPTY ; /* CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; - + CLEAR_FLAG (Common) ; + ASSERT (check_flag (Common)) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ---------------------------------------------------------------------- */ @@ -532,3 +532,4 @@ int CHOLMOD(rowcolcounts) return (TRUE) ; } #endif + diff --git a/CHOLMOD/Cholesky/cholmod_rowfac.c b/CHOLMOD/Cholesky/cholmod_rowfac.c index 30751bc4e..079d2c686 100644 --- a/CHOLMOD/Cholesky/cholmod_rowfac.c +++ b/CHOLMOD/Cholesky/cholmod_rowfac.c @@ -297,7 +297,8 @@ int CHOLMOD(row_subtree) Flag = Common->Flag ; /* size nrow, Flag [i] < mark must hold */ /* mark = CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; + ASSERT (check_flag (Common)) ; mark = Common->mark ; /* ---------------------------------------------------------------------- */ diff --git a/CHOLMOD/Cholesky/cholmod_solve.c b/CHOLMOD/Cholesky/cholmod_solve.c index 78cb85ddd..d29c679ab 100644 --- a/CHOLMOD/Cholesky/cholmod_solve.c +++ b/CHOLMOD/Cholesky/cholmod_solve.c @@ -1153,13 +1153,12 @@ int CHOLMOD(solve2) /* returns TRUE on success, FALSE on failure */ /* convert a supernodal L to simplicial when using Bset */ if (L->is_super) { - /* Can only use Bset on a simplicial factorization. The supernodal - * factor L is converted to simplicial, leaving the xtype unchanged - * (real, complex, or zomplex). Since the supernodal factorization - * is already LL', it is left in that form. This conversion uses - * the ll_super_to_simplicial_numeric function in - * cholmod_change_factor. - */ + // Can only use Bset on a simplicial factorization. The supernodal + // factor L is converted to simplicial, leaving the xtype unchanged + // (real, complex, or zomplex). Since the supernodal factorization + // is already LL', it is left in that form. This conversion uses + // the super_num_to_simplicial_num function in + // cholmod_change_factor. CHOLMOD(change_factor) ( CHOLMOD_REAL, /* ignored, since L is already numeric */ TRUE, /* convert to LL' (no change to num. values) */ @@ -1548,6 +1547,13 @@ int CHOLMOD(solve2) /* returns TRUE on success, FALSE on failure */ Common->blas_ok = TRUE ; dual = (L->xtype == CHOLMOD_REAL && B->xtype != CHOLMOD_REAL) ? 2 : 1 ; Y = CHOLMOD(ensure_dense) (Y_Handle, n, dual*nrhs, n, L->xtype, Common); + + if (Common->status < CHOLMOD_OK) + { + /* out of memory */ + return (FALSE) ; + } + E = CHOLMOD(ensure_dense) (E_Handle, dual*nrhs, L->maxesize, dual*nrhs, L->xtype, Common) ; diff --git a/CHOLMOD/Cholesky/cholmod_spsolve.c b/CHOLMOD/Cholesky/cholmod_spsolve.c index 744de84da..1f0d00893 100644 --- a/CHOLMOD/Cholesky/cholmod_spsolve.c +++ b/CHOLMOD/Cholesky/cholmod_spsolve.c @@ -232,7 +232,7 @@ cholmod_sparse *CHOLMOD(spsolve) /* returns the sparse solution X */ for (i = 0 ; i < n ; i++) { x = X4x [i + j_n] ; - if (IS_NONZERO (x)) + if (x != 0) { Xi [xnz] = i ; Xx [xnz] = x ; @@ -246,7 +246,7 @@ cholmod_sparse *CHOLMOD(spsolve) /* returns the sparse solution X */ { x = X4x [2*(i + j_n) ] ; z = X4x [2*(i + j_n)+1] ; - if (IS_NONZERO (x) || IS_NONZERO (z)) + if ((x != 0) || (z != 0)) { Xi [xnz] = i ; Xx [2*xnz ] = x ; @@ -261,7 +261,7 @@ cholmod_sparse *CHOLMOD(spsolve) /* returns the sparse solution X */ { x = X4x [i + j_n] ; z = X4z [i + j_n] ; - if (IS_NONZERO (x) || IS_NONZERO (z)) + if ((x != 0) || (z != 0)) { Xi [xnz] = i ; Xx [xnz] = x ; @@ -287,7 +287,7 @@ cholmod_sparse *CHOLMOD(spsolve) /* returns the sparse solution X */ for (i = 0 ; i < n ; i++) { x = X4x [i + j_n] ; - if (IS_NONZERO (x)) + if (x != 0) { EXPAND_AS_NEEDED ; Xi [xnz] = i ; @@ -302,7 +302,7 @@ cholmod_sparse *CHOLMOD(spsolve) /* returns the sparse solution X */ { x = X4x [2*(i + j_n) ] ; z = X4x [2*(i + j_n)+1] ; - if (IS_NONZERO (x) || IS_NONZERO (z)) + if ((x != 0) || (z != 0)) { EXPAND_AS_NEEDED ; Xi [xnz] = i ; @@ -318,7 +318,7 @@ cholmod_sparse *CHOLMOD(spsolve) /* returns the sparse solution X */ { x = X4x [i + j_n] ; z = X4z [i + j_n] ; - if (IS_NONZERO (x) || IS_NONZERO (z)) + if ((x != 0) || (z != 0)) { EXPAND_AS_NEEDED ; Xi [xnz] = i ; diff --git a/CHOLMOD/Cholesky/t_cholmod_rowfac.c b/CHOLMOD/Cholesky/t_cholmod_rowfac.c index 1f1758f48..4b343176a 100644 --- a/CHOLMOD/Cholesky/t_cholmod_rowfac.c +++ b/CHOLMOD/Cholesky/t_cholmod_rowfac.c @@ -94,7 +94,7 @@ static int TEMPLATE (cholmod_rowfac) packed = A->packed ; sorted = A->sorted ; - use_dbound = IS_GT_ZERO (Common->dbound) ; + use_dbound = (Common->dbound > 0) ; /* get the current factors L (and D for LDL'); allocate space if needed */ is_ll = L->is_ll ; @@ -157,7 +157,8 @@ static int TEMPLATE (cholmod_rowfac) * zomplex. Xwork [i] == 0 must hold. */ Wz = Wx + n ; /* size n for zomplex case only */ mark = Common->mark ; - ASSERT ((Int) Common->xworksize >= (L->xtype == CHOLMOD_REAL ? 1:2)*n) ; + size_t wsize = (L->xtype == CHOLMOD_REAL ? 1:2) * n ; + ASSERT (Common->xworkbytes >= wsize * sizeof (Real)) ; /* ---------------------------------------------------------------------- */ /* compute LDL' or LL' factorization by rows */ @@ -179,7 +180,7 @@ static int TEMPLATE (cholmod_rowfac) /* column k of L is currently empty */ ASSERT (Lnz [k] == 1) ; - ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 2*n, Common)) ; + ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, wsize, Common)) ; top = n ; /* Stack is empty */ Flag [k] = mark ; /* do not include diagonal entry in Stack */ @@ -262,7 +263,7 @@ static int TEMPLATE (cholmod_rowfac) * Flag [Stack [top..n-1]] is equal to mark, but no longer needed */ /* mark = CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; mark = Common->mark ; /* ------------------------------------------------------------------ */ @@ -315,7 +316,7 @@ static int TEMPLATE (cholmod_rowfac) /* di = Lx [p] ; the diagonal entry L or D(i,i), which is real */ ASSIGN_REAL (di,0, Lx,p) ; - if (i >= (Int) L->minor || IS_ZERO (di [0])) + if (i >= (Int) L->minor || (di [0] == 0)) { /* For the LL' factorization, L(i,i) is zero. For the LDL', * D(i,i) is zero. Skip column i of L, and set L(k,i) = 0. */ @@ -386,7 +387,7 @@ static int TEMPLATE (cholmod_rowfac) /* W [i] = 0 ; */ CLEAR (Wx,Wz,i) ; } - ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, n, Common)) ; + ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, wsize, Common)) ; return (FALSE) ; } Li = L->i ; /* L->i, L->x, L->z may have moved */ @@ -420,7 +421,7 @@ static int TEMPLATE (cholmod_rowfac) /* modify the diagonal to force LL' or LDL' to exist */ dk [0] = CHOLMOD(dbound) (is_ll ? fabs (dk [0]) : dk [0], Common) ; } - else if ((is_ll ? (IS_LE_ZERO (dk [0])) : (IS_ZERO (dk [0]))) + else if ((is_ll ? (dk [0] <= 0) : (dk [0] == 0)) #ifndef REAL || dk_imaginary #endif @@ -449,7 +450,7 @@ static int TEMPLATE (cholmod_rowfac) Common->rowfacfl = fl ; DEBUG (CHOLMOD(dump_factor) (L, "final cholmod_rowfac", Common)) ; - ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, n, Common)) ; + ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, wsize, Common)) ; return (TRUE) ; } #undef PATTERN diff --git a/CHOLMOD/Config/cholmod.h.in b/CHOLMOD/Config/cholmod.h.in index 37c3212d9..f22fd7903 100644 --- a/CHOLMOD/Config/cholmod.h.in +++ b/CHOLMOD/Config/cholmod.h.in @@ -2,14 +2,14 @@ // CHOLMOD/Include/cholmod.h: include file for CHOLMOD //------------------------------------------------------------------------------ -// CHOLMOD/Include/cholmod.h. Copyright (C) 2005-2022, Timothy A. Davis. +// CHOLMOD/Include/cholmod.h. Copyright (C) 2005-2023, Timothy A. Davis. // All Rights Reserved. // Each Module of CHOLMOD has its own license, and a shared cholmod.h file. // CHOLMOD/Check: SPDX-License-Identifier: LGPL-2.1+ // CHOLMOD/Cholesky: SPDX-License-Identifier: LGPL-2.1+ -// CHOLMOD/Core: SPDX-License-Identifier: LGPL-2.1+ +// CHOLMOD/Utility: SPDX-License-Identifier: LGPL-2.1+ // CHOLMOD/Partition: SPDX-License-Identifier: LGPL-2.1+ // CHOLMOD/Demo: SPDX-License-Identifier: GPL-2.0+ @@ -19,433 +19,203 @@ // CHOLMOD/Modify: SPDX-License-Identifier: GPL-2.0+ // CHOLMOD/Supernodal: SPDX-License-Identifier: GPL-2.0+ // CHOLMOD/Tcov: SPDX-License-Identifier: GPL-2.0+ -// CHOLMOD/Valgrind: SPDX-License-Identifier: GPL-2.0+ //------------------------------------------------------------------------------ - -/* CHOLMOD consists of a set of Modules, each with their own license: either - * LGPL-2.1+ or GPL-2.0+. This cholmod.h file includes defintions of the - * CHOLMOD API for all Modules, and this cholmod.h file itself is provided to - * you with a permissive license (Apache-2.0). You are permitted to provide - * the hooks for an optional interface to CHOLMOD in a non-GPL/non-LGPL code, - * without requiring you to agree to the GPL/LGPL license of the Modules, as - * long as you don't use the *.c files in the relevant Modules. The Modules - * themselves can only be functional if their GPL or LGPL licenses are used. - * - * Portions of CHOLMOD (the Core and Partition Modules) are copyrighted by the - * University of Florida. The Modify Module is co-authored by William W. - * Hager, Univ. of Florida. - * - * Acknowledgements: this work was supported in part by the National Science - * Foundation (NFS CCR-0203270 and DMS-9803599), and a grant from Sandia - * National Laboratories (Dept. of Energy) which supported the development of - * CHOLMOD's Partition Module. - * -------------------------------------------------------------------------- */ - -/* CHOLMOD include file, for inclusion user programs. - * - * The include files listed below include a short description of each user- - * callable routine. Each routine in CHOLMOD has a consistent interface. - * More details about the CHOLMOD data types is in the cholmod_core.h file. - * - * Naming convention: - * ------------------ - * - * All routine names, data types, and CHOLMOD library files use the - * cholmod_ prefix. All macros and other #define's use the CHOLMOD - * prefix. - * - * Return value: - * ------------- - * - * Most CHOLMOD routines return an int (TRUE (1) if successful, or FALSE - * (0) otherwise. An int32_t, int64_t, or double return value is >= 0 if - * successful, or -1 otherwise. A size_t return value is > 0 if - * successful, or 0 otherwise. - * - * If a routine returns a pointer, it is a pointer to a newly allocated - * object or NULL if a failure occured, with one exception. cholmod_free - * always returns NULL. - * - * "Common" parameter: - * ------------------ - * - * The last parameter in all CHOLMOD routines is a pointer to the CHOLMOD - * "Common" object. This contains control parameters, statistics, and - * workspace used between calls to CHOLMOD. It is always an input/output - * parameter. - * - * Input, Output, and Input/Output parameters: - * ------------------------------------------- - * - * Input parameters are listed first. They are not modified by CHOLMOD. - * - * Input/output are listed next. They must be defined on input, and - * are modified on output. - * - * Output parameters are listed next. If they are pointers, they must - * point to allocated space on input, but their contents are not defined - * on input. - * - * Workspace parameters appear next. They are used in only two routines - * in the Supernodal module. - * - * The cholmod_common *Common parameter always appears as the last - * parameter. It is always an input/output parameter. - */ +// CHOLMOD consists of a set of Modules, each with their own license: either +// LGPL-2.1+ or GPL-2.0+. This cholmod.h file includes defintions of the +// CHOLMOD API for all Modules, and this cholmod.h file itself is provided to +// you with a permissive license (Apache-2.0). You are permitted to provide +// the hooks for an optional interface to CHOLMOD in a non-GPL/non-LGPL code, +// without requiring you to agree to the GPL/LGPL license of the Modules, as +// long as you don't use the *.c files in the relevant Modules. The Modules +// themselves can only be functional if their GPL or LGPL licenses are used. +// +// The Modify Module is co-authored by William W. Hager. +// +// Acknowledgements: this work was supported in part by the National Science +// Foundation (NFS CCR-0203270 and DMS-9803599), and a grant from Sandia +// National Laboratories (Dept. of Energy) which supported the development of +// CHOLMOD's Partition Module. +// ----------------------------------------------------------------------------- + +// Each routine in CHOLMOD has a consistent interface. +// +// Naming convention: +// ------------------ +// +// All routine names, data types, and CHOLMOD library files use the +// cholmod_ prefix. All macros and other #define's use the CHOLMOD +// prefix. +// +// Return value: +// ------------- +// +// Most CHOLMOD routines return an int (TRUE (1) if successful, or FALSE +// (0) otherwise. An int32_t, int64_t, double, or float return value +// is >= 0 if successful, or -1 otherwise. A size_t return value +// is > 0 if successful, or 0 otherwise. +// +// If a routine returns a pointer, it is a pointer to a newly allocated +// object or NULL if a failure occured, with one exception. cholmod_free +// always returns NULL. +// +// "Common" parameter: +// ------------------ +// +// The last parameter in all CHOLMOD routines is a pointer to the CHOLMOD +// "Common" object. This contains control parameters, statistics, and +// workspace used between calls to CHOLMOD. It is always an input/output +// parameter. +// +// Input, Output, and Input/Output parameters: +// ------------------------------------------- +// +// Input parameters are listed first. They are not modified by CHOLMOD. +// +// Input/output are listed next. They must be defined on input, and +// are modified on output. +// +// Output parameters are listed next. If they are pointers, they must +// point to allocated space on input, but their contents are not defined +// on input. +// +// Workspace parameters appear next. They are used in only two routines +// in the Supernodal module. +// +// The cholmod_common *Common parameter always appears as the last +// parameter. It is always an input/output parameter. #ifndef CHOLMOD_H #define CHOLMOD_H +//============================================================================== +// version control +//============================================================================== + #define CHOLMOD_DATE "@CHOLMOD_DATE@" #define CHOLMOD_MAIN_VERSION @CHOLMOD_VERSION_MAJOR@ #define CHOLMOD_SUB_VERSION @CHOLMOD_VERSION_MINOR@ #define CHOLMOD_SUBSUB_VERSION @CHOLMOD_VERSION_SUB@ -/* ========================================================================== */ -/* === Include/cholmod_io64 ================================================= */ -/* ========================================================================== */ - -/* assume large file support. If problems occur, compile with -DNLARGEFILE */ - -/* Definitions required for large file I/O, which must come before any other - * #includes. These are not used if -DNLARGEFILE is defined at compile time. - * Large file support may not be portable across all platforms and compilers; - * if you encounter an error here, compile your code with -DNLARGEFILE. In - * particular, you must use -DNLARGEFILE for MATLAB 6.5 or earlier (which does - * not have the io64.h include file). - */ +#define CHOLMOD_VER_CODE(main,sub) ((main) * 1000 + (sub)) +#define CHOLMOD_VERSION \ + CHOLMOD_VER_CODE(CHOLMOD_MAIN_VERSION,CHOLMOD_SUB_VERSION) +#define CHOLMOD_HAS_VERSION_FUNCTION -/* skip all of this if NLARGEFILE is defined at the compiler command line */ -#ifndef NLARGEFILE +#ifdef __cplusplus +extern "C" { +#endif -#if defined(MATLAB_MEX_FILE) || defined(MATHWORKS) +int cholmod_version // returns CHOLMOD_VERSION, defined above +( + // if version is not NULL, then cholmod_version returns its contents as: + // version [0] = CHOLMOD_MAIN_VERSION + // version [1] = CHOLMOD_SUB_VERSION + // version [2] = CHOLMOD_SUBSUB_VERSION + int version [3] +) ; +int cholmod_l_version (int version [3]) ; -/* CHOLMOD is being compiled as a MATLAB mexFunction, or for use in MATLAB */ -#include "io64.h" +#ifdef __cplusplus +} +#endif -#else +//============================================================================== +// Large file support +//============================================================================== -/* CHOLMOD is being compiled in a stand-alone library */ -#undef _LARGEFILE64_SOURCE -#define _LARGEFILE64_SOURCE -#undef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 64 +// CHOLMOD assumes large file support. If problems occur, compile with +// -DNLARGEFILE -#endif +// Definitions required for large file I/O, which must come before any other +// #includes. These are not used if -DNLARGEFILE is defined at compile time. +// Large file support may not be portable across all platforms and compilers; +// if you encounter an error here, compile your code with -DNLARGEFILE. In +// particular, you must use -DNLARGEFILE for MATLAB 6.5 or earlier (which does +// not have the io64.h include file). +// skip all of this if NLARGEFILE is defined at the compiler command line +#ifndef NLARGEFILE + #if defined(MATLAB_MEX_FILE) || defined(MATHWORKS) + // CHOLMOD compiled as a MATLAB mexFunction, or for use in MATLAB + #include "io64.h" + #else + // CHOLMOD is being compiled in a stand-alone library + #undef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #undef _FILE_OFFSET_BITS + #define _FILE_OFFSET_BITS 64 + #endif #endif -/* ========================================================================== */ -/* === SuiteSparse_config.h ================================================= */ -/* ========================================================================== */ +//============================================================================== +// SuiteSparse_config +//============================================================================== #include "SuiteSparse_config.h" -/* ========================================================================== */ -/* === Include/cholmod_config.h ============================================= */ -/* ========================================================================== */ - -/* CHOLMOD configuration file, for inclusion in user programs. - * - * You do not have to edit any CHOLMOD files to compile and install CHOLMOD. - * However, if you do not use all of CHOLMOD's modules, you need to compile - * with the appropriate flag, or edit this file to add the appropriate #define. - * - * Compiler flags for CHOLMOD: - * - * -DNCHECK do not include the Check module. - * -DNCHOLESKY do not include the Cholesky module. - * -DNPARTITION do not include the Partition module. - * -DNCAMD do not include the interfaces to CAMD, - * CCOLAMD, CSYMAND in Partition module. - * -DNMATRIXOPS do not include the MatrixOps module. - * -DNMODIFY do not include the Modify module. - * -DNSUPERNODAL do not include the Supernodal module. - * - * -DNPRINT do not print anything - * - * The Core Module is always included in the CHOLMOD library. - */ - -/* Use the compiler flag, or uncomment the definition(s), if you want to use - * one or more non-default installation options: */ - -/* -#define NCHECK -#define NCHOLESKY -#define NCAMD -#define NPARTITION -#define NMATRIXOPS -#define NMODIFY -#define NSUPERNODAL -#define NPRINT -#define NGPL -*/ - -/* The NGPL option disables the MatrixOps, Modify, and Supernodal modules. The - existence of this #define here, and its use in these 3 modules, does not - affect the license itself; see CHOLMOD/Doc/License.txt for your actual - license. - */ +//============================================================================== +// CHOLMOD configuration +//============================================================================== + +// You do not have to edit any CHOLMOD files to compile and install CHOLMOD. +// However, if you do not use all of CHOLMOD's modules, you need to compile +// with the appropriate flag, or edit this file to add the appropriate #define. +// +// Compiler flags for CHOLMOD +// +// -DNCHECK do not include the Check module. +// -DNCHOLESKY do not include the Cholesky module. +// -DNPARTITION do not include the Partition module. +// -DNCAMD do not include the interfaces to CAMD, +// CCOLAMD, CSYMAND in Partition module. +// -DNMATRIXOPS do not include the MatrixOps module. +// -DNMODIFY do not include the Modify module. +// -DNSUPERNODAL do not include the Supernodal module. +// +// -DNPRINT do not print anything +// +// The Utility Module is always included in the CHOLMOD library. + +// Use the compiler flag, or uncomment the definition(s), if you want to use +// one or more non-default installation options: + +// #define NCHECK +// #define NCHOLESKY +// #define NCAMD +// #define NPARTITION +// #define NMATRIXOPS +// #define NMODIFY +// #define NSUPERNODAL +// #define NPRINT +// #define NGPL + +// The NGPL option disables the MatrixOps, Modify, and Supernodal modules. The +// existence of this #define here, and its use in these 3 modules, does not +// affect the license itself; see CHOLMOD/Doc/License.txt for your actual +// license. #ifdef NGPL -#undef NMATRIXOPS -#define NMATRIXOPS -#undef NMODIFY -#define NMODIFY -#undef NSUPERNODAL -#define NSUPERNODAL + #undef NMATRIXOPS + #define NMATRIXOPS + #undef NMODIFY + #define NMODIFY + #undef NSUPERNODAL + #define NSUPERNODAL #endif +//============================================================================== +// CHOLMOD:Utility Module +//============================================================================== -/* ========================================================================== */ -/* === Include/cholmod_core.h =============================================== */ -/* ========================================================================== */ - -/* CHOLMOD Core module: basic CHOLMOD objects and routines. - * Required by all CHOLMOD modules. Requires no other module or package. - * - * The CHOLMOD modules are: - * - * Core basic data structures and definitions - * Check check/print the 5 CHOLMOD objects, & 3 types of integer vectors - * Cholesky sparse Cholesky factorization - * Modify sparse Cholesky update/downdate/row-add/row-delete - * MatrixOps sparse matrix functions (add, multiply, norm, ...) - * Supernodal supernodal sparse Cholesky factorization - * Partition graph-partitioning based orderings - * - * The CHOLMOD objects: - * -------------------- - * - * cholmod_common parameters, statistics, and workspace - * cholmod_sparse a sparse matrix in compressed column form - * cholmod_factor an LL' or LDL' factorization - * cholmod_dense a dense matrix - * cholmod_triplet a sparse matrix in "triplet" form - * - * The Core module described here defines the CHOLMOD data structures, and - * basic operations on them. To create and solve a sparse linear system Ax=b, - * the user must create A and b, populate them with values, and then pass them - * to the routines in the CHOLMOD Cholesky module. There are two primary - * methods for creating A: (1) allocate space for a column-oriented sparse - * matrix and fill it with pattern and values, or (2) create a triplet form - * matrix and convert it to a sparse matrix. The latter option is simpler. - * - * The matrices b and x are typically dense matrices, but can also be sparse. - * You can allocate and free them as dense matrices with the - * cholmod_allocate_dense and cholmod_free_dense routines. - * - * The cholmod_factor object contains the symbolic and numeric LL' or LDL' - * factorization of sparse symmetric matrix. The matrix must be positive - * definite for an LL' factorization. It need only be symmetric and have well- - * conditioned leading submatrices for it to have an LDL' factorization - * (CHOLMOD does not pivot for numerical stability). It is typically created - * with the cholmod_factorize routine in the Cholesky module, but can also - * be initialized to L=D=I in the Core module and then modified by the Modify - * module. It must be freed with cholmod_free_factor, defined below. - * - * The Core routines for each object are described below. Each list is split - * into two parts: the primary routines and secondary routines. - * - * ============================================================================ - * === cholmod_common ========================================================= - * ============================================================================ - * - * The Common object contains control parameters, statistics, and - * You must call cholmod_start before calling any other CHOLMOD routine, and - * must call cholmod_finish as your last call to CHOLMOD, with two exceptions: - * you may call cholmod_print_common and cholmod_check_common in the Check - * module after calling cholmod_finish. - * - * cholmod_start first call to CHOLMOD - * cholmod_finish last call to CHOLMOD - * ----------------------------- - * cholmod_defaults restore default parameters - * cholmod_maxrank maximum rank for update/downdate - * cholmod_allocate_work allocate workspace in Common - * cholmod_free_work free workspace in Common - * cholmod_clear_flag clear Flag workspace in Common - * cholmod_error called when CHOLMOD encounters an error - * cholmod_dbound for internal use in CHOLMOD only - * cholmod_hypot compute sqrt (x*x + y*y) accurately - * cholmod_divcomplex complex division, c = a/b - * - * ============================================================================ - * === cholmod_sparse ========================================================= - * ============================================================================ - * - * A sparse matrix is held in compressed column form. In the basic type - * ("packed", which corresponds to a MATLAB sparse matrix), an n-by-n matrix - * with nz entries is held in three arrays: p of size n+1, i of size nz, and x - * of size nz. Row indices of column j are held in i [p [j] ... p [j+1]-1] and - * in the same locations in x. There may be no duplicate entries in a column. - * Row indices in each column may be sorted or unsorted (CHOLMOD keeps track). - * A->stype determines the storage mode: 0 if both upper/lower parts are stored, - * -1 if A is symmetric and just tril(A) is stored, +1 if symmetric and triu(A) - * is stored. - * - * cholmod_allocate_sparse allocate a sparse matrix - * cholmod_free_sparse free a sparse matrix - * ----------------------------- - * cholmod_reallocate_sparse change the size (# entries) of sparse matrix - * cholmod_nnz number of nonzeros in a sparse matrix - * cholmod_speye sparse identity matrix - * cholmod_spzeros sparse zero matrix - * cholmod_transpose transpose a sparse matrix - * cholmod_ptranspose transpose/permute a sparse matrix - * cholmod_transpose_unsym transpose/permute an unsymmetric sparse matrix - * cholmod_transpose_sym transpose/permute a symmetric sparse matrix - * cholmod_sort sort row indices in each column of sparse matrix - * cholmod_band C = tril (triu (A,k1), k2) - * cholmod_band_inplace A = tril (triu (A,k1), k2) - * cholmod_aat C = A*A' - * cholmod_copy_sparse C = A, create an exact copy of a sparse matrix - * cholmod_copy C = A, with possible change of stype - * cholmod_add C = alpha*A + beta*B - * cholmod_sparse_xtype change the xtype of a sparse matrix - * - * ============================================================================ - * === cholmod_factor ========================================================= - * ============================================================================ - * - * The data structure for an LL' or LDL' factorization is too complex to - * describe in one sentence. This object can hold the symbolic analysis alone, - * or in combination with a "simplicial" (similar to a sparse matrix) or - * "supernodal" form of the numerical factorization. Only the routine to free - * a factor is primary, since a factor object is created by the factorization - * routine (cholmod_factorize). It must be freed with cholmod_free_factor. - * - * cholmod_free_factor free a factor - * ----------------------------- - * cholmod_allocate_factor allocate a factor (LL' or LDL') - * cholmod_reallocate_factor change the # entries in a factor - * cholmod_change_factor change the type of factor (e.g., LDL' to LL') - * cholmod_pack_factor pack the columns of a factor - * cholmod_reallocate_column resize a single column of a factor - * cholmod_factor_to_sparse create a sparse matrix copy of a factor - * cholmod_copy_factor create a copy of a factor - * cholmod_factor_xtype change the xtype of a factor - * - * Note that there is no cholmod_sparse_to_factor routine to create a factor - * as a copy of a sparse matrix. It could be done, after a fashion, but a - * lower triangular sparse matrix would not necessarily have a chordal graph, - * which would break the many CHOLMOD routines that rely on this property. - * - * ============================================================================ - * === cholmod_dense ========================================================== - * ============================================================================ - * - * The solve routines and some of the MatrixOps and Modify routines use dense - * matrices as inputs. These are held in column-major order. With a leading - * dimension of d, the entry in row i and column j is held in x [i+j*d]. - * - * cholmod_allocate_dense allocate a dense matrix - * cholmod_free_dense free a dense matrix - * ----------------------------- - * cholmod_zeros allocate a dense matrix of all zeros - * cholmod_ones allocate a dense matrix of all ones - * cholmod_eye allocate a dense identity matrix - * cholmod_sparse_to_dense create a dense matrix copy of a sparse matrix - * cholmod_dense_to_sparse create a sparse matrix copy of a dense matrix - * cholmod_copy_dense create a copy of a dense matrix - * cholmod_copy_dense2 copy a dense matrix (pre-allocated) - * cholmod_dense_xtype change the xtype of a dense matrix - * cholmod_ensure_dense ensure a dense matrix has a given size and type - * - * ============================================================================ - * === cholmod_triplet ======================================================== - * ============================================================================ - * - * A sparse matrix held in triplet form is the simplest one for a user to - * create. It consists of a list of nz entries in arbitrary order, held in - * three arrays: i, j, and x, each of length nk. The kth entry is in row i[k], - * column j[k], with value x[k]. There may be duplicate values; if A(i,j) - * appears more than once, its value is the sum of the entries with those row - * and column indices. - * - * cholmod_allocate_triplet allocate a triplet matrix - * cholmod_triplet_to_sparse create a sparse matrix copy of a triplet matrix - * cholmod_free_triplet free a triplet matrix - * ----------------------------- - * cholmod_reallocate_triplet change the # of entries in a triplet matrix - * cholmod_sparse_to_triplet create a triplet matrix copy of a sparse matrix - * cholmod_copy_triplet create a copy of a triplet matrix - * cholmod_triplet_xtype change the xtype of a triplet matrix - * - * ============================================================================ - * === memory management ====================================================== - * ============================================================================ - * - * cholmod_malloc malloc wrapper - * cholmod_calloc calloc wrapper - * cholmod_free free wrapper - * cholmod_realloc realloc wrapper - * cholmod_realloc_multiple realloc wrapper for multiple objects - * - * ============================================================================ - * === Core CHOLMOD prototypes ================================================ - * ============================================================================ - * - * All CHOLMOD routines (in all modules) use the following protocol for return - * values, with one exception: - * - * int TRUE (1) if successful, or FALSE (0) otherwise. - * (exception: cholmod_divcomplex) - * int32_t a value >= 0 if successful, or -1 otherwise. - * int64_t a value >= 0 if successful, or -1 otherwise. - * double a value >= 0 if successful, or -1 otherwise. - * size_t a value > 0 if successful, or 0 otherwise. - * void * a non-NULL pointer to newly allocated memory if - * successful, or NULL otherwise. - * cholmod_sparse * a non-NULL pointer to a newly allocated matrix - * if successful, or NULL otherwise. - * cholmod_factor * a non-NULL pointer to a newly allocated factor - * if successful, or NULL otherwise. - * cholmod_triplet * a non-NULL pointer to a newly allocated triplet - * matrix if successful, or NULL otherwise. - * cholmod_dense * a non-NULL pointer to a newly allocated triplet - * matrix if successful, or NULL otherwise. - * - * The last parameter to all routines is always a pointer to the CHOLMOD - * Common object. - * - * TRUE and FALSE are not defined here, since they may conflict with the user - * program. A routine that described here returning TRUE or FALSE returns 1 - * or 0, respectively. Any TRUE/FALSE parameter is true if nonzero, false if - * zero. - */ - -/* ========================================================================== */ -/* === CHOLMOD version ====================================================== */ -/* ========================================================================== */ - -/* All versions of CHOLMOD will include the following definitions. - * As an example, to test if the version you are using is 1.3 or later: - * - * if (CHOLMOD_VERSION >= CHOLMOD_VER_CODE (1,3)) ... - * - * This also works during compile-time: - * - * #if CHOLMOD_VERSION >= CHOLMOD_VER_CODE (1,3) - * printf ("This is version 1.3 or later\n") ; - * #else - * printf ("This is version is earlier than 1.3\n") ; - * #endif - */ +// the CHOLMOD:Utility Module is always required +#if 1 -#define CHOLMOD_HAS_VERSION_FUNCTION -#define CHOLMOD_VER_CODE(main,sub) ((main) * 1000 + (sub)) -#define CHOLMOD_VERSION \ - CHOLMOD_VER_CODE(CHOLMOD_MAIN_VERSION,CHOLMOD_SUB_VERSION) - - -/* ========================================================================== */ -/* === CUDA BLAS for the GPU ================================================ */ -/* ========================================================================== */ +//------------------------------------------------------------------------------ +// CUDA BLAS +//------------------------------------------------------------------------------ -/* Define buffering parameters for GPU processing */ +// Define buffering parameters for GPU processing #ifndef SUITESPARSE_GPU_EXTERN_ON #ifdef SUITESPARSE_CUDA #include @@ -456,724 +226,529 @@ #define CHOLMOD_HOST_SUPERNODE_BUFFERS 8 #define CHOLMOD_DEVICE_STREAMS 2 -/* ========================================================================== */ -/* === CHOLMOD objects ====================================================== */ -/* ========================================================================== */ - -/* Each CHOLMOD object has its own type code. */ +//------------------------------------------------------------------------------ +// CHOLMOD objects +//------------------------------------------------------------------------------ +// CHOLMOD object enums #define CHOLMOD_COMMON 0 #define CHOLMOD_SPARSE 1 #define CHOLMOD_FACTOR 2 #define CHOLMOD_DENSE 3 #define CHOLMOD_TRIPLET 4 -/* ========================================================================== */ -/* === CHOLMOD Common ======================================================= */ -/* ========================================================================== */ - -/* itype defines the types of integer used: */ -#define CHOLMOD_INT 0 /* all integer arrays are int32_t */ -#define CHOLMOD_INTLONG 1 /* most are int32_t, some are int64_t */ -#define CHOLMOD_LONG 2 /* all integer arrays are int64_t */ - -/* The itype of all parameters for all CHOLMOD routines must match. - * FUTURE WORK: CHOLMOD_INTLONG is not yet supported. - */ - -/* dtype defines what the numerical type is (double or float): */ -#define CHOLMOD_DOUBLE 0 /* all numerical values are double */ -#define CHOLMOD_SINGLE 1 /* all numerical values are float */ - -/* The dtype of all parameters for all CHOLMOD routines must match. - * - * Scalar floating-point values are always passed as double arrays of size 2 - * (for the real and imaginary parts). They are typecast to float as needed. - * FUTURE WORK: the float case is not supported yet. - */ +// enums used by cholmod_symmetry and cholmod_write +#define CHOLMOD_MM_RECTANGULAR 1 +#define CHOLMOD_MM_UNSYMMETRIC 2 +#define CHOLMOD_MM_SYMMETRIC 3 +#define CHOLMOD_MM_HERMITIAN 4 +#define CHOLMOD_MM_SKEW_SYMMETRIC 5 +#define CHOLMOD_MM_SYMMETRIC_POSDIAG 6 +#define CHOLMOD_MM_HERMITIAN_POSDIAG 7 -/* xtype defines the kind of numerical values used: */ -#define CHOLMOD_PATTERN 0 /* pattern only, no numerical values */ -#define CHOLMOD_REAL 1 /* a real matrix */ -#define CHOLMOD_COMPLEX 2 /* a complex matrix (ANSI C99 compatible) */ -#define CHOLMOD_ZOMPLEX 3 /* a complex matrix (MATLAB compatible) */ +//------------------------------------------------------------------------------ +// CHOLMOD Common object +//------------------------------------------------------------------------------ -/* The xtype of all parameters for all CHOLMOD routines must match. - * - * CHOLMOD_PATTERN: x and z are ignored. - * CHOLMOD_DOUBLE: x is non-null of size nzmax, z is ignored. - * CHOLMOD_COMPLEX: x is non-null of size 2*nzmax doubles, z is ignored. - * CHOLMOD_ZOMPLEX: x and z are non-null of size nzmax - * - * In the real case, z is ignored. The kth entry in the matrix is x [k]. - * There are two methods for the complex case. In the ANSI C99-compatible - * CHOLMOD_COMPLEX case, the real and imaginary parts of the kth entry - * are in x [2*k] and x [2*k+1], respectively. z is ignored. In the - * MATLAB-compatible CHOLMOD_ZOMPLEX case, the real and imaginary - * parts of the kth entry are in x [k] and z [k]. - * - * Scalar floating-point values are always passed as double arrays of size 2 - * (real and imaginary parts). The imaginary part of a scalar is ignored if - * the routine operates on a real matrix. - * - * These Modules support complex and zomplex matrices, with a few exceptions: - * - * Check all routines - * Cholesky all routines - * Core all except cholmod_aat, add, band, copy - * Demo all routines - * Partition all routines - * Supernodal all routines support any real, complex, or zomplex input. - * There will never be a supernodal zomplex L; a complex - * supernodal L is created if A is zomplex. - * Tcov all routines - * Valgrind all routines - * - * These Modules provide partial support for complex and zomplex matrices: - * - * MATLAB all routines support real and zomplex only, not complex, - * with the exception of ldlupdate, which supports - * real matrices only. This is a minor constraint since - * MATLAB's matrices are all real or zomplex. - * MatrixOps only norm_dense, norm_sparse, and sdmult support complex - * and zomplex - * - * These Modules do not support complex and zomplex matrices at all: - * - * Modify all routines support real matrices only - */ +// itype: integer sizes +// The itype is held in the Common object and must match the method used. +#define CHOLMOD_INT 0 /* int32, for cholmod_* methods (no _l_) */ +#define CHOLMOD_LONG 2 /* int64, for cholmod_l_* methods */ + +// dtype: floating point sizes (double or float) +// The dtype of all parameters for all CHOLMOD routines must match. +// NOTE: CHOLMOD_SINGLE is still under development. +#define CHOLMOD_DOUBLE 0 /* matrix or factorization is double precision */ +#define CHOLMOD_SINGLE 4 /* matrix or factorization is single precision */ + +// xtype: pattern, real, complex, or zomplex +#define CHOLMOD_PATTERN 0 /* no numerical values */ +#define CHOLMOD_REAL 1 /* real (double or single), not complex */ +#define CHOLMOD_COMPLEX 2 /* complex (double or single), interleaved */ +#define CHOLMOD_ZOMPLEX 3 /* complex (double or single), with real and imag */ + /* parts held in different arrays */ + +// xdtype is (xtype + dtype), which combines the two type parameters into +// a single number handling all 8 cases: +// +// (0) CHOLMOD_DOUBLE + CHOLMOD_PATTERN a pattern-only matrix +// (1) CHOLMOD_DOUBLE + CHOLMOD_REAL a double real matrix +// (2) CHOLMOD_DOUBLE + CHOLMOD_COMPLEX a double complex matrix +// (3) CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX a double zomplex matrix +// (4) CHOLMOD_SINGLE + CHOLMOD_PATTERN a pattern-only matrix +// (5) CHOLMOD_SINGLE + CHOLMOD_REAL a float real matrix +// (6) CHOLMOD_SINGLE + CHOLMOD_COMPLEX a float complex matrix +// (7) CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX a float zomplex matrix + +// max # of ordering methods in Common +#define CHOLMOD_MAXMETHODS 9 + +// Common->status for error handling: 0 is ok, negative is a fatal error, +// and positive is a warning +#define CHOLMOD_OK (0) +#define CHOLMOD_NOT_INSTALLED (-1) /* module not installed */ +#define CHOLMOD_OUT_OF_MEMORY (-2) /* malloc, calloc, or realloc failed */ +#define CHOLMOD_TOO_LARGE (-3) /* integer overflow */ +#define CHOLMOD_INVALID (-4) /* input invalid */ +#define CHOLMOD_GPU_PROBLEM (-5) /* CUDA error */ +#define CHOLMOD_NOT_POSDEF (1) /* matrix not positive definite */ +#define CHOLMOD_DSMALL (2) /* diagonal entry very small */ + +// ordering method +#define CHOLMOD_NATURAL 0 /* no preordering */ +#define CHOLMOD_GIVEN 1 /* user-provided permutation */ +#define CHOLMOD_AMD 2 /* AMD: approximate minimum degree */ +#define CHOLMOD_METIS 3 /* METIS: mested dissection */ +#define CHOLMOD_NESDIS 4 /* CHOLMOD's nested dissection */ +#define CHOLMOD_COLAMD 5 /* AMD for A, COLAMD for AA' or A'A */ +#define CHOLMOD_POSTORDERED 6 /* natural then postordered */ + +// supernodal strategy +#define CHOLMOD_SIMPLICIAL 0 /* always use simplicial method */ +#define CHOLMOD_AUTO 1 /* auto select simplicial vs supernodal */ +#define CHOLMOD_SUPERNODAL 2 /* always use supernoda method */ -/* Definitions for cholmod_common: */ -#define CHOLMOD_MAXMETHODS 9 /* maximum number of different methods that */ - /* cholmod_analyze can try. Must be >= 9. */ - -/* Common->status values. zero means success, negative means a fatal error, - * positive is a warning. */ -#define CHOLMOD_OK 0 /* success */ -#define CHOLMOD_NOT_INSTALLED (-1) /* failure: method not installed */ -#define CHOLMOD_OUT_OF_MEMORY (-2) /* failure: out of memory */ -#define CHOLMOD_TOO_LARGE (-3) /* failure: integer overflow occured */ -#define CHOLMOD_INVALID (-4) /* failure: invalid input */ -#define CHOLMOD_GPU_PROBLEM (-5) /* failure: GPU fatal error */ -#define CHOLMOD_NOT_POSDEF (1) /* warning: matrix not pos. def. */ -#define CHOLMOD_DSMALL (2) /* warning: D for LDL' or diag(L) or */ - /* LL' has tiny absolute value */ - -/* ordering method (also used for L->ordering) */ -#define CHOLMOD_NATURAL 0 /* use natural ordering */ -#define CHOLMOD_GIVEN 1 /* use given permutation */ -#define CHOLMOD_AMD 2 /* use minimum degree (AMD) */ -#define CHOLMOD_METIS 3 /* use METIS' nested dissection */ -#define CHOLMOD_NESDIS 4 /* use CHOLMOD's version of nested dissection:*/ - /* node bisector applied recursively, followed - * by constrained minimum degree (CSYMAMD or - * CCOLAMD) */ -#define CHOLMOD_COLAMD 5 /* use AMD for A, COLAMD for A*A' */ - -/* POSTORDERED is not a method, but a result of natural ordering followed by a - * weighted postorder. It is used for L->ordering, not method [ ].ordering. */ -#define CHOLMOD_POSTORDERED 6 /* natural ordering, postordered. */ - -/* supernodal strategy (for Common->supernodal) */ -#define CHOLMOD_SIMPLICIAL 0 /* always do simplicial */ -#define CHOLMOD_AUTO 1 /* select simpl/super depending on matrix */ -#define CHOLMOD_SUPERNODAL 2 /* always do supernodal */ - -/* make it easy for C++ programs to include CHOLMOD */ #ifdef __cplusplus extern "C" { #endif typedef struct cholmod_common_struct { - /* ---------------------------------------------------------------------- */ - /* parameters for symbolic/numeric factorization and update/downdate */ - /* ---------------------------------------------------------------------- */ - - double dbound ; /* Smallest absolute value of diagonal entries of D - * for LDL' factorization and update/downdate/rowadd/ - * rowdel, or the diagonal of L for an LL' factorization. - * Entries in the range 0 to dbound are replaced with dbound. - * Entries in the range -dbound to 0 are replaced with -dbound. No - * changes are made to the diagonal if dbound <= 0. Default: zero */ - - double grow0 ; /* For a simplicial factorization, L->i and L->x can - * grow if necessary. grow0 is the factor by which - * it grows. For the initial space, L is of size MAX (1,grow0) times - * the required space. If L runs out of space, the new size of L is - * MAX(1.2,grow0) times the new required space. If you do not plan on - * modifying the LDL' factorization in the Modify module, set grow0 to - * zero (or set grow2 to 0, see below). Default: 1.2 */ - - double grow1 ; - - size_t grow2 ; /* For a simplicial factorization, each column j of L - * is initialized with space equal to - * grow1*L->ColCount[j] + grow2. If grow0 < 1, grow1 < 1, or grow2 == 0, - * then the space allocated is exactly equal to L->ColCount[j]. If the - * column j runs out of space, it increases to grow1*need + grow2 in - * size, where need is the total # of nonzeros in that column. If you do - * not plan on modifying the factorization in the Modify module, set - * grow2 to zero. Default: grow1 = 1.2, grow2 = 5. */ - - size_t maxrank ; /* rank of maximum update/downdate. Valid values: - * 2, 4, or 8. A value < 2 is set to 2, and a - * value > 8 is set to 8. It is then rounded up to the next highest - * power of 2, if not already a power of 2. Workspace (Xwork, below) of - * size nrow-by-maxrank double's is allocated for the update/downdate. - * If an update/downdate of rank-k is requested, with k > maxrank, - * it is done in steps of maxrank. Default: 8, which is fastest. - * Memory usage can be reduced by setting maxrank to 2 or 4. - */ - - double supernodal_switch ; /* supernodal vs simplicial factorization */ - int supernodal ; /* If Common->supernodal <= CHOLMOD_SIMPLICIAL - * (0) then cholmod_analyze performs a - * simplicial analysis. If >= CHOLMOD_SUPERNODAL (2), then a supernodal - * analysis is performed. If == CHOLMOD_AUTO (1) and - * flop/nnz(L) < Common->supernodal_switch, then a simplicial analysis - * is done. A supernodal analysis done otherwise. - * Default: CHOLMOD_AUTO. Default supernodal_switch = 40 */ - - int final_asis ; /* If TRUE, then ignore the other final_* parameters - * (except for final_pack). - * The factor is left as-is when done. Default: TRUE.*/ - - int final_super ; /* If TRUE, leave a factor in supernodal form when - * supernodal factorization is finished. If FALSE, - * then convert to a simplicial factor when done. - * Default: TRUE */ - - int final_ll ; /* If TRUE, leave factor in LL' form when done. - * Otherwise, leave in LDL' form. Default: FALSE */ - - int final_pack ; /* If TRUE, pack the columns when done. If TRUE, and - * cholmod_factorize is called with a symbolic L, L is - * allocated with exactly the space required, using L->ColCount. If you - * plan on modifying the factorization, set Common->final_pack to FALSE, - * and each column will be given a little extra slack space for future - * growth in fill-in due to updates. Default: TRUE */ - - int final_monotonic ; /* If TRUE, ensure columns are monotonic when done. - * Default: TRUE */ - - int final_resymbol ;/* if cholmod_factorize performed a supernodal - * factorization, final_resymbol is true, and - * final_super is FALSE (convert a simplicial numeric factorization), - * then numerically zero entries that resulted from relaxed supernodal - * amalgamation are removed. This does not remove entries that are zero - * due to exact numeric cancellation, since doing so would break the - * update/downdate rowadd/rowdel routines. Default: FALSE. */ - - /* supernodal relaxed amalgamation parameters: */ - double zrelax [3] ; - size_t nrelax [3] ; - - /* Let ns be the total number of columns in two adjacent supernodes. - * Let z be the fraction of zero entries in the two supernodes if they - * are merged (z includes zero entries from prior amalgamations). The - * two supernodes are merged if: - * (ns <= nrelax [0]) || (no new zero entries added) || - * (ns <= nrelax [1] && z < zrelax [0]) || - * (ns <= nrelax [2] && z < zrelax [1]) || (z < zrelax [2]) - * - * Default parameters result in the following rule: - * (ns <= 4) || (no new zero entries added) || - * (ns <= 16 && z < 0.8) || (ns <= 48 && z < 0.1) || (z < 0.05) - */ - - int prefer_zomplex ; /* X = cholmod_solve (sys, L, B, Common) computes - * x=A\b or solves a related system. If L and B are - * both real, then X is real. Otherwise, X is returned as - * CHOLMOD_COMPLEX if Common->prefer_zomplex is FALSE, or - * CHOLMOD_ZOMPLEX if Common->prefer_zomplex is TRUE. This parameter - * is needed because there is no supernodal zomplex L. Suppose the - * caller wants all complex matrices to be stored in zomplex form - * (MATLAB, for example). A supernodal L is returned in complex form - * if A is zomplex. B can be real, and thus X = cholmod_solve (L,B) - * should return X as zomplex. This cannot be inferred from the input - * arguments L and B. Default: FALSE, since all data types are - * supported in CHOLMOD_COMPLEX form and since this is the native type - * of LAPACK and the BLAS. Note that the MATLAB/cholmod.c mexFunction - * sets this parameter to TRUE, since MATLAB matrices are in - * CHOLMOD_ZOMPLEX form. - */ - - int prefer_upper ; /* cholmod_analyze and cholmod_factorize work - * fastest when a symmetric matrix is stored in - * upper triangular form when a fill-reducing ordering is used. In - * MATLAB, this corresponds to how x=A\b works. When the matrix is - * ordered as-is, they work fastest when a symmetric matrix is in lower - * triangular form. In MATLAB, R=chol(A) does the opposite. This - * parameter affects only how cholmod_read returns a symmetric matrix. - * If TRUE (the default case), a symmetric matrix is always returned in - * upper-triangular form (A->stype = 1). */ - - int quick_return_if_not_posdef ; /* if TRUE, the supernodal numeric - * factorization will return quickly if - * the matrix is not positive definite. Default: FALSE. */ - - int prefer_binary ; /* cholmod_read_triplet converts a symmetric - * pattern-only matrix into a real matrix. If - * prefer_binary is FALSE, the diagonal entries are set to 1 + the degree - * of the row/column, and off-diagonal entries are set to -1 (resulting - * in a positive definite matrix if the diagonal is zero-free). Most - * symmetric patterns are the pattern a positive definite matrix. If - * this parameter is TRUE, then the matrix is returned with a 1 in each - * entry, instead. Default: FALSE. Added in v1.3. */ - - /* ---------------------------------------------------------------------- */ - /* printing and error handling options */ - /* ---------------------------------------------------------------------- */ - - int print ; /* print level. Default: 3 */ - int precise ; /* if TRUE, print 16 digits. Otherwise print 5 */ - - /* CHOLMOD print_function replaced with SuiteSparse_config print_func */ - - int try_catch ; /* if TRUE, then ignore errors; CHOLMOD is in the middle - * of a try/catch block. No error message is printed - * and the Common->error_handler function is not called. */ - - void (*error_handler) (int status, const char *file, - int line, const char *message) ; - - /* Common->error_handler is the user's error handling routine. If not - * NULL, this routine is called if an error occurs in CHOLMOD. status - * can be CHOLMOD_OK (0), negative for a fatal error, and positive for - * a warning. file is a string containing the name of the source code - * file where the error occured, and line is the line number in that - * file. message is a string describing the error in more detail. */ - - /* ---------------------------------------------------------------------- */ - /* ordering options */ - /* ---------------------------------------------------------------------- */ - - /* The cholmod_analyze routine can try many different orderings and select - * the best one. It can also try one ordering method multiple times, with - * different parameter settings. The default is to use three orderings, - * the user's permutation (if provided), AMD which is the fastest ordering - * and generally gives good fill-in, and METIS. CHOLMOD's nested dissection - * (METIS with a constrained AMD) usually gives a better ordering than METIS - * alone (by about 5% to 10%) but it takes more time. - * - * If you know the method that is best for your matrix, set Common->nmethods - * to 1 and set Common->method [0] to the set of parameters for that method. - * If you set it to 1 and do not provide a permutation, then only AMD will - * be called. - * - * If METIS is not available, the default # of methods tried is 2 (the user - * permutation, if any, and AMD). - * - * To try other methods, set Common->nmethods to the number of methods you - * want to try. The suite of default methods and their parameters is - * described in the cholmod_defaults routine, and summarized here: - * - * Common->method [i]: - * i = 0: user-provided ordering (cholmod_analyze_p only) - * i = 1: AMD (for both A and A*A') - * i = 2: METIS - * i = 3: CHOLMOD's nested dissection (NESDIS), default parameters - * i = 4: natural - * i = 5: NESDIS with nd_small = 20000 - * i = 6: NESDIS with nd_small = 4, no constrained minimum degree - * i = 7: NESDIS with no dense node removal - * i = 8: AMD for A, COLAMD for A*A' - * - * You can modify the suite of methods you wish to try by modifying - * Common.method [...] after calling cholmod_start or cholmod_defaults. - * - * For example, to use AMD, followed by a weighted postordering: - * - * Common->nmethods = 1 ; - * Common->method [0].ordering = CHOLMOD_AMD ; - * Common->postorder = TRUE ; - * - * To use the natural ordering (with no postordering): - * - * Common->nmethods = 1 ; - * Common->method [0].ordering = CHOLMOD_NATURAL ; - * Common->postorder = FALSE ; - * - * If you are going to factorize hundreds or more matrices with the same - * nonzero pattern, you may wish to spend a great deal of time finding a - * good permutation. In this case, try setting Common->nmethods to 9. - * The time spent in cholmod_analysis will be very high, but you need to - * call it only once. - * - * cholmod_analyze sets Common->current to a value between 0 and nmethods-1. - * Each ordering method uses the set of options defined by this parameter. - */ - - int nmethods ; /* The number of ordering methods to try. Default: 0. - * nmethods = 0 is a special case. cholmod_analyze - * will try the user-provided ordering (if given) and AMD. Let fl and - * lnz be the flop count and nonzeros in L from AMD's ordering. Let - * anz be the number of nonzeros in the upper or lower triangular part - * of the symmetric matrix A. If fl/lnz < 500 or lnz/anz < 5, then this - * is a good ordering, and METIS is not attempted. Otherwise, METIS is - * tried. The best ordering found is used. If nmethods > 0, the - * methods used are given in the method[ ] array, below. The first - * three methods in the default suite of orderings is (1) use the given - * permutation (if provided), (2) use AMD, and (3) use METIS. Maximum - * allowed value is CHOLMOD_MAXMETHODS. */ - - int current ; /* The current method being tried. Default: 0. Valid - * range is 0 to nmethods-1. */ - - int selected ; /* The best method found. */ - - /* The suite of ordering methods and parameters: */ + //-------------------------------------------------------------------------- + // primary parameters for factorization and update/downdate + //-------------------------------------------------------------------------- + + double dbound ; // Bounds the diagonal entries of D for LDL' + // factorization and update/downdate/rowadd. Entries outside this + // bound are replaced with dbound. Default: 0. + // dbound is used for double precision factorization only. + // See sbound for single precision factorization. + + double grow0 ; // default: 1.2 + double grow1 ; // default: 1.2 + size_t grow2 ; // default: 5 + // Initial space for simplicial factorization is max(grow0,1) times the + // required space. If space is exhausted, L is grown by + // max(grow0,1.2) times the required space. grow1 and grow2 control + // how each column of L can grow in an update/downdate; if space runs + // out, then grow1*(required space) + grow2 is allocated. + + size_t maxrank ; // maximum rank for update/downdate. Valid values are + // 2, 4, and 8. Default is 8. If a larger update/downdate is done, + // it is done in steps of maxrank. + + double supernodal_switch ; // default: 40 + int supernodal ; // default: CHOLMOD_AUTO. + // Controls supernodal vs simplicial factorization. If + // Common->supernodal is CHOLMOD_SIMPLICIAL, a simplicial factorization + // is always done; if CHOLMOD_SUPERNODAL, a supernodal factorization is + // always done. If CHOLMOD_AUTO, then a simplicial factorization is + // down if flops/nnz(L) < Common->supernodal_switch. + + int final_asis ; // if true, other final_* parameters are ignored, + // except for final_pack and the factors are left as-is when done. + // Default: true. + + int final_super ; // if true, leave factor in supernodal form. + // if false, convert to simplicial. Default: true. + + int final_ll ; // if true, simplicial factors are converted to LL', + // otherwise left as LDL. Default: false. + + int final_pack ; // if true, the factorize are allocated with exactly + // the space required. Set this to false if you expect future + // updates/downdates (giving a little extra space for future growth), + // Default: true. + + int final_monotonic ; // if true, columns are sorted when done, by + // ascending row index. Default: true. + + int final_resymbol ; // if true, a supernodal factorization converted + // to simplicial is reanalyzed, to remove zeros added for relaxed + // amalgamation. Default: false. + + double zrelax [3] ; size_t nrelax [3] ; + // The zrelax and nrelax parameters control relaxed supernodal + // amalgamation, If ns is the # of columns in two adjacent supernodes, + // and z is the fraction of zeros in the two supernodes if merged, then + // the two supernodes are merged if any of the 5 following condition + // are true: + // + // no new zero entries added if the two supernodes are merged + // (ns <= nrelax [0]) + // (ns <= nrelax [1] && z < zrelax [0]) + // (ns <= nrelax [2] && z < zrelax [1]) + // (z < zrelax [2]) + // + // With the defaults, the rules become: + // + // no new zero entries added if the two supernodes are merged + // (ns <= 4) + // (ns <= 16 && z < 0.8) + // (ns <= 48 && z < 0.1) + // (z < 0.05) + + int prefer_zomplex ; // if true, and a complex system is solved, + // X is returned as zomplex (with two arrays, one for the real part + // and one for the imaginary part). If false, then X is returned as + // a single array with interleaved real and imaginary parts. + // Default: false. + + int prefer_upper ; // if true, then a preference is given for holding + // a symmetric matrix by just its upper triangular form. This gives + // the best performance by the CHOLMOD analysis and factorization + // methods. Only used by cholmod_read. Default: true. + + int quick_return_if_not_posdef ; // if true, a supernodal factorization + // returns immediately if it finds the matrix is not positive definite. + // If false, the failed supernode is refactorized, up to but not + // including the failed column (required by MATLAB). + + int prefer_binary ; // if true, cholmod_read_triplet converts a symmetric + // pattern-only matrix to a real matrix with all values set to 1. + // if false, diagonal entries A(k,k) are set to one plus the # of + // entries in row/column k, and off-diagonals are set to -1. + // Default: false. + + int print ; // print level. Default is 3. + int precise ; // if true, print 16 digits, otherwise 5. Default: false. + + int try_catch ; // if true, ignore errors (CHOLMOD is assumed to be inside + // a try/catch block. No error messages are printed and the + // error_handler function is not called. Default: false. + + void (*error_handler) (int status, const char *file, int line, + const char *message) ; + // User error handling routine; default is NULL. + // This function is called if an error occurs, with parameters: + // status: the Common->status result. + // file: filename where the error occurred. + // line: line number where the error occurred. + // message: a string that describes the error. + + //-------------------------------------------------------------------------- + // ordering options + //-------------------------------------------------------------------------- + + // CHOLMOD can try many ordering options and then pick the best result it + // finds. The default is to use one or two orderings: the user's + // permutation (if given), and AMD. + + // Common->nmethods is the number of methods to try. If the + // Common->method array is left unmodified, the methods are: + + // (0) given (skipped if no user permutation) + // (1) amd + // (2) metis + // (3) nesdis with defaults (CHOLMOD's nested dissection, based on METIS) + // (4) natural + // (5) nesdis: stop at subgraphs of 20000 nodes + // (6) nesdis: stop at subgraphs of 4 nodes, do not use CAMD + // (7) nesdis: no pruning on of dense rows/cols + // (8) colamd + + // To use all 9 of the above methods, set Common->nmethods to 9. The + // analysis will take a long time, but that might be worth it if the + // ordering will be reused many many times. + + // Common->nmethods and Common->methods can be revised to use a different + // set of orderings. For example, to use just a single method + // (AMD with a weighted postordering): + // + // Common->nmethods = 1 ; + // Common->method [0].ordering = CHOLMOD_AMD ; + // Common->postorder = TRUE ; + // + // + + int nmethods ; // Number of methods to try, default is 0. + // The value of 0 is a special case, and tells CHOLMOD to use the user + // permutation (if not NULL) and then AMD. Next, if fl is lnz are the + // flop counts and number of nonzeros in L as found by AMD, then the + // this ordering is used if fl/lnz < 500 or lnz/anz < 5, where anz is + // the number of entries in A. If this condition fails, METIS is tried + // as well. + // + // Otherwise, if Common->nmethods > 0, then the methods defined by + // Common->method [0 ... Common->nmethods-1] are used. + + int current ; // The current method being tried in the analysis. + int selected ; // The selected method: Common->method [Common->selected] + + // The Common->method parameter is an array of structs that defines up + // to 9 methods: struct cholmod_method_struct { - /* statistics for this method */ - double lnz ; /* nnz(L) excl. zeros from supernodal amalgamation, - * for a "pure" L */ - - double fl ; /* flop count for a "pure", real simplicial LL' - * factorization, with no extra work due to - * amalgamation. Subtract n to get the LDL' flop count. Multiply - * by about 4 if the matrix is complex or zomplex. */ - - /* ordering method parameters */ - double prune_dense ;/* dense row/col control for AMD, SYMAMD, CSYMAMD, - * and NESDIS (cholmod_nested_dissection). For a - * symmetric n-by-n matrix, rows/columns with more than - * MAX (16, prune_dense * sqrt (n)) entries are removed prior to - * ordering. They appear at the end of the re-ordered matrix. - * - * If prune_dense < 0, only completely dense rows/cols are removed. - * - * This paramater is also the dense column control for COLAMD and - * CCOLAMD. For an m-by-n matrix, columns with more than - * MAX (16, prune_dense * sqrt (MIN (m,n))) entries are removed prior - * to ordering. They appear at the end of the re-ordered matrix. - * CHOLMOD factorizes A*A', so it calls COLAMD and CCOLAMD with A', - * not A. Thus, this parameter affects the dense *row* control for - * CHOLMOD's matrix, and the dense *column* control for COLAMD and - * CCOLAMD. - * - * Removing dense rows and columns improves the run-time of the - * ordering methods. It has some impact on ordering quality - * (usually minimal, sometimes good, sometimes bad). - * - * Default: 10. */ - - double prune_dense2 ;/* dense row control for COLAMD and CCOLAMD. - * Rows with more than MAX (16, dense2 * sqrt (n)) - * for an m-by-n matrix are removed prior to ordering. CHOLMOD's - * matrix is transposed before ordering it with COLAMD or CCOLAMD, - * so this controls the dense *columns* of CHOLMOD's matrix, and - * the dense *rows* of COLAMD's or CCOLAMD's matrix. - * - * If prune_dense2 < 0, only completely dense rows/cols are removed. - * - * Default: -1. Note that this is not the default for COLAMD and - * CCOLAMD. -1 is best for Cholesky. 10 is best for LU. */ - - double nd_oksep ; /* in NESDIS, when a node separator is computed, it - * discarded if nsep >= nd_oksep*n, where nsep is - * the number of nodes in the separator, and n is the size of the - * graph being cut. Valid range is 0 to 1. If 1 or greater, the - * separator is discarded if it consists of the entire graph. - * Default: 1 */ - - double other_1 [4] ; /* future expansion */ - - size_t nd_small ; /* do not partition graphs with fewer nodes than - * nd_small, in NESDIS. Default: 200 (same as - * METIS) */ - - size_t other_2 [4] ; /* future expansion */ - - int aggressive ; /* Aggresive absorption in AMD, COLAMD, SYMAMD, - * CCOLAMD, and CSYMAMD. Default: TRUE */ - - int order_for_lu ; /* CCOLAMD can be optimized to produce an ordering - * for LU or Cholesky factorization. CHOLMOD only - * performs a Cholesky factorization. However, you may wish to use - * CHOLMOD as an interface for CCOLAMD but use it for your own LU - * factorization. In this case, order_for_lu should be set to FALSE. - * When factorizing in CHOLMOD itself, you should *** NEVER *** set - * this parameter FALSE. Default: TRUE. */ - - int nd_compress ; /* If TRUE, compress the graph and subgraphs before - * partitioning them in NESDIS. Default: TRUE */ - - int nd_camd ; /* If 1, follow the nested dissection ordering - * with a constrained minimum degree ordering that - * respects the partitioning just found (using CAMD). If 2, use - * CSYMAMD instead. If you set nd_small very small, you may not need - * this ordering, and can save time by setting it to zero (no - * constrained minimum degree ordering). Default: 1. */ - - int nd_components ; /* The nested dissection ordering finds a node - * separator that splits the graph into two parts, - * which may be unconnected. If nd_components is TRUE, each of - * these connected components is split independently. If FALSE, - * each part is split as a whole, even if it consists of more than - * one connected component. Default: FALSE */ - - /* fill-reducing ordering to use */ - int ordering ; - - size_t other_3 [4] ; /* future expansion */ - - } method [CHOLMOD_MAXMETHODS + 1] ; - - int postorder ; /* If TRUE, cholmod_analyze follows the ordering with a - * weighted postorder of the elimination tree. Improves - * supernode amalgamation. Does not affect fundamental nnz(L) and - * flop count. Default: TRUE. */ - - int default_nesdis ; /* Default: FALSE. If FALSE, then the default - * ordering strategy (when Common->nmethods == 0) - * is to try the given ordering (if present), AMD, and then METIS if AMD - * reports high fill-in. If Common->default_nesdis is TRUE then NESDIS - * is used instead in the default strategy. */ - - /* ---------------------------------------------------------------------- */ - /* memory management, complex divide, and hypot function pointers moved */ - /* ---------------------------------------------------------------------- */ - - /* Function pointers moved from here (in CHOLMOD 2.2.0) to - SuiteSparse_config.[ch]. See CHOLMOD/Include/cholmod_back.h - for a set of macros that can be #include'd or copied into your - application to define these function pointers on any version of CHOLMOD. - */ - - /* ---------------------------------------------------------------------- */ - /* METIS workarounds */ - /* ---------------------------------------------------------------------- */ - - /* These workarounds were put into place for METIS 4.0.1. They are safe - to use with METIS 5.1.0, but they might not longer be necessary. */ - - double metis_memory ; /* This is a parameter for CHOLMOD's interface to - * METIS, not a parameter to METIS itself. METIS - * uses an amount of memory that is difficult to estimate precisely - * beforehand. If it runs out of memory, it terminates your program. - * All routines in CHOLMOD except for CHOLMOD's interface to METIS - * return an error status and safely return to your program if they run - * out of memory. To mitigate this problem, the CHOLMOD interface - * can allocate a single block of memory equal in size to an empirical - * upper bound of METIS's memory usage times the Common->metis_memory - * parameter, and then immediately free it. It then calls METIS. If - * this pre-allocation fails, it is possible that METIS will fail as - * well, and so CHOLMOD returns with an out-of-memory condition without - * calling METIS. - * - * METIS_NodeND (used in the CHOLMOD_METIS ordering option) with its - * default parameter settings typically uses about (4*nz+40n+4096) - * times sizeof(int) memory, where nz is equal to the number of entries - * in A for the symmetric case or AA' if an unsymmetric matrix is - * being ordered (where nz includes both the upper and lower parts - * of A or AA'). The observed "upper bound" (with 2 exceptions), - * measured in an instrumented copy of METIS 4.0.1 on thousands of - * matrices, is (10*nz+50*n+4096) * sizeof(int). Two large matrices - * exceeded this bound, one by almost a factor of 2 (Gupta/gupta2). - * - * If your program is terminated by METIS, try setting metis_memory to - * 2.0, or even higher if needed. By default, CHOLMOD assumes that METIS - * does not have this problem (so that CHOLMOD will work correctly when - * this issue is fixed in METIS). Thus, the default value is zero. - * This work-around is not guaranteed anyway. - * - * If a matrix exceeds this predicted memory usage, AMD is attempted - * instead. It, too, may run out of memory, but if it does so it will - * not terminate your program. - */ - - double metis_dswitch ; /* METIS_NodeND in METIS 4.0.1 gives a seg */ - size_t metis_nswitch ; /* fault with one matrix of order n = 3005 and - * nz = 6,036,025. This is a very dense graph. - * The workaround is to use AMD instead of METIS for matrices of dimension - * greater than Common->metis_nswitch (default 3000) or more and with - * density of Common->metis_dswitch (default 0.66) or more. - * cholmod_nested_dissection has no problems with the same matrix, even - * though it uses METIS_ComputeVertexSeparator on this matrix. If this - * seg fault does not affect you, set metis_nswitch to zero or less, - * and CHOLMOD will not switch to AMD based just on the density of the - * matrix (it will still switch to AMD if the metis_memory parameter - * causes the switch). - */ - - /* ---------------------------------------------------------------------- */ - /* workspace */ - /* ---------------------------------------------------------------------- */ - - /* CHOLMOD has several routines that take less time than the size of - * workspace they require. Allocating and initializing the workspace would - * dominate the run time, unless workspace is allocated and initialized - * just once. CHOLMOD allocates this space when needed, and holds it here - * between calls to CHOLMOD. cholmod_start sets these pointers to NULL - * (which is why it must be the first routine called in CHOLMOD). - * cholmod_finish frees the workspace (which is why it must be the last - * call to CHOLMOD). - */ - - size_t nrow ; /* size of Flag and Head */ - int64_t mark ; /* mark value for Flag array */ - size_t iworksize ; /* size of Iwork. Upper bound: 6*nrow+ncol */ - size_t xworksize ; /* size of Xwork, in bytes. - * maxrank*nrow*sizeof(double) for update/downdate. - * 2*nrow*sizeof(double) otherwise */ - - /* initialized workspace: contents needed between calls to CHOLMOD */ - void *Flag ; /* size nrow, an integer array. Kept cleared between - * calls to cholmod rouines (Flag [i] < mark) */ - - void *Head ; /* size nrow+1, an integer array. Kept cleared between - * calls to cholmod routines (Head [i] = EMPTY) */ - - void *Xwork ; /* a double array. Its size varies. It is nrow for - * most routines (cholmod_rowfac, cholmod_add, - * cholmod_aat, cholmod_norm, cholmod_ssmult) for the real case, twice - * that when the input matrices are complex or zomplex. It is of size - * 2*nrow for cholmod_rowadd and cholmod_rowdel. For cholmod_updown, - * its size is maxrank*nrow where maxrank is 2, 4, or 8. Kept cleared - * between calls to cholmod (set to zero). */ - - /* uninitialized workspace, contents not needed between calls to CHOLMOD */ - void *Iwork ; /* size iworksize, 2*nrow+ncol for most routines, - * up to 6*nrow+ncol for cholmod_analyze. */ - - int itype ; /* If CHOLMOD_LONG, Flag, Head, and Iwork are - * int64_t. Otherwise all three are int. */ - - int dtype ; /* double or float */ - - /* Common->itype and Common->dtype are used to define the types of all - * sparse matrices, triplet matrices, dense matrices, and factors - * created using this Common struct. The itypes and dtypes of all - * parameters to all CHOLMOD routines must match. */ - - int no_workspace_reallocate ; /* this is an internal flag, used as a - * precaution by cholmod_analyze. It is normally false. If true, - * cholmod_allocate_work is not allowed to reallocate any workspace; - * they must use the existing workspace in Common (Iwork, Flag, Head, - * and Xwork). Added for CHOLMOD v1.1 */ - - /* ---------------------------------------------------------------------- */ - /* statistics */ - /* ---------------------------------------------------------------------- */ - - /* fl and lnz are set only in cholmod_analyze and cholmod_rowcolcounts, - * in the Cholesky modudle. modfl is set only in the Modify module. */ - - int status ; /* error code */ - double fl ; /* LL' flop count from most recent analysis */ - double lnz ; /* fundamental nz in L */ - double anz ; /* nonzeros in tril(A) if A is symmetric/lower, - * triu(A) if symmetric/upper, or tril(A*A') if - * unsymmetric, in last call to cholmod_analyze. */ - double modfl ; /* flop count from most recent update/downdate/ - * rowadd/rowdel (excluding flops to modify the - * solution to Lx=b, if computed) */ - size_t malloc_count ; /* # of objects malloc'ed minus the # free'd*/ - size_t memory_usage ; /* peak memory usage in bytes */ - size_t memory_inuse ; /* current memory usage in bytes */ - - double nrealloc_col ; /* # of column reallocations */ - double nrealloc_factor ;/* # of factor reallocations due to col. reallocs */ - double ndbounds_hit ; /* # of times diagonal modified by dbound */ - - double rowfacfl ; /* # of flops in last call to cholmod_rowfac */ - double aatfl ; /* # of flops to compute A(:,f)*A(:,f)' */ - - int called_nd ; /* TRUE if the last call to - * cholmod_analyze called NESDIS or METIS. */ - int blas_ok ; /* FALSE if SUITESPARSE_BLAS_INT overflow; - TRUE otherwise */ - - /* ---------------------------------------------------------------------- */ - /* SuiteSparseQR control parameters: */ - /* ---------------------------------------------------------------------- */ - - double SPQR_grain ; /* task size is >= max (total flops / grain) */ - double SPQR_small ; /* task size is >= small */ - int SPQR_shrink ; /* controls stack realloc method */ - int SPQR_nthreads ; /* number of TBB threads, 0 = auto */ - - /* ---------------------------------------------------------------------- */ - /* SuiteSparseQR statistics */ - /* ---------------------------------------------------------------------- */ - - /* was other1 [0:3] */ - double SPQR_flopcount ; /* flop count for SPQR */ - double SPQR_analyze_time ; /* analysis time in seconds for SPQR */ - double SPQR_factorize_time ; /* factorize time in seconds for SPQR */ - double SPQR_solve_time ; /* backsolve time in seconds */ - - /* was SPQR_xstat [0:3] */ - double SPQR_flopcount_bound ; /* upper bound on flop count */ - double SPQR_tol_used ; /* tolerance used */ - double SPQR_norm_E_fro ; /* Frobenius norm of dropped entries */ - - /* was SPQR_istat [0:9] */ - int64_t SPQR_istat [10] ; - - /* ---------------------------------------------------------------------- */ - /* GPU configuration and statistics */ - /* ---------------------------------------------------------------------- */ - - /* useGPU: 1 if gpu-acceleration is requested */ - /* 0 if gpu-acceleration is prohibited */ - /* -1 if gpu-acceleration is undefined in which case the */ - /* environment CHOLMOD_USE_GPU will be queried and used. */ - /* useGPU=-1 is only used by CHOLMOD and treated as 0 by SPQR */ - int useGPU; - - /* for CHOLMOD: */ - size_t maxGpuMemBytes; - double maxGpuMemFraction; - - /* for SPQR: */ - size_t gpuMemorySize; /* Amount of memory in bytes on the GPU */ - double gpuKernelTime; /* Time taken by GPU kernels */ - int64_t gpuFlops; /* Number of flops performed by the GPU */ - int gpuNumKernelLaunches; /* Number of GPU kernel launches */ - - /* If not using the GPU, these items are not used, but they should be - present so that the CHOLMOD Common has the same size whether the GPU - is used or not. This way, all packages will agree on the size of - the CHOLMOD Common, regardless of whether or not they are compiled - with the GPU libraries or not */ -#ifdef SUITESPARSE_CUDA - /* in CUDA, these three types are pointers */ - #define CHOLMOD_CUBLAS_HANDLE cublasHandle_t - #define CHOLMOD_CUDASTREAM cudaStream_t - #define CHOLMOD_CUDAEVENT cudaEvent_t -#else - /* ... so make them void * pointers if the GPU is not being used */ - #define CHOLMOD_CUBLAS_HANDLE void * - #define CHOLMOD_CUDASTREAM void * - #define CHOLMOD_CUDAEVENT void * -#endif + //---------------------------------------------------------------------- + // statistics from the ordering + //---------------------------------------------------------------------- + + double lnz ; // number of nonzeros in L + double fl ; // Cholesky flop count for this ordering (each + // multiply and each add counted once (doesn't count complex + // flops). + + //---------------------------------------------------------------------- + // ordering parameters: + //---------------------------------------------------------------------- + + double prune_dense ; // dense row/col control. Default: 10. + // Rows/cols with more than max (prune_dense*sqrt(n),16) are + // removed prior to orderingm and placed last. If negative, + // only completely dense rows/cols are removed. Removing these + // rows/cols with many entries can speed up the ordering, but + // removing too many can reduce the ordering quality. + // + // For AMD, SYMAMD, and CSYMAMD, this is the only dense row/col + // parameter. For COLAMD and CCOLAMD, this parameter controls + // how dense columns are handled. + + double prune_dense2 ; // dense row control for COLAMD and CCOLAMD. + // Default -1. When computing the Cholesky factorization of AA' + // rows with more than max(prune_dense2*sqrt(n),16) entries + // are removed prior to ordering. If negative, only completely + // dense rows are removed. + + double nd_oksep ; // for CHOLMOD's nesdis method. Default 1. + // A node separator with nsep nodes is discarded if + // nsep >= nd_oksep*n. + + double other_1 [4] ; // unused, for future expansion + + size_t nd_small ; // for CHOLMOD's nesdis method. Default 200. + // Subgraphs with fewer than nd_small nodes are not partitioned. + + double other_2 [4] ; // unused, for future expansion + + int aggressive ; // if true, AMD, COLAMD, SYMAMD, CCOLAMD, and + // CSYMAMD perform aggresive absorption. Default: true + + int order_for_lu ; // Default: false. If the CHOLMOD analysis/ + // ordering methods are used as an ordering method for an LU + // factorization, then set this to true. For use in a Cholesky + // factorization by CHOLMOD itself, never set this to true. + + int nd_compress ; // if true, then the graph and subgraphs are + // compressed before partitioning them in CHOLMOD's nesdis + // method. Default: true. + + int nd_camd ; // if 1, then CHOLMOD's nesdis is followed by + // CAMD. If 2: followed by CSYMAMD. If nd_small is very small, + // then use 0, which skips CAMD or CSYMAMD. Default: 1. + + int nd_components ; // CHOLMOD's nesdis can partition a graph and then + // find that the subgraphs are unconnected. If true, each of these + // components is partitioned separately. If false, the whole + // subgraph is partitioned. Default: false. + + int ordering ; // ordering method to use + + size_t other_3 [4] ; // unused, for future expansion + + } + method [CHOLMOD_MAXMETHODS + 1] ; + + int postorder ; // if true, CHOLMOD performs a weighted postordering + // after its fill-reducing ordering, which improves supernodal + // amalgamation. Has no effect on flop count or nnz(L). + // Default: true. + + int default_nesdis ; // If false, then the default ordering strategy + // when Common->nmethods is zero is to try the user's permutation + // if given, then AMD, and then METIS if the AMD ordering results in + // a lot of fill-in. If true, then nesdis is used instead of METIS. + // Default: false. + + //-------------------------------------------------------------------------- + // METIS workarounds + //-------------------------------------------------------------------------- + + // These workarounds were put into place for METIS 4.0.1. They are safe + // to use with METIS 5.1.0, but they might not longer be necessary. + + double metis_memory ; // default: 0. If METIS terminates your + // program when it runs out of memory, try 2, or higher. + double metis_dswitch ; // default: 0.66 + size_t metis_nswitch ; // default: 3000 + // If a matrix has n > metis_nswitch and a density (nnz(A)/n^2) > + // metis_dswitch, then METIS is not used. + + //-------------------------------------------------------------------------- + // workspace + //-------------------------------------------------------------------------- + + // This workspace is kept in the CHOLMOD Common object. cholmod_start + // sets these arrays to NULL, and cholmod_finish frees them. + + size_t nrow ; // Flag has size nrow, Head has size nrow+1 + int64_t mark ; // Flag is cleared if Flag [0..nrow-1] < mark. + size_t iworksize ; // size of Iwork, in Ints (int32 or int64). + // This is at most 6*nrow + ncol. + size_t xworkbytes ; // size of Xwork, in bytes. for update/downdate: + // maxrank*nrow*sizeof(double or float), 2*nrow*sizeof(double or float) + // otherwise. NOTE: in CHOLMOD v4 and earlier, xworkwise was in terms + // of # of doubles, not # of bytes. + + void *Flag ; // size nrow. If this is "cleared" then + // Flag [i] < mark for all i = 0:nrow-1. Flag is kept cleared between + // calls to CHOLMOD. + + void *Head ; // size nrow+1. If Head [i] = EMPTY (-1) then that + // entry is "cleared". Head is kept cleared between calls to CHOLMOD. + + void *Xwork ; // a double or float array. It has size nrow for most + // routines, or 2*nrow if complex matrices are being handled. + // It has size 2*nrow for cholmod_rowadd/rowdel, and maxrank*nrow for + // cholmod_updown, where maxrank is 2, 4, or 8. Xwork is kept all + // zero between calls to CHOLMOD. + + void *Iwork ; // size iworksize integers (int32's or int64's). + // Uninitialized integer workspace, of size at most 6*nrow+ncol. + + int itype ; // cholmod_start (for int32's) sets this to CHOLMOD_INT, + // and cholmod_l_start sets this to CHOLMOD_LONG. It defines the + // integer sizes for th Flag, Head, and Iwork arrays, and also + // defines the integers for all objects created by CHOLMOD. + // The itype of the Common object must match the function name + // and all objects passed to it. + + int other_5 ; // unused: for future expansion + + int no_workspace_reallocate ; // an internal flag, usually false. + // This is set true to disable any reallocation of the workspace + // in the Common object. + + //-------------------------------------------------------------------------- + // statistics + //-------------------------------------------------------------------------- + + int status ; // status code (0: ok, negative: error, pos: warning + double fl ; // flop count from last analysis + double lnz ; // nnz(L) from last analysis + double anz ; // in last analysis: nnz(tril(A)) or nnz(triu(A)) if A + // symmetric, or tril(A*A') if A is unsymmetric. + double modfl ; // flop count from last update/downdate/rowadd/rowdel, + // not included the flops to revise the solution to Lx=b, + // if that was performed. + + size_t malloc_count ; // # of malloc'd objects not yet freed + size_t memory_usage ; // peak memory usage in bytes + size_t memory_inuse ; // current memory usage in bytes + + double nrealloc_col ; // # of column reallocations + double nrealloc_factor ;// # of factor reallocations due to col. reallocs + double ndbounds_hit ; // # of times diagonal modified by dbound + + double rowfacfl ; // flop count of cholmod_rowfac + double aatfl ; // flop count to compute A(:,f)*A(:,f)' + + int called_nd ; // true if last analysis used nesdis or METIS. + int blas_ok ; // true if no integer overflow has occured when trying to + // call the BLAS. The typical BLAS library uses 32-bit integers for + // its input parameters, even on a 64-bit platform. CHOLMOD uses int64 + // in its cholmod_l_* methods, and these must be typecast to the BLAS + // integer. If integer overflow occurs, this is set false. + + //-------------------------------------------------------------------------- + // SuiteSparseQR control parameters and statistics + //-------------------------------------------------------------------------- + + // SPQR uses the CHOLMOD Common object for its control and statistics. + // These parameters are not used by CHOLMOD itself. + + // control parameters: + double SPQR_grain ; // task size is >= max (total flops / grain) + double SPQR_small ; // task size is >= small + int SPQR_shrink ; // controls stack realloc method + int SPQR_nthreads ; // number of TBB threads, 0 = auto + + // statistics: + double SPQR_flopcount ; // flop count for SPQR + double SPQR_analyze_time ; // analysis time in seconds for SPQR + double SPQR_factorize_time ; // factorize time in seconds for SPQR + double SPQR_solve_time ; // backsolve time in seconds + double SPQR_flopcount_bound ; // upper bound on flop count + double SPQR_tol_used ; // tolerance used + double SPQR_norm_E_fro ; // Frobenius norm of dropped entries + + //-------------------------------------------------------------------------- + // Revised for CHOLMOD v5.0 + //-------------------------------------------------------------------------- + + // was size 10 in CHOLMOD v4.2; reduced to 8 in CHOLMOD v5: + int64_t SPQR_istat [8] ; // other statistics + + //-------------------------------------------------------------------------- + // Added for CHOLMOD v5.0 + //-------------------------------------------------------------------------- + + // These terms have been added to the CHOLMOD Common struct for v5.0, and + // on most systems they will total 16 bytes. The preceding term, + // SPQR_istat, was reduced by 16 bytes, since those last 2 entries were + // unused in CHOLMOD v4.2. As a result, the Common struct in v5.0 has the + // same size as v4.0, and all entries would normally be in the same offset, + // as well. This mitigates any changes between v4.0 and v5.0, and may make + // it easier to upgrade from v4 to v5. + + double nsbounds_hit ; // # of times diagonal modified by sbound. This + // ought to be int64_t, but ndbounds_hit was double in v4 + // (see above), so nsbounds_hit is made the same type for + // consistency. + float sbound ; // Same as dbound, but for single precision factorization. + float other_6 ; // for future expansion + + //-------------------------------------------------------------------------- + // GPU configuration and statistics + //-------------------------------------------------------------------------- + + int useGPU ; // 1 if GPU is requested for CHOLMOD + // 0 if GPU is not requested for CHOLMOD + // -1 if the use of the GPU is in CHOLMOD controled by the + // CHOLMOD_USE_GPU environment variable. + + size_t maxGpuMemBytes ; // GPU control for CHOLMOD + double maxGpuMemFraction ; // GPU control for CHOLMOD + + // for SPQR: + size_t gpuMemorySize ; // Amount of memory in bytes on the GPU + double gpuKernelTime ; // Time taken by GPU kernels + int64_t gpuFlops ; // Number of flops performed by the GPU + int gpuNumKernelLaunches ; // Number of GPU kernel launches + + #ifdef SUITESPARSE_CUDA + // these three types are pointers defined by CUDA: + #define CHOLMOD_CUBLAS_HANDLE cublasHandle_t + #define CHOLMOD_CUDASTREAM cudaStream_t + #define CHOLMOD_CUDAEVENT cudaEvent_t + #else + // they are (void *) if CUDA is not in use: + #define CHOLMOD_CUBLAS_HANDLE void * + #define CHOLMOD_CUDASTREAM void * + #define CHOLMOD_CUDAEVENT void * + #endif CHOLMOD_CUBLAS_HANDLE cublasHandle ; - /* a set of streams for general use */ - CHOLMOD_CUDASTREAM gpuStream[CHOLMOD_HOST_SUPERNODE_BUFFERS]; + // a set of streams for general use + CHOLMOD_CUDASTREAM gpuStream [CHOLMOD_HOST_SUPERNODE_BUFFERS] ; - CHOLMOD_CUDAEVENT cublasEventPotrf [3] ; - CHOLMOD_CUDAEVENT updateCKernelsComplete; - CHOLMOD_CUDAEVENT updateCBuffersFree[CHOLMOD_HOST_SUPERNODE_BUFFERS]; + CHOLMOD_CUDAEVENT cublasEventPotrf [3] ; + CHOLMOD_CUDAEVENT updateCKernelsComplete ; + CHOLMOD_CUDAEVENT updateCBuffersFree [CHOLMOD_HOST_SUPERNODE_BUFFERS] ; - void *dev_mempool; /* pointer to single allocation of device memory */ - size_t dev_mempool_size; + void *dev_mempool ; // pointer to single allocation of device memory + size_t dev_mempool_size ; - void *host_pinned_mempool; /* pointer to single allocation of pinned mem */ - size_t host_pinned_mempool_size; + void *host_pinned_mempool ; // pointer to single alloc of pinned mem + size_t host_pinned_mempool_size ; - size_t devBuffSize; - int ibuffer; + size_t devBuffSize ; + int ibuffer ; + double syrkStart ; // time syrk started - double syrkStart ; /* time syrk started */ - - /* run times of the different parts of CHOLMOD (GPU and CPU) */ + // run times of the different parts of CHOLMOD (GPU and CPU): double cholmod_cpu_gemm_time ; double cholmod_cpu_syrk_time ; double cholmod_cpu_trsm_time ; @@ -1185,7 +760,7 @@ typedef struct cholmod_common_struct double cholmod_assemble_time ; double cholmod_assemble_time2 ; - /* number of times the BLAS are called on the CPU and the GPU */ + // number of times the BLAS are called on the CPU and the GPU: size_t cholmod_cpu_gemm_calls ; size_t cholmod_cpu_syrk_calls ; size_t cholmod_cpu_trsm_calls ; @@ -1195,15 +770,16 @@ typedef struct cholmod_common_struct size_t cholmod_gpu_trsm_calls ; size_t cholmod_gpu_potrf_calls ; - double chunk ; // chunksize for computing # of threads to use. - // Given nwork work to do, # of threads is - // max (1, min (floor (work / chunk), nthreads_max)) - int nthreads_max ; // max # of threads to use in CHOLMOD. Defaults to - // SUITESPARSE_OPENMP_MAX_THREADS. + double chunk ; // chunksize for computing # of OpenMP threads to use. + // Given nwork work to do, # of threads is + // max (1, min (floor (work / chunk), nthreads_max)) + + int nthreads_max ; // max # of OpenMP threads to use in CHOLMOD. + // Defaults to SUITESPARSE_OPENMP_MAX_THREADS. } cholmod_common ; -/* size_t BLAS statistcs in Common: */ +// size_t BLAS statistcs in Common: #define CHOLMOD_CPU_GEMM_CALLS cholmod_cpu_gemm_calls #define CHOLMOD_CPU_SYRK_CALLS cholmod_cpu_syrk_calls #define CHOLMOD_CPU_TRSM_CALLS cholmod_cpu_trsm_calls @@ -1213,7 +789,7 @@ typedef struct cholmod_common_struct #define CHOLMOD_GPU_TRSM_CALLS cholmod_gpu_trsm_calls #define CHOLMOD_GPU_POTRF_CALLS cholmod_gpu_potrf_calls -/* double BLAS statistics in Common: */ +// double BLAS statistics in Common: #define CHOLMOD_CPU_GEMM_TIME cholmod_cpu_gemm_time #define CHOLMOD_CPU_SYRK_TIME cholmod_cpu_syrk_time #define CHOLMOD_CPU_TRSM_TIME cholmod_cpu_trsm_time @@ -1225,1422 +801,1138 @@ typedef struct cholmod_common_struct #define CHOLMOD_ASSEMBLE_TIME cholmod_assemble_time #define CHOLMOD_ASSEMBLE_TIME2 cholmod_assemble_time2 -/* for supernodal analysis */ +// for supernodal analysis: #define CHOLMOD_ANALYZE_FOR_SPQR 0 #define CHOLMOD_ANALYZE_FOR_CHOLESKY 1 #define CHOLMOD_ANALYZE_FOR_SPQRGPU 2 -/* -------------------------------------------------------------------------- */ -/* cholmod_start: first call to CHOLMOD */ -/* -------------------------------------------------------------------------- */ - -int cholmod_start -( - cholmod_common *Common -) ; +//------------------------------------------------------------------------------ +// cholmod_start: first call to CHOLMOD +//------------------------------------------------------------------------------ +int cholmod_start (cholmod_common *Common) ; int cholmod_l_start (cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_finish: last call to CHOLMOD */ -/* -------------------------------------------------------------------------- */ - -int cholmod_finish -( - cholmod_common *Common -) ; +//------------------------------------------------------------------------------ +// cholmod_finish: last call to CHOLMOD +//------------------------------------------------------------------------------ +int cholmod_finish (cholmod_common *Common) ; int cholmod_l_finish (cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_defaults: restore default parameters */ -/* -------------------------------------------------------------------------- */ - -int cholmod_defaults -( - cholmod_common *Common -) ; +//------------------------------------------------------------------------------ +// cholmod_defaults: set default parameters +//------------------------------------------------------------------------------ +int cholmod_defaults (cholmod_common *Common) ; int cholmod_l_defaults (cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_maxrank: return valid maximum rank for update/downdate */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_maxrank: return valid maximum rank for update/downdate +//------------------------------------------------------------------------------ -size_t cholmod_maxrank /* returns validated value of Common->maxrank */ +size_t cholmod_maxrank // return validated Common->maxrank ( - /* ---- input ---- */ - size_t n, /* A and L will have n rows */ - /* --------------- */ + size_t n, // # of rows of L and A cholmod_common *Common ) ; - size_t cholmod_l_maxrank (size_t, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_allocate_work: allocate workspace in Common */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_allocate_work: allocate workspace in Common +//------------------------------------------------------------------------------ + +// This method always allocates Xwork as double, for backward compatibility +// with CHOLMOD v4 and earlier. See cholmod_alloc_work for CHOLMOD v5. int cholmod_allocate_work ( - /* ---- input ---- */ - size_t nrow, /* size: Common->Flag (nrow), Common->Head (nrow+1) */ - size_t iworksize, /* size of Common->Iwork */ - size_t xworksize, /* size of Common->Xwork */ - /* --------------- */ + size_t nrow, // size of Common->Flag (nrow int32's) + // and Common->Head (nrow+1 int32's) + size_t iworksize, // size of Common->Iwork (# of int32's) + size_t xworksize, // size of Common->Xwork (# of double's) cholmod_common *Common ) ; - int cholmod_l_allocate_work (size_t, size_t, size_t, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_free_work: free workspace in Common */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_alloc_work: allocate workspace in Common +//------------------------------------------------------------------------------ -int cholmod_free_work +// Added for CHOLMOD v5: allocates Xwork as either double or single. + +int cholmod_alloc_work ( + size_t nrow, // size of Common->Flag (nrow int32's) + // and Common->Head (nrow+1 int32's) + size_t iworksize, // size of Common->Iwork (# of int32's) + size_t xworksize, // size of Common->Xwork (# of entries) + int dtype, // CHOLMOD_DOUBLE or CHOLMOD_SINGLE cholmod_common *Common ) ; +int cholmod_l_alloc_work (size_t, size_t, size_t, int, cholmod_common *) ; + +//------------------------------------------------------------------------------ +// cholmod_free_work: free workspace in Common +//------------------------------------------------------------------------------ +int cholmod_free_work (cholmod_common *Common) ; int cholmod_l_free_work (cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_clear_flag: clear Flag workspace in Common */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_clear_flag: clear Flag workspace in Common +//------------------------------------------------------------------------------ -/* use a macro for speed */ -#define CHOLMOD_CLEAR_FLAG(Common) \ -{ \ - Common->mark++ ; \ - if (Common->mark <= 0) \ - { \ - Common->mark = EMPTY ; \ - CHOLMOD (clear_flag) (Common) ; \ - } \ +// This macro is deprecated; do not use it: +#define CHOLMOD_CLEAR_FLAG(Common) \ +{ \ + Common->mark++ ; \ + if (Common->mark <= 0 || Common->mark >= INT32_MAX) \ + { \ + Common->mark = EMPTY ; \ + CHOLMOD (clear_flag) (Common) ; \ + } \ } -int64_t cholmod_clear_flag -( - cholmod_common *Common -) ; - +int64_t cholmod_clear_flag (cholmod_common *Common) ; int64_t cholmod_l_clear_flag (cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_error: called when CHOLMOD encounters an error */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_error: called when CHOLMOD encounters an error +//------------------------------------------------------------------------------ int cholmod_error ( - /* ---- input ---- */ - int status, /* error status */ - const char *file, /* name of source code file where error occured */ - int line, /* line number in source code file where error occured*/ - const char *message,/* error message */ - /* --------------- */ + int status, // Common->status + const char *file, // source file where error occurred + int line, // line number where error occurred + const char *message, // error message to print cholmod_common *Common ) ; - int cholmod_l_error (int, const char *, int, const char *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_dbound: for internal use in CHOLMOD only */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_dbound and cholmod_sbound: for internal use in CHOLMOD only +//------------------------------------------------------------------------------ -double cholmod_dbound /* returns modified diagonal entry of D or L */ -( - /* ---- input ---- */ - double dj, /* diagonal entry of D for LDL' or L for LL' */ - /* --------------- */ - cholmod_common *Common -) ; +// These were once documented functions but no are no longer meant to be used +// by the user application. They remain here for backward compatibility. +double cholmod_dbound (double, cholmod_common *) ; double cholmod_l_dbound (double, cholmod_common *) ; +float cholmod_sbound (float, cholmod_common *) ; +float cholmod_l_sbound (float, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_hypot: compute sqrt (x*x + y*y) accurately */ -/* -------------------------------------------------------------------------- */ - -double cholmod_hypot -( - /* ---- input ---- */ - double x, double y -) ; +//------------------------------------------------------------------------------ +// cholmod_hypot: compute sqrt (x*x + y*y) accurately +//------------------------------------------------------------------------------ +double cholmod_hypot (double x, double y) ; double cholmod_l_hypot (double, double) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_divcomplex: complex division, c = a/b */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_divcomplex: complex division, c = a/b +//------------------------------------------------------------------------------ -int cholmod_divcomplex /* return 1 if divide-by-zero, 0 otherise */ +int cholmod_divcomplex // return 1 if divide-by-zero, 0 if OK ( - /* ---- input ---- */ - double ar, double ai, /* real and imaginary parts of a */ - double br, double bi, /* real and imaginary parts of b */ - /* ---- output --- */ - double *cr, double *ci /* real and imaginary parts of c */ + double ar, double ai, // a (real, imaginary) + double br, double bi, // b (real, imaginary) + double *cr, double *ci // c (real, imaginary) ) ; - int cholmod_l_divcomplex (double, double, double, double, double *, double *) ; - -/* ========================================================================== */ -/* === Core/cholmod_sparse ================================================== */ -/* ========================================================================== */ - -/* A sparse matrix stored in compressed-column form. */ +//============================================================================== +// cholmod_sparse: a sparse matrix in compressed-column (CSC) form +//============================================================================== typedef struct cholmod_sparse_struct { - size_t nrow ; /* the matrix is nrow-by-ncol */ - size_t ncol ; - size_t nzmax ; /* maximum number of entries in the matrix */ - - /* pointers to int32_t or int64_t: */ - void *p ; /* p [0..ncol], the column pointers */ - void *i ; /* i [0..nzmax-1], the row indices */ - - /* for unpacked matrices only: */ - void *nz ; /* nz [0..ncol-1], the # of nonzeros in each col. In - * packed form, the nonzero pattern of column j is in - * A->i [A->p [j] ... A->p [j+1]-1]. In unpacked form, column j is in - * A->i [A->p [j] ... A->p [j]+A->nz[j]-1] instead. In both cases, the - * numerical values (if present) are in the corresponding locations in - * the array x (or z if A->xtype is CHOLMOD_ZOMPLEX). */ - - /* pointers to double or float: */ - void *x ; /* size nzmax or 2*nzmax, if present */ - void *z ; /* size nzmax, if present */ - - int stype ; /* Describes what parts of the matrix are considered: - * - * 0: matrix is "unsymmetric": use both upper and lower triangular parts - * (the matrix may actually be symmetric in pattern and value, but - * both parts are explicitly stored and used). May be square or - * rectangular. - * >0: matrix is square and symmetric, use upper triangular part. - * Entries in the lower triangular part are ignored. - * <0: matrix is square and symmetric, use lower triangular part. - * Entries in the upper triangular part are ignored. - * - * Note that stype>0 and stype<0 are different for cholmod_sparse and - * cholmod_triplet. See the cholmod_triplet data structure for more - * details. - */ - - int itype ; /* CHOLMOD_INT: p, i, and nz are int32_t. - * CHOLMOD_INTLONG: p is int64_t, - * i and nz are int32_t. - * CHOLMOD_LONG: p, i, and nz are int64_t */ - - int xtype ; /* pattern, real, complex, or zomplex */ - int dtype ; /* x and z are double or float */ - int sorted ; /* TRUE if columns are sorted, FALSE otherwise */ - int packed ; /* TRUE if packed (nz ignored), FALSE if unpacked - * (nz is required) */ + size_t nrow ; // # of rows of the matrix + size_t ncol ; // # of colums of the matrix + size_t nzmax ; // max # of entries that can be held in the matrix + + // int32_t or int64_t arrays: + void *p ; // A->p [0..ncol], column "pointers" of the CSC matrix + void *i ; // A->i [0..nzmax-1], the row indices + + // for unpacked matrices only: + void *nz ; // A->nz [0..ncol-1], is the # of nonzeros in each col. + // This is NULL for a "packed" matrix (conventional CSC). + // For a packed matrix, the jth column is held in A->i and A->x in + // postions A->p [j] to A->p [j+1]-1, with no gaps between columns. + // For an "unpacked" matrix, there can be gaps between columns, so + // the jth columns appears in positions A-p [j] to + // A->p [j] + A->nz [j] - 1. + + // double or float arrays: + void *x ; // size nzmax or 2*nzmax, or NULL + void *z ; // size nzmax, or NULL + + int stype ; // A->stype defines what parts of the matrix is held: + // 0: the matrix is unsymmetric with both lower and upper parts stored. + // >0: the matrix is square and symmetric, with just the upper + // triangular part stored. + // <0: the matrix is square and symmetric, with just the lower + // triangular part stored. + + int itype ; // A->itype defines the integers used for A->p, A->i, and A->nz. + // if CHOLMOD_INT, these arrays are all of type int32_t. + // if CHOLMOD_LONG, these arrays are all of type int64_t. + int xtype ; // pattern, real, complex, or zomplex + int dtype ; // x and z are double or single + int sorted ; // true if columns are sorted, false otherwise + int packed ; // true if packed (A->nz ignored), false if unpacked } cholmod_sparse ; -typedef struct cholmod_descendant_score_t -{ - double score ; - int64_t d ; -} -descendantScore ; - -/* For sorting descendant supernodes with qsort */ -int cholmod_score_comp (struct cholmod_descendant_score_t *i, - struct cholmod_descendant_score_t *j) ; - -int cholmod_l_score_comp (struct cholmod_descendant_score_t *i, - struct cholmod_descendant_score_t *j) ; - -/* -------------------------------------------------------------------------- */ -/* cholmod_allocate_sparse: allocate a sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_allocate_sparse: allocate a sparse matrix +//------------------------------------------------------------------------------ cholmod_sparse *cholmod_allocate_sparse ( - /* ---- input ---- */ - size_t nrow, /* # of rows of A */ - size_t ncol, /* # of columns of A */ - size_t nzmax, /* max # of nonzeros of A */ - int sorted, /* TRUE if columns of A sorted, FALSE otherwise */ - int packed, /* TRUE if A will be packed, FALSE otherwise */ - int stype, /* stype of A */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t nzmax, // max # of entries the matrix can hold + int sorted, // true if columns are sorted + int packed, // true if A is be packed (A->nz NULL), false if unpacked + int stype, // the stype of the matrix (unsym, tril, or triu) + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_allocate_sparse (size_t, size_t, size_t, int, int, int, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_free_sparse: free a sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_free_sparse: free a sparse matrix +//------------------------------------------------------------------------------ int cholmod_free_sparse ( - /* ---- in/out --- */ - cholmod_sparse **A, /* matrix to deallocate, NULL on output */ - /* --------------- */ + cholmod_sparse **A, // handle of sparse matrix to free cholmod_common *Common ) ; - int cholmod_l_free_sparse (cholmod_sparse **, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_reallocate_sparse: change the size (# entries) of sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_reallocate_sparse: change max # of entries in a sparse matrix +//------------------------------------------------------------------------------ int cholmod_reallocate_sparse ( - /* ---- input ---- */ - size_t nznew, /* new # of entries in A */ - /* ---- in/out --- */ - cholmod_sparse *A, /* matrix to reallocate */ - /* --------------- */ + size_t nznew, // new max # of nonzeros the sparse matrix can hold + cholmod_sparse *A, // sparse matrix to reallocate cholmod_common *Common ) ; +int cholmod_l_reallocate_sparse (size_t, cholmod_sparse *, cholmod_common *) ; -int cholmod_l_reallocate_sparse ( size_t, cholmod_sparse *, cholmod_common *) ; - -/* -------------------------------------------------------------------------- */ -/* cholmod_nnz: return number of nonzeros in a sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_nnz: # of entries in a sparse matrix +//------------------------------------------------------------------------------ -int64_t cholmod_nnz +int64_t cholmod_nnz // return # of entries in the sparse matrix ( - /* ---- input ---- */ - cholmod_sparse *A, - /* --------------- */ + cholmod_sparse *A, // sparse matrix to query cholmod_common *Common ) ; - int64_t cholmod_l_nnz (cholmod_sparse *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_speye: sparse identity matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_speye: sparse identity matrix (possibly rectangular) +//------------------------------------------------------------------------------ cholmod_sparse *cholmod_speye ( - /* ---- input ---- */ - size_t nrow, /* # of rows of A */ - size_t ncol, /* # of columns of A */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_speye (size_t, size_t, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_spzeros: sparse zero matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_spzeros: sparse matrix with no entries +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_spzeros +// Identical to cholmod_allocate_sparse, with packed = true, sorted = true, +// and stype = 0. + +cholmod_sparse *cholmod_spzeros // return a sparse matrix with no entries ( - /* ---- input ---- */ - size_t nrow, /* # of rows of A */ - size_t ncol, /* # of columns of A */ - size_t nzmax, /* max # of nonzeros of A */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t nzmax, // max # of entries the matrix can hold + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_spzeros (size_t, size_t, size_t, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_transpose: transpose a sparse matrix */ -/* -------------------------------------------------------------------------- */ - -/* Return A' or A.' The "values" parameter is 0, 1, or 2 to denote the pattern - * transpose, the array transpose (A.'), and the complex conjugate transpose - * (A'). - */ +//------------------------------------------------------------------------------ +// cholmod_transpose: transpose a sparse matrix +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_transpose +cholmod_sparse *cholmod_transpose // return new sparse matrix C ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to transpose */ - int values, /* 0: pattern, 1: array transpose, 2: conj. transpose */ - /* --------------- */ + cholmod_sparse *A, // input matrix + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // <= 0: pattern (with diag) cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_transpose (cholmod_sparse *, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_transpose_unsym: transpose an unsymmetric sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_transpose_unsym: transpose an unsymmetric sparse matrix +//------------------------------------------------------------------------------ -/* Compute F = A', A (:,f)', or A (p,f)', where A is unsymmetric and F is - * already allocated. See cholmod_transpose for a simpler routine. */ +// Compute C = A', A (:,f)', or A (p,f)', where A is unsymmetric and C is +// already allocated. See cholmod_transpose for a routine with a simpler +// interface. int cholmod_transpose_unsym ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to transpose */ - int values, /* 0: pattern, 1: array transpose, 2: conj. transpose */ - int32_t *Perm, /* size nrow, if present (can be NULL) */ - int32_t *fset, /* subset of 0:(A->ncol)-1 */ - size_t fsize, /* size of fset */ - /* ---- output --- */ - cholmod_sparse *F, /* F = A', A(:,f)', or A(p,f)' */ - /* --------------- */ + cholmod_sparse *A, // input matrix + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // <= 0: pattern (with diag) + int32_t *Perm, // permutation for C=A(p,f)', or NULL + int32_t *fset, // a list of column indices in range 0:A->ncol-1 + size_t fsize, // # of entries in fset + cholmod_sparse *C, // output matrix, must be allocated on input cholmod_common *Common ) ; +int cholmod_l_transpose_unsym (cholmod_sparse *, int, int64_t *, int64_t *, + size_t, cholmod_sparse *, cholmod_common *) ; -int cholmod_l_transpose_unsym (cholmod_sparse *, int, int64_t *, - int64_t *, size_t, cholmod_sparse *, cholmod_common *) ; - -/* -------------------------------------------------------------------------- */ -/* cholmod_transpose_sym: transpose a symmetric sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_transpose_sym: symmetric permuted transpose +//------------------------------------------------------------------------------ -/* Compute F = A' or A (p,p)', where A is symmetric and F is already allocated. - * See cholmod_transpose for a simpler routine. */ +// C = A' or C = A(p,p)' where A and C are both symmetric and C is already +// allocated. See cholmod_transpose or cholmod_ptranspose for a routine with +// a simpler interface. int cholmod_transpose_sym ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to transpose */ - int values, /* 0: pattern, 1: array transpose, 2: conj. transpose */ - int32_t *Perm, /* size nrow, if present (can be NULL) */ - /* ---- output --- */ - cholmod_sparse *F, /* F = A' or A(p,p)' */ - /* --------------- */ + cholmod_sparse *A, // input matrix + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // <= 0: pattern (with diag) + int32_t *Perm, // permutation for C=A(p,p)', or NULL + cholmod_sparse *C, // output matrix, must be allocated on input cholmod_common *Common ) ; +int cholmod_l_transpose_sym (cholmod_sparse *, int, int64_t *, cholmod_sparse *, + cholmod_common *) ; -int cholmod_l_transpose_sym (cholmod_sparse *, int, int64_t *, - cholmod_sparse *, cholmod_common *) ; - -/* -------------------------------------------------------------------------- */ -/* cholmod_ptranspose: transpose a sparse matrix */ -/* -------------------------------------------------------------------------- */ - -/* Return A' or A(p,p)' if A is symmetric. Return A', A(:,f)', or A(p,f)' if - * A is unsymmetric. */ +//------------------------------------------------------------------------------ +// cholmod_ptranspose: C = A', A(:,f)', A(p,p)', or A(p,f)' +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_ptranspose +cholmod_sparse *cholmod_ptranspose // return new sparse matrix C ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to transpose */ - int values, /* 0: pattern, 1: array transpose, 2: conj. transpose */ - int32_t *Perm, /* if non-NULL, F = A(p,f) or A(p,p) */ - int32_t *fset, /* subset of 0:(A->ncol)-1 */ - size_t fsize, /* size of fset */ - /* --------------- */ + cholmod_sparse *A, // input matrix + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // <= 0: pattern (with diag) + int32_t *Perm, // permutation for C=A(p,f)', or NULL + int32_t *fset, // a list of column indices in range 0:A->ncol-1 + size_t fsize, // # of entries in fset cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_ptranspose (cholmod_sparse *, int, int64_t *, int64_t *, size_t, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_sort: sort row indices in each column of sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_sort: sort the indices of a sparse matrix +//------------------------------------------------------------------------------ int cholmod_sort ( - /* ---- in/out --- */ - cholmod_sparse *A, /* matrix to sort */ - /* --------------- */ + cholmod_sparse *A, // input/output matrix to sort cholmod_common *Common ) ; - int cholmod_l_sort (cholmod_sparse *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_band: C = tril (triu (A,k1), k2) */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_band_nnz: # of entries within a band of a sparse matrix +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_band +int64_t cholmod_band_nnz // return # of entries in a band (-1 if error) ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to extract band matrix from */ - int64_t k1, /* ignore entries below the k1-st diagonal */ - int64_t k2, /* ignore entries above the k2-nd diagonal */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ - /* --------------- */ + cholmod_sparse *A, // matrix to examine + int64_t k1, // count entries in k1:k2 diagonals + int64_t k2, + bool ignore_diag, // if true, exclude any diagonal entries cholmod_common *Common ) ; +int64_t cholmod_l_band_nnz (cholmod_sparse *, int64_t, int64_t, bool, + cholmod_common *) ; -cholmod_sparse *cholmod_l_band (cholmod_sparse *, int64_t, - int64_t, int, cholmod_common *) ; +//------------------------------------------------------------------------------ +// cholmod_band: C = tril (triu (A,k1), k2) +//------------------------------------------------------------------------------ -/* -------------------------------------------------------------------------- */ -/* cholmod_band_inplace: A = tril (triu (A,k1), k2) */ -/* -------------------------------------------------------------------------- */ +cholmod_sparse *cholmod_band // return a new matrix C +( + cholmod_sparse *A, // input matrix + int64_t k1, // count entries in k1:k2 diagonals + int64_t k2, + int mode, // >0: numerical, 0: pattern, <0: pattern (no diag) + cholmod_common *Common +) ; +cholmod_sparse *cholmod_l_band (cholmod_sparse *, int64_t, int64_t, int, + cholmod_common *) ; + +//------------------------------------------------------------------------------ +// cholmod_band_inplace: A = tril (triu (A,k1), k2) */ +//------------------------------------------------------------------------------ int cholmod_band_inplace ( - /* ---- input ---- */ - int64_t k1, /* ignore entries below the k1-st diagonal */ - int64_t k2, /* ignore entries above the k2-nd diagonal */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ - /* ---- in/out --- */ - cholmod_sparse *A, /* matrix from which entries not in band are removed */ - /* --------------- */ + int64_t k1, // count entries in k1:k2 diagonals + int64_t k2, + int mode, // >0: numerical, 0: pattern, <0: pattern (no diag) + cholmod_sparse *A, // input/output matrix cholmod_common *Common ) ; +int cholmod_l_band_inplace (int64_t, int64_t, int, cholmod_sparse *, + cholmod_common *) ; -int cholmod_l_band_inplace (int64_t, int64_t, int, - cholmod_sparse *, cholmod_common *) ; - -/* -------------------------------------------------------------------------- */ -/* cholmod_aat: C = A*A' or A(:,f)*A(:,f)' */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_aat: C = A*A' or A(:,f)*A(:,f)' +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_aat +cholmod_sparse *cholmod_aat // return sparse matrix C ( - /* ---- input ---- */ - cholmod_sparse *A, /* input matrix; C=A*A' is constructed */ - int32_t *fset, /* subset of 0:(A->ncol)-1 */ - size_t fsize, /* size of fset */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag), - * -2: pattern only, no diagonal, add 50%+n extra - * space to C */ - /* --------------- */ + cholmod_sparse *A, // input matrix + int32_t *fset, // a list of column indices in range 0:A->ncol-1 + size_t fsize, // # of entries in fset + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // 0: pattern (with diag), -1: pattern (remove diag), + // -2: pattern (remove diag; add ~50% extra space in C) cholmod_common *Common ) ; +cholmod_sparse *cholmod_l_aat (cholmod_sparse *, int64_t *, size_t, int, + cholmod_common *) ; -cholmod_sparse *cholmod_l_aat (cholmod_sparse *, int64_t *, size_t, - int, cholmod_common *) ; +//------------------------------------------------------------------------------ +// cholmod_copy_sparse: C = A, create an exact copy of a sparse matrix +//------------------------------------------------------------------------------ -/* -------------------------------------------------------------------------- */ -/* cholmod_copy_sparse: C = A, create an exact copy of a sparse matrix */ -/* -------------------------------------------------------------------------- */ +// Creates an exact copy of a sparse matrix. For making a copy with a change +// of stype and/or copying the pattern of a numerical matrix, see cholmod_copy. +// For changing the xtype and/or dtype, see cholmod_sparse_xtype. -cholmod_sparse *cholmod_copy_sparse +cholmod_sparse *cholmod_copy_sparse // return new sparse matrix ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ - /* --------------- */ + cholmod_sparse *A, // sparse matrix to copy cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_copy_sparse (cholmod_sparse *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_copy: C = A, with possible change of stype */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_copy: C = A, with possible change of stype +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_copy +cholmod_sparse *cholmod_copy // return new sparse matrix ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ - int stype, /* requested stype of C */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ - /* --------------- */ + cholmod_sparse *A, // input matrix, not modified + int stype, // stype of C + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // 0: pattern (with diag), -1: pattern (remove diag), + // -2: pattern (remove diag; add ~50% extra space in C) cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_copy (cholmod_sparse *, int, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_add: C = alpha*A + beta*B */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_add: C = alpha*A + beta*B +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_add +cholmod_sparse *cholmod_add // return C = alpha*A + beta*B ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to add */ - cholmod_sparse *B, /* matrix to add */ - double alpha [2], /* scale factor for A */ - double beta [2], /* scale factor for B */ - int values, /* if TRUE compute the numerical values of C */ - int sorted, /* if TRUE, sort columns of C */ - /* --------------- */ + cholmod_sparse *A, // input matrix + cholmod_sparse *B, // input matrix + double alpha [2], // scale factor for A (two entires used if complex) + double beta [2], // scale factor for A (two entires used if complex) + int values, // if TRUE compute the numerical values of C + int sorted, // ignored; C is now always returned as sorted cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_add (cholmod_sparse *, cholmod_sparse *, double *, double *, int, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_sparse_xtype: change the xtype of a sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_sparse_xtype: change the xtype and/or dtype of a sparse matrix +//------------------------------------------------------------------------------ int cholmod_sparse_xtype ( - /* ---- input ---- */ - int to_xtype, /* requested xtype (pattern, real, complex, zomplex) */ - /* ---- in/out --- */ - cholmod_sparse *A, /* sparse matrix to change */ - /* --------------- */ + int to_xdtype, // requested xtype and dtype + cholmod_sparse *A, // sparse matrix to change cholmod_common *Common ) ; - int cholmod_l_sparse_xtype (int, cholmod_sparse *, cholmod_common *) ; - -/* ========================================================================== */ -/* === Core/cholmod_factor ================================================== */ -/* ========================================================================== */ - -/* A symbolic and numeric factorization, either simplicial or supernodal. - * In all cases, the row indices in the columns of L are kept sorted. */ +//============================================================================== +// cholmod_factor: symbolic or numeric factorization (simplicial or supernodal) +//============================================================================== typedef struct cholmod_factor_struct { - /* ---------------------------------------------------------------------- */ - /* for both simplicial and supernodal factorizations */ - /* ---------------------------------------------------------------------- */ - - size_t n ; /* L is n-by-n */ - - size_t minor ; /* If the factorization failed, L->minor is the column - * at which it failed (in the range 0 to n-1). A value - * of n means the factorization was successful or - * the matrix has not yet been factorized. */ - - /* ---------------------------------------------------------------------- */ - /* symbolic ordering and analysis */ - /* ---------------------------------------------------------------------- */ - - void *Perm ; /* size n, permutation used */ - void *ColCount ; /* size n, column counts for simplicial L */ - - void *IPerm ; /* size n, inverse permutation. Only created by - * cholmod_solve2 if Bset is used. */ - - /* ---------------------------------------------------------------------- */ - /* simplicial factorization */ - /* ---------------------------------------------------------------------- */ - - size_t nzmax ; /* size of i and x */ - - void *p ; /* p [0..ncol], the column pointers */ - void *i ; /* i [0..nzmax-1], the row indices */ - void *x ; /* x [0..nzmax-1], the numerical values */ - void *z ; - void *nz ; /* nz [0..ncol-1], the # of nonzeros in each column. - * i [p [j] ... p [j]+nz[j]-1] contains the row indices, - * and the numerical values are in the same locatins - * in x. The value of i [p [k]] is always k. */ - - void *next ; /* size ncol+2. next [j] is the next column in i/x */ - void *prev ; /* size ncol+2. prev [j] is the prior column in i/x. - * head of the list is ncol+1, and the tail is ncol. */ - - /* ---------------------------------------------------------------------- */ - /* supernodal factorization */ - /* ---------------------------------------------------------------------- */ - - /* Note that L->x is shared with the simplicial data structure. L->x has - * size L->nzmax for a simplicial factor, and size L->xsize for a supernodal - * factor. */ - - size_t nsuper ; /* number of supernodes */ - size_t ssize ; /* size of s, integer part of supernodes */ - size_t xsize ; /* size of x, real part of supernodes */ - size_t maxcsize ; /* size of largest update matrix */ - size_t maxesize ; /* max # of rows in supernodes, excl. triangular part */ - - void *super ; /* size nsuper+1, first col in each supernode */ - void *pi ; /* size nsuper+1, pointers to integer patterns */ - void *px ; /* size nsuper+1, pointers to real parts */ - void *s ; /* size ssize, integer part of supernodes */ - - /* ---------------------------------------------------------------------- */ - /* factorization type */ - /* ---------------------------------------------------------------------- */ - - int ordering ; /* ordering method used */ - - int is_ll ; /* TRUE if LL', FALSE if LDL' */ - int is_super ; /* TRUE if supernodal, FALSE if simplicial */ - int is_monotonic ; /* TRUE if columns of L appear in order 0..n-1. - * Only applicable to simplicial numeric types. */ - - /* There are 8 types of factor objects that cholmod_factor can represent - * (only 6 are used): - * - * Numeric types (xtype is not CHOLMOD_PATTERN) - * -------------------------------------------- - * - * simplicial LDL': (is_ll FALSE, is_super FALSE). Stored in compressed - * column form, using the simplicial components above (nzmax, p, i, - * x, z, nz, next, and prev). The unit diagonal of L is not stored, - * and D is stored in its place. There are no supernodes. - * - * simplicial LL': (is_ll TRUE, is_super FALSE). Uses the same storage - * scheme as the simplicial LDL', except that D does not appear. - * The first entry of each column of L is the diagonal entry of - * that column of L. - * - * supernodal LDL': (is_ll FALSE, is_super TRUE). Not used. - * FUTURE WORK: add support for supernodal LDL' - * - * supernodal LL': (is_ll TRUE, is_super TRUE). A supernodal factor, - * using the supernodal components described above (nsuper, ssize, - * xsize, maxcsize, maxesize, super, pi, px, s, x, and z). - * - * - * Symbolic types (xtype is CHOLMOD_PATTERN) - * ----------------------------------------- - * - * simplicial LDL': (is_ll FALSE, is_super FALSE). Nothing is present - * except Perm and ColCount. - * - * simplicial LL': (is_ll TRUE, is_super FALSE). Identical to the - * simplicial LDL', except for the is_ll flag. - * - * supernodal LDL': (is_ll FALSE, is_super TRUE). Not used. - * FUTURE WORK: add support for supernodal LDL' - * - * supernodal LL': (is_ll TRUE, is_super TRUE). A supernodal symbolic - * factorization. The simplicial symbolic information is present - * (Perm and ColCount), as is all of the supernodal factorization - * except for the numerical values (x and z). - */ - - int itype ; /* The integer arrays are Perm, ColCount, p, i, nz, - * next, prev, super, pi, px, and s. If itype is - * CHOLMOD_INT, all of these are int arrays. - * CHOLMOD_INTLONG: p, pi, px are int64_t, others int. - * CHOLMOD_LONG: all integer arrays are int64_t. */ - int xtype ; /* pattern, real, complex, or zomplex */ - int dtype ; /* x and z double or float */ - - int useGPU; /* Indicates the symbolic factorization supports - * GPU acceleration */ + size_t n ; // L is n-by-n + + size_t minor ; // If the factorization failed because of numerical issues + // (the matrix being factorized is found to be singular or not positive + // definte), then L->minor is the column at which it failed. L->minor + // = n means the factorization was successful. + + //-------------------------------------------------------------------------- + // symbolic ordering and analysis + //-------------------------------------------------------------------------- + + void *Perm ; // int32/int64, size n, fill-reducing ordering + void *ColCount ;// int32/int64, size n, # entries in each column of L + void *IPerm ; // int32/int64, size n, created by cholmod_solve2; + // containing the inverse of L->Perm + + //-------------------------------------------------------------------------- + // simplicial factorization (not supernodal) + //-------------------------------------------------------------------------- + + size_t nzmax ; // # of entries that L->i, L->x, and L->z can hold + + void *p ; // int32/int64, size n+1, column pointers + void *i ; // int32/int64, size nzmax, row indices + void *x ; // float/double, size nzmax or 2*nzmax, numerical values + void *z ; // float/double, size nzmax or empty, imaginary values + void *nz ; // int32/int64, size ncol, # of entries in each column + + // The row indices of L(:,j) are held in + // L->i [L->p [j] ... L->p [j] + L->nz [j] - 1]. + + // The numeical values of L(:,j) are held in the same positions in L->x + // (and L->z if L is zomplex) + + // L->next and L->prev hold a link list of columns of L, that tracks the + // order they appear in the arrays L->i, L->x, and L->z. The head and tail + // of the list is n+1 and n, respectively. + + void *next ; // int32/int64, size n+2 + void *prev ; // int32/int64, size n+2 + + //-------------------------------------------------------------------------- + // supernodal factorization (not simplicial) + //-------------------------------------------------------------------------- + + // L->x is shared with the simplicial structure above. L->z is not used + // for the supernodal case since a supernodal factor cannot be zomplex. + + size_t nsuper ; // # of supernodes + size_t ssize ; // # of integers in L->s + size_t xsize ; // # of entries in L->x + size_t maxcsize ; // size of largest update matrix + size_t maxesize ; // max # of rows in supernodes, excl. triangular part + + // the following are int32/int64 and are size nsuper+1: + void *super ; // first column in each supernode + void *pi ; // index into L->s for integer part of a supernode + void *px ; // index into L->x for numeric part of a supernode + + void *s ; // int32/int64, ssize, integer part of supernodes + + //-------------------------------------------------------------------------- + // type of the factorization + //-------------------------------------------------------------------------- + + int ordering ; // the fill-reducing method used (CHOLMOD_NATURAL, + // CHOLMOD_GIVEN, CHOLMOD_AMD, CHOLMOD_METIS, CHOLMOD_NESDIS, + // CHOLMOD_COLAMD, or CHOLMOD_POSTORDERED). + + int is_ll ; // true: an LL' factorization; false: LDL' instead + int is_super ; // true: supernodal; false: simplicial + int is_monotonic ; // true: columns appear in order 0 to n-1 in L, for a + // simplicial factorization only + + // Two boolean values above (is_ll, is_super) and L->xtype (pattern or + // otherwise, define eight types of factorizations, but only 6 are used: + + // If L->xtype is CHOLMOD_PATTERN, then L is a symbolic factor: + // + // simplicial LDL': (is_ll false, is_super false). Nothing is present + // except Perm and ColCount. + // + // simplicial LL': (is_ll true, is_super false). Identical to the + // simplicial LDL', except for the is_ll flag. + // + // supernodal LL': (is_ll true, is_super true). A supernodal symbolic + // factorization. The simplicial symbolic information is present + // (Perm and ColCount), as is all of the supernodal factorization + // except for the numerical values (x and z). + // + // If L->xtype is CHOLMOD_REAL, CHOLMOD_COMPLEX, or CHOLMOD_ZOMPLEX, + // then L is a numeric factor: + // + // + // simplicial LDL': (is_ll false, is_super false). Stored in compressed + // column form, using the simplicial components above (nzmax, p, i, + // x, z, nz, next, and prev). The unit diagonal of L is not stored, + // and D is stored in its place. There are no supernodes. + // + // simplicial LL': (is_ll true, is_super false). Uses the same storage + // scheme as the simplicial LDL', except that D does not appear. + // The first entry of each column of L is the diagonal entry of + // that column of L. + // + // supernodal LL': (is_ll true, is_super true). A supernodal factor, + // using the supernodal components described above (nsuper, ssize, + // xsize, maxcsize, maxesize, super, pi, px, s, x, and z). + // A supernodal factorization is never zomplex. + + int itype ; // integer type for L->Perm, L->ColCount, L->p, L->i, L->nz, + // L->next, L->prev, L->super, L->pi, L->px, and L->s. + // These are all int32 if L->itype is CHOLMOD_INT, or all int64 + // if L->itype is CHOLMOD_LONG. + + int xtype ; // pattern, real, complex, or zomplex + int dtype ; // x and z are double or single + + int useGPU; // if true, symbolic factorization allows for use of the GPU } cholmod_factor ; +//------------------------------------------------------------------------------ +// cholmod_allocate_factor: allocate a numerical factor +//------------------------------------------------------------------------------ -/* -------------------------------------------------------------------------- */ -/* cholmod_allocate_factor: allocate a factor (symbolic LL' or LDL') */ -/* -------------------------------------------------------------------------- */ +// L is returned as double precision -cholmod_factor *cholmod_allocate_factor +cholmod_factor *cholmod_allocate_factor // return the new factor L ( - /* ---- input ---- */ - size_t n, /* L is n-by-n */ - /* --------------- */ + size_t n, // L is factorization of an n-by-n matrix cholmod_common *Common ) ; - cholmod_factor *cholmod_l_allocate_factor (size_t, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_free_factor: free a factor */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_alloc_factor: allocate a numerical factor (double or single) +//------------------------------------------------------------------------------ -int cholmod_free_factor +cholmod_factor *cholmod_alloc_factor // return the new factor L ( - /* ---- in/out --- */ - cholmod_factor **L, /* factor to free, NULL on output */ - /* --------------- */ + size_t n, // L is factorization of an n-by-n matrix + int dtype, // CHOLMOD_SINGLE or CHOLMOD_DOUBLE cholmod_common *Common ) ; +cholmod_factor *cholmod_l_alloc_factor (size_t, int, cholmod_common *) ; +//------------------------------------------------------------------------------ +// cholmod_free_factor: free a factor +//------------------------------------------------------------------------------ + +int cholmod_free_factor +( + cholmod_factor **L, // handle of sparse factorization to free + cholmod_common *Common +) ; int cholmod_l_free_factor (cholmod_factor **, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_reallocate_factor: change the # entries in a factor */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_reallocate_factor: change the # entries in a factor +//------------------------------------------------------------------------------ int cholmod_reallocate_factor ( - /* ---- input ---- */ - size_t nznew, /* new # of entries in L */ - /* ---- in/out --- */ - cholmod_factor *L, /* factor to modify */ - /* --------------- */ + size_t nznew, // new max # of nonzeros the factor matrix can hold + cholmod_factor *L, // factor to reallocate cholmod_common *Common ) ; - int cholmod_l_reallocate_factor (size_t, cholmod_factor *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_change_factor: change the type of factor (e.g., LDL' to LL') */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_change_factor: change the type of factor (e.g., LDL' to LL') +//------------------------------------------------------------------------------ int cholmod_change_factor ( - /* ---- input ---- */ - int to_xtype, /* to CHOLMOD_PATTERN, _REAL, _COMPLEX, _ZOMPLEX */ - int to_ll, /* TRUE: convert to LL', FALSE: LDL' */ - int to_super, /* TRUE: convert to supernodal, FALSE: simplicial */ - int to_packed, /* TRUE: pack simplicial columns, FALSE: do not pack */ - int to_monotonic, /* TRUE: put simplicial columns in order, FALSE: not */ - /* ---- in/out --- */ - cholmod_factor *L, /* factor to modify */ - /* --------------- */ + int to_xtype, // CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX + int to_ll, // if true: convert to LL'; else to LDL' + int to_super, // if true: convert to supernodal; else to simplicial + int to_packed, // if true: pack simplicial columns' else: do not pack + int to_monotonic, // if true, put simplicial columns in order + cholmod_factor *L, // factor to change. cholmod_common *Common ) ; - -int cholmod_l_change_factor ( int, int, int, int, int, cholmod_factor *, +int cholmod_l_change_factor (int, int, int, int, int, cholmod_factor *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_pack_factor: pack the columns of a factor */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_pack_factor: pack a factor +//------------------------------------------------------------------------------ -/* Pack the columns of a simplicial factor. Unlike cholmod_change_factor, - * it can pack the columns of a factor even if they are not stored in their - * natural order (non-monotonic). */ +// Removes all slack space from all columns in a factor. int cholmod_pack_factor ( - /* ---- in/out --- */ - cholmod_factor *L, /* factor to modify */ - /* --------------- */ + cholmod_factor *L, // factor to pack cholmod_common *Common ) ; - int cholmod_l_pack_factor (cholmod_factor *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_reallocate_column: resize a single column of a factor */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_reallocate_column: reallocate a single column L(:,j) +//------------------------------------------------------------------------------ int cholmod_reallocate_column ( - /* ---- input ---- */ - size_t j, /* the column to reallocate */ - size_t need, /* required size of column j */ - /* ---- in/out --- */ - cholmod_factor *L, /* factor to modify */ - /* --------------- */ + size_t j, // reallocate L(:,j) + size_t need, // space in L(:,j) for this # of entries + cholmod_factor *L, // L factor modified, L(:,j) resized cholmod_common *Common ) ; - int cholmod_l_reallocate_column (size_t, size_t, cholmod_factor *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_factor_to_sparse: create a sparse matrix copy of a factor */ -/* -------------------------------------------------------------------------- */ - -/* Only operates on numeric factors, not symbolic ones */ +//------------------------------------------------------------------------------ +// cholmod_factor_to_sparse: create a sparse matrix copy of a factor +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_factor_to_sparse +cholmod_sparse *cholmod_factor_to_sparse // return a new sparse matrix ( - /* ---- in/out --- */ - cholmod_factor *L, /* factor to copy, converted to symbolic on output */ - /* --------------- */ + cholmod_factor *L, // input: factor to convert; output: L is converted + // to a simplicial symbolic factor cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_factor_to_sparse (cholmod_factor *, - cholmod_common *) ; + cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_copy_factor: create a copy of a factor */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_copy_factor: create a copy of a factor +//------------------------------------------------------------------------------ -cholmod_factor *cholmod_copy_factor +cholmod_factor *cholmod_copy_factor // return a copy of the factor ( - /* ---- input ---- */ - cholmod_factor *L, /* factor to copy */ - /* --------------- */ + cholmod_factor *L, // factor to copy (not modified) cholmod_common *Common ) ; - cholmod_factor *cholmod_l_copy_factor (cholmod_factor *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_factor_xtype: change the xtype of a factor */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_factor_xtype: change the xtype and/or dtype of a factor +//------------------------------------------------------------------------------ int cholmod_factor_xtype ( - /* ---- input ---- */ - int to_xtype, /* requested xtype (real, complex, or zomplex) */ - /* ---- in/out --- */ - cholmod_factor *L, /* factor to change */ - /* --------------- */ + int to_xdtype, // requested xtype and dtype + cholmod_factor *L, // factor to change cholmod_common *Common ) ; - int cholmod_l_factor_xtype (int, cholmod_factor *, cholmod_common *) ; - -/* ========================================================================== */ -/* === Core/cholmod_dense =================================================== */ -/* ========================================================================== */ - -/* A dense matrix in column-oriented form. It has no itype since it contains - * no integers. Entry in row i and column j is located in x [i+j*d]. - */ +//============================================================================== +// cholmod_dense: a dense matrix, held by column +//============================================================================== typedef struct cholmod_dense_struct { - size_t nrow ; /* the matrix is nrow-by-ncol */ + size_t nrow ; // the matrix is nrow-by-ncol size_t ncol ; - size_t nzmax ; /* maximum number of entries in the matrix */ - size_t d ; /* leading dimension (d >= nrow must hold) */ - void *x ; /* size nzmax or 2*nzmax, if present */ - void *z ; /* size nzmax, if present */ - int xtype ; /* pattern, real, complex, or zomplex */ - int dtype ; /* x and z double or float */ + size_t nzmax ; // maximum number of entries in the matrix + size_t d ; // leading dimension (d >= nrow must hold) + void *x ; // size nzmax or 2*nzmax, if present + void *z ; // size nzmax, if present + int xtype ; // pattern, real, complex, or zomplex + int dtype ; // x and z double or single } cholmod_dense ; -/* -------------------------------------------------------------------------- */ -/* cholmod_allocate_dense: allocate a dense matrix (contents uninitialized) */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_allocate_dense: allocate a dense matrix (contents not initialized) +//------------------------------------------------------------------------------ cholmod_dense *cholmod_allocate_dense ( - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - size_t d, /* leading dimension */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t d, // leading dimension + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_dense *cholmod_l_allocate_dense (size_t, size_t, size_t, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_zeros: allocate a dense matrix and set it to zero */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_zeros: allocate a dense matrix and set it to zero +//------------------------------------------------------------------------------ cholmod_dense *cholmod_zeros ( - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_dense *cholmod_l_zeros (size_t, size_t, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_ones: allocate a dense matrix and set it to all ones */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_ones: allocate a dense matrix of all 1's +//------------------------------------------------------------------------------ cholmod_dense *cholmod_ones ( - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (_REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_dense *cholmod_l_ones (size_t, size_t, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_eye: allocate a dense matrix and set it to the identity matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_eye: allocate a dense identity matrix +//------------------------------------------------------------------------------ -cholmod_dense *cholmod_eye +cholmod_dense *cholmod_eye // return a dense identity matrix ( - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (_REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_dense *cholmod_l_eye (size_t, size_t, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_free_dense: free a dense matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_free_dense: free a dense matrix +//------------------------------------------------------------------------------ int cholmod_free_dense ( - /* ---- in/out --- */ - cholmod_dense **X, /* dense matrix to deallocate, NULL on output */ - /* --------------- */ + cholmod_dense **X, // handle of dense matrix to free cholmod_common *Common ) ; - int cholmod_l_free_dense (cholmod_dense **, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_ensure_dense: ensure a dense matrix has a given size and type */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_ensure_dense: ensure a dense matrix has a given size and type +//------------------------------------------------------------------------------ cholmod_dense *cholmod_ensure_dense ( - /* ---- input/output ---- */ - cholmod_dense **XHandle, /* matrix handle to check */ - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - size_t d, /* leading dimension */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + cholmod_dense **X, // matrix to resize as needed (*X may be NULL) + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t d, // leading dimension + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; +cholmod_dense *cholmod_l_ensure_dense (cholmod_dense **, size_t, size_t, + size_t, int, cholmod_common *) ; -cholmod_dense *cholmod_l_ensure_dense (cholmod_dense **, size_t, size_t, size_t, - int, cholmod_common *) ; - -/* -------------------------------------------------------------------------- */ -/* cholmod_sparse_to_dense: create a dense matrix copy of a sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_sparse_to_dense: create a dense matrix copy of a sparse matrix +//------------------------------------------------------------------------------ -cholmod_dense *cholmod_sparse_to_dense +cholmod_dense *cholmod_sparse_to_dense // return a dense matrix ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ - /* --------------- */ + cholmod_sparse *A, // input matrix cholmod_common *Common ) ; +cholmod_dense *cholmod_l_sparse_to_dense (cholmod_sparse *, cholmod_common *) ; -cholmod_dense *cholmod_l_sparse_to_dense (cholmod_sparse *, - cholmod_common *) ; - -/* -------------------------------------------------------------------------- */ -/* cholmod_dense_to_sparse: create a sparse matrix copy of a dense matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_dense_nnz: count # of nonzeros in a dense matrix +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_dense_to_sparse +int64_t cholmod_dense_nnz // return # of entries in the dense matrix ( - /* ---- input ---- */ - cholmod_dense *X, /* matrix to copy */ - int values, /* TRUE if values to be copied, FALSE otherwise */ - /* --------------- */ + cholmod_dense *X, // input matrix cholmod_common *Common ) ; +int64_t cholmod_l_dense_nnz (cholmod_dense *, cholmod_common *) ; + +//------------------------------------------------------------------------------ +// cholmod_dense_to_sparse: create a sparse matrix copy of a dense matrix +//------------------------------------------------------------------------------ +cholmod_sparse *cholmod_dense_to_sparse // return a sparse matrix C +( + cholmod_dense *X, // input matrix + int values, // if true, copy the values; if false, C is pattern + cholmod_common *Common +) ; cholmod_sparse *cholmod_l_dense_to_sparse (cholmod_dense *, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_copy_dense: create a copy of a dense matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_copy_dense: create a copy of a dense matrix +//------------------------------------------------------------------------------ -cholmod_dense *cholmod_copy_dense +cholmod_dense *cholmod_copy_dense // returns new dense matrix ( - /* ---- input ---- */ - cholmod_dense *X, /* matrix to copy */ - /* --------------- */ + cholmod_dense *X, // input dense matrix cholmod_common *Common ) ; - cholmod_dense *cholmod_l_copy_dense (cholmod_dense *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_copy_dense2: copy a dense matrix (pre-allocated) */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_copy_dense2: copy a dense matrix (pre-allocated) +//------------------------------------------------------------------------------ int cholmod_copy_dense2 ( - /* ---- input ---- */ - cholmod_dense *X, /* matrix to copy */ - /* ---- output --- */ - cholmod_dense *Y, /* copy of matrix X */ - /* --------------- */ + cholmod_dense *X, // input dense matrix + cholmod_dense *Y, // output dense matrix (already allocated on input) cholmod_common *Common ) ; - int cholmod_l_copy_dense2 (cholmod_dense *, cholmod_dense *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_dense_xtype: change the xtype of a dense matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_dense_xtype: change the xtype and/or dtype of a dense matrix +//------------------------------------------------------------------------------ int cholmod_dense_xtype ( - /* ---- input ---- */ - int to_xtype, /* requested xtype (real, complex,or zomplex) */ - /* ---- in/out --- */ - cholmod_dense *X, /* dense matrix to change */ - /* --------------- */ + int to_xdtype, // requested xtype and dtype + cholmod_dense *X, // dense matrix to change cholmod_common *Common ) ; - int cholmod_l_dense_xtype (int, cholmod_dense *, cholmod_common *) ; - -/* ========================================================================== */ -/* === Core/cholmod_triplet ================================================= */ -/* ========================================================================== */ - -/* A sparse matrix stored in triplet form. */ +//============================================================================= +// cholmod_triplet: a sparse matrix in triplet form +//============================================================================= typedef struct cholmod_triplet_struct { - size_t nrow ; /* the matrix is nrow-by-ncol */ - size_t ncol ; - size_t nzmax ; /* maximum number of entries in the matrix */ - size_t nnz ; /* number of nonzeros in the matrix */ - - void *i ; /* i [0..nzmax-1], the row indices */ - void *j ; /* j [0..nzmax-1], the column indices */ - void *x ; /* size nzmax or 2*nzmax, if present */ - void *z ; /* size nzmax, if present */ - - int stype ; /* Describes what parts of the matrix are considered: - * - * 0: matrix is "unsymmetric": use both upper and lower triangular parts - * (the matrix may actually be symmetric in pattern and value, but - * both parts are explicitly stored and used). May be square or - * rectangular. - * >0: matrix is square and symmetric. Entries in the lower triangular - * part are transposed and added to the upper triangular part when - * the matrix is converted to cholmod_sparse form. - * <0: matrix is square and symmetric. Entries in the upper triangular - * part are transposed and added to the lower triangular part when - * the matrix is converted to cholmod_sparse form. - * - * Note that stype>0 and stype<0 are different for cholmod_sparse and - * cholmod_triplet. The reason is simple. You can permute a symmetric - * triplet matrix by simply replacing a row and column index with their - * new row and column indices, via an inverse permutation. Suppose - * P = L->Perm is your permutation, and Pinv is an array of size n. - * Suppose a symmetric matrix A is represent by a triplet matrix T, with - * entries only in the upper triangular part. Then the following code: - * - * Ti = T->i ; - * Tj = T->j ; - * for (k = 0 ; k < n ; k++) Pinv [P [k]] = k ; - * for (k = 0 ; k < nz ; k++) Ti [k] = Pinv [Ti [k]] ; - * for (k = 0 ; k < nz ; k++) Tj [k] = Pinv [Tj [k]] ; - * - * creates the triplet form of C=P*A*P'. However, if T initially - * contains just the upper triangular entries (T->stype = 1), after - * permutation it has entries in both the upper and lower triangular - * parts. These entries should be transposed when constructing the - * cholmod_sparse form of A, which is what cholmod_triplet_to_sparse - * does. Thus: - * - * C = cholmod_triplet_to_sparse (T, 0, &Common) ; - * - * will return the matrix C = P*A*P'. - * - * Since the triplet matrix T is so simple to generate, it's quite easy - * to remove entries that you do not want, prior to converting T to the - * cholmod_sparse form. So if you include these entries in T, CHOLMOD - * assumes that there must be a reason (such as the one above). Thus, - * no entry in a triplet matrix is ever ignored. - */ - - int itype ; /* CHOLMOD_LONG: i and j are int64_t. Otherwise int */ - int xtype ; /* pattern, real, complex, or zomplex */ - int dtype ; /* x and z are double or float */ + size_t nrow ; // # of rows of the matrix + size_t ncol ; // # of colums of the matrix + size_t nzmax ; // max # of entries that can be held in the matrix + size_t nnz ; // current # of entries can be held in the matrix + + // int32 or int64 arrays (depending on T->itype) + void *i ; // i [0..nzmax-1], the row indices + void *j ; // j [0..nzmax-1], the column indices + + // double or float arrays: + void *x ; // size nzmax or 2*nzmax, or NULL + void *z ; // size nzmax, or NULL + + int stype ; // T->stype defines what parts of the matrix is held: + // 0: the matrix is unsymmetric with both lower and upper parts stored. + // >0: the matrix is square and symmetric, where entries in the lower + // triangular part are transposed and placed in the upper + // triangular part of A if T is converted into a sparse matrix A. + // <0: the matrix is square and symmetric, where entries in the upper + // triangular part are transposed and placed in the lower + // triangular part of A if T is converted into a sparse matrix A. + // + // Note that A->stype (for a sparse matrix) and T->stype (for a + // triplet matrix) are handled differently. In a triplet matrix T, + // no entry is ever ignored. For a sparse matrix A, if A->stype < 0 + // or A->stype > 0, then entries not in the correct triangular part + // are ignored. + + int itype ; // T->itype defines the integers used for T->i and T->j. + // if CHOLMOD_INT, these arrays are all of type int32_t. + // if CHOLMOD_LONG, these arrays are all of type int64_t. + int xtype ; // pattern, real, complex, or zomplex + int dtype ; // x and z are double or single } cholmod_triplet ; -/* -------------------------------------------------------------------------- */ -/* cholmod_allocate_triplet: allocate a triplet matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_allocate_triplet: allocate a triplet matrix +//------------------------------------------------------------------------------ -cholmod_triplet *cholmod_allocate_triplet +cholmod_triplet *cholmod_allocate_triplet // return triplet matrix T ( - /* ---- input ---- */ - size_t nrow, /* # of rows of T */ - size_t ncol, /* # of columns of T */ - size_t nzmax, /* max # of nonzeros of T */ - int stype, /* stype of T */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t nzmax, // max # of entries the matrix can hold + int stype, // the stype of the matrix (unsym, tril, or triu) + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_triplet *cholmod_l_allocate_triplet (size_t, size_t, size_t, int, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_free_triplet: free a triplet matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_free_triplet: free a triplet matrix +//------------------------------------------------------------------------------ int cholmod_free_triplet ( - /* ---- in/out --- */ - cholmod_triplet **T, /* triplet matrix to deallocate, NULL on output */ - /* --------------- */ + cholmod_triplet **T, // handle of triplet matrix to free cholmod_common *Common ) ; - int cholmod_l_free_triplet (cholmod_triplet **, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_reallocate_triplet: change the # of entries in a triplet matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_reallocate_triplet: change max # of entries in a triplet matrix +//------------------------------------------------------------------------------ int cholmod_reallocate_triplet ( - /* ---- input ---- */ - size_t nznew, /* new # of entries in T */ - /* ---- in/out --- */ - cholmod_triplet *T, /* triplet matrix to modify */ - /* --------------- */ + size_t nznew, // new max # of nonzeros the triplet matrix can hold + cholmod_triplet *T, // triplet matrix to reallocate cholmod_common *Common ) ; - int cholmod_l_reallocate_triplet (size_t, cholmod_triplet *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_sparse_to_triplet: create a triplet matrix copy of a sparse matrix*/ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_sparse_to_triplet: create a triplet matrix copy of a sparse matrix +//------------------------------------------------------------------------------ cholmod_triplet *cholmod_sparse_to_triplet ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ - /* --------------- */ + cholmod_sparse *A, // matrix to copy into triplet form T cholmod_common *Common ) ; - cholmod_triplet *cholmod_l_sparse_to_triplet (cholmod_sparse *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_triplet_to_sparse: create a sparse matrix copy of a triplet matrix*/ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_triplet_to_sparse: create a sparse matrix from of triplet matrix +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_triplet_to_sparse +cholmod_sparse *cholmod_triplet_to_sparse // return sparse matrix A ( - /* ---- input ---- */ - cholmod_triplet *T, /* matrix to copy */ - size_t nzmax, /* allocate at least this much space in output matrix */ - /* --------------- */ + cholmod_triplet *T, // input triplet matrix + size_t nzmax, // allocate space for max(nzmax,nnz(A)) entries cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_triplet_to_sparse (cholmod_triplet *, size_t, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_copy_triplet: create a copy of a triplet matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_copy_triplet: copy a triplet matrix +//------------------------------------------------------------------------------ -cholmod_triplet *cholmod_copy_triplet +cholmod_triplet *cholmod_copy_triplet // return new triplet matrix ( - /* ---- input ---- */ - cholmod_triplet *T, /* matrix to copy */ - /* --------------- */ + cholmod_triplet *T, // triplet matrix to copy cholmod_common *Common ) ; - cholmod_triplet *cholmod_l_copy_triplet (cholmod_triplet *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_triplet_xtype: change the xtype of a triplet matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_triplet_xtype: change the xtype and/or dtype of a triplet matrix +//------------------------------------------------------------------------------ int cholmod_triplet_xtype ( - /* ---- input ---- */ - int to_xtype, /* requested xtype (pattern, real, complex,or zomplex)*/ - /* ---- in/out --- */ - cholmod_triplet *T, /* triplet matrix to change */ - /* --------------- */ + int to_xdtype, // requested xtype and dtype + cholmod_triplet *T, // triplet matrix to change cholmod_common *Common ) ; - int cholmod_l_triplet_xtype (int, cholmod_triplet *, cholmod_common *) ; +//============================================================================== +// memory allocation +//============================================================================== -/* ========================================================================== */ -/* === Core/cholmod_memory ================================================== */ -/* ========================================================================== */ - -/* The user may make use of these, just like malloc and free. You can even - * malloc an object and safely free it with cholmod_free, and visa versa - * (except that the memory usage statistics will be corrupted). These routines - * do differ from malloc and free. If cholmod_free is given a NULL pointer, - * for example, it does nothing (unlike the ANSI free). cholmod_realloc does - * not return NULL if given a non-NULL pointer and a nonzero size, even if it - * fails (it returns the original pointer and sets an error code in - * Common->status instead). - * - * CHOLMOD keeps track of the amount of memory it has allocated, and so the - * cholmod_free routine also takes the size of the object being freed. This - * is only used for statistics. If you, the user of CHOLMOD, pass the wrong - * size, the only consequence is that the memory usage statistics will be - * corrupted. - */ +// These methods act like malloc/calloc/realloc/free, with some differences. +// They are simple wrappers around the memory management functions in +// SuiteSparse_config. cholmod_malloc and cholmod_calloc have the same +// signature, unlike malloc and calloc. If cholmod_free is given a NULL +// pointer, it safely does nothing. cholmod_free must be passed the size of +// the object being freed, but that is just to keep track of memory usage +// statistics. cholmod_realloc does not return NULL if it fails; instead, it +// returns the pointer to the unmodified block of memory. -void *cholmod_malloc /* returns pointer to the newly malloc'd block */ +void *cholmod_malloc // return pointer to newly allocated memory ( - /* ---- input ---- */ - size_t n, /* number of items */ - size_t size, /* size of each item */ - /* --------------- */ + size_t n, // number of items + size_t size, // size of each item cholmod_common *Common ) ; - void *cholmod_l_malloc (size_t, size_t, cholmod_common *) ; -void *cholmod_calloc /* returns pointer to the newly calloc'd block */ +void *cholmod_calloc // return pointer to newly allocated memory ( - /* ---- input ---- */ - size_t n, /* number of items */ - size_t size, /* size of each item */ - /* --------------- */ + size_t n, // number of items + size_t size, // size of each item cholmod_common *Common ) ; - void *cholmod_l_calloc (size_t, size_t, cholmod_common *) ; -void *cholmod_free /* always returns NULL */ +void *cholmod_free // returns NULL to simplify its usage ( - /* ---- input ---- */ - size_t n, /* number of items */ - size_t size, /* size of each item */ - /* ---- in/out --- */ - void *p, /* block of memory to free */ - /* --------------- */ + size_t n, // number of items + size_t size, // size of each item + void *p, // memory to free cholmod_common *Common ) ; - void *cholmod_l_free (size_t, size_t, void *, cholmod_common *) ; -void *cholmod_realloc /* returns pointer to reallocated block */ +void *cholmod_realloc // return newly reallocated block of memory ( - /* ---- input ---- */ - size_t nnew, /* requested # of items in reallocated block */ - size_t size, /* size of each item */ - /* ---- in/out --- */ - void *p, /* block of memory to realloc */ - size_t *n, /* current size on input, nnew on output if successful*/ - /* --------------- */ + size_t nnew, // # of items in newly reallocate memory + size_t size, // size of each item + void *p, // pointer to memory to reallocate (may be NULL) + size_t *n, // # of items in p on input; nnew on output if success cholmod_common *Common ) ; - void *cholmod_l_realloc (size_t, size_t, void *, size_t *, cholmod_common *) ; -int cholmod_realloc_multiple +int cholmod_realloc_multiple // returns true if successful, false otherwise ( - /* ---- input ---- */ - size_t nnew, /* requested # of items in reallocated blocks */ - int nint, /* number of int32_t/int64_t blocks */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* ---- in/out --- */ - void **Iblock, /* int32_t or int64_t block */ - void **Jblock, /* int32_t or int64_t block */ - void **Xblock, /* complex, double, or float block */ - void **Zblock, /* zomplex case only: double or float block */ - size_t *n, /* current size of the I,J,X,Z blocks on input, - * nnew on output if successful */ - /* --------------- */ + size_t nnew, // # of items in newly reallocate memory + int nint, // 0: do not allocate I or J, 1: just I, 2: both I and J + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) + // input/output: + void **I, // integer block of memory (int32_t or int64_t) + void **J, // integer block of memory (int32_t or int64_t) + void **X, // real or complex, double or single, block + void **Z, // zomplex only: double or single block + size_t *n, // current size of I, J, X, and/or Z blocks on input, + // changed to nnew on output, if successful cholmod_common *Common ) ; - int cholmod_l_realloc_multiple (size_t, int, int, void **, void **, void **, void **, size_t *, cholmod_common *) ; -/* ========================================================================== */ -/* === version control ====================================================== */ -/* ========================================================================== */ - -int cholmod_version /* returns CHOLMOD_VERSION */ -( - /* output, contents not defined on input. Not used if NULL. - version [0] = CHOLMOD_MAIN_VERSION - version [1] = CHOLMOD_SUB_VERSION - version [2] = CHOLMOD_SUBSUB_VERSION - */ - int version [3] -) ; - -int cholmod_l_version (int version [3]) ; - -/* Versions prior to 2.1.1 do not have the above function. The following - code fragment will work with any version of CHOLMOD: - #ifdef CHOLMOD_HAS_VERSION_FUNCTION - v = cholmod_version (NULL) ; - #else - v = CHOLMOD_VERSION ; - #endif -*/ - -/* ========================================================================== */ -/* === symmetry types ======================================================= */ -/* ========================================================================== */ - -#define CHOLMOD_MM_RECTANGULAR 1 -#define CHOLMOD_MM_UNSYMMETRIC 2 -#define CHOLMOD_MM_SYMMETRIC 3 -#define CHOLMOD_MM_HERMITIAN 4 -#define CHOLMOD_MM_SKEW_SYMMETRIC 5 -#define CHOLMOD_MM_SYMMETRIC_POSDIAG 6 -#define CHOLMOD_MM_HERMITIAN_POSDIAG 7 +//============================================================================== +// numerical comparisons +//============================================================================== -/* ========================================================================== */ -/* === Numerical relop macros =============================================== */ -/* ========================================================================== */ - -/* These macros correctly handle the NaN case. - * - * CHOLMOD_IS_NAN(x): - * True if x is NaN. False otherwise. The commonly-existing isnan(x) - * function could be used, but it's not in Kernighan & Ritchie 2nd edition - * (ANSI C89). It may appear in , but I'm not certain about - * portability. The expression x != x is true if and only if x is NaN, - * according to the IEEE 754 floating-point standard. - * - * CHOLMOD_IS_ZERO(x): - * True if x is zero. False if x is nonzero, NaN, or +/- Inf. - * This is (x == 0) if the compiler is IEEE 754 compliant. - * - * CHOLMOD_IS_NONZERO(x): - * True if x is nonzero, NaN, or +/- Inf. False if x zero. - * This is (x != 0) if the compiler is IEEE 754 compliant. - * - * CHOLMOD_IS_LT_ZERO(x): - * True if x is < zero or -Inf. False if x is >= 0, NaN, or +Inf. - * This is (x < 0) if the compiler is IEEE 754 compliant. - * - * CHOLMOD_IS_GT_ZERO(x): - * True if x is > zero or +Inf. False if x is <= 0, NaN, or -Inf. - * This is (x > 0) if the compiler is IEEE 754 compliant. - * - * CHOLMOD_IS_LE_ZERO(x): - * True if x is <= zero or -Inf. False if x is > 0, NaN, or +Inf. - * This is (x <= 0) if the compiler is IEEE 754 compliant. - */ +// These macros were different on Windows for older versions of CHOLMOD. +// They are no longer needed but are kept for backward compatibility. -#ifdef CHOLMOD_WINDOWS - -/* Yes, this is exceedingly ugly. Blame Microsoft, which hopelessly */ -/* violates the IEEE 754 floating-point standard in a bizarre way. */ -/* If you're using an IEEE 754-compliant compiler, then x != x is true */ -/* iff x is NaN. For Microsoft, (x < x) is true iff x is NaN. */ -/* So either way, this macro safely detects a NaN. */ -#define CHOLMOD_IS_NAN(x) (((x) != (x)) || (((x) < (x)))) -#define CHOLMOD_IS_ZERO(x) (((x) == 0.) && !CHOLMOD_IS_NAN(x)) -#define CHOLMOD_IS_NONZERO(x) (((x) != 0.) || CHOLMOD_IS_NAN(x)) -#define CHOLMOD_IS_LT_ZERO(x) (((x) < 0.) && !CHOLMOD_IS_NAN(x)) -#define CHOLMOD_IS_GT_ZERO(x) (((x) > 0.) && !CHOLMOD_IS_NAN(x)) -#define CHOLMOD_IS_LE_ZERO(x) (((x) <= 0.) && !CHOLMOD_IS_NAN(x)) - -#else - -/* These all work properly, according to the IEEE 754 standard ... except on */ -/* a PC with windows. Works fine in Linux on the same PC... */ -#define CHOLMOD_IS_NAN(x) ((x) != (x)) -#define CHOLMOD_IS_ZERO(x) ((x) == 0.) -#define CHOLMOD_IS_NONZERO(x) ((x) != 0.) -#define CHOLMOD_IS_LT_ZERO(x) ((x) < 0.) -#define CHOLMOD_IS_GT_ZERO(x) ((x) > 0.) -#define CHOLMOD_IS_LE_ZERO(x) ((x) <= 0.) +#define CHOLMOD_IS_NAN(x) isnan (x) +#define CHOLMOD_IS_ZERO(x) ((x) == 0.) +#define CHOLMOD_IS_NONZERO(x) ((x) != 0.) +#define CHOLMOD_IS_LT_ZERO(x) ((x) < 0.) +#define CHOLMOD_IS_GT_ZERO(x) ((x) > 0.) +#define CHOLMOD_IS_LE_ZERO(x) ((x) <= 0.) #endif +//============================================================================== +// CHOLMOD:Check Module +//============================================================================== +#ifndef NCHECK - -/* ========================================================================== */ -/* === Include/cholmod_check.h ============================================== */ -/* ========================================================================== */ - -/* CHOLMOD Check module. - * - * Routines that check and print the 5 basic data types in CHOLMOD, and 3 kinds +/* Routines that check and print the 5 basic data types in CHOLMOD, and 3 kinds * of integer vectors (subset, perm, and parent), and read in matrices from a * file: * @@ -2684,15 +1976,13 @@ int cholmod_l_version (int version [3]) ; * cholmod_print_common and cholmod_check_common are the only two routines that * you may call after calling cholmod_finish. * - * Requires the Core module. Not required by any CHOLMOD module, except when + * Requires the Utility module. Not required by any CHOLMOD module, except when * debugging is enabled (in which case all modules require the Check module). * * See cholmod_read.c for a description of the file formats supported by the * cholmod_read_* routines. */ -#ifndef NCHECK - /* -------------------------------------------------------------------------- */ /* cholmod_check_common: check the Common object */ /* -------------------------------------------------------------------------- */ @@ -2839,7 +2129,8 @@ int cholmod_print_triplet cholmod_common *Common ) ; -int cholmod_l_print_triplet (cholmod_triplet *, const char *, cholmod_common *); +int cholmod_l_print_triplet (cholmod_triplet *, const char *, + cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_check_subset: check a subset */ @@ -2982,7 +2273,7 @@ cholmod_dense *cholmod_read_dense cholmod_common *Common ) ; -cholmod_dense *cholmod_l_read_dense (FILE *, cholmod_common *) ; +cholmod_dense *cholmod_l_read_dense (FILE *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_read_matrix: read a sparse or dense matrix from a file */ @@ -3018,7 +2309,7 @@ void *cholmod_l_read_matrix (FILE *, int, int *, cholmod_common *) ; /* cholmod_write_sparse: write a sparse matrix to a file */ /* -------------------------------------------------------------------------- */ -int cholmod_write_sparse +int cholmod_write_sparse // returns the same result as cholmod_symmetry ( /* ---- input ---- */ FILE *f, /* file to write to, must already be open */ @@ -3048,25 +2339,21 @@ int cholmod_write_dense int cholmod_l_write_dense (FILE *, cholmod_dense *, const char *, cholmod_common *) ; -#endif - - - +#endif +//============================================================================== +// CHOLMOD:Cholesky Module +//============================================================================== -/* ========================================================================== */ -/* === Include/cholmod_cholesky.h =========================================== */ -/* ========================================================================== */ +#ifndef NCHOLESKY -/* CHOLMOD Cholesky module. - * - * Sparse Cholesky routines: analysis, factorization, and solve. +/* Sparse Cholesky routines: analysis, factorization, and solve. * * The primary routines are all that a user requires to order, analyze, and * factorize a sparse symmetric positive definite matrix A (or A*A'), and * to solve Ax=b (or A*A'x=b). The primary routines rely on the secondary - * routines, the CHOLMOD Core module, and the AMD and COLAMD packages. They + * routines, the CHOLMOD Utility module, and the AMD and COLAMD packages. They * make optional use of the CHOLMOD Supernodal and Partition modules, the * METIS package, and the CCOLAMD package. * @@ -3097,13 +2384,11 @@ int cholmod_l_write_dense (FILE *, cholmod_dense *, const char *, * cholmod_resymbol_noperm recompute the symbolic pattern of L, no L->Perm * cholmod_postorder postorder a tree * - * Requires the Core module, and two packages: AMD and COLAMD. + * Requires the Utility module, and two packages: AMD and COLAMD. * Optionally uses the Supernodal and Partition modules. * Required by the Partition module. */ -#ifndef NCHOLESKY - /* -------------------------------------------------------------------------- */ /* cholmod_analyze: order and analyze (simplicial or supernodal) */ /* -------------------------------------------------------------------------- */ @@ -3111,7 +2396,7 @@ int cholmod_l_write_dense (FILE *, cholmod_dense *, const char *, /* Orders and analyzes A, AA', PAP', or PAA'P' and returns a symbolic factor * that can later be passed to cholmod_factorize. */ -cholmod_factor *cholmod_analyze +cholmod_factor *cholmod_analyze // order and analyze ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order and analyze */ @@ -3174,7 +2459,7 @@ cholmod_factor *cholmod_l_analyze_p2 (int, cholmod_sparse *, int64_t *, * routine a second time with another matrix. A must have the same nonzero * pattern as that passed to cholmod_analyze. */ -int cholmod_factorize +int cholmod_factorize // simplicial or superodal Cholesky factorization ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ @@ -3550,7 +2835,7 @@ int cholmod_l_row_lsubtree (cholmod_sparse *, int64_t *, size_t, * first permutes A according to L->Perm. A can be upper/lower/unsymmetric, * in contrast to cholmod_resymbol_noperm (which can be lower or unsym). */ -int cholmod_resymbol +int cholmod_resymbol // recompute symbolic pattern of L ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ @@ -3619,19 +2904,18 @@ int32_t cholmod_postorder /* return # of nodes postordered */ cholmod_common *Common ) ; -int64_t cholmod_l_postorder (int64_t *, size_t, - int64_t *, int64_t *, cholmod_common *) ; +int64_t cholmod_l_postorder (int64_t *, size_t, int64_t *, int64_t *, + cholmod_common *) ; #endif +//============================================================================== +// CHOLMOD:MatrixOps Module +//============================================================================== -/* ========================================================================== */ -/* === Include/cholmod_matrixops.h ========================================== */ -/* ========================================================================== */ +#ifndef NMATRIXOPS -/* CHOLMOD MatrixOps module. - * - * Basic operations on sparse and dense matrices. +/* Basic operations on sparse and dense matrices. * * cholmod_drop A = entries in A with abs. value >= tol * cholmod_norm_dense s = norm (X), 1-norm, inf-norm, or 2-norm @@ -3647,11 +2931,9 @@ int64_t cholmod_l_postorder (int64_t *, size_t, * X, Y: dense matrices (cholmod_dense) * s: scalar or vector * - * Requires the Core module. Not required by any other CHOLMOD module. + * Requires the Utility module. Not required by any other CHOLMOD module. */ -#ifndef NMATRIXOPS - /* -------------------------------------------------------------------------- */ /* cholmod_drop: drop entries with small absolute value */ /* -------------------------------------------------------------------------- */ @@ -3807,8 +3089,7 @@ cholmod_sparse *cholmod_submatrix ) ; cholmod_sparse *cholmod_l_submatrix (cholmod_sparse *, int64_t *, - int64_t, int64_t *, int64_t, int, int, - cholmod_common *) ; + int64_t, int64_t *, int64_t, int, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_vertcat: C = [A ; B] */ @@ -3845,18 +3126,16 @@ int cholmod_symmetry cholmod_common *Common ) ; -int cholmod_l_symmetry (cholmod_sparse *, int, int64_t *, - int64_t *, int64_t *, int64_t *, - cholmod_common *) ; +int cholmod_l_symmetry (cholmod_sparse *, int, int64_t *, int64_t *, int64_t *, + int64_t *, cholmod_common *) ; #endif +//============================================================================== +// CHOLMOD:Modify Module +//============================================================================== - - -/* ========================================================================== */ -/* === Include/cholmod_modify.h ============================================= */ -/* ========================================================================== */ +#ifndef NMODIFY /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_modify.h. @@ -3864,13 +3143,11 @@ int cholmod_l_symmetry (cholmod_sparse *, int, int64_t *, * http://www.suitesparse.com * -------------------------------------------------------------------------- */ -/* CHOLMOD Modify module. - * - * Sparse Cholesky modification routines: update / downdate / rowadd / rowdel. +/* Sparse Cholesky modification routines: update / downdate / rowadd / rowdel. * Can also modify a corresponding solution to Lx=b when L is modified. This * module is most useful when applied on a Cholesky factorization computed by * the Cholesky module, but it does not actually require the Cholesky module. - * The Core module can create an identity Cholesky factorization (LDL' where + * The Utility module can create an identity Cholesky factorization (LDL' where * L=D=I) that can then by modified by these routines. * * Primary routines: @@ -3892,12 +3169,9 @@ int cholmod_l_symmetry (cholmod_sparse *, int, int64_t *, * cholmod_rowdel_solve delete a row, and downdate Lx=b * cholmod_rowdel_mark delete a row, and downdate solution to partial Lx=b * - * Requires the Core module. Not required by any other CHOLMOD module. + * Requires the Utility module. Not required by any other CHOLMOD module. */ - -#ifndef NMODIFY - /* -------------------------------------------------------------------------- */ /* cholmod_updown: multiple rank update/downdate */ /* -------------------------------------------------------------------------- */ @@ -3906,7 +3180,7 @@ int cholmod_l_symmetry (cholmod_sparse *, int, int64_t *, * (a downdate). The factor object L need not be an LDL' factorization; it * is converted to one if it isn't. */ -int cholmod_updown +int cholmod_updown // update/downdate ( /* ---- input ---- */ int update, /* TRUE for update, FALSE for downdate */ @@ -3916,9 +3190,8 @@ int cholmod_updown /* --------------- */ cholmod_common *Common ) ; +int cholmod_l_updown (int, cholmod_sparse *, cholmod_factor *, cholmod_common *) ; -int cholmod_l_updown (int, cholmod_sparse *, cholmod_factor *, - cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_updown_solve: update/downdate, and modify solution to Lx=b */ @@ -4030,7 +3303,7 @@ int cholmod_l_updown_mask2 (int, cholmod_sparse *, int64_t *, * computed as the factorization of the kth row/column of the matrix to * factorize, which is provided as a single n-by-1 sparse matrix R. */ -int cholmod_rowadd +int cholmod_rowadd // add a row to an LDL' factorization ( /* ---- input ---- */ size_t k, /* row/column index to add */ @@ -4108,7 +3381,7 @@ int cholmod_l_rowadd_mark (size_t, cholmod_sparse *, double *, * a little more time. */ -int cholmod_rowdel +int cholmod_rowdel // delete a rw from an LDL' factorization ( /* ---- input ---- */ size_t k, /* row/column index to delete */ @@ -4177,11 +3450,11 @@ int cholmod_l_rowdel_mark (size_t, cholmod_sparse *, double *, #endif +//============================================================================== +// CHOLMOD:Partition Module (CAMD, CCOLAMD, and CSYMAMD) +//============================================================================== - -/* ========================================================================== */ -/* === Include/cholmod_camd.h =============================================== */ -/* ========================================================================== */ +#ifndef NCAMD /* CHOLMOD Partition module, interface to CAMD, CCOLAMD, and CSYMAMD * @@ -4195,12 +3468,10 @@ int cholmod_l_rowdel_mark (size_t, cholmod_sparse *, double *, * cholmod_csymamd interface to CSYMAMD ordering * cholmod_camd interface to CAMD ordering * - * Requires the Core and Cholesky modules, and two packages: CAMD, + * Requires the Utility and Cholesky modules, and two packages: CAMD, * and CCOLAMD. Used by functions in the Partition Module. */ -#ifndef NCAMD - /* -------------------------------------------------------------------------- */ /* cholmod_ccolamd */ /* -------------------------------------------------------------------------- */ @@ -4271,9 +3542,13 @@ int cholmod_l_camd (cholmod_sparse *, int64_t *, size_t, #endif -/* ========================================================================== */ -/* === Include/cholmod_partition.h ========================================== */ -/* ========================================================================== */ +//============================================================================== +// CHOLMOD:Partition Module (graph partition methods) +//============================================================================== + +// These routines still exist if CHOLMOD is compiled with -DNPARTITION, +// but they return Common->status = CHOLMOD_NOT_INSTALLED in that case. +#if 1 /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_partition.h. @@ -4293,7 +3568,7 @@ int cholmod_l_camd (cholmod_sparse *, int64_t *, size_t, * cholmod_bisect graph partitioner (currently based on METIS) * cholmod_metis_bisector direct interface to METIS_ComputeVertexSeparator * - * Requires the Core and Cholesky modules, and three packages: METIS, CAMD, + * Requires the Utility and Cholesky modules, and three packages: METIS, CAMD, * and CCOLAMD. Optionally used by the Cholesky module. * * Note that METIS does not have a version that uses int64_t integers. If you @@ -4304,9 +3579,6 @@ int cholmod_l_camd (cholmod_sparse *, int64_t *, size_t, * idxtype. */ -// These routines still exist if CHOLMOD is compiled with -DNPARTITION, -// but they return Common->status = CHOLMOD_NOT_INSTALLED. - /* -------------------------------------------------------------------------- */ /* cholmod_nested_dissection */ /* -------------------------------------------------------------------------- */ @@ -4334,9 +3606,8 @@ int64_t cholmod_nested_dissection /* returns # of components */ cholmod_common *Common ) ; -int64_t cholmod_l_nested_dissection (cholmod_sparse *, - int64_t *, size_t, int64_t *, int64_t *, - int64_t *, cholmod_common *) ; +int64_t cholmod_l_nested_dissection (cholmod_sparse *, int64_t *, size_t, + int64_t *, int64_t *, int64_t *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_metis */ @@ -4357,8 +3628,8 @@ int cholmod_metis cholmod_common *Common ) ; -int cholmod_l_metis (cholmod_sparse *, int64_t *, size_t, int, - int64_t *, cholmod_common *) ; +int cholmod_l_metis (cholmod_sparse *, int64_t *, size_t, int, int64_t *, + cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_bisect */ @@ -4381,8 +3652,8 @@ int64_t cholmod_bisect /* returns # of nodes in separator */ cholmod_common *Common ) ; -int64_t cholmod_l_bisect (cholmod_sparse *, int64_t *, - size_t, int, int64_t *, cholmod_common *) ; +int64_t cholmod_l_bisect (cholmod_sparse *, int64_t *, size_t, int, int64_t *, + cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_metis_bisector */ @@ -4396,7 +3667,7 @@ int64_t cholmod_metis_bisector /* returns separator size */ /* ---- input ---- */ cholmod_sparse *A, /* matrix to bisect */ int32_t *Anw, /* size A->nrow, node weights, can be NULL, */ - /* which means the graph is unweighted. */ + /* which means the graph is unweighted. */ int32_t *Aew, /* size nz, edge weights (silently ignored). */ /* This option was available with METIS 4, but not */ /* in METIS 5. This argument is now unused, but */ @@ -4408,9 +3679,8 @@ int64_t cholmod_metis_bisector /* returns separator size */ cholmod_common *Common ) ; -int64_t cholmod_l_metis_bisector (cholmod_sparse *, - int64_t *, int64_t *, int64_t *, - cholmod_common *) ; +int64_t cholmod_l_metis_bisector (cholmod_sparse *, int64_t *, int64_t *, + int64_t *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_collapse_septree */ @@ -4432,16 +3702,18 @@ int64_t cholmod_collapse_septree cholmod_common *Common ) ; -int64_t cholmod_l_collapse_septree (size_t, size_t, double, size_t, - int64_t *, int64_t *, cholmod_common *) ; +int64_t cholmod_l_collapse_septree (size_t, size_t, double, size_t, int64_t *, + int64_t *, cholmod_common *) ; + +#endif -/* ========================================================================== */ -/* === Include/cholmod_supernodal.h ========================================= */ -/* ========================================================================== */ +//============================================================================== +// CHOLMOD:Supernodal Module +//============================================================================== -/* CHOLMOD Supernodal module. - * - * Supernodal analysis, factorization, and solve. The simplest way to use +#ifndef NSUPERNODAL + +/* Supernodal analysis, factorization, and solve. The simplest way to use * these routines is via the Cholesky module. It does not provide any * fill-reducing orderings, but does accept the orderings computed by the * Cholesky module. It does not require the Cholesky module itself, however. @@ -4468,12 +3740,10 @@ int64_t cholmod_l_collapse_septree (size_t, size_t, double, size_t, * ---------------- * dpotrf LAPACK: A=chol(tril(A)) * - * Requires the Core module, and two external packages: LAPACK and the BLAS. + * Requires the Utility module, and two external packages: LAPACK and the BLAS. * Optionally used by the Cholesky module. */ -#ifndef NSUPERNODAL - /* -------------------------------------------------------------------------- */ /* cholmod_super_symbolic */ /* -------------------------------------------------------------------------- */ @@ -4496,8 +3766,8 @@ int cholmod_super_symbolic cholmod_common *Common ) ; -int cholmod_l_super_symbolic (cholmod_sparse *, cholmod_sparse *, - int64_t *, cholmod_factor *, cholmod_common *) ; +int cholmod_l_super_symbolic (cholmod_sparse *, cholmod_sparse *, int64_t *, + cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_super_symbolic2 */ @@ -4600,19 +3870,37 @@ int cholmod_l_super_ltsolve (cholmod_factor *, cholmod_dense *, cholmod_dense *, } #endif +//============================================================================== +// CHOLMOD:SupernodalGPU Module +//============================================================================== -/* ========================================================================== */ -/* === Include/cholmod_gpu.h ================================================ */ -/* ========================================================================== */ +//------------------------------------------------------------------------------ +// cholmod_score_comp: for sorting descendant supernodes with qsort +//------------------------------------------------------------------------------ -/* ----------------------------------------------------------------------------- - * CHOLMOD/Include/cholmod_gpu.h. - * Copyright (C) 2014, Timothy A. Davis - * http://www.suitesparse.com - * -------------------------------------------------------------------------- */ +#ifdef __cplusplus +extern "C" { +#endif -/* CHOLMOD GPU module - */ +typedef struct cholmod_descendant_score_t +{ + double score ; + int64_t d ; +} +descendantScore ; + +int cholmod_score_comp (struct cholmod_descendant_score_t *i, + struct cholmod_descendant_score_t *j) ; +int cholmod_l_score_comp (struct cholmod_descendant_score_t *i, + struct cholmod_descendant_score_t *j) ; + +#ifdef __cplusplus +} +#endif + +//------------------------------------------------------------------------------ +// remainder of SupernodalGPU Module +//------------------------------------------------------------------------------ #ifdef SUITESPARSE_CUDA @@ -4635,11 +3923,10 @@ int cholmod_l_super_ltsolve (cholmod_factor *, cholmod_dense *, cholmod_dense *, #define CHOLMOD_POTRF_LIMIT 512 /* required cols for POTRF & TRSM on GPU */ /* # of host supernodes to perform before checking for free pinned buffers */ -#define CHOLMOD_GPU_SKIP 3 +#define CHOLMOD_GPU_SKIP 3 #define CHOLMOD_HANDLE_CUDA_ERROR(e,s) {if (e) {ERROR(CHOLMOD_GPU_PROBLEM,s);}} -/* make it easy for C++ programs to include CHOLMOD */ #ifdef __cplusplus extern "C" { #endif @@ -4669,7 +3956,7 @@ int cholmod_l_gpu_memorysize /* GPU memory size available, 1 if no GPU */ size_t *available_mem, cholmod_common *Common ) ; - + int cholmod_gpu_probe ( cholmod_common *Common ) ; int cholmod_l_gpu_probe ( cholmod_common *Common ) ; @@ -4689,3 +3976,4 @@ int cholmod_l_gpu_allocate ( cholmod_common *Common ) ; #endif #endif + diff --git a/CHOLMOD/Core/cholmod_aat.c b/CHOLMOD/Core/cholmod_aat.c deleted file mode 100644 index d1c21f760..000000000 --- a/CHOLMOD/Core/cholmod_aat.c +++ /dev/null @@ -1,298 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_aat: compute A*A' or A(:,f)*A(:,f)' -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* C = A*A' or C = A(:,f)*A(:,f)' - * - * A can be packed or unpacked, sorted or unsorted, but must be stored with - * both upper and lower parts (A->stype of zero). C is returned as packed, - * C->stype of zero (both upper and lower parts present), and unsorted. See - * cholmod_ssmult in the MatrixOps Module for a more general matrix-matrix - * multiply. - * - * You can trivially convert C into a symmetric upper/lower matrix by - * changing C->stype = 1 or -1 after calling this routine. - * - * workspace: - * Flag (A->nrow), - * Iwork (max (A->nrow, A->ncol)) if fset present, - * Iwork (A->nrow) if no fset, - * W (A->nrow) if mode > 0, - * allocates temporary copy for A'. - * - * A can be pattern or real. Complex or zomplex cases are supported only - * if the mode is <= 0 (in which case the numerical values are ignored). - */ - -#include "cholmod_internal.h" - -cholmod_sparse *CHOLMOD(aat) -( - /* ---- input ---- */ - cholmod_sparse *A, /* input matrix; C=A*A' is constructed */ - Int *fset, /* subset of 0:(A->ncol)-1 */ - size_t fsize, /* size of fset */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) - * -2: pattern only, no diagonal, add 50% + n extra - * space to C */ - /* --------------- */ - cholmod_common *Common -) -{ - double fjt ; - double *Ax, *Fx, *Cx, *W ; - Int *Ap, *Anz, *Ai, *Fp, *Fi, *Cp, *Ci, *Flag ; - cholmod_sparse *C, *F ; - Int packed, j, i, pa, paend, pf, pfend, n, mark, cnz, t, p, values, diag, - extra ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - RETURN_IF_NULL (A, NULL) ; - values = (mode > 0) && (A->xtype != CHOLMOD_PATTERN) ; - RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, - values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; - if (A->stype) - { - ERROR (CHOLMOD_INVALID, "matrix cannot be symmetric") ; - return (NULL) ; - } - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* allocate workspace */ - /* ---------------------------------------------------------------------- */ - - diag = (mode >= 0) ; - n = A->nrow ; - CHOLMOD(allocate_work) (n, MAX (A->ncol, A->nrow), values ? n : 0, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n : 0, Common)) ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - ASSERT (CHOLMOD(dump_sparse) (A, "A", Common) >= 0) ; - - /* get the A matrix */ - Ap = A->p ; - Anz = A->nz ; - Ai = A->i ; - Ax = A->x ; - packed = A->packed ; - - /* get workspace */ - W = Common->Xwork ; /* size n, unused if values is FALSE */ - Flag = Common->Flag ; /* size n, Flag [0..n-1] < mark on input*/ - - /* ---------------------------------------------------------------------- */ - /* F = A' or A(:,f)' */ - /* ---------------------------------------------------------------------- */ - - /* workspace: Iwork (nrow if no fset; MAX (nrow,ncol) if fset)*/ - F = CHOLMOD(ptranspose) (A, values, NULL, fset, fsize, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - - Fp = F->p ; - Fi = F->i ; - Fx = F->x ; - - /* ---------------------------------------------------------------------- */ - /* count the number of entries in the result C */ - /* ---------------------------------------------------------------------- */ - - cnz = 0 ; - for (j = 0 ; j < n ; j++) - { - /* clear the Flag array */ - /* mark = CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; - mark = Common->mark ; - - /* exclude the diagonal, if requested */ - if (!diag) - { - Flag [j] = mark ; - } - - /* for each nonzero F(t,j) in column j, do: */ - pfend = Fp [j+1] ; - for (pf = Fp [j] ; pf < pfend ; pf++) - { - /* F(t,j) is nonzero */ - t = Fi [pf] ; - - /* add the nonzero pattern of A(:,t) to the pattern of C(:,j) */ - pa = Ap [t] ; - paend = (packed) ? (Ap [t+1]) : (pa + Anz [t]) ; - for ( ; pa < paend ; pa++) - { - i = Ai [pa] ; - if (Flag [i] != mark) - { - Flag [i] = mark ; - cnz++ ; - } - } - } - if (cnz < 0) - { - break ; /* integer overflow case */ - } - } - - extra = (mode == -2) ? (cnz/2 + n) : 0 ; - - mark = CHOLMOD(clear_flag) (Common) ; - - /* ---------------------------------------------------------------------- */ - /* check for integer overflow */ - /* ---------------------------------------------------------------------- */ - - if (cnz < 0 || (cnz + extra) < 0) - { - ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; - CHOLMOD(clear_flag) (Common) ; - CHOLMOD(free_sparse) (&F, Common) ; - return (NULL) ; /* problem too large */ - } - - /* ---------------------------------------------------------------------- */ - /* allocate C */ - /* ---------------------------------------------------------------------- */ - - C = CHOLMOD(allocate_sparse) (n, n, cnz + extra, FALSE, TRUE, 0, - values ? A->xtype : CHOLMOD_PATTERN, Common) ; - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free_sparse) (&F, Common) ; - return (NULL) ; /* out of memory */ - } - - Cp = C->p ; - Ci = C->i ; - Cx = C->x ; - - /* ---------------------------------------------------------------------- */ - /* C = A*A' */ - /* ---------------------------------------------------------------------- */ - - cnz = 0 ; - - if (values) - { - - /* pattern and values */ - for (j = 0 ; j < n ; j++) - { - /* clear the Flag array */ - mark = CHOLMOD(clear_flag) (Common) ; - - /* start column j of C */ - Cp [j] = cnz ; - - /* for each nonzero F(t,j) in column j, do: */ - pfend = Fp [j+1] ; - for (pf = Fp [j] ; pf < pfend ; pf++) - { - /* F(t,j) is nonzero */ - t = Fi [pf] ; - fjt = Fx [pf] ; - - /* add the nonzero pattern of A(:,t) to the pattern of C(:,j) - * and scatter the values into W */ - pa = Ap [t] ; - paend = (packed) ? (Ap [t+1]) : (pa + Anz [t]) ; - for ( ; pa < paend ; pa++) - { - i = Ai [pa] ; - if (Flag [i] != mark) - { - Flag [i] = mark ; - Ci [cnz++] = i ; - } - W [i] += Ax [pa] * fjt ; - } - } - - /* gather the values into C(:,j) */ - for (p = Cp [j] ; p < cnz ; p++) - { - i = Ci [p] ; - Cx [p] = W [i] ; - W [i] = 0 ; - } - } - - } - else - { - - /* pattern only */ - for (j = 0 ; j < n ; j++) - { - /* clear the Flag array */ - mark = CHOLMOD(clear_flag) (Common) ; - - /* exclude the diagonal, if requested */ - if (!diag) - { - Flag [j] = mark ; - } - - /* start column j of C */ - Cp [j] = cnz ; - - /* for each nonzero F(t,j) in column j, do: */ - pfend = Fp [j+1] ; - for (pf = Fp [j] ; pf < pfend ; pf++) - { - /* F(t,j) is nonzero */ - t = Fi [pf] ; - - /* add the nonzero pattern of A(:,t) to the pattern of C(:,j) */ - pa = Ap [t] ; - paend = (packed) ? (Ap [t+1]) : (pa + Anz [t]) ; - for ( ; pa < paend ; pa++) - { - i = Ai [pa] ; - if (Flag [i] != mark) - { - Flag [i] = mark ; - Ci [cnz++] = i ; - } - } - } - } - } - - Cp [n] = cnz ; - ASSERT (IMPLIES (mode != -2, MAX (1,cnz) == C->nzmax)) ; - - /* ---------------------------------------------------------------------- */ - /* clear workspace and free temporary matrices and return result */ - /* ---------------------------------------------------------------------- */ - - CHOLMOD(free_sparse) (&F, Common) ; - CHOLMOD(clear_flag) (Common) ; - ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n : 0, Common)) ; - DEBUG (i = CHOLMOD(dump_sparse) (C, "aat", Common)) ; - ASSERT (IMPLIES (mode < 0, i == 0)) ; - return (C) ; -} diff --git a/CHOLMOD/Core/cholmod_add.c b/CHOLMOD/Core/cholmod_add.c deleted file mode 100644 index 371b981e0..000000000 --- a/CHOLMOD/Core/cholmod_add.c +++ /dev/null @@ -1,278 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_add: compute alpha*A + beta*B -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* C = alpha*A + beta*B, or spones(A+B). Result is packed, with sorted or - * unsorted columns. This routine is much faster and takes less memory if C - * is allowed to have unsorted columns. - * - * If A and B are both symmetric (in upper form) then C is the same. Likewise, - * if A and B are both symmetric (in lower form) then C is the same. - * Otherwise, C is unsymmetric. A and B must have the same dimension. - * - * workspace: Flag (nrow), W (nrow) if values, Iwork (max (nrow,ncol)). - * allocates temporary copies for A and B if they are symmetric. - * allocates temporary copy of C if it is to be returned sorted. - * - * A and B can have an xtype of pattern or real. Complex or zomplex cases - * are supported only if the "values" input parameter is FALSE. - */ - -#include "cholmod_internal.h" - -cholmod_sparse *CHOLMOD(add) -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to add */ - cholmod_sparse *B, /* matrix to add */ - double alpha [2], /* scale factor for A */ - double beta [2], /* scale factor for B */ - int values, /* if TRUE compute the numerical values of C */ - int sorted, /* if TRUE, sort columns of C */ - /* --------------- */ - cholmod_common *Common -) -{ - double *Ax, *Bx, *Cx, *W ; - Int apacked, up, lo, nrow, ncol, bpacked, nzmax, pa, paend, pb, pbend, i, - j, p, mark, nz ; - Int *Ap, *Ai, *Anz, *Bp, *Bi, *Bnz, *Flag, *Cp, *Ci ; - cholmod_sparse *A2, *B2, *C ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - RETURN_IF_NULL (A, NULL) ; - RETURN_IF_NULL (B, NULL) ; - values = values && - (A->xtype != CHOLMOD_PATTERN) && (B->xtype != CHOLMOD_PATTERN) ; - RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, - values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; - RETURN_IF_XTYPE_INVALID (B, CHOLMOD_PATTERN, - values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; - if (A->nrow != B->nrow || A->ncol != B->ncol) - { - /* A and B must have the same dimensions */ - ERROR (CHOLMOD_INVALID, "A and B dimesions do not match") ; - return (NULL) ; - } - /* A and B must have the same numerical type if values is TRUE (both must - * be CHOLMOD_REAL, this is implicitly checked above) */ - - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* allocate workspace */ - /* ---------------------------------------------------------------------- */ - - nrow = A->nrow ; - ncol = A->ncol ; - CHOLMOD(allocate_work) (nrow, MAX (nrow,ncol), values ? nrow : 0, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - if (nrow <= 1) - { - /* C will be implicitly sorted, so no need to sort it here */ - sorted = FALSE ; - } - - /* convert A or B to unsymmetric, if necessary */ - A2 = NULL ; - B2 = NULL ; - - if (A->stype != B->stype) - { - if (A->stype) - { - /* workspace: Iwork (max (nrow,ncol)) */ - A2 = CHOLMOD(copy) (A, 0, values, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - A = A2 ; - } - if (B->stype) - { - /* workspace: Iwork (max (nrow,ncol)) */ - B2 = CHOLMOD(copy) (B, 0, values, Common) ; - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free_sparse) (&A2, Common) ; - return (NULL) ; /* out of memory */ - } - B = B2 ; - } - } - - /* get the A matrix */ - ASSERT (A->stype == B->stype) ; - up = (A->stype > 0) ; - lo = (A->stype < 0) ; - - Ap = A->p ; - Anz = A->nz ; - Ai = A->i ; - Ax = A->x ; - apacked = A->packed ; - - /* get the B matrix */ - Bp = B->p ; - Bnz = B->nz ; - Bi = B->i ; - Bx = B->x ; - bpacked = B->packed ; - - /* get workspace */ - W = Common->Xwork ; /* size nrow, used if values is TRUE */ - Flag = Common->Flag ; /* size nrow, Flag [0..nrow-1] < mark on input */ - - /* ---------------------------------------------------------------------- */ - /* allocate the result C */ - /* ---------------------------------------------------------------------- */ - - /* If integer overflow occurs, nzmax < 0 and the allocate fails properly - * (likewise in most other matrix manipulation routines). */ - - nzmax = CHOLMOD(nnz) (A, Common) + CHOLMOD(nnz) (B, Common) ; - - C = CHOLMOD(allocate_sparse) (nrow, ncol, nzmax, FALSE, TRUE, - SIGN (A->stype), values ? A->xtype : CHOLMOD_PATTERN, Common) ; - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free_sparse) (&A2, Common) ; - CHOLMOD(free_sparse) (&B2, Common) ; - return (NULL) ; /* out of memory */ - } - - Cp = C->p ; - Ci = C->i ; - Cx = C->x ; - - /* ---------------------------------------------------------------------- */ - /* compute C = alpha*A + beta*B */ - /* ---------------------------------------------------------------------- */ - - nz = 0 ; - for (j = 0 ; j < ncol ; j++) - { - Cp [j] = nz ; - - /* clear the Flag array */ - /* mark = CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; - mark = Common->mark ; - - /* scatter B into W */ - pb = Bp [j] ; - pbend = (bpacked) ? (Bp [j+1]) : (pb + Bnz [j]) ; - for (p = pb ; p < pbend ; p++) - { - i = Bi [p] ; - if ((up && i > j) || (lo && i < j)) - { - continue ; - } - Flag [i] = mark ; - if (values) - { - W [i] = beta [0] * Bx [p] ; - } - } - - /* add A and gather from W into C(:,j) */ - pa = Ap [j] ; - paend = (apacked) ? (Ap [j+1]) : (pa + Anz [j]) ; - for (p = pa ; p < paend ; p++) - { - i = Ai [p] ; - if ((up && i > j) || (lo && i < j)) - { - continue ; - } - Flag [i] = EMPTY ; - Ci [nz] = i ; - if (values) - { - Cx [nz] = W [i] + alpha [0] * Ax [p] ; - W [i] = 0 ; - } - nz++ ; - } - - /* gather remaining entries into C(:,j), using pattern of B */ - for (p = pb ; p < pbend ; p++) - { - i = Bi [p] ; - if ((up && i > j) || (lo && i < j)) - { - continue ; - } - if (Flag [i] == mark) - { - Ci [nz] = i ; - if (values) - { - Cx [nz] = W [i] ; - W [i] = 0 ; - } - nz++ ; - } - } - } - - Cp [ncol] = nz ; - - /* ---------------------------------------------------------------------- */ - /* reduce C in size and free temporary matrices */ - /* ---------------------------------------------------------------------- */ - - ASSERT (MAX (1,nz) <= C->nzmax) ; - CHOLMOD(reallocate_sparse) (nz, C, Common) ; - ASSERT (Common->status >= CHOLMOD_OK) ; - - /* clear the Flag array */ - mark = CHOLMOD(clear_flag) (Common) ; - - CHOLMOD(free_sparse) (&A2, Common) ; - CHOLMOD(free_sparse) (&B2, Common) ; - - /* ---------------------------------------------------------------------- */ - /* sort C, if requested */ - /* ---------------------------------------------------------------------- */ - - if (sorted) - { - /* workspace: Iwork (max (nrow,ncol)) */ - if (!CHOLMOD(sort) (C, Common)) - { - CHOLMOD(free_sparse) (&C, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - } - } - - /* ---------------------------------------------------------------------- */ - /* return result */ - /* ---------------------------------------------------------------------- */ - - ASSERT (CHOLMOD(dump_sparse) (C, "add", Common) >= 0) ; - return (C) ; -} diff --git a/CHOLMOD/Core/cholmod_band.c b/CHOLMOD/Core/cholmod_band.c deleted file mode 100644 index ebc5bc7c7..000000000 --- a/CHOLMOD/Core/cholmod_band.c +++ /dev/null @@ -1,370 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_band: extract entries within a band -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* C = tril (triu (A,k1), k2) - * - * C is a matrix consisting of the diagonals of A from k1 to k2. - * - * k=0 is the main diagonal of A, k=1 is the superdiagonal, k=-1 is the - * subdiagonal, and so on. If A is m-by-n, then: - * - * k1=-m C = tril (A,k2) - * k2=n C = triu (A,k1) - * k1=0 and k2=0 C = diag(A), except C is a matrix, not a vector - * - * Values of k1 and k2 less than -m are treated as -m, and values greater - * than n are treated as n. - * - * A can be of any symmetry (upper, lower, or unsymmetric); C is returned in - * the same form, and packed. If A->stype > 0, entries in the lower - * triangular part of A are ignored, and the opposite is true if - * A->stype < 0. If A has sorted columns, then so does C. - * C has the same size as A. - * - * If inplace is TRUE, then the matrix A is modified in place. - * Only packed matrices can be converted in place. - * - * C can be returned as a numerical valued matrix (if A has numerical values - * and mode > 0), as a pattern-only (mode == 0), or as a pattern-only but with - * the diagonal entries removed (mode < 0). - * - * workspace: none - * - * A can have an xtype of pattern or real. Complex and zomplex cases supported - * only if mode <= 0 (in which case the numerical values are ignored). - */ - -#include "cholmod_internal.h" - -static cholmod_sparse *band /* returns C, or NULL if failure */ -( - /* ---- input or in/out if inplace is TRUE --- */ - cholmod_sparse *A, - /* ---- input ---- */ - int64_t k1, /* ignore entries below the k1-st diagonal */ - int64_t k2, /* ignore entries above the k2-nd diagonal */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diagonal) */ - int inplace, /* if TRUE, then convert A in place */ - /* --------------- */ - cholmod_common *Common -) -{ - double *Ax, *Cx ; - Int packed, nz, j, p, pend, i, ncol, nrow, jlo, jhi, ilo, ihi, sorted, - values, diag ; - Int *Ap, *Anz, *Ai, *Cp, *Ci ; - cholmod_sparse *C ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - RETURN_IF_NULL (A, NULL) ; - values = (mode > 0) && (A->xtype != CHOLMOD_PATTERN) ; - RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, - values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; - packed = A->packed ; - diag = (mode >= 0) ; - if (inplace && !packed) - { - /* cannot operate on an unpacked matrix in place */ - ERROR (CHOLMOD_INVALID, "cannot operate on unpacked matrix in-place") ; - return (NULL) ; - } - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - - PRINT1 (("k1 %ld k2 %ld\n", k1, k2)) ; - Ap = A->p ; - Anz = A->nz ; - Ai = A->i ; - Ax = A->x ; - sorted = A->sorted ; - - - if (A->stype > 0) - { - /* ignore any entries in strictly lower triangular part of A */ - k1 = MAX (k1, 0) ; - } - if (A->stype < 0) - { - /* ignore any entries in strictly upper triangular part of A */ - k2 = MIN (k2, 0) ; - } - ncol = A->ncol ; - nrow = A->nrow ; - - /* ensure k1 and k2 are in the range -nrow to +ncol to - * avoid possible integer overflow if k1 and k2 are huge */ - k1 = MAX (-nrow, k1) ; - k1 = MIN (k1, ncol) ; - k2 = MAX (-nrow, k2) ; - k2 = MIN (k2, ncol) ; - - /* consider columns jlo to jhi. columns outside this range are empty */ - jlo = MAX (k1, 0) ; - jhi = MIN (k2+nrow, ncol) ; - - if (k1 > k2) - { - /* nothing to do */ - jlo = ncol ; - jhi = ncol ; - } - - /* ---------------------------------------------------------------------- */ - /* allocate C, or operate on A in place */ - /* ---------------------------------------------------------------------- */ - - if (inplace) - { - /* convert A in place */ - C = A ; - } - else - { - /* count the number of entries in the result C */ - nz = 0 ; - if (sorted) - { - for (j = jlo ; j < jhi ; j++) - { - ilo = j-k2 ; - ihi = j-k1 ; - p = Ap [j] ; - pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (i > ihi) - { - break ; - } - if (i >= ilo && (diag || i != j)) - { - nz++ ; - } - } - } - } - else - { - for (j = jlo ; j < jhi ; j++) - { - ilo = j-k2 ; - ihi = j-k1 ; - p = Ap [j] ; - pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (i >= ilo && i <= ihi && (diag || i != j)) - { - nz++ ; - } - } - } - } - /* allocate C; A will not be modified. C is sorted if A is sorted */ - C = CHOLMOD(allocate_sparse) (A->nrow, ncol, nz, sorted, TRUE, - A->stype, values ? A->xtype : CHOLMOD_PATTERN, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - } - - Cp = C->p ; - Ci = C->i ; - Cx = C->x ; - - /* ---------------------------------------------------------------------- */ - /* construct C */ - /* ---------------------------------------------------------------------- */ - - /* columns 0 to jlo-1 are empty */ - for (j = 0 ; j < jlo ; j++) - { - Cp [j] = 0 ; - } - - nz = 0 ; - if (sorted) - { - if (values) - { - /* pattern and values */ - ASSERT (diag) ; - for (j = jlo ; j < jhi ; j++) - { - ilo = j-k2 ; - ihi = j-k1 ; - p = Ap [j] ; - pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; - Cp [j] = nz ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (i > ihi) - { - break ; - } - if (i >= ilo) - { - Ci [nz] = i ; - Cx [nz] = Ax [p] ; - nz++ ; - } - } - } - } - else - { - /* pattern only, perhaps with no diagonal */ - for (j = jlo ; j < jhi ; j++) - { - ilo = j-k2 ; - ihi = j-k1 ; - p = Ap [j] ; - pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; - Cp [j] = nz ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (i > ihi) - { - break ; - } - if (i >= ilo && (diag || i != j)) - { - Ci [nz++] = i ; - } - } - } - } - } - else - { - if (values) - { - /* pattern and values */ - ASSERT (diag) ; - for (j = jlo ; j < jhi ; j++) - { - ilo = j-k2 ; - ihi = j-k1 ; - p = Ap [j] ; - pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; - Cp [j] = nz ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (i >= ilo && i <= ihi) - { - Ci [nz] = i ; - Cx [nz] = Ax [p] ; - nz++ ; - } - } - } - } - else - { - /* pattern only, perhaps with no diagonal */ - for (j = jlo ; j < jhi ; j++) - { - ilo = j-k2 ; - ihi = j-k1 ; - p = Ap [j] ; - pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; - Cp [j] = nz ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (i >= ilo && i <= ihi && (diag || i != j)) - { - Ci [nz++] = i ; - } - } - } - } - } - - /* columns jhi to ncol-1 are empty */ - for (j = jhi ; j <= ncol ; j++) - { - Cp [j] = nz ; - } - - /* ---------------------------------------------------------------------- */ - /* reduce A in size if done in place */ - /* ---------------------------------------------------------------------- */ - - if (inplace) - { - /* free the unused parts of A, and reduce A->i and A->x in size */ - ASSERT (MAX (1,nz) <= A->nzmax) ; - CHOLMOD(reallocate_sparse) (nz, A, Common) ; - ASSERT (Common->status >= CHOLMOD_OK) ; - } - - /* ---------------------------------------------------------------------- */ - /* return the result C */ - /* ---------------------------------------------------------------------- */ - - DEBUG (i = CHOLMOD(dump_sparse) (C, "band", Common)) ; - ASSERT (IMPLIES (mode < 0, i == 0)) ; - return (C) ; -} - - -/* ========================================================================== */ -/* === cholmod_band ========================================================= */ -/* ========================================================================== */ - -cholmod_sparse *CHOLMOD(band) -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to extract band matrix from */ - int64_t k1, /* ignore entries below the k1-st diagonal */ - int64_t k2, /* ignore entries above the k2-nd diagonal */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ - /* --------------- */ - cholmod_common *Common -) -{ - return (band (A, k1, k2, mode, FALSE, Common)) ; -} - - -/* ========================================================================== */ -/* === cholmod_band_inplace ================================================= */ -/* ========================================================================== */ - -int CHOLMOD(band_inplace) -( - /* ---- input ---- */ - int64_t k1, /* ignore entries below the k1-st diagonal */ - int64_t k2, /* ignore entries above the k2-nd diagonal */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ - /* ---- in/out --- */ - cholmod_sparse *A, /* matrix from which entries not in band are removed */ - /* --------------- */ - cholmod_common *Common -) -{ - return (band (A, k1, k2, mode, TRUE, Common) != NULL) ; -} diff --git a/CHOLMOD/Core/cholmod_change_factor.c b/CHOLMOD/Core/cholmod_change_factor.c deleted file mode 100644 index 223a71b24..000000000 --- a/CHOLMOD/Core/cholmod_change_factor.c +++ /dev/null @@ -1,1223 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_change_factor: change format of a Cholesky factorization -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* Change the numeric/symbolic, LL/LDL, simplicial/super, packed/unpacked, - * monotonic/non-monotonic status of a cholmod_factor object. - * - * There are four basic classes of factor types: - * - * (1) simplicial symbolic: Consists of two size-n arrays: the fill-reducing - * permutation (L->Perm) and the nonzero count for each column of L - * (L->ColCount). All other factor types also include this information. - * L->ColCount may be exact (obtained from the analysis routines), or - * it may be a guess. During factorization, and certainly after update/ - * downdate, the columns of L can have a different number of nonzeros. - * L->ColCount is used to allocate space. L->ColCount is exact for the - * supernodal factorizations. The nonzero pattern of L is not kept. - * - * (2) simplicial numeric: These represent L in a compressed column form. The - * variants of this type are: - * - * LDL': L is unit diagonal. Row indices in column j are located in - * L->i [L->p [j] ... L->p [j] + L->nz [j]], and corresponding numeric - * values are in the same locations in L->x. The total number of - * entries is the sum of L->nz [j]. The unit diagonal is not stored; - * D is stored on the diagonal of L instead. L->p may or may not be - * monotonic. The order of storage of the columns in L->i and L->x is - * given by a doubly-linked list (L->prev and L->next). L->p is of - * size n+1, but only the first n entries are used (it is used if L - * is converted to a sparse matrix via cholmod_factor_to_sparse). - * - * For the complex case, L->x is stored interleaved with real/imag - * parts, and is of size 2*lnz*sizeof(double). For the zomplex case, - * L->x is of size lnz*sizeof(double) and holds the real part; L->z - * is the same size and holds the imaginary part. - * - * LL': This is identical to the LDL' form, except that the non-unit - * diagonal of L is stored as the first entry in each column of L. - * - * (3) supernodal symbolic: A representation of the nonzero pattern of the - * supernodes for a supernodal factorization. There are L->nsuper - * supernodes. Columns L->super [k] to L->super [k+1]-1 are in the kth - * supernode. The row indices for the kth supernode are in - * L->s [L->pi [k] ... L->pi [k+1]-1]. The numerical values are not - * allocated (L->x), but when they are they will be located in - * L->x [L->px [k] ... L->px [k+1]-1], and the L->px array is defined - * in this factor type. - * - * For the complex case, L->x is stored interleaved with real/imag parts, - * and is of size 2*L->xsize*sizeof(double). The zomplex supernodal case - * is not supported, since it is not compatible with LAPACK and the BLAS. - * - * (4) supernodal numeric: Always an LL' factorization. L is non-unit - * diagonal. L->x contains the numerical values of the supernodes, as - * described above for the supernodal symbolic factor. - * For the complex case, L->x is stored interleaved, and is of size - * 2*L->xsize*sizeof(double). The zomplex supernodal case is not - * supported, since it is not compatible with LAPACK and the BLAS. - * - * FUTURE WORK: support a supernodal LDL' factor. - * - * - * In all cases, the row indices in each column (L->i for simplicial L and - * L->s for supernodal L) are kept sorted from low indices to high indices. - * This means the diagonal of L (or D for LDL' factors) is always kept as the - * first entry in each column. - * - * The cholmod_change_factor routine can do almost all possible conversions. - * It cannot do the following conversions: - * - * (1) Simplicial numeric types cannot be converted to a supernodal - * symbolic type. This would simultaneously deallocate the - * simplicial pattern and numeric values and reallocate uninitialized - * space for the supernodal pattern. This isn't useful for the user, - * and not needed by CHOLMOD's own routines either. - * - * (2) Only a symbolic factor (simplicial to supernodal) can be converted - * to a supernodal numeric factor. - * - * Some conversions are meant only to be used internally by other CHOLMOD - * routines, and should not be performed by the end user. They allocate space - * whose contents are undefined: - * - * (1) converting from simplicial symbolic to supernodal symbolic. - * (2) converting any factor to supernodal numeric. - * - * workspace: no conversion routine uses workspace in Common. No temporary - * workspace is allocated. - * - * Supports all xtypes, except that there is no supernodal zomplex L. - * - * The to_xtype parameter is used only when converting from symbolic to numeric - * or numeric to symbolic. It cannot be used to convert a numeric xtype (real, - * complex, or zomplex) to a different numeric xtype. For that conversion, - * use cholmod_factor_xtype instead. - */ - -#include "cholmod_internal.h" - -static void natural_list (cholmod_factor *L) ; - -/* ========================================================================== */ -/* === TEMPLATE ============================================================= */ -/* ========================================================================== */ - -#define REAL -#include "t_cholmod_change_factor.c" -#define COMPLEX -#include "t_cholmod_change_factor.c" -#define ZOMPLEX -#include "t_cholmod_change_factor.c" - - -/* ========================================================================== */ -/* === L_is_packed ========================================================== */ -/* ========================================================================== */ - -/* Return TRUE if the columns of L are packed, FALSE otherwise. For debugging - * only. */ - -#ifndef NDEBUG -static int L_is_packed (cholmod_factor *L, cholmod_common *Common) -{ - Int j ; - Int *Lnz = L->nz ; - Int *Lp = L->p ; - Int n = L->n ; - - if (L->xtype == CHOLMOD_PATTERN || L->is_super) - { - return (TRUE) ; - } - - if (Lnz == NULL || Lp == NULL) - { - return (TRUE) ; - } - - for (j = 0 ; j < n ; j++) - { - PRINT3 (("j: "ID" Lnz "ID" Lp[j+1] "ID" Lp[j] "ID"\n", j, Lnz [j], - Lp [j+1], Lp [j])) ; - if (Lnz [j] != (Lp [j+1] - Lp [j])) - { - PRINT2 (("L is not packed\n")) ; - return (FALSE) ; - } - } - return (TRUE) ; -} -#endif - - -/* ========================================================================== */ -/* === natural_list ========================================================= */ -/* ========================================================================== */ - -/* Create a naturally-ordered doubly-linked list of columns. */ - -static void natural_list (cholmod_factor *L) -{ - Int head, tail, n, j ; - Int *Lnext, *Lprev ; - Lnext = L->next ; - Lprev = L->prev ; - ASSERT (Lprev != NULL && Lnext != NULL) ; - n = L->n ; - head = n+1 ; - tail = n ; - Lnext [head] = 0 ; - Lprev [head] = EMPTY ; - Lnext [tail] = EMPTY ; - Lprev [tail] = n-1 ; - for (j = 0 ; j < n ; j++) - { - Lnext [j] = j+1 ; - Lprev [j] = j-1 ; - } - Lprev [0] = head ; - L->is_monotonic = TRUE ; -} - - -/* ========================================================================== */ -/* === allocate_simplicial_numeric ========================================== */ -/* ========================================================================== */ - -/* Allocate O(n) arrays for simplicial numeric factorization. Initializes - * the link lists only. Does not allocate the L->i, L->x, or L->z arrays. */ - -static int allocate_simplicial_numeric -( - cholmod_factor *L, - cholmod_common *Common -) -{ - Int n ; - Int *Lp, *Lnz, *Lprev, *Lnext ; - size_t n1, n2 ; - - PRINT1 (("Allocate simplicial\n")) ; - - ASSERT (L->xtype == CHOLMOD_PATTERN || L->is_super) ; - ASSERT (L->p == NULL) ; - ASSERT (L->nz == NULL) ; - ASSERT (L->prev == NULL) ; - ASSERT (L->next == NULL) ; - - n = L->n ; - - /* this cannot cause size_t overflow */ - n1 = ((size_t) n) + 1 ; - n2 = ((size_t) n) + 2 ; - - Lp = CHOLMOD(malloc) (n1, sizeof (Int), Common) ; - Lnz = CHOLMOD(malloc) (n, sizeof (Int), Common) ; - Lprev = CHOLMOD(malloc) (n2, sizeof (Int), Common) ; - Lnext = CHOLMOD(malloc) (n2, sizeof (Int), Common) ; - - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free) (n1, sizeof (Int), Lp, Common) ; - CHOLMOD(free) (n, sizeof (Int), Lnz, Common) ; - CHOLMOD(free) (n2, sizeof (Int), Lprev, Common) ; - CHOLMOD(free) (n2, sizeof (Int), Lnext, Common) ; - PRINT1 (("Allocate simplicial failed\n")) ; - return (FALSE) ; /* out of memory */ - } - - /* ============================================== commit the changes to L */ - - L->p = Lp ; - L->nz = Lnz ; - L->prev = Lprev ; - L->next = Lnext ; - /* initialize a doubly linked list for columns in natural order */ - natural_list (L) ; - PRINT1 (("Allocate simplicial done\n")) ; - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === simplicial_symbolic_to_super_symbolic ================================ */ -/* ========================================================================== */ - -/* Convert a simplicial symbolic factor supernodal symbolic factor. Does not - * initialize the new space. */ - -static int simplicial_symbolic_to_super_symbolic -( - cholmod_factor *L, - cholmod_common *Common -) -{ - Int nsuper, xsize, ssize ; - Int *Lsuper, *Lpi, *Lpx, *Ls ; - size_t nsuper1 ; - - ASSERT (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) ; - - xsize = L->xsize ; - ssize = L->ssize ; - nsuper = L->nsuper ; - nsuper1 = ((size_t) nsuper) + 1 ; - - PRINT1 (("simple sym to super sym: ssize "ID" xsize "ID" nsuper "ID"" - " status %d\n", ssize, xsize, nsuper, Common->status)) ; - - /* O(nsuper) arrays, where nsuper <= n */ - Lsuper = CHOLMOD(malloc) (nsuper1, sizeof (Int), Common) ; - Lpi = CHOLMOD(malloc) (nsuper1, sizeof (Int), Common) ; - Lpx = CHOLMOD(malloc) (nsuper1, sizeof (Int), Common) ; - - /* O(ssize) array, where ssize <= nnz(L), and usually much smaller */ - Ls = CHOLMOD(malloc) (ssize, sizeof (Int), Common) ; - - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free) (nsuper1, sizeof (Int), Lsuper, Common) ; - CHOLMOD(free) (nsuper1, sizeof (Int), Lpi, Common) ; - CHOLMOD(free) (nsuper1, sizeof (Int), Lpx, Common) ; - CHOLMOD(free) (ssize, sizeof (Int), Ls, Common) ; - return (FALSE) ; /* out of memory */ - } - - /* ============================================== commit the changes to L */ - - ASSERT (Lsuper != NULL && Lpi != NULL && Lpx != NULL && Ls != NULL) ; - - L->maxcsize = 0 ; - L->maxesize = 0 ; - - L->super = Lsuper ; - L->pi = Lpi ; - L->px = Lpx ; - L->s = Ls ; - Ls [0] = EMPTY ; /* supernodal pattern undefined */ - - L->is_super = TRUE ; - L->is_ll = TRUE ; /* supernodal LDL' not supported */ - L->xtype = CHOLMOD_PATTERN ; - L->dtype = DTYPE ; - L->minor = L->n ; - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === any_to_simplicial_symbolic =========================================== */ -/* ========================================================================== */ - -/* Convert any factor L to a simplicial symbolic factor, leaving only L->Perm - * and L->ColCount. Cannot fail. Any of the components of L (except Perm and - * ColCount) may already be free'd. */ - -static void any_to_simplicial_symbolic -( - cholmod_factor *L, - int to_ll, - cholmod_common *Common -) -{ - Int n, lnz, xs, ss, s, e ; - size_t n1, n2 ; - - /* ============================================== commit the changes to L */ - - n = L->n ; - lnz = L->nzmax ; - s = L->nsuper + 1 ; - xs = (L->is_super) ? ((Int) (L->xsize)) : (lnz) ; - e = (L->xtype == CHOLMOD_COMPLEX ? 2 : 1) ; - ss = L->ssize ; - - /* this cannot cause size_t overflow */ - n1 = ((size_t) n) + 1 ; - n2 = ((size_t) n) + 2 ; - - /* free all but the symbolic analysis (Perm and ColCount) */ - L->p = CHOLMOD(free) (n1, sizeof (Int), L->p, Common) ; - L->i = CHOLMOD(free) (lnz, sizeof (Int), L->i, Common) ; - L->x = CHOLMOD(free) (xs, e*sizeof (double), L->x, Common) ; - L->z = CHOLMOD(free) (lnz, sizeof (double), L->z, Common) ; - L->nz = CHOLMOD(free) (n, sizeof (Int), L->nz, Common) ; - L->next = CHOLMOD(free) (n2, sizeof (Int), L->next, Common) ; - L->prev = CHOLMOD(free) (n2, sizeof (Int), L->prev, Common) ; - L->super = CHOLMOD(free) (s, sizeof (Int), L->super, Common) ; - L->pi = CHOLMOD(free) (s, sizeof (Int), L->pi, Common) ; - L->px = CHOLMOD(free) (s, sizeof (Int), L->px, Common) ; - L->s = CHOLMOD(free) (ss, sizeof (Int), L->s, Common) ; - L->nzmax = 0 ; - L->is_super = FALSE ; - L->xtype = CHOLMOD_PATTERN ; - L->dtype = DTYPE ; - L->minor = n ; - L->is_ll = to_ll ; -} - - -/* ========================================================================== */ -/* === ll_super_to_super_symbolic =========================================== */ -/* ========================================================================== */ - -/* Convert a numerical supernodal L to symbolic supernodal. Cannot fail. */ - -static void ll_super_to_super_symbolic -( - cholmod_factor *L, - cholmod_common *Common -) -{ - - /* ============================================== commit the changes to L */ - - /* free all but the supernodal numerical factor */ - ASSERT (L->xtype != CHOLMOD_PATTERN && L->is_super && L->is_ll) ; - DEBUG (CHOLMOD(dump_factor) (L, "start to super symbolic", Common)) ; - L->x = CHOLMOD(free) (L->xsize, - (L->xtype == CHOLMOD_COMPLEX ? 2 : 1) * sizeof (double), L->x, - Common) ; - L->xtype = CHOLMOD_PATTERN ; - L->dtype = DTYPE ; - L->minor = L->n ; - L->is_ll = TRUE ; /* supernodal LDL' not supported */ - DEBUG (CHOLMOD(dump_factor) (L, "done to super symbolic", Common)) ; -} - - -/* ========================================================================== */ -/* === simplicial_symbolic_to_simplicial_numeric ============================ */ -/* ========================================================================== */ - -/* Convert a simplicial symbolic L to a simplicial numeric L; allocate space - * for L using L->ColCount from symbolic analysis, and set L to identity. - * - * If packed < 0, then this routine is creating a copy of another factor - * (via cholmod_copy_factor). In this case, the space is not initialized. */ - -static void simplicial_symbolic_to_simplicial_numeric -( - cholmod_factor *L, - int to_ll, - int packed, - int to_xtype, - cholmod_common *Common -) -{ - double grow0, grow1, xlen, xlnz ; - double *Lx, *Lz ; - Int *Li, *Lp, *Lnz, *ColCount ; - Int n, grow, grow2, p, j, lnz, len, ok, e ; - - ASSERT (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) ; - if (!allocate_simplicial_numeric (L, Common)) - { - PRINT1 (("out of memory, allocate simplicial numeric\n")) ; - return ; /* out of memory */ - } - ASSERT (L->ColCount != NULL && L->nz != NULL && L->p != NULL) ; - ASSERT (L->x == NULL && L->z == NULL && L->i == NULL) ; - - ColCount = L->ColCount ; - Lnz = L->nz ; - Lp = L->p ; - ok = TRUE ; - n = L->n ; - - if (packed < 0) - { - - /* ------------------------------------------------------------------ */ - /* used by cholmod_copy_factor to allocate a copy of a factor object */ - /* ------------------------------------------------------------------ */ - - lnz = L->nzmax ; - L->nzmax = 0 ; - - } - else if (packed) - { - - /* ------------------------------------------------------------------ */ - /* LDL' or LL' packed */ - /* ------------------------------------------------------------------ */ - - PRINT1 (("convert to packed LL' or LDL'\n")) ; - lnz = 0 ; - for (j = 0 ; ok && j < n ; j++) - { - /* ensure len is in the range 1 to n-j */ - len = ColCount [j] ; - len = MAX (1, len) ; - len = MIN (len, n-j) ; - lnz += len ; - ok = (lnz >= 0) ; - } - for (j = 0 ; j <= n ; j++) - { - Lp [j] = j ; - } - for (j = 0 ; j < n ; j++) - { - Lnz [j] = 1 ; - } - - } - else - { - - /* ------------------------------------------------------------------ */ - /* LDL' unpacked */ - /* ------------------------------------------------------------------ */ - - PRINT1 (("convert to unpacked\n")) ; - /* compute new lnzmax */ - /* if any parameter is NaN, grow is false */ - grow0 = Common->grow0 ; - grow1 = Common->grow1 ; - grow2 = Common->grow2 ; - grow0 = IS_NAN (grow0) ? 1 : grow0 ; - grow1 = IS_NAN (grow1) ? 1 : grow1 ; - /* fl.pt. compare, but no NaN's: */ - grow = (grow0 >= 1.0) && (grow1 >= 1.0) && (grow2 > 0) ; - PRINT1 (("init, grow1 %g grow2 "ID"\n", grow1, grow2)) ; - /* initialize Lp and Lnz for each column */ - lnz = 0 ; - for (j = 0 ; ok && j < n ; j++) - { - Lp [j] = lnz ; - Lnz [j] = 1 ; - - /* ensure len is in the range 1 to n-j */ - len = ColCount [j] ; - len = MAX (1, len) ; - len = MIN (len, n-j) ; - - /* compute len in double to avoid integer overflow */ - PRINT1 (("ColCount ["ID"] = "ID"\n", j, len)) ; - if (grow) - { - xlen = (double) len ; - xlen = grow1 * xlen + grow2 ; - xlen = MIN (xlen, n-j) ; - len = (Int) xlen ; - } - ASSERT (len >= 1 && len <= n-j) ; - lnz += len ; - ok = (lnz >= 0) ; - } - if (ok) - { - Lp [n] = lnz ; - if (grow) - { - /* add extra space */ - xlnz = (double) lnz ; - xlnz *= grow0 ; - xlnz = MIN (xlnz, (double) SIZE_MAX) ; - xlnz = MIN (xlnz, ((double) n * (double) n + (double) n) / 2) ; - lnz = (Int) xlnz ; - } - } - } - - lnz = MAX (1, lnz) ; - - if (!ok) - { - ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; - } - - /* allocate L->i, L->x, and L->z */ - PRINT1 (("resizing from zero size to lnz "ID"\n", lnz)) ; - ASSERT (L->nzmax == 0) ; - e = (to_xtype == CHOLMOD_COMPLEX ? 2 : 1) ; - if (!ok || !CHOLMOD(realloc_multiple) (lnz, 1, to_xtype, &(L->i), NULL, - &(L->x), &(L->z), &(L->nzmax), Common)) - { - L->p = CHOLMOD(free) (n+1, sizeof (Int), L->p, Common) ; - L->nz = CHOLMOD(free) (n, sizeof (Int), L->nz, Common) ; - L->prev = CHOLMOD(free) (n+2, sizeof (Int), L->prev, Common) ; - L->next = CHOLMOD(free) (n+2, sizeof (Int), L->next, Common) ; - L->i = CHOLMOD(free) (lnz, sizeof (Int), L->i, Common) ; - L->x = CHOLMOD(free) (lnz, e*sizeof (double), L->x, Common) ; - L->z = CHOLMOD(free) (lnz, sizeof (double), L->z, Common) ; - PRINT1 (("cannot realloc simplicial numeric\n")) ; - return ; /* out of memory */ - } - - /* ============================================== commit the changes to L */ - - /* initialize L to be the identity matrix */ - L->xtype = to_xtype ; - L->dtype = DTYPE ; - L->minor = n ; - - Li = L->i ; - Lx = L->x ; - Lz = L->z ; - -#if 0 - if (lnz == 1) - { - /* the user won't expect to access this entry, but some CHOLMOD - * routines may. Set it to zero so that valgrind doesn't complain. */ - switch (to_xtype) - { - case CHOLMOD_REAL: - Lx [0] = 0 ; - break ; - - case CHOLMOD_COMPLEX: - Lx [0] = 0 ; - Lx [1] = 0 ; - break ; - - case CHOLMOD_ZOMPLEX: - Lx [0] = 0 ; - Lz [0] = 0 ; - break ; - } - } -#endif - - if (packed >= 0) - { - /* create the unit diagonal for either the LL' or LDL' case */ - - switch (L->xtype) - { - case CHOLMOD_REAL: - for (j = 0 ; j < n ; j++) - { - ASSERT (Lp [j] < Lp [j+1]) ; - p = Lp [j] ; - Li [p] = j ; - Lx [p] = 1 ; - } - break ; - - case CHOLMOD_COMPLEX: - for (j = 0 ; j < n ; j++) - { - ASSERT (Lp [j] < Lp [j+1]) ; - p = Lp [j] ; - Li [p] = j ; - Lx [2*p ] = 1 ; - Lx [2*p+1] = 0 ; - } - break ; - - case CHOLMOD_ZOMPLEX: - for (j = 0 ; j < n ; j++) - { - ASSERT (Lp [j] < Lp [j+1]) ; - p = Lp [j] ; - Li [p] = j ; - Lx [p] = 1 ; - Lz [p] = 0 ; - } - break ; - } - } - - L->is_ll = to_ll ; - - PRINT1 (("done convert simplicial symbolic to numeric\n")) ; -} - - -/* ========================================================================== */ -/* === change_simplicial_numeric ============================================ */ -/* ========================================================================== */ - -/* Change LL' to LDL', LDL' to LL', or leave as-is. - * - * If to_packed is TRUE, then the columns of L are packed and made monotonic - * (to_monotonic is ignored; it is implicitly TRUE). - * - * If to_monotonic is TRUE but to_packed is FALSE, the columns of L are made - * monotonic but not packed. - * - * If both to_packed and to_monotonic are FALSE, then the columns of L are - * left as-is, and the conversion is done in place. - * - * If L is already monotonic, or if it is to be left non-monotonic, then this - * conversion always succeeds. - * - * When converting an LDL' to LL' factorization, any column with a negative - * or zero diagonal entry is not modified so that conversion back to LDL' will - * succeed. This can result in a matrix L with a negative entry on the diagonal - * If the kth entry on the diagonal of D is negative, it and the kth column of - * L are left unchanged. A subsequent conversion back to an LDL' form will also - * leave the column unchanged, so the correct LDL' factorization will be - * restored. L->minor is set to the smallest k for which D (k,k) is negative. - */ - -static void change_simplicial_numeric -( - cholmod_factor *L, - int to_ll, - int to_packed, - int to_monotonic, - cholmod_common *Common -) -{ - double grow0, grow1, xlen, xlnz ; - void *newLi, *newLx, *newLz ; - double *Lx, *Lz ; - Int *Lp, *Li, *Lnz ; - Int make_monotonic, grow2, n, j, lnz, len, grow, ok, make_ll, make_ldl ; - size_t nzmax0 ; - - PRINT1 (("\n===Change simplicial numeric: %d %d %d\n", - to_ll, to_packed, to_monotonic)) ; - DEBUG (CHOLMOD(dump_factor) (L, "change simplicial numeric", Common)) ; - ASSERT (L->xtype != CHOLMOD_PATTERN && !(L->is_super)) ; - - make_monotonic = ((to_packed || to_monotonic) && !(L->is_monotonic)) ; - make_ll = (to_ll && !(L->is_ll)) ; - make_ldl = (!to_ll && L->is_ll) ; - - n = L->n ; - Lp = L->p ; - Li = L->i ; - Lx = L->x ; - Lz = L->z ; - Lnz = L->nz ; - - grow = FALSE ; - grow0 = Common->grow0 ; - grow1 = Common->grow1 ; - grow2 = Common->grow2 ; - grow0 = IS_NAN (grow0) ? 1 : grow0 ; - grow1 = IS_NAN (grow1) ? 1 : grow1 ; - ok = TRUE ; - newLi = NULL ; - newLx = NULL ; - newLz = NULL ; - lnz = 0 ; - - if (make_monotonic) - { - - /* ------------------------------------------------------------------ */ - /* Columns out of order, but will be reordered and optionally packed. */ - /* ------------------------------------------------------------------ */ - - PRINT1 (("L is non-monotonic\n")) ; - - /* compute new L->nzmax */ - if (!to_packed) - { - /* if any parameter is NaN, grow is false */ - /* fl.pt. comparisons below are false if any parameter is NaN */ - grow = (grow0 >= 1.0) && (grow1 >= 1.0) && (grow2 > 0) ; - } - for (j = 0 ; ok && j < n ; j++) - { - len = Lnz [j] ; - ASSERT (len >= 1 && len <= n-j) ; - - /* compute len in double to avoid integer overflow */ - if (grow) - { - xlen = (double) len ; - xlen = grow1 * xlen + grow2 ; - xlen = MIN (xlen, n-j) ; - len = (Int) xlen ; - } - ASSERT (len >= Lnz [j] && len <= n-j) ; - - PRINT2 (("j: "ID" Lnz[j] "ID" len "ID" p "ID"\n", - j, Lnz [j], len, lnz)) ; - - lnz += len ; - ok = (lnz >= 0) ; - } - - if (!ok) - { - ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; - return ; - } - - if (grow) - { - xlnz = (double) lnz ; - xlnz *= grow0 ; - xlnz = MIN (xlnz, (double) SIZE_MAX) ; - xlnz = MIN (xlnz, ((double) n * (double) n + (double) n) / 2) ; - lnz = (Int) xlnz ; - } - - lnz = MAX (1, lnz) ; - PRINT1 (("final lnz "ID"\n", lnz)) ; - nzmax0 = 0 ; - - CHOLMOD(realloc_multiple) (lnz, 1, L->xtype, &newLi, NULL, - &newLx, &newLz, &nzmax0, Common) ; - - if (Common->status < CHOLMOD_OK) - { - return ; /* out of memory */ - } - } - - /* ============================================== commit the changes to L */ - - /* ---------------------------------------------------------------------- */ - /* convert the simplicial L, using template routine */ - /* ---------------------------------------------------------------------- */ - - switch (L->xtype) - { - - case CHOLMOD_REAL: - r_change_simplicial_numeric (L, to_ll, to_packed, - newLi, newLx, newLz, lnz, grow, grow1, grow2, - make_ll, make_monotonic, make_ldl, Common) ; - break ; - - case CHOLMOD_COMPLEX: - c_change_simplicial_numeric (L, to_ll, to_packed, - newLi, newLx, newLz, lnz, grow, grow1, grow2, - make_ll, make_monotonic, make_ldl, Common) ; - break ; - - case CHOLMOD_ZOMPLEX: - z_change_simplicial_numeric (L, to_ll, to_packed, - newLi, newLx, newLz, lnz, grow, grow1, grow2, - make_ll, make_monotonic, make_ldl, Common) ; - break ; - } - - DEBUG (CHOLMOD(dump_factor) (L, "L simplicial changed", Common)) ; -} - - -/* ========================================================================== */ -/* === ll_super_to_simplicial_numeric ======================================= */ -/* ========================================================================== */ - -/* Convert a supernodal numeric factorization to any simplicial numeric one. - * Leaves L->xtype unchanged (real or complex, not zomplex since there is - * no supernodal zomplex L). */ - -static void ll_super_to_simplicial_numeric -( - cholmod_factor *L, - int to_packed, - int to_ll, - cholmod_common *Common -) -{ - Int *Ls, *Lpi, *Lpx, *Super, *Li ; - Int n, lnz, s, nsuper, psi, psend, nsrow, nscol, k1, k2, erows ; - - DEBUG (CHOLMOD(dump_factor) (L, "start LL super to simplicial", Common)) ; - PRINT1 (("super -> simplicial (%d %d)\n", to_packed, to_ll)) ; - ASSERT (L->xtype != CHOLMOD_PATTERN && L->is_ll && L->is_super) ; - ASSERT (L->x != NULL && L->i == NULL) ; - - n = L->n ; - nsuper = L->nsuper ; - Lpi = L->pi ; - Lpx = L->px ; - Ls = L->s ; - Super = L->super ; - - /* Int overflow cannot occur since supernodal L already exists */ - - if (to_packed) - { - /* count the number of nonzeros in L. Each supernode is of the form - * - * l . . . For this example, nscol = 4 (# columns). nsrow = 9. - * l l . . The "." entries are allocated in the supernodal - * l l l . factor, but not used. They are not copied to the - * l l l l simplicial factor. Some "l" and "e" entries may be - * e e e e numerically zero and even symbolically zero if a - * e e e e tight simplicial factorization or resymbol were - * e e e e done, because of numerical cancellation and relaxed - * e e e e supernode amalgamation, respectively. - * e e e e - */ - lnz = 0 ; - for (s = 0 ; s < nsuper ; s++) - { - k1 = Super [s] ; - k2 = Super [s+1] ; - psi = Lpi [s] ; - psend = Lpi [s+1] ; - nsrow = psend - psi ; - nscol = k2 - k1 ; - ASSERT (nsrow >= nscol) ; - erows = nsrow - nscol ; - - /* lower triangular part, including the diagonal, - * counting the "l" terms in the figure above. */ - lnz += nscol * (nscol+1) / 2 ; - - /* rectangular part, below the diagonal block (the "e" terms) */ - lnz += nscol * erows ; - } - ASSERT (lnz <= (Int) (L->xsize)) ; - } - else - { - /* Li will be the same size as Lx */ - lnz = L->xsize ; - } - ASSERT (lnz >= 0) ; - PRINT1 (("simplicial lnz = "ID" to_packed: %d to_ll: %d L->xsize %g\n", - lnz, to_ll, to_packed, (double) L->xsize)) ; - - Li = CHOLMOD(malloc) (lnz, sizeof (Int), Common) ; - if (Common->status < CHOLMOD_OK) - { - return ; /* out of memory */ - } - - if (!allocate_simplicial_numeric (L, Common)) - { - CHOLMOD(free) (lnz, sizeof (Int), Li, Common) ; - return ; /* out of memory */ - } - - /* ============================================== commit the changes to L */ - - L->i = Li ; - L->nzmax = lnz ; - - /* ---------------------------------------------------------------------- */ - /* convert the supernodal L, using template routine */ - /* ---------------------------------------------------------------------- */ - - switch (L->xtype) - { - - case CHOLMOD_REAL: - r_ll_super_to_simplicial_numeric (L, to_packed, to_ll, Common) ; - break ; - - case CHOLMOD_COMPLEX: - c_ll_super_to_simplicial_numeric (L, to_packed, to_ll, Common) ; - break ; - } - - /* ---------------------------------------------------------------------- */ - /* free unused parts of L */ - /* ---------------------------------------------------------------------- */ - - L->super = CHOLMOD(free) (nsuper+1, sizeof (Int), L->super, Common) ; - L->pi = CHOLMOD(free) (nsuper+1, sizeof (Int), L->pi, Common) ; - L->px = CHOLMOD(free) (nsuper+1, sizeof (Int), L->px, Common) ; - L->s = CHOLMOD(free) (L->ssize, sizeof (Int), L->s, Common) ; - - L->ssize = 0 ; - L->xsize = 0 ; - L->nsuper = 0 ; - L->maxesize = 0 ; - L->maxcsize = 0 ; - - L->is_super = FALSE ; - - DEBUG (CHOLMOD(dump_factor) (L, "done LL super to simplicial", Common)) ; -} - - -/* ========================================================================== */ -/* === super_symbolic_to_ll_super =========================================== */ -/* ========================================================================== */ - -/* Convert a supernodal symbolic factorization to a supernodal numeric - * factorization by allocating L->x. Contents of L->x are undefined. - */ - -static int super_symbolic_to_ll_super -( - int to_xtype, - cholmod_factor *L, - cholmod_common *Common -) -{ - double *Lx ; - Int wentry = (to_xtype == CHOLMOD_REAL) ? 1 : 2 ; - PRINT1 (("convert super sym to num\n")) ; - ASSERT (L->xtype == CHOLMOD_PATTERN && L->is_super) ; - Lx = CHOLMOD(malloc) (L->xsize, wentry * sizeof (double), Common) ; - PRINT1 (("xsize %g\n", (double) L->xsize)) ; - if (Common->status < CHOLMOD_OK) - { - return (FALSE) ; /* out of memory */ - } - - /* ============================================== commit the changes to L */ - - if (L->xsize == 1) - { - /* the caller won't expect to access this entry, but some CHOLMOD - * routines may. Set it to zero so that valgrind doesn't complain. */ - switch (to_xtype) - { - case CHOLMOD_REAL: - Lx [0] = 0 ; - break ; - - case CHOLMOD_COMPLEX: - Lx [0] = 0 ; - Lx [1] = 0 ; - break ; - } - } - - L->x = Lx ; - L->xtype = to_xtype ; - L->dtype = DTYPE ; - L->minor = L->n ; - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === cholmod_change_factor ================================================ */ -/* ========================================================================== */ - -/* Convert a factor L. Some conversions simply allocate uninitialized space - * that meant to be filled later. - * - * If the conversion fails, the factor is left in its original form, with one - * exception. Converting a supernodal symbolic factor to a simplicial numeric - * one (with L=D=I) may leave the factor in simplicial symbolic form. - * - * Memory allocated for each conversion is listed below. - */ - -int CHOLMOD(change_factor) -( - /* ---- input ---- */ - int to_xtype, /* convert to CHOLMOD_PATTERN, _REAL, _COMPLEX, or - * _ZOMPLEX */ - int to_ll, /* TRUE: convert to LL', FALSE: LDL' */ - int to_super, /* TRUE: convert to supernodal, FALSE: simplicial */ - int to_packed, /* TRUE: pack simplicial columns, FALSE: do not pack */ - int to_monotonic, /* TRUE: put simplicial columns in order, FALSE: not */ - /* ---- in/out --- */ - cholmod_factor *L, /* factor to modify */ - /* --------------- */ - cholmod_common *Common -) -{ - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (FALSE) ; - RETURN_IF_NULL (L, FALSE) ; - RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; - if (to_xtype < CHOLMOD_PATTERN || to_xtype > CHOLMOD_ZOMPLEX) - { - ERROR (CHOLMOD_INVALID, "xtype invalid") ; - return (FALSE) ; - } - Common->status = CHOLMOD_OK ; - - PRINT1 (("-----convert from (%d,%d,%d,%d,%d) to (%d,%d,%d,%d,%d)\n", - L->xtype, L->is_ll, L->is_super, L_is_packed (L, Common), L->is_monotonic, - to_xtype, to_ll, to_super, to_packed, to_monotonic)) ; - - /* ensure all parameters are TRUE/FALSE */ - to_ll = BOOLEAN (to_ll) ; - to_super = BOOLEAN (to_super) ; - - ASSERT (BOOLEAN (L->is_ll) == L->is_ll) ; - ASSERT (BOOLEAN (L->is_super) == L->is_super) ; - - if (to_super && to_xtype == CHOLMOD_ZOMPLEX) - { - ERROR (CHOLMOD_INVALID, "supernodal zomplex L not supported") ; - return (FALSE) ; - } - - /* ---------------------------------------------------------------------- */ - /* convert */ - /* ---------------------------------------------------------------------- */ - - if (to_xtype == CHOLMOD_PATTERN) - { - - /* ------------------------------------------------------------------ */ - /* convert to symbolic */ - /* ------------------------------------------------------------------ */ - - if (!to_super) - { - - /* -------------------------------------------------------------- */ - /* convert any factor into a simplicial symbolic factor */ - /* -------------------------------------------------------------- */ - - any_to_simplicial_symbolic (L, to_ll, Common) ; /* cannot fail */ - - } - else - { - - /* -------------------------------------------------------------- */ - /* convert to a supernodal symbolic factor */ - /* -------------------------------------------------------------- */ - - if (L->xtype != CHOLMOD_PATTERN && L->is_super) - { - /* convert from supernodal numeric to supernodal symbolic. - * this preserves symbolic pattern of L, discards numeric - * values */ - ll_super_to_super_symbolic (L, Common) ; /* cannot fail */ - } - else if (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) - { - /* convert from simplicial symbolic to supernodal symbolic. - * contents of supernodal pattern are uninitialized. Not meant - * for the end user. */ - simplicial_symbolic_to_super_symbolic (L, Common) ; - } - else - { - /* cannot convert from simplicial numeric to supernodal - * symbolic */ - ERROR (CHOLMOD_INVALID, - "cannot convert L to supernodal symbolic") ; - } - } - - } - else - { - - /* ------------------------------------------------------------------ */ - /* convert to numeric */ - /* ------------------------------------------------------------------ */ - - if (to_super) - { - - /* -------------------------------------------------------------- */ - /* convert to supernodal numeric factor */ - /* -------------------------------------------------------------- */ - - if (L->xtype == CHOLMOD_PATTERN) - { - if (L->is_super) - { - /* Convert supernodal symbolic to supernodal numeric. - * Contents of supernodal numeric values are uninitialized. - * This is used by cholmod_super_numeric. Not meant for - * the end user. */ - super_symbolic_to_ll_super (to_xtype, L, Common) ; - } - else - { - /* Convert simplicial symbolic to supernodal numeric. - * Contents not defined. This is used by - * Core/cholmod_copy_factor only. Not meant for the end - * user. */ - if (!simplicial_symbolic_to_super_symbolic (L, Common)) - { - /* failure, convert back to simplicial symbolic */ - any_to_simplicial_symbolic (L, to_ll, Common) ; - } - else - { - /* conversion to super symbolic OK, allocate numeric - * part */ - super_symbolic_to_ll_super (to_xtype, L, Common) ; - } - } - } - else - { - /* nothing to do if L is already in supernodal numeric form */ - if (!(L->is_super)) - { - ERROR (CHOLMOD_INVALID, - "cannot convert simplicial L to supernodal") ; - } - /* FUTURE WORK: convert to/from supernodal LL' and LDL' */ - } - - } - else - { - - /* -------------------------------------------------------------- */ - /* convert any factor to simplicial numeric */ - /* -------------------------------------------------------------- */ - - if (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) - { - - /* ---------------------------------------------------------- */ - /* convert simplicial symbolic to simplicial numeric (L=I,D=I)*/ - /* ---------------------------------------------------------- */ - - simplicial_symbolic_to_simplicial_numeric (L, to_ll, to_packed, - to_xtype, Common) ; - - } - else if (L->xtype != CHOLMOD_PATTERN && L->is_super) - { - - /* ---------------------------------------------------------- */ - /* convert a supernodal LL' to simplicial numeric */ - /* ---------------------------------------------------------- */ - - ll_super_to_simplicial_numeric (L, to_packed, to_ll, Common) ; - - } - else if (L->xtype == CHOLMOD_PATTERN && L->is_super) - { - - /* ---------------------------------------------------------- */ - /* convert a supernodal symbolic to simplicial numeric (L=D=I)*/ - /* ---------------------------------------------------------- */ - - any_to_simplicial_symbolic (L, to_ll, Common) ; - /* if the following fails, it leaves the factor in simplicial - * symbolic form */ - simplicial_symbolic_to_simplicial_numeric (L, to_ll, to_packed, - to_xtype, Common) ; - - } - else - { - - /* ---------------------------------------------------------- */ - /* change a simplicial numeric factor */ - /* ---------------------------------------------------------- */ - - /* change LL' to LDL', LDL' to LL', or leave as-is. pack the - * columns of L, or leave as-is. Ensure the columns are - * monotonic, or leave as-is. */ - - change_simplicial_numeric (L, to_ll, to_packed, to_monotonic, - Common) ; - } - } - } - - /* ---------------------------------------------------------------------- */ - /* return result */ - /* ---------------------------------------------------------------------- */ - - return (Common->status >= CHOLMOD_OK) ; -} diff --git a/CHOLMOD/Core/cholmod_common.c b/CHOLMOD/Core/cholmod_common.c deleted file mode 100644 index 7bf3c3ccb..000000000 --- a/CHOLMOD/Core/cholmod_common.c +++ /dev/null @@ -1,755 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_common: core methods for cholmod_common object -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* Core utility routines for the cholmod_common object: - * - * Primary routines: - * ----------------- - * cholmod_start the first call to CHOLMOD - * cholmod_finish the last call to CHOLMOD - * - * Secondary routines: - * ------------------- - * cholmod_defaults restore (most) default control parameters - * cholmod_allocate_work allocate (or reallocate) workspace in Common - * cholmod_free_work free workspace in Common - * cholmod_clear_flag clear Common->Flag in workspace - * cholmod_maxrank column dimension of Common->Xwork workspace - * - * The Common object is unique. It cannot be allocated or deallocated by - * CHOLMOD, since it contains the definition of the memory management routines - * used (pointers to malloc, free, realloc, and calloc, or their equivalent). - * The Common object contains workspace that is used between calls to - * CHOLMOD routines. This workspace allocated by CHOLMOD as needed, by - * cholmod_allocate_work and cholmod_free_work. - */ - -#include "cholmod_internal.h" - -/* ========================================================================== */ -/* === cholmod_start ======================================================== */ -/* ========================================================================== */ - -/* Initialize Common default parameters and statistics. Sets workspace - * pointers to NULL. - * - * This routine must be called just once, prior to calling any other CHOLMOD - * routine. Do not call this routine after any other CHOLMOD routine (except - * cholmod_finish, to start a new CHOLMOD session), or a memory leak will - * occur. - * - * workspace: none - */ - -int CHOLMOD(start) -( - cholmod_common *Common -) -{ - int k ; - - if (Common == NULL) - { - return (FALSE) ; - } - - /* ---------------------------------------------------------------------- */ - /* user error handling routine */ - /* ---------------------------------------------------------------------- */ - - Common->error_handler = NULL ; - - /* ---------------------------------------------------------------------- */ - /* integer and numerical types */ - /* ---------------------------------------------------------------------- */ - - Common->itype = ITYPE ; - Common->dtype = DTYPE ; - - /* ---------------------------------------------------------------------- */ - /* default control parameters */ - /* ---------------------------------------------------------------------- */ - - CHOLMOD(defaults) (Common) ; - Common->try_catch = FALSE ; - - /* ---------------------------------------------------------------------- */ - /* memory management routines */ - /* ---------------------------------------------------------------------- */ - - /* moved to SuiteSparse_config */ - - /* ---------------------------------------------------------------------- */ - /* complex arithmetic routines */ - /* ---------------------------------------------------------------------- */ - - /* moved to SuiteSparse_config */ - - /* ---------------------------------------------------------------------- */ - /* print routine */ - /* ---------------------------------------------------------------------- */ - - /* moved to SuiteSparse_config */ - - /* ---------------------------------------------------------------------- */ - /* workspace */ - /* ---------------------------------------------------------------------- */ - - /* This code assumes the workspace held in Common is not initialized. If - * it is, then a memory leak will occur because the pointers are - * overwritten with NULL. */ - - Common->nrow = 0 ; - Common->mark = EMPTY ; - Common->xworksize = 0 ; - Common->iworksize = 0 ; - Common->Flag = NULL ; - Common->Head = NULL ; - Common->Iwork = NULL ; - Common->Xwork = NULL ; - Common->no_workspace_reallocate = FALSE ; - - /* ---------------------------------------------------------------------- */ - /* statistics */ - /* ---------------------------------------------------------------------- */ - - /* fl and lnz are computed in cholmod_analyze and cholmod_rowcolcounts */ - Common->fl = EMPTY ; - Common->lnz = EMPTY ; - - /* modfl is computed in cholmod_updown, cholmod_rowadd, and cholmod_rowdel*/ - Common->modfl = EMPTY ; - - /* all routines use status as their error-report code */ - Common->status = CHOLMOD_OK ; - - Common->malloc_count = 0 ; /* # calls to malloc minus # calls to free */ - Common->memory_usage = 0 ; /* peak memory usage (in bytes) */ - Common->memory_inuse = 0 ; /* current memory in use (in bytes) */ - - Common->nrealloc_col = 0 ; - Common->nrealloc_factor = 0 ; - Common->ndbounds_hit = 0 ; - Common->rowfacfl = 0 ; - Common->aatfl = EMPTY ; - - /* Common->called_nd is TRUE if cholmod_analyze called or NESDIS */ - Common->called_nd = FALSE ; - - Common->blas_ok = TRUE ; /* false if SUITESPARSE_BLAS_INT overflows */ - - /* ---------------------------------------------------------------------- */ - /* default SuiteSparseQR knobs and statististics */ - /* ---------------------------------------------------------------------- */ - - for (k = 0 ; k < 10 ; k++) Common->SPQR_istat [k] = 0 ; - - Common->SPQR_flopcount_bound = 0 ; /* upper bound on flop count */ - Common->SPQR_tol_used = 0 ; /* tolerance used */ - Common->SPQR_norm_E_fro = 0 ; /* Frobenius norm of dropped entries */ - - Common->SPQR_grain = 1 ; /* no Intel TBB multitasking, by default */ - Common->SPQR_small = 1e6 ; /* target min task size for TBB */ - Common->SPQR_shrink = 1 ; /* controls SPQR shrink realloc */ - Common->SPQR_nthreads = 0 ; /* 0: let TBB decide how many threads to use */ - - Common->SPQR_flopcount = 0 ; /* flop count for SPQR */ - Common->SPQR_analyze_time = 0 ; /* analysis time for SPQR */ - Common->SPQR_factorize_time = 0 ; /* factorize time for SPQR */ - Common->SPQR_solve_time = 0 ; /* backsolve time for SPQR */ - - /* ---------------------------------------------------------------------- */ - /* GPU initializations */ - /* ---------------------------------------------------------------------- */ - - /* these are destroyed by cholmod_gpu_deallocate and cholmod_gpu_end */ - Common->cublasHandle = NULL ; - Common->cublasEventPotrf [0] = NULL ; - Common->cublasEventPotrf [1] = NULL ; - Common->cublasEventPotrf [2] = NULL ; - for (k = 0 ; k < CHOLMOD_HOST_SUPERNODE_BUFFERS ; k++) - { - Common->gpuStream [k] = NULL ; - Common->updateCBuffersFree [k] = NULL ; - } - Common->updateCKernelsComplete = NULL; - - /* these are destroyed by cholmod_gpu_deallocate */ - Common->dev_mempool = NULL; - Common->dev_mempool_size = 0; - Common->host_pinned_mempool = NULL; - Common->host_pinned_mempool_size = 0; - - Common->syrkStart = 0 ; - - Common->cholmod_cpu_gemm_time = 0 ; - Common->cholmod_cpu_syrk_time = 0 ; - Common->cholmod_cpu_trsm_time = 0 ; - Common->cholmod_cpu_potrf_time = 0 ; - Common->cholmod_gpu_gemm_time = 0 ; - Common->cholmod_gpu_syrk_time = 0 ; - Common->cholmod_gpu_trsm_time = 0 ; - Common->cholmod_gpu_potrf_time = 0 ; - Common->cholmod_assemble_time = 0 ; - Common->cholmod_assemble_time2 = 0 ; - - Common->cholmod_cpu_gemm_calls = 0 ; - Common->cholmod_cpu_syrk_calls = 0 ; - Common->cholmod_cpu_trsm_calls = 0 ; - Common->cholmod_cpu_potrf_calls = 0 ; - - Common->cholmod_gpu_gemm_calls = 0 ; - Common->cholmod_gpu_syrk_calls = 0 ; - Common->cholmod_gpu_trsm_calls = 0 ; - Common->cholmod_gpu_potrf_calls = 0 ; - - Common->maxGpuMemBytes = 0; - Common->maxGpuMemFraction = 0.0; - - /* SPQR statistics and settings */ - Common->gpuMemorySize = 1 ; /* default: no GPU memory available */ - Common->gpuKernelTime = 0.0 ; - Common->gpuFlops = 0 ; - Common->gpuNumKernelLaunches = 0 ; - - // ------------------------------------------------------------------------- - // OpenMP initializations - // ------------------------------------------------------------------------- - - Common->chunk = 128000 ; - Common->nthreads_max = SUITESPARSE_OPENMP_MAX_THREADS ; - - // ------------------------------------------------------------------------- - // return result - // ------------------------------------------------------------------------- - - DEBUG_INIT ("cholmod start", Common) ; - - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === cholmod_defaults ===================================================== */ -/* ========================================================================== */ - -/* Set Common default parameters, except for the function pointers. - * - * workspace: none - */ - -int CHOLMOD(defaults) -( - cholmod_common *Common -) -{ - Int i ; - - RETURN_IF_NULL_COMMON (FALSE) ; - - /* ---------------------------------------------------------------------- */ - /* default control parameters */ - /* ---------------------------------------------------------------------- */ - - Common->dbound = 0.0 ; - Common->grow0 = 1.2 ; - Common->grow1 = 1.2 ; - Common->grow2 = 5 ; - Common->maxrank = 8 ; - - Common->final_asis = TRUE ; - Common->final_super = TRUE ; - Common->final_ll = FALSE ; - Common->final_pack = TRUE ; - Common->final_monotonic = TRUE ; - Common->final_resymbol = FALSE ; - - /* use simplicial factorization if flop/nnz(L) < 40, supernodal otherwise */ - Common->supernodal = CHOLMOD_AUTO ; - Common->supernodal_switch = 40 ; - - Common->nrelax [0] = 4 ; - Common->nrelax [1] = 16 ; - Common->nrelax [2] = 48 ; - Common->zrelax [0] = 0.8 ; - Common->zrelax [1] = 0.1 ; - Common->zrelax [2] = 0.05 ; - - Common->prefer_zomplex = FALSE ; - Common->prefer_upper = TRUE ; - Common->prefer_binary = FALSE ; - Common->quick_return_if_not_posdef = FALSE ; - - /* METIS workarounds */ - Common->metis_memory = 0.0 ; /* > 0 for memory guard (2 is reasonable) */ - Common->metis_nswitch = 3000 ; - Common->metis_dswitch = 0.66 ; - - Common->print = 3 ; - Common->precise = FALSE ; - - /* ---------------------------------------------------------------------- */ - /* default ordering methods */ - /* ---------------------------------------------------------------------- */ - - /* Note that if the Partition module is not installed, the CHOLMOD_METIS - * and CHOLMOD_NESDIS methods will not be available. cholmod_analyze will - * report the CHOLMOD_NOT_INSTALLED error, and safely skip over them. - */ - -#if (CHOLMOD_MAXMETHODS < 9) -#error "CHOLMOD_MAXMETHODS must be 9 or more (defined in cholmod_core.h)." -#endif - - /* default strategy: try given, AMD, and then METIS if AMD reports high - * fill-in. NESDIS can be used instead, if Common->default_nesdis is TRUE. - */ - Common->nmethods = 0 ; /* use default strategy */ - Common->default_nesdis = FALSE ; /* use METIS in default strategy */ - - Common->current = 0 ; /* current method being tried */ - Common->selected = 0 ; /* the best method selected */ - - /* first, fill each method with default parameters */ - for (i = 0 ; i <= CHOLMOD_MAXMETHODS ; i++) - { - /* CHOLMOD's default method is AMD for A or AA' */ - Common->method [i].ordering = CHOLMOD_AMD ; - - /* CHOLMOD nested dissection and minimum degree parameter */ - Common->method [i].prune_dense = 10.0 ; /* dense row/col control */ - - /* min degree parameters (AMD, COLAMD, SYMAMD, CAMD, CCOLAMD, CSYMAMD)*/ - Common->method [i].prune_dense2 = -1 ; /* COLAMD dense row control */ - Common->method [i].aggressive = TRUE ; /* aggressive absorption */ - Common->method [i].order_for_lu = FALSE ;/* order for Cholesky not LU */ - - /* CHOLMOD's nested dissection (METIS + constrained AMD) */ - Common->method [i].nd_small = 200 ; /* small graphs aren't cut */ - Common->method [i].nd_compress = TRUE ; /* compress graph & subgraphs */ - Common->method [i].nd_camd = 1 ; /* use CAMD */ - Common->method [i].nd_components = FALSE ; /* lump connected comp. */ - Common->method [i].nd_oksep = 1.0 ; /* sep ok if < oksep*n */ - - /* statistics for each method are not yet computed */ - Common->method [i].fl = EMPTY ; - Common->method [i].lnz = EMPTY ; - } - - Common->postorder = TRUE ; /* follow ordering with weighted postorder */ - - /* Next, define some methods. The first five use default parameters. */ - Common->method [0].ordering = CHOLMOD_GIVEN ; /* skip if UserPerm NULL */ - Common->method [1].ordering = CHOLMOD_AMD ; - Common->method [2].ordering = CHOLMOD_METIS ; - Common->method [3].ordering = CHOLMOD_NESDIS ; - Common->method [4].ordering = CHOLMOD_NATURAL ; - - /* CHOLMOD's nested dissection with large leaves of separator tree */ - Common->method [5].ordering = CHOLMOD_NESDIS ; - Common->method [5].nd_small = 20000 ; - - /* CHOLMOD's nested dissection with tiny leaves, and no AMD ordering */ - Common->method [6].ordering = CHOLMOD_NESDIS ; - Common->method [6].nd_small = 4 ; - Common->method [6].nd_camd = 0 ; /* no CSYMAMD or CAMD */ - - /* CHOLMOD's nested dissection with no dense node removal */ - Common->method [7].ordering = CHOLMOD_NESDIS ; - Common->method [7].prune_dense = -1. ; - - /* COLAMD for A*A', AMD for A */ - Common->method [8].ordering = CHOLMOD_COLAMD ; - - /* ---------------------------------------------------------------------- */ - /* GPU configuration and statistics */ - /* ---------------------------------------------------------------------- */ - -#ifdef DLONG - Common->useGPU = EMPTY ; -#else - /* GPU acceleration is not supported for int version of CHOLMOD */ - Common->useGPU = 0 ; -#endif - - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === cholmod_finish ======================================================= */ -/* ========================================================================== */ - -/* The last call to CHOLMOD must be cholmod_finish. You may call this routine - * more than once, and can safely call any other CHOLMOD routine after calling - * it (including cholmod_start). - * - * The statistics and parameter settings in Common are preserved. The - * workspace in Common is freed. This routine is just another name for - * cholmod_free_work. - */ - -int CHOLMOD(finish) -( - cholmod_common *Common -) -{ - return (CHOLMOD(free_work) (Common)) ; -} - - -/* ========================================================================== */ -/* === cholmod_allocate_work ================================================ */ -/* ========================================================================== */ - -/* Allocate and initialize workspace for CHOLMOD routines, or increase the size - * of already-allocated workspace. If enough workspace is already allocated, - * then nothing happens. - * - * workspace: Flag (nrow), Head (nrow+1), Iwork (iworksize), Xwork (xworksize) - */ - -int CHOLMOD(allocate_work) -( - /* ---- input ---- */ - size_t nrow, /* # of rows in the matrix A */ - size_t iworksize, /* size of Iwork */ - size_t xworksize, /* size of Xwork */ - /* --------------- */ - cholmod_common *Common -) -{ - double *W ; - Int *Head ; - Int i ; - size_t nrow1 ; - int ok = TRUE ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (FALSE) ; - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* Allocate Flag (nrow) and Head (nrow+1) */ - /* ---------------------------------------------------------------------- */ - - nrow = MAX (1, nrow) ; - - /* nrow1 = nrow + 1 */ - nrow1 = CHOLMOD(add_size_t) (nrow, 1, &ok) ; - if (!ok) - { - /* nrow+1 causes size_t overflow ; problem is too large */ - Common->status = CHOLMOD_TOO_LARGE ; - CHOLMOD(free_work) (Common) ; - return (FALSE) ; - } - - if (nrow > Common->nrow) - { - - if (Common->no_workspace_reallocate) - { - /* CHOLMOD is not allowed to change the workspace here */ - Common->status = CHOLMOD_INVALID ; - return (FALSE) ; - } - - /* free the old workspace (if any) and allocate new space */ - Common->Flag = CHOLMOD(free) (Common->nrow, sizeof (Int), Common->Flag, - Common) ; - Common->Head = CHOLMOD(free) (Common->nrow+1,sizeof (Int), Common->Head, - Common) ; - Common->Flag = CHOLMOD(malloc) (nrow, sizeof (Int), Common) ; - Common->Head = CHOLMOD(malloc) (nrow1, sizeof (Int), Common) ; - - /* record the new size of Flag and Head */ - Common->nrow = nrow ; - - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free_work) (Common) ; - return (FALSE) ; - } - - /* initialize Flag and Head */ - Common->mark = EMPTY ; - CHOLMOD(clear_flag) (Common) ; - Head = Common->Head ; - for (i = 0 ; i <= (Int) (nrow) ; i++) - { - Head [i] = EMPTY ; - } - } - - /* ---------------------------------------------------------------------- */ - /* Allocate Iwork (iworksize) */ - /* ---------------------------------------------------------------------- */ - - iworksize = MAX (1, iworksize) ; - if (iworksize > Common->iworksize) - { - - if (Common->no_workspace_reallocate) - { - /* CHOLMOD is not allowed to change the workspace here */ - Common->status = CHOLMOD_INVALID ; - return (FALSE) ; - } - - /* free the old workspace (if any) and allocate new space. - * integer overflow safely detected in cholmod_malloc */ - CHOLMOD(free) (Common->iworksize, sizeof (Int), Common->Iwork, Common) ; - Common->Iwork = CHOLMOD(malloc) (iworksize, sizeof (Int), Common) ; - - /* record the new size of Iwork */ - Common->iworksize = iworksize ; - - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free_work) (Common) ; - return (FALSE) ; - } - - /* note that Iwork does not need to be initialized */ - } - - /* ---------------------------------------------------------------------- */ - /* Allocate Xwork (xworksize) and set it to ((double) 0.) */ - /* ---------------------------------------------------------------------- */ - - /* make sure xworksize is >= 1 */ - xworksize = MAX (1, xworksize) ; - if (xworksize > Common->xworksize) - { - - if (Common->no_workspace_reallocate) - { - /* CHOLMOD is not allowed to change the workspace here */ - Common->status = CHOLMOD_INVALID ; - return (FALSE) ; - } - - /* free the old workspace (if any) and allocate new space */ - CHOLMOD(free) (Common->xworksize, sizeof (double), Common->Xwork, - Common) ; - Common->Xwork = CHOLMOD(malloc) (xworksize, sizeof (double), Common) ; - - /* record the new size of Xwork */ - Common->xworksize = xworksize ; - - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free_work) (Common) ; - return (FALSE) ; - } - - /* initialize Xwork */ - W = Common->Xwork ; - for (i = 0 ; i < (Int) xworksize ; i++) - { - W [i] = 0. ; - } - } - - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === cholmod_free_work ==================================================== */ -/* ========================================================================== */ - -/* Deallocate the CHOLMOD workspace. - * - * workspace: deallocates all workspace in Common - */ - -int CHOLMOD(free_work) -( - cholmod_common *Common -) -{ - RETURN_IF_NULL_COMMON (FALSE) ; - Common->Flag = CHOLMOD(free) (Common->nrow, sizeof (Int), - Common->Flag, Common) ; - Common->Head = CHOLMOD(free) (Common->nrow+1, sizeof (Int), - Common->Head, Common) ; - Common->Iwork = CHOLMOD(free) (Common->iworksize, sizeof (Int), - Common->Iwork, Common) ; - Common->Xwork = CHOLMOD(free) (Common->xworksize, sizeof (double), - Common->Xwork, Common) ; - Common->nrow = 0 ; - Common->iworksize = 0 ; - Common->xworksize = 0 ; - -#ifdef SUITESPARSE_CUDA - CHOLMOD(gpu_deallocate) (Common) ; -#endif - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === cholmod_clear_flag =================================================== */ -/* ========================================================================== */ - -/* Increment mark to ensure Flag [0..nrow-1] < mark. If integer overflow - * occurs, or mark was initially negative, reset the entire array. This is - * not an error condition, but an intended function of the Flag workspace. - * - * workspace: Flag (nrow). Does not modify Flag if nrow is zero. - */ - -int64_t CHOLMOD(clear_flag) -( - cholmod_common *Common -) -{ - Int i, nrow, *Flag ; - - RETURN_IF_NULL_COMMON (-1) ; - - Common->mark++ ; - if (Common->mark <= 0) - { - nrow = Common->nrow ; - Flag = Common->Flag ; - PRINT2 (("reset Flag: nrow "ID"\n", nrow)) ; - PRINT2 (("reset Flag: mark %ld\n", Common->mark)) ; - for (i = 0 ; i < nrow ; i++) - { - Flag [i] = EMPTY ; - } - Common->mark = 0 ; - } - return (Common->mark) ; -} - - -/* ========================================================================== */ -/* ==== cholmod_maxrank ===================================================== */ -/* ========================================================================== */ - -/* Find a valid value of Common->maxrank. Returns 0 if error, or 2, 4, or 8 - * if successful. */ - -size_t CHOLMOD(maxrank) /* returns validated value of Common->maxrank */ -( - /* ---- input ---- */ - size_t n, /* A and L will have n rows */ - /* --------------- */ - cholmod_common *Common -) -{ - size_t maxrank ; - RETURN_IF_NULL_COMMON (0) ; - maxrank = Common->maxrank ; - if (n > 0) - { - /* Ensure maxrank*n*sizeof(double) does not result in integer overflow. - * If n is so large that 2*n*sizeof(double) results in integer overflow - * (n = 268,435,455 if an Int is 32 bits), then maxrank will be 0 or 1, - * but maxrank will be set to 2 below. 2*n will not result in integer - * overflow, and CHOLMOD will run out of memory or safely detect integer - * overflow elsewhere. - */ - maxrank = MIN (maxrank, SIZE_MAX / (n * sizeof (double))) ; - } - if (maxrank <= 2) - { - maxrank = 2 ; - } - else if (maxrank <= 4) - { - maxrank = 4 ; - } - else - { - maxrank = 8 ; - } - return (maxrank) ; -} - - -/* ========================================================================== */ -/* === cholmod_dbound ======================================================= */ -/* ========================================================================== */ - -/* Ensure the absolute value of a diagonal entry, D (j,j), is greater than - * Common->dbound. This routine is not meant for the user to call. It is used - * by the various LDL' factorization and update/downdate routines. The - * default value of Common->dbound is zero, and in that case this routine is not - * called at all. No change is made if D (j,j) is NaN. CHOLMOD does not call - * this routine if Common->dbound is NaN. - */ - -double CHOLMOD(dbound) /* returns modified diagonal entry of D */ -( - /* ---- input ---- */ - double dj, /* diagonal entry of D, for LDL' factorization */ - /* --------------- */ - cholmod_common *Common -) -{ - double dbound ; - RETURN_IF_NULL_COMMON (0) ; - if (!IS_NAN (dj)) - { - dbound = Common->dbound ; - if (dj < 0) - { - if (dj > -dbound) - { - dj = -dbound ; - Common->ndbounds_hit++ ; - if (Common->status == CHOLMOD_OK) - { - ERROR (CHOLMOD_DSMALL, "diagonal below threshold") ; - } - } - } - else - { - if (dj < dbound) - { - dj = dbound ; - Common->ndbounds_hit++ ; - if (Common->status == CHOLMOD_OK) - { - ERROR (CHOLMOD_DSMALL, "diagonal below threshold") ; - } - } - } - } - return (dj) ; -} - - -/* ========================================================================== */ -/* === scorecomp ============================================================ */ -/* ========================================================================== */ - -/* For sorting descendant supernodes with qsort */ -int CHOLMOD(score_comp) (struct cholmod_descendant_score_t *i, - struct cholmod_descendant_score_t *j) -{ - if ((*i).score < (*j).score) - { - return (1) ; - } - else - { - return (-1) ; - } -} diff --git a/CHOLMOD/Core/cholmod_complex.c b/CHOLMOD/Core/cholmod_complex.c deleted file mode 100644 index f2026a19d..000000000 --- a/CHOLMOD/Core/cholmod_complex.c +++ /dev/null @@ -1,487 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_complex: complex functions -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* If you convert a matrix that contains uninitialized data, valgrind will - * complain. This can occur in a factor L which has gaps (a partial - * factorization, or after updates that change the nonzero pattern), an - * unpacked sparse matrix, a dense matrix with leading dimension d > # of rows, - * or any matrix (dense, sparse, triplet, or factor) with more space allocated - * than is used. You can safely ignore any of these complaints by valgrind. */ - -#include "cholmod_internal.h" - -/* ========================================================================== */ -/* === cholmod_hypot ======================================================== */ -/* ========================================================================== */ - -double CHOLMOD(hypot) (double x, double y) -{ - return (SuiteSparse_config_hypot (x, y)) ; -} - - -/* ========================================================================== */ -/* === cholmod_divcomplex =================================================== */ -/* ========================================================================== */ - -/* c = a/b where c, a, and b are complex. The real and imaginary parts are - * passed as separate arguments to this routine. The NaN case is ignored - * for the double relop br >= bi. Returns 1 if the denominator is zero, - * 0 otherwise. Note that this return value is the single exception to the - * rule that all CHOLMOD routines that return int return TRUE if successful - * or FALSE otherise. - * - * This uses ACM Algo 116, by R. L. Smith, 1962, which tries to avoid - * underflow and overflow. - * - * c can be the same variable as a or b. - * - * Default value of the SuiteSparse_config divcomplex_func pointer is - * SuiteSparse_divcomplex, located in SuiteSparse_config.c. - */ - -int CHOLMOD(divcomplex) -( - double ar, double ai, /* real and imaginary parts of a */ - double br, double bi, /* real and imaginary parts of b */ - double *cr, double *ci /* real and imaginary parts of c */ -) -{ - return (SuiteSparse_config_divcomplex (ar, ai, br, bi, cr, ci)) ; -} - - -/* ========================================================================== */ -/* === change_complexity ==================================================== */ -/* ========================================================================== */ - -/* X and Z represent an array of size nz, with numeric xtype given by xtype_in. - * - * If xtype_in is: - * CHOLMOD_PATTERN: X and Z must be NULL. - * CHOLMOD_REAL: X is of size nz, Z must be NULL. - * CHOLMOD_COMPLEX: X is of size 2*nz, Z must be NULL. - * CHOLMOD_ZOMPLEX: X is of size nz, Z is of size nz. - * - * The array is changed into the numeric xtype given by xtype_out, with the - * same definitions of X and Z above. Note that the input conditions, above, - * are not checked. These are checked in the caller routine. - * - * Returns TRUE if successful, FALSE otherwise. X and Z are not modified if - * not successful. - */ - -static int change_complexity -( - /* ---- input ---- */ - Int nz, /* size of X and/or Z */ - int xtype_in, /* xtype of X and Z on input */ - int xtype_out, /* requested xtype of X and Z on output */ - int xtype1, /* xtype_out must be in the range [xtype1 .. xtype2] */ - int xtype2, - /* ---- in/out --- */ - void **XX, /* old X on input, new X on output */ - void **ZZ, /* old Z on input, new Z on output */ - /* --------------- */ - cholmod_common *Common -) -{ - double *Xold, *Zold, *Xnew, *Znew ; - Int k ; - size_t nz2 ; - - if (xtype_out < xtype1 || xtype_out > xtype2) - { - ERROR (CHOLMOD_INVALID, "invalid xtype") ; - return (FALSE) ; - } - - Common->status = CHOLMOD_OK ; - Xold = *XX ; - Zold = *ZZ ; - - switch (xtype_in) - { - - /* ------------------------------------------------------------------ */ - /* converting from pattern */ - /* ------------------------------------------------------------------ */ - - case CHOLMOD_PATTERN: - - switch (xtype_out) - { - - /* ---------------------------------------------------------- */ - /* pattern -> real */ - /* ---------------------------------------------------------- */ - - case CHOLMOD_REAL: - /* allocate X and set to all ones */ - Xnew = CHOLMOD(malloc) (nz, sizeof (double), Common) ; - if (Common->status < CHOLMOD_OK) - { - return (FALSE) ; - } - for (k = 0 ; k < nz ; k++) - { - Xnew [k] = 1 ; - } - *XX = Xnew ; - break ; - - /* ---------------------------------------------------------- */ - /* pattern -> complex */ - /* ---------------------------------------------------------- */ - - case CHOLMOD_COMPLEX: - /* allocate X and set to all ones */ - Xnew = CHOLMOD(malloc) (nz, 2*sizeof (double), Common) ; - if (Common->status < CHOLMOD_OK) - { - return (FALSE) ; - } - for (k = 0 ; k < nz ; k++) - { - Xnew [2*k ] = 1 ; - Xnew [2*k+1] = 0 ; - } - *XX = Xnew ; - break ; - - /* ---------------------------------------------------------- */ - /* pattern -> zomplex */ - /* ---------------------------------------------------------- */ - - case CHOLMOD_ZOMPLEX: - /* allocate X and Z and set to all ones */ - Xnew = CHOLMOD(malloc) (nz, sizeof (double), Common) ; - Znew = CHOLMOD(malloc) (nz, sizeof (double), Common) ; - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free) (nz, sizeof (double), Xnew, Common) ; - CHOLMOD(free) (nz, sizeof (double), Znew, Common) ; - return (FALSE) ; - } - for (k = 0 ; k < nz ; k++) - { - Xnew [k] = 1 ; - Znew [k] = 0 ; - } - *XX = Xnew ; - *ZZ = Znew ; - break ; - } - break ; - - /* ------------------------------------------------------------------ */ - /* converting from real */ - /* ------------------------------------------------------------------ */ - - case CHOLMOD_REAL: - - switch (xtype_out) - { - - /* ---------------------------------------------------------- */ - /* real -> pattern */ - /* ---------------------------------------------------------- */ - - case CHOLMOD_PATTERN: - /* free X */ - *XX = CHOLMOD(free) (nz, sizeof (double), *XX, Common) ; - break ; - - /* ---------------------------------------------------------- */ - /* real -> complex */ - /* ---------------------------------------------------------- */ - - case CHOLMOD_COMPLEX: - /* allocate a new X and copy the old X */ - Xnew = CHOLMOD(malloc) (nz, 2*sizeof (double), Common) ; - if (Common->status < CHOLMOD_OK) - { - return (FALSE) ; - } - for (k = 0 ; k < nz ; k++) - { - Xnew [2*k ] = Xold [k] ; - Xnew [2*k+1] = 0 ; - } - CHOLMOD(free) (nz, sizeof (double), *XX, Common) ; - *XX = Xnew ; - break ; - - /* ---------------------------------------------------------- */ - /* real -> zomplex */ - /* ---------------------------------------------------------- */ - - case CHOLMOD_ZOMPLEX: - /* allocate a new Z and set it to zero */ - Znew = CHOLMOD(malloc) (nz, sizeof (double), Common) ; - if (Common->status < CHOLMOD_OK) - { - return (FALSE) ; - } - for (k = 0 ; k < nz ; k++) - { - Znew [k] = 0 ; - } - *ZZ = Znew ; - break ; - } - break ; - - /* ------------------------------------------------------------------ */ - /* converting from complex */ - /* ------------------------------------------------------------------ */ - - case CHOLMOD_COMPLEX: - - switch (xtype_out) - { - - /* ---------------------------------------------------------- */ - /* complex -> pattern */ - /* ---------------------------------------------------------- */ - - case CHOLMOD_PATTERN: - /* free X */ - *XX = CHOLMOD(free) (nz, 2*sizeof (double), *XX, Common) ; - break ; - - /* ---------------------------------------------------------- */ - /* complex -> real */ - /* ---------------------------------------------------------- */ - - case CHOLMOD_REAL: - /* pack the real part of X, discarding the imaginary part */ - for (k = 0 ; k < nz ; k++) - { - Xold [k] = Xold [2*k] ; - } - /* shrink X in half (this cannot fail) */ - nz2 = 2*nz ; - *XX = CHOLMOD(realloc) (nz, sizeof (double), *XX, &nz2, - Common) ; - break ; - - /* ---------------------------------------------------------- */ - /* complex -> zomplex */ - /* ---------------------------------------------------------- */ - - case CHOLMOD_ZOMPLEX: - /* allocate X and Z and copy the old X into them */ - Xnew = CHOLMOD(malloc) (nz, sizeof (double), Common) ; - Znew = CHOLMOD(malloc) (nz, sizeof (double), Common) ; - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free) (nz, sizeof (double), Xnew, Common) ; - CHOLMOD(free) (nz, sizeof (double), Znew, Common) ; - return (FALSE) ; - } - for (k = 0 ; k < nz ; k++) - { - Xnew [k] = Xold [2*k ] ; - Znew [k] = Xold [2*k+1] ; - } - CHOLMOD(free) (nz, 2*sizeof (double), *XX, Common) ; - *XX = Xnew ; - *ZZ = Znew ; - break ; - } - break ; - - /* ------------------------------------------------------------------ */ - /* converting from zomplex */ - /* ------------------------------------------------------------------ */ - - case CHOLMOD_ZOMPLEX: - - switch (xtype_out) - { - - /* ---------------------------------------------------------- */ - /* zomplex -> pattern */ - /* ---------------------------------------------------------- */ - - case CHOLMOD_PATTERN: - /* free X and Z */ - *XX = CHOLMOD(free) (nz, sizeof (double), *XX, Common) ; - *ZZ = CHOLMOD(free) (nz, sizeof (double), *ZZ, Common) ; - break ; - - /* ---------------------------------------------------------- */ - /* zomplex -> real */ - /* ---------------------------------------------------------- */ - - case CHOLMOD_REAL: - /* free the imaginary part */ - *ZZ = CHOLMOD(free) (nz, sizeof (double), *ZZ, Common) ; - break ; - - /* ---------------------------------------------------------- */ - /* zomplex -> complex */ - /* ---------------------------------------------------------- */ - - case CHOLMOD_COMPLEX: - Xnew = CHOLMOD(malloc) (nz, 2*sizeof (double), Common) ; - if (Common->status < CHOLMOD_OK) - { - return (FALSE) ; - } - for (k = 0 ; k < nz ; k++) - { - Xnew [2*k ] = Xold [k] ; - Xnew [2*k+1] = Zold [k] ; - } - CHOLMOD(free) (nz, sizeof (double), *XX, Common) ; - CHOLMOD(free) (nz, sizeof (double), *ZZ, Common) ; - *XX = Xnew ; - *ZZ = NULL ; - break ; - - } - break ; - } - - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === cholmod_sparse_xtype ================================================= */ -/* ========================================================================== */ - -/* Change the numeric xtype of a sparse matrix. Supports any type on input - * and output (pattern, real, complex, or zomplex). */ - -int CHOLMOD(sparse_xtype) -( - /* ---- input ---- */ - int to_xtype, /* requested xtype */ - /* ---- in/out --- */ - cholmod_sparse *A, /* sparse matrix to change */ - /* --------------- */ - cholmod_common *Common -) -{ - Int ok ; - RETURN_IF_NULL_COMMON (FALSE) ; - RETURN_IF_NULL (A, FALSE) ; - RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; - - ok = change_complexity (A->nzmax, A->xtype, to_xtype, - CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, &(A->x), &(A->z), Common) ; - if (ok) - { - A->xtype = to_xtype ; - } - return (ok) ; -} - - -/* ========================================================================== */ -/* === cholmod_triplet_xtype ================================================ */ -/* ========================================================================== */ - -/* Change the numeric xtype of a triplet matrix. Supports any type on input - * and output (pattern, real, complex, or zomplex). */ - -int CHOLMOD(triplet_xtype) -( - /* ---- input ---- */ - int to_xtype, /* requested xtype */ - /* ---- in/out --- */ - cholmod_triplet *T, /* triplet matrix to change */ - /* --------------- */ - cholmod_common *Common -) -{ - Int ok ; - RETURN_IF_NULL_COMMON (FALSE) ; - RETURN_IF_NULL (T, FALSE) ; - RETURN_IF_XTYPE_INVALID (T, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; - ok = change_complexity (T->nzmax, T->xtype, to_xtype, - CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, &(T->x), &(T->z), Common) ; - if (ok) - { - T->xtype = to_xtype ; - } - return (ok) ; -} - - -/* ========================================================================== */ -/* === cholmod_dense_xtype ================================================= */ -/* ========================================================================== */ - -/* Change the numeric xtype of a dense matrix. Supports real, complex or - * zomplex on input and output */ - -int CHOLMOD(dense_xtype) -( - /* ---- input ---- */ - int to_xtype, /* requested xtype */ - /* ---- in/out --- */ - cholmod_dense *X, /* dense matrix to change */ - /* --------------- */ - cholmod_common *Common -) -{ - Int ok ; - RETURN_IF_NULL_COMMON (FALSE) ; - RETURN_IF_NULL (X, FALSE) ; - RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; - ok = change_complexity (X->nzmax, X->xtype, to_xtype, - CHOLMOD_REAL, CHOLMOD_ZOMPLEX, &(X->x), &(X->z), Common) ; - if (ok) - { - X->xtype = to_xtype ; - } - return (ok) ; -} - - -/* ========================================================================== */ -/* === cholmod_factor_xtype ================================================= */ -/* ========================================================================== */ - -/* Change the numeric xtype of a factor. Supports real, complex or zomplex on - * input and output. Supernodal zomplex factors are not supported. */ - -int CHOLMOD(factor_xtype) -( - /* ---- input ---- */ - int to_xtype, /* requested xtype */ - /* ---- in/out --- */ - cholmod_factor *L, /* factor to change */ - /* --------------- */ - cholmod_common *Common -) -{ - Int ok ; - RETURN_IF_NULL_COMMON (FALSE) ; - RETURN_IF_NULL (L, FALSE) ; - RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; - if (L->is_super && - (L->xtype == CHOLMOD_ZOMPLEX || to_xtype == CHOLMOD_ZOMPLEX)) - { - ERROR (CHOLMOD_INVALID, "invalid xtype for supernodal L") ; - return (FALSE) ; - } - ok = change_complexity ((L->is_super ? L->xsize : L->nzmax), L->xtype, - to_xtype, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, &(L->x), &(L->z), Common) ; - if (ok) - { - L->xtype = to_xtype ; - } - return (ok) ; -} diff --git a/CHOLMOD/Core/cholmod_copy.c b/CHOLMOD/Core/cholmod_copy.c deleted file mode 100644 index 000e750af..000000000 --- a/CHOLMOD/Core/cholmod_copy.c +++ /dev/null @@ -1,402 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_copy: copy a matrix -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* C = A, which allocates C and copies A into C, with possible change of - * stype. The diagonal can optionally be removed. The numerical entries - * can optionally be copied. This routine differs from cholmod_copy_sparse, - * which makes an exact copy of a sparse matrix. - * - * A can be of any type (packed/unpacked, upper/lower/unsymmetric). C is - * packed and can be of any stype (upper/lower/unsymmetric), except that if - * A is rectangular C can only be unsymmetric. If the stype of A and C - * differ, then the appropriate conversion is made. - * - * Symmetry of A (A->stype): - * <0: lower: assume A is symmetric with just tril(A); the rest of A is ignored - * 0 unsym: assume A is unsymmetric; consider all entries in A - * >0 upper: assume A is symmetric with just triu(A); the rest of A is ignored - * - * Symmetry of C (stype parameter): - * <0 lower: return just tril(C) - * 0 unsym: return all of C - * >0 upper: return just triu(C) - * - * In MATLAB: Using cholmod_copy: - * ---------- ---------------------------- - * C = A ; A unsymmetric, C unsymmetric - * C = tril (A) ; A unsymmetric, C lower - * C = triu (A) ; A unsymmetric, C upper - * U = triu (A) ; L = tril (U',-1) ; C = L+U ; A upper, C unsymmetric - * C = triu (A)' ; A upper, C lower - * C = triu (A) ; A upper, C upper - * L = tril (A) ; U = triu (L',1) ; C = L+U ; A lower, C unsymmetric - * C = tril (A) ; A lower, C lower - * C = tril (A)' ; A lower, C upper - * - * workspace: Iwork (max (nrow,ncol)) - * - * A can have an xtype of pattern or real. Complex and zomplex cases only - * supported when mode <= 0 (in which case the numerical values are ignored). - */ - -#include "cholmod_internal.h" - -/* ========================================================================== */ -/* === copy_sym_to_unsym ==================================================== */ -/* ========================================================================== */ - -/* Construct an unsymmetric copy of a symmetric sparse matrix. This does the - * work for as C = cholmod_copy (A, 0, mode, Common) when A is symmetric. - * In this case, extra space can be added to C. - */ - -static cholmod_sparse *copy_sym_to_unsym -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) - * -2: pattern only, no diagonal, add 50% + n extra - * space to C */ - /* --------------- */ - cholmod_common *Common -) -{ - double aij ; - double *Ax, *Cx ; - Int *Ap, *Ai, *Anz, *Cp, *Ci, *Wj, *Iwork ; - cholmod_sparse *C ; - Int nrow, ncol, nz, packed, j, p, pend, i, pc, up, lo, values, diag, - astype, extra ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - nrow = A->nrow ; - ncol = A->ncol ; - Ap = A->p ; - Anz = A->nz ; - Ai = A->i ; - Ax = A->x ; - packed = A->packed ; - values = (mode > 0) && (A->xtype != CHOLMOD_PATTERN) ; - diag = (mode >= 0) ; - - astype = SIGN (A->stype) ; - up = (astype > 0) ; - lo = (astype < 0) ; - ASSERT (astype != 0) ; - - /* ---------------------------------------------------------------------- */ - /* create an unsymmetric copy of a symmetric matrix */ - /* ---------------------------------------------------------------------- */ - - Iwork = Common->Iwork ; - Wj = Iwork ; /* size ncol (i/i/l) */ - - /* In MATLAB notation, for converting a symmetric/upper matrix: - * U = triu (A) ; - * L = tril (U',-1) ; - * C = L + U ; - * - * For converting a symmetric/lower matrix to unsymmetric: - * L = tril (A) ; - * U = triu (L',1) ; - * C = L + U ; - */ - ASSERT (up || lo) ; - PRINT1 (("copy: convert symmetric to unsym\n")) ; - - /* count the number of entries in each column of C */ - for (j = 0 ; j < ncol ; j++) - { - Wj [j] = 0 ; - } - for (j = 0 ; j < ncol ; j++) - { - p = Ap [j] ; - pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (i == j) - { - /* the diagonal entry A(i,i) will appear just once - * (unless it is excluded with mode < 0) */ - if (diag) - { - Wj [j]++ ; - } - } - else if ((up && i < j) || (lo && i > j)) - { - /* upper case: A(i,j) is in the strictly upper part; - * A(j,i) will be added to the strictly lower part of C. - * lower case is the opposite. */ - Wj [j]++ ; - Wj [i]++ ; - } - } - } - nz = 0 ; - for (j = 0 ; j < ncol ; j++) - { - nz += Wj [j] ; - } - - extra = (mode == -2) ? (nz/2 + ncol) : 0 ; - - /* allocate C. C is sorted if and only if A is sorted */ - C = CHOLMOD(allocate_sparse) (nrow, ncol, nz + extra, A->sorted, TRUE, 0, - values ? A->xtype : CHOLMOD_PATTERN, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; - } - - Cp = C->p ; - Ci = C->i ; - Cx = C->x ; - - /* construct the column pointers for C */ - p = 0 ; - for (j = 0 ; j < ncol ; j++) - { - Cp [j] = p ; - p += Wj [j] ; - } - Cp [ncol] = p ; - for (j = 0 ; j < ncol ; j++) - { - Wj [j] = Cp [j] ; - } - - /* construct C */ - if (values) - { - - /* pattern and values */ - ASSERT (diag) ; - for (j = 0 ; j < ncol ; j++) - { - p = Ap [j] ; - pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - aij = Ax [p] ; - if (i == j) - { - /* add diagonal entry A(i,i) to column i */ - pc = Wj [i]++ ; - Ci [pc] = i ; - Cx [pc] = aij ; - } - else if ((up && i < j) || (lo && i > j)) - { - /* add A(i,j) to column j */ - pc = Wj [j]++ ; - Ci [pc] = i ; - Cx [pc] = aij ; - /* add A(j,i) to column i */ - pc = Wj [i]++ ; - Ci [pc] = j ; - Cx [pc] = aij ; - } - } - } - - } - else - { - - /* pattern only, possibly excluding the diagonal */ - for (j = 0 ; j < ncol ; j++) - { - p = Ap [j] ; - pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (i == j) - { - /* add diagonal entry A(i,i) to column i - * (unless it is excluded with mode < 0) */ - if (diag) - { - Ci [Wj [i]++] = i ; - } - } - else if ((up && i < j) || (lo && i > j)) - { - /* add A(i,j) to column j */ - Ci [Wj [j]++] = i ; - /* add A(j,i) to column i */ - Ci [Wj [i]++] = j ; - } - } - } - } - - /* ---------------------------------------------------------------------- */ - /* return the result */ - /* ---------------------------------------------------------------------- */ - - DEBUG (i = CHOLMOD(dump_sparse) (C, "copy_sym_to_unsym", Common)) ; - PRINT1 (("mode %d nnzdiag "ID"\n", mode, i)) ; - ASSERT (IMPLIES (mode < 0, i == 0)) ; - return (C) ; -} - - -/* ========================================================================== */ -/* === cholmod_copy ========================================================= */ -/* ========================================================================== */ - -cholmod_sparse *CHOLMOD(copy) -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ - int stype, /* requested stype of C */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_sparse *C ; - Int nrow, ncol, up, lo, values, diag, astype ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - RETURN_IF_NULL (A, NULL) ; - values = (mode > 0) && (A->xtype != CHOLMOD_PATTERN) ; - RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, - values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ; - nrow = A->nrow ; - ncol = A->ncol ; - if ((stype || A->stype) && nrow != ncol) - { - /* inputs invalid */ - ERROR (CHOLMOD_INVALID, "matrix invalid") ; - return (NULL) ; - } - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* allocate workspace */ - /* ---------------------------------------------------------------------- */ - - CHOLMOD(allocate_work) (0, MAX (nrow,ncol), 0, Common) ; - if (Common->status < CHOLMOD_OK) - { - /* out of memory */ - return (NULL) ; - } - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - diag = (mode >= 0) ; - astype = SIGN (A->stype) ; - stype = SIGN (stype) ; - up = (astype > 0) ; - lo = (astype < 0) ; - - /* ---------------------------------------------------------------------- */ - /* copy the matrix */ - /* ---------------------------------------------------------------------- */ - - if (astype == stype) - { - - /* ------------------------------------------------------------------ */ - /* symmetry of A and C are the same */ - /* ------------------------------------------------------------------ */ - - /* copy A into C, keeping the same symmetry. If A is symmetric - * entries in the ignored part of A are not copied into C */ - C = CHOLMOD(band) (A, -nrow, ncol, mode, Common) ; - - } - else if (!astype) - { - - /* ------------------------------------------------------------------ */ - /* convert unsymmetric matrix A into a symmetric matrix C */ - /* ------------------------------------------------------------------ */ - - if (stype > 0) - { - /* C = triu (A) */ - C = CHOLMOD(band) (A, 0, ncol, mode, Common) ; - } - else - { - /* C = tril (A) */ - C = CHOLMOD(band) (A, -nrow, 0, mode, Common) ; - } - if (Common->status < CHOLMOD_OK) - { - /* out of memory */ - return (NULL) ; - } - C->stype = stype ; - - } - else if (astype == -stype) - { - - /* ------------------------------------------------------------------ */ - /* transpose a symmetric matrix */ - /* ------------------------------------------------------------------ */ - - /* converting upper to lower or lower to upper */ - /* workspace: Iwork (nrow) */ - C = CHOLMOD(transpose) (A, values, Common) ; - if (!diag) - { - /* remove diagonal, if requested */ - CHOLMOD(band_inplace) (-nrow, ncol, -1, C, Common) ; - } - - } - else - { - - /* ------------------------------------------------------------------ */ - /* create an unsymmetric copy of a symmetric matrix */ - /* ------------------------------------------------------------------ */ - - C = copy_sym_to_unsym (A, mode, Common) ; - } - - /* ---------------------------------------------------------------------- */ - /* return if error */ - /* ---------------------------------------------------------------------- */ - - if (Common->status < CHOLMOD_OK) - { - /* out of memory */ - return (NULL) ; - } - - /* ---------------------------------------------------------------------- */ - /* return the result */ - /* ---------------------------------------------------------------------- */ - - DEBUG (diag = CHOLMOD(dump_sparse) (C, "copy", Common)) ; - PRINT1 (("mode %d nnzdiag "ID"\n", mode, diag)) ; - ASSERT (IMPLIES (mode < 0, diag == 0)) ; - return (C) ; -} diff --git a/CHOLMOD/Core/cholmod_dense.c b/CHOLMOD/Core/cholmod_dense.c deleted file mode 100644 index 9e80337fb..000000000 --- a/CHOLMOD/Core/cholmod_dense.c +++ /dev/null @@ -1,684 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_dense: core methods for the cholmod_dense object -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* Core utility routines for the cholmod_dense object: - * - * The solve routines and some of the MatrixOps and Modify routines use dense - * matrices as inputs. These are held in column-major order. With a leading - * dimension of d, the entry in row i and column j is held in x [i+j*d]. - * - * Primary routines: - * ----------------- - * cholmod_allocate_dense allocate a dense matrix - * cholmod_free_dense free a dense matrix - * - * Secondary routines: - * ------------------- - * cholmod_zeros allocate a dense matrix of all zeros - * cholmod_ones allocate a dense matrix of all ones - * cholmod_eye allocate a dense identity matrix - * cholmod_sparse_to_dense create a dense matrix copy of a sparse matrix - * cholmod_dense_to_sparse create a sparse matrix copy of a dense matrix - * cholmod_copy_dense create a copy of a dense matrix - * cholmod_copy_dense2 copy a dense matrix (pre-allocated) - * - * All routines in this file can handle the real, complex, and zomplex cases. - * Pattern-only dense matrices are not supported. cholmod_sparse_to_dense can - * take a pattern-only input sparse matrix, however, and cholmod_dense_to_sparse - * can generate a pattern-only output sparse matrix. - */ - -#include "cholmod_internal.h" - -/* ========================================================================== */ -/* === TEMPLATE ============================================================= */ -/* ========================================================================== */ - -#define PATTERN -#include "t_cholmod_dense.c" -#define REAL -#include "t_cholmod_dense.c" -#define COMPLEX -#include "t_cholmod_dense.c" -#define ZOMPLEX -#include "t_cholmod_dense.c" - -/* ========================================================================== */ -/* === cholmod_allocate_dense =============================================== */ -/* ========================================================================== */ - -/* Allocate a dense matrix with leading dimension d. The space is not - * initialized. - */ - -cholmod_dense *CHOLMOD(allocate_dense) -( - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - size_t d, /* leading dimension */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_dense *X ; - size_t nzmax, nzmax0 ; - int ok = TRUE ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - if (d < nrow) - { - ERROR (CHOLMOD_INVALID, "leading dimension invalid") ; - return (NULL) ; - } - if (xtype < CHOLMOD_REAL || xtype > CHOLMOD_ZOMPLEX) - { - ERROR (CHOLMOD_INVALID, "xtype invalid") ; - return (NULL) ; - } - - /* ensure the dimensions do not cause integer overflow */ - (void) CHOLMOD(add_size_t) (ncol, 2, &ok) ; - - /* nzmax = MAX (1, d*ncol) ; */ - nzmax = CHOLMOD(mult_size_t) (d, ncol, &ok) ; - nzmax = MAX (1, nzmax) ; - - if (!ok || (int64_t) nrow >= Int_max - || (int64_t) ncol >= Int_max - || (int64_t) nzmax >= Int_max) - { - ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; - return (NULL) ; - } - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* allocate header */ - /* ---------------------------------------------------------------------- */ - - X = CHOLMOD(malloc) (sizeof (cholmod_dense), 1, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - - PRINT1 (("cholmod_allocate_dense %d-by-%d nzmax %d xtype %d\n", - nrow, ncol, nzmax, xtype)) ; - - X->nrow = nrow ; - X->ncol = ncol ; - X->nzmax = nzmax ; - X->xtype = xtype ; - X->dtype = DTYPE ; - X->x = NULL ; - X->z = NULL ; - X->d = d ; - - /* ---------------------------------------------------------------------- */ - /* allocate the matrix itself */ - /* ---------------------------------------------------------------------- */ - - nzmax0 = 0 ; - CHOLMOD(realloc_multiple) (nzmax, 0, xtype, NULL, NULL, &(X->x), &(X->z), - &nzmax0, Common) ; - - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free_dense) (&X, Common) ; - return (NULL) ; /* out of memory */ - } - - return (X) ; -} - - -/* ========================================================================== */ -/* === cholmod_zeros ======================================================== */ -/* ========================================================================== */ - -/* Allocate a dense matrix and set it to zero */ - -cholmod_dense *CHOLMOD(zeros) -( - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_dense *X ; - double *Xx, *Xz ; - Int i, nz ; - - /* ---------------------------------------------------------------------- */ - /* allocate a dense matrix and set it to zero */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - X = CHOLMOD(allocate_dense) (nrow, ncol, nrow, xtype, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* NULL Common, out of memory, or inputs invalid */ - } - - Xx = X->x ; - Xz = X->z ; - nz = MAX (1, X->nzmax) ; - - switch (xtype) - { - case CHOLMOD_REAL: - for (i = 0 ; i < nz ; i++) - { - Xx [i] = 0 ; - } - break ; - - case CHOLMOD_COMPLEX: - for (i = 0 ; i < 2*nz ; i++) - { - Xx [i] = 0 ; - } - break ; - - case CHOLMOD_ZOMPLEX: - for (i = 0 ; i < nz ; i++) - { - Xx [i] = 0 ; - } - for (i = 0 ; i < nz ; i++) - { - Xz [i] = 0 ; - } - break ; - } - - return (X) ; -} - - -/* ========================================================================== */ -/* === cholmod_ones ========================================================= */ -/* ========================================================================== */ - -/* Allocate a dense matrix and set it to zero */ - -cholmod_dense *CHOLMOD(ones) -( - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_dense *X ; - double *Xx, *Xz ; - Int i, nz ; - - /* ---------------------------------------------------------------------- */ - /* allocate a dense matrix and set it to all ones */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - X = CHOLMOD(allocate_dense) (nrow, ncol, nrow, xtype, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* NULL Common, out of memory, or inputs invalid */ - } - - Xx = X->x ; - Xz = X->z ; - nz = MAX (1, X->nzmax) ; - - switch (xtype) - { - case CHOLMOD_REAL: - for (i = 0 ; i < nz ; i++) - { - Xx [i] = 1 ; - } - break ; - - case CHOLMOD_COMPLEX: - for (i = 0 ; i < nz ; i++) - { - Xx [2*i ] = 1 ; - Xx [2*i+1] = 0 ; - } - break ; - - case CHOLMOD_ZOMPLEX: - for (i = 0 ; i < nz ; i++) - { - Xx [i] = 1 ; - } - for (i = 0 ; i < nz ; i++) - { - Xz [i] = 0 ; - } - break ; - } - - return (X) ; -} - - -/* ========================================================================== */ -/* === cholmod_eye ========================================================== */ -/* ========================================================================== */ - -/* Allocate a dense matrix and set it to the identity matrix */ - -cholmod_dense *CHOLMOD(eye) -( - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_dense *X ; - double *Xx, *Xz ; - Int i, n, nz ; - - /* ---------------------------------------------------------------------- */ - /* allocate a dense matrix and set it to the identity matrix */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - X = CHOLMOD(zeros) (nrow, ncol, xtype, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* NULL Common, out of memory, or inputs invalid */ - } - - nz = MAX (1, nrow*ncol) ; - Xx = X->x ; - Xz = X->z ; - - n = MIN (nrow, ncol) ; - - switch (xtype) - { - case CHOLMOD_REAL: - case CHOLMOD_ZOMPLEX: - for (i = 0 ; i < n ; i++) - { - Xx [i + i*nrow] = 1 ; - } - break ; - - case CHOLMOD_COMPLEX: - for (i = 0 ; i < n ; i++) - { - Xx [2 * (i + i*nrow)] = 1 ; - } - break ; - } - - return (X) ; -} - -/* ========================================================================== */ -/* === cholmod_free_dense =================================================== */ -/* ========================================================================== */ - -/* free a dense matrix - * - * workspace: none - */ - -int CHOLMOD(free_dense) -( - /* ---- in/out --- */ - cholmod_dense **XHandle, /* dense matrix to deallocate, NULL on output */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_dense *X ; - - RETURN_IF_NULL_COMMON (FALSE) ; - - if (XHandle == NULL) - { - /* nothing to do */ - return (TRUE) ; - } - X = *XHandle ; - if (X == NULL) - { - /* nothing to do */ - return (TRUE) ; - } - - switch (X->xtype) - { - case CHOLMOD_REAL: - X->x = CHOLMOD(free) (X->nzmax, sizeof (double), X->x, Common) ; - break ; - - case CHOLMOD_COMPLEX: - X->x = CHOLMOD(free) (X->nzmax, 2*sizeof (double), X->x, Common) ; - break ; - - case CHOLMOD_ZOMPLEX: - X->x = CHOLMOD(free) (X->nzmax, sizeof (double), X->x, Common) ; - X->z = CHOLMOD(free) (X->nzmax, sizeof (double), X->z, Common) ; - break ; - } - - *XHandle = CHOLMOD(free) (1, sizeof (cholmod_dense), (*XHandle), Common) ; - return (TRUE) ; -} - -/* ========================================================================== */ -/* === cholmod_ensure_dense ================================================= */ -/* ========================================================================== */ - -/* Ensure that the input matrix has a certain size and type. If not, free - * the existing matrix and reallocate one of the right size and type. - * Returns a pointer to the cholmod_dense matrix, possibly reallocated. - * Also modifies the input matrix handle, XHandle, if necessary. - */ - -cholmod_dense *CHOLMOD(ensure_dense) -( - /* ---- input/output ---- */ - cholmod_dense **XHandle, /* matrix handle to check */ - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - size_t d, /* leading dimension */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_dense *X ; - - RETURN_IF_NULL_COMMON (NULL) ; - if (XHandle == NULL) - { - ERROR (CHOLMOD_INVALID, "matrix invalid") ; - return (NULL) ; - } - - X = *XHandle ; - if (X == NULL || X->nrow != nrow || X->ncol != ncol - || X->d != d || X->xtype != xtype) - { - /* Matrix X is not allocated, or has the wrong size. Free it and - * reallocate it in the right size and shape. If an error occurs - * (out of memory or inputs nrow, etc invalid), then the error is - * set in cholmod_allocate_dense and X is returned as NULL. */ - CHOLMOD(free_dense) (XHandle, Common) ; - X = CHOLMOD(allocate_dense) (nrow, ncol, d, xtype, Common) ; - *XHandle = X ; - } - return (X) ; -} - - -/* ========================================================================== */ -/* === cholmod_sparse_to_dense ============================================== */ -/* ========================================================================== */ - -/* Convert a sparse matrix to a dense matrix. - * The output dense matrix has the same xtype as the input sparse matrix, - * except that a pattern-only sparse matrix A is converted into a real dense - * matrix X, with 1's and 0's. All xtypes are supported. - */ - -cholmod_dense *CHOLMOD(sparse_to_dense) -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_dense *X = NULL ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - RETURN_IF_NULL (A, NULL) ; - RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; - if (A->stype && A->nrow != A->ncol) - { - ERROR (CHOLMOD_INVALID, "matrix invalid") ; - return (NULL) ; - } - Common->status = CHOLMOD_OK ; - ASSERT (CHOLMOD(dump_sparse) (A, "A", Common) >= 0) ; - - /* ---------------------------------------------------------------------- */ - /* convert the matrix, using template routine */ - /* ---------------------------------------------------------------------- */ - - switch (A->xtype) - { - case CHOLMOD_PATTERN: - X = p_cholmod_sparse_to_dense (A, Common) ; - break ; - - case CHOLMOD_REAL: - X = r_cholmod_sparse_to_dense (A, Common) ; - break ; - - case CHOLMOD_COMPLEX: - X = c_cholmod_sparse_to_dense (A, Common) ; - break ; - - case CHOLMOD_ZOMPLEX: - X = z_cholmod_sparse_to_dense (A, Common) ; - break ; - } - return (X) ; -} - - -/* ========================================================================== */ -/* === cholmod_dense_to_sparse ============================================== */ -/* ========================================================================== */ - -/* Convert a dense matrix to a sparse matrix, similar to the MATLAB statements: - * - * C = sparse (X) values = TRUE - * C = spones (sparse (X)) values = FALSE - * - * except that X must be double (it can be of many different types in MATLAB) - * - * The resulting sparse matrix C has the same numeric xtype as the input dense - * matrix X, unless "values" is FALSE (in which case C is real, where C(i,j)=1 - * if (i,j) is an entry in X. - */ - -cholmod_sparse *CHOLMOD(dense_to_sparse) -( - /* ---- input ---- */ - cholmod_dense *X, /* matrix to copy */ - int values, /* TRUE if values to be copied, FALSE otherwise */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_sparse *C = NULL ; - - DEBUG (CHOLMOD(dump_dense) (X, "X", Common)) ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - RETURN_IF_NULL (X, NULL) ; - RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, NULL) ; - if (X->d < X->nrow) - { - ERROR (CHOLMOD_INVALID, "matrix invalid") ; - return (NULL) ; - } - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* convert the matrix, using template routine */ - /* ---------------------------------------------------------------------- */ - - switch (X->xtype) - { - case CHOLMOD_REAL: - C = r_cholmod_dense_to_sparse (X, values, Common) ; - break ; - - case CHOLMOD_COMPLEX: - C = c_cholmod_dense_to_sparse (X, values, Common) ; - break ; - - case CHOLMOD_ZOMPLEX: - C = z_cholmod_dense_to_sparse (X, values, Common) ; - break ; - } - return (C) ; -} - - -/* ========================================================================== */ -/* === cholmod_copy_dense2 ================================================== */ -/* ========================================================================== */ - -/* Y = X, where X and Y are both already allocated. The leading dimensions of - * X and Y may differ, but both must be >= the # of rows in X and Y. - * Entries in rows nrow to d-1 are not copied from X, since the space might not - * be initialized. Y->nzmax is unchanged. X->nzmax is typically - * (X->d)*(X->ncol), but a user might modify that condition outside of any - * CHOLMOD routine. - * - * The two dense matrices X and Y must have the same numeric xtype. - */ - -int CHOLMOD(copy_dense2) -( - /* ---- input ---- */ - cholmod_dense *X, /* matrix to copy */ - /* ---- output --- */ - cholmod_dense *Y, /* copy of matrix X */ - /* --------------- */ - cholmod_common *Common -) -{ - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (FALSE) ; - RETURN_IF_NULL (X, FALSE) ; - RETURN_IF_NULL (Y, FALSE) ; - RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; - RETURN_IF_XTYPE_INVALID (Y, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; - if (X->nrow != Y->nrow || X->ncol != Y->ncol || X->xtype != Y->xtype) - { - ERROR (CHOLMOD_INVALID, "X and Y must have same dimensions and xtype") ; - return (FALSE) ; - } - if (X->d < X->nrow || Y->d < Y->nrow - || (X->d * X->ncol) > X->nzmax || (Y->d * Y->ncol) > Y->nzmax) - { - ERROR (CHOLMOD_INVALID, "X and/or Y invalid") ; - return (FALSE) ; - } - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* copy the matrix, using template routine */ - /* ---------------------------------------------------------------------- */ - - switch (X->xtype) - { - case CHOLMOD_REAL: - r_cholmod_copy_dense2 (X, Y) ; - break ; - - case CHOLMOD_COMPLEX: - c_cholmod_copy_dense2 (X, Y) ; - break ; - - case CHOLMOD_ZOMPLEX: - z_cholmod_copy_dense2 (X, Y) ; - break ; - } - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === cholmod_copy_dense =================================================== */ -/* ========================================================================== */ - -/* Y = X, copy a dense matrix */ - -cholmod_dense *CHOLMOD(copy_dense) -( - /* ---- input ---- */ - cholmod_dense *X, /* matrix to copy */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_dense *Y ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - RETURN_IF_NULL (X, NULL) ; - RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, NULL) ; - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* allocate result */ - /* ---------------------------------------------------------------------- */ - - Y = CHOLMOD(allocate_dense) (X->nrow, X->ncol, X->d, X->xtype, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory or X invalid */ - } - - /* ---------------------------------------------------------------------- */ - /* Y = X */ - /* ---------------------------------------------------------------------- */ - - /* This cannot fail (X and Y are allocated, and have the same nrow, ncol - * d, and xtype) */ - CHOLMOD(copy_dense2) (X, Y, Common) ; - - /* ---------------------------------------------------------------------- */ - /* return result */ - /* ---------------------------------------------------------------------- */ - - return (Y) ; -} diff --git a/CHOLMOD/Core/cholmod_error.c b/CHOLMOD/Core/cholmod_error.c deleted file mode 100644 index c56e6852c..000000000 --- a/CHOLMOD/Core/cholmod_error.c +++ /dev/null @@ -1,96 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_error: error handling routine -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -#include "cholmod_internal.h" - -/* ========================================================================== */ -/* ==== cholmod_error ======================================================= */ -/* ========================================================================== */ - -/* An error has occurred. Set the status, optionally print an error message, - * and call the user error-handling routine (if it exists). If - * Common->try_catch is TRUE, then CHOLMOD is inside a try/catch block. - * The status is set, but no message is printed and the user error handler - * is not called. This is not (yet) an error, since CHOLMOD may recover. - * - * In the current version, this try/catch mechanism is used internally only in - * cholmod_analyze, which tries multiple ordering methods and picks the best - * one. If one or more ordering method fails, it keeps going. Only one - * ordering needs to succeed for cholmod_analyze to succeed. - */ - -int CHOLMOD(error) -( - /* ---- input ---- */ - int status, /* error status */ - const char *file, /* name of source code file where error occured */ - int line, /* line number in source code file where error occured*/ - const char *message, /* error message */ - /* --------------- */ - cholmod_common *Common -) -{ - RETURN_IF_NULL_COMMON (FALSE) ; - - Common->status = status ; - - if (!(Common->try_catch)) - { - -#ifndef NPRINT - /* print a warning or error message */ - int (*printf_func) (const char *, ...) ; - printf_func = SuiteSparse_config_printf_func_get ( ) ; - if (printf_func != NULL) - { - if (status > 0 && Common->print > 1) - { - printf_func ("CHOLMOD warning:") ; - if (message != NULL) - { - printf_func (" %s.", message) ; - } - if (file != NULL) - { - printf_func (" file: %s", file) ; - printf_func (" line: %d", line) ; - } - printf_func ("\n") ; - fflush (stdout) ; - fflush (stderr) ; - } - else if (Common->print > 0) - { - printf_func ("CHOLMOD error:") ; - if (message != NULL) - { - printf_func (" %s.", message) ; - } - if (file != NULL) - { - printf_func (" file: %s", file) ; - printf_func (" line: %d", line) ; - } - printf_func ("\n") ; - fflush (stdout) ; - fflush (stderr) ; - } - } -#endif - - /* call the user error handler, if it exists */ - if (Common->error_handler != NULL) - { - Common->error_handler (status, file, line, message) ; - } - } - - return (TRUE) ; -} diff --git a/CHOLMOD/Core/cholmod_factor.c b/CHOLMOD/Core/cholmod_factor.c deleted file mode 100644 index f60c1ee00..000000000 --- a/CHOLMOD/Core/cholmod_factor.c +++ /dev/null @@ -1,933 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_factor: core methods for cholmod_factor object -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* Core utility routines for the cholmod_factor object: - * - * The data structure for an LL' or LDL' factorization is too complex to - * describe in one sentence. This object can hold the symbolic analysis alone, - * or in combination with a "simplicial" (similar to a sparse matrix) or - * "supernodal" form of the numerical factorization. Only the routine to free - * a factor is primary, since a factor object is created by the factorization - * routine (cholmod_factorize). It must be freed with cholmod_free_factor. - * - * Primary routine: - * ---------------- - * cholmod_free_factor free a factor - * - * Secondary routines: - * ------------------- - * cholmod_allocate_factor allocate a symbolic factor (LL' or LDL') - * cholmod_reallocate_factor change the # entries in a factor - * cholmod_change_factor change the type of factor (e.g., LDL' to LL') - * cholmod_pack_factor pack the columns of a factor - * cholmod_reallocate_column resize a single column of a factor - * cholmod_factor_to_sparse create a sparse matrix copy of a factor - * cholmod_copy_factor create a copy of a factor - * - * Note that there is no cholmod_sparse_to_factor routine to create a factor - * as a copy of a sparse matrix. It could be done, after a fashion, but a - * lower triangular sparse matrix would not necessarily have a chordal graph, - * which would break the many CHOLMOD routines that rely on this property. - * - * The cholmod_factor_to_sparse routine is provided so that matrix operations - * in the MatrixOps module may be applied to L. Those operations operate on - * cholmod_sparse objects, and they are not guaranteed to maintain the chordal - * property of L. Such a modified L cannot be safely converted back to a - * cholmod_factor object. - */ - -#include "cholmod_internal.h" - -/* ========================================================================== */ -/* === cholmod_allocate_factor ============================================== */ -/* ========================================================================== */ - -/* Allocate a simplicial symbolic factor, with L->Perm and L->ColCount allocated - * and initialized to "empty" values (Perm [k] = k, and ColCount[k] = 1). - * The integer and numerical parts of L are not allocated. L->xtype is returned - * as CHOLMOD_PATTERN and L->is_super are returned as FALSE. L->is_ll is also - * returned FALSE, but this may be modified when the matrix is factorized. - * - * This is sufficient (but far from ideal) for input to cholmod_factorize, - * since the simplicial LL' or LDL' factorization (cholmod_rowfac) can - * reallocate the columns of L as needed. The primary purpose of this routine - * is to allocate space for a symbolic factorization, for the "expert" user to - * do his or her own symbolic analysis. The typical user should use - * cholmod_analyze instead of this routine. - * - * workspace: none - */ - -cholmod_factor *CHOLMOD(allocate_factor) -( - /* ---- input ---- */ - size_t n, /* L is n-by-n */ - /* --------------- */ - cholmod_common *Common -) -{ - Int j ; - Int *Perm, *ColCount ; - cholmod_factor *L ; - int ok = TRUE ; - - RETURN_IF_NULL_COMMON (FALSE) ; - Common->status = CHOLMOD_OK ; - - /* ensure the dimension does not cause integer overflow */ - (void) CHOLMOD(add_size_t) (n, 2, &ok) ; - if (!ok || (int64_t) n >= Int_max) - { - ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; - return (NULL) ; - } - - L = CHOLMOD(malloc) (sizeof (cholmod_factor), 1, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - L->n = n ; - L->is_ll = FALSE ; - L->is_super = FALSE ; - L->is_monotonic = TRUE ; - L->itype = ITYPE ; - L->xtype = CHOLMOD_PATTERN ; - L->dtype = DTYPE ; - - /* allocate the purely symbolic part of L */ - L->ordering = CHOLMOD_NATURAL ; - L->Perm = CHOLMOD(malloc) (n, sizeof (Int), Common) ; - L->IPerm = NULL ; /* only created by cholmod_solve2 when needed */ - L->ColCount = CHOLMOD(malloc) (n, sizeof (Int), Common) ; - - /* simplicial part of L is empty */ - L->nzmax = 0 ; - L->p = NULL ; - L->i = NULL ; - L->x = NULL ; - L->z = NULL ; - L->nz = NULL ; - L->next = NULL ; - L->prev = NULL ; - - /* supernodal part of L is also empty */ - L->nsuper = 0 ; - L->ssize = 0 ; - L->xsize = 0 ; - L->maxesize = 0 ; - L->maxcsize = 0 ; - L->super = NULL ; - L->pi = NULL ; - L->px = NULL ; - L->s = NULL ; - L->useGPU = 0; - - /* L has not been factorized */ - L->minor = n ; - - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free_factor) (&L, Common) ; - return (NULL) ; /* out of memory */ - } - - /* initialize Perm and ColCount */ - Perm = L->Perm ; - for (j = 0 ; j < ((Int) n) ; j++) - { - Perm [j] = j ; - } - ColCount = L->ColCount ; - for (j = 0 ; j < ((Int) n) ; j++) - { - ColCount [j] = 1 ; - } - - return (L) ; -} - - -/* ========================================================================== */ -/* === cholmod_free_factor ================================================== */ -/* ========================================================================== */ - -/* Free a factor object. - * - * workspace: none - */ - -int CHOLMOD(free_factor) -( - /* ---- in/out --- */ - cholmod_factor **LHandle, /* factor to free, NULL on output */ - /* --------------- */ - cholmod_common *Common -) -{ - Int n, lnz, xs, ss, s ; - cholmod_factor *L ; - - RETURN_IF_NULL_COMMON (FALSE) ; - - if (LHandle == NULL) - { - /* nothing to do */ - return (TRUE) ; - } - L = *LHandle ; - if (L == NULL) - { - /* nothing to do */ - return (TRUE) ; - } - - n = L->n ; - lnz = L->nzmax ; - s = L->nsuper + 1 ; - xs = (L->is_super) ? ((Int) (L->xsize)) : (lnz) ; - ss = L->ssize ; - - /* symbolic part of L */ - CHOLMOD(free) (n, sizeof (Int), L->Perm, Common) ; - CHOLMOD(free) (n, sizeof (Int), L->IPerm, Common) ; - CHOLMOD(free) (n, sizeof (Int), L->ColCount, Common) ; - - /* simplicial form of L */ - CHOLMOD(free) (n+1, sizeof (Int), L->p, Common) ; - CHOLMOD(free) (lnz, sizeof (Int), L->i, Common) ; - CHOLMOD(free) (n, sizeof (Int), L->nz, Common) ; - CHOLMOD(free) (n+2, sizeof (Int), L->next, Common) ; - CHOLMOD(free) (n+2, sizeof (Int), L->prev, Common) ; - - /* supernodal form of L */ - CHOLMOD(free) (s, sizeof (Int), L->pi, Common) ; - CHOLMOD(free) (s, sizeof (Int), L->px, Common) ; - CHOLMOD(free) (s, sizeof (Int), L->super, Common) ; - CHOLMOD(free) (ss, sizeof (Int), L->s, Common) ; - - /* numerical values for both simplicial and supernodal L */ - if (L->xtype == CHOLMOD_REAL) - { - CHOLMOD(free) (xs, sizeof (double), L->x, Common) ; - } - else if (L->xtype == CHOLMOD_COMPLEX) - { - CHOLMOD(free) (xs, 2*sizeof (double), L->x, Common) ; - } - else if (L->xtype == CHOLMOD_ZOMPLEX) - { - CHOLMOD(free) (xs, sizeof (double), L->x, Common) ; - CHOLMOD(free) (xs, sizeof (double), L->z, Common) ; - } - - *LHandle = CHOLMOD(free) (1, sizeof (cholmod_factor), (*LHandle), Common) ; - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === cholmod_reallocate_factor ============================================ */ -/* ========================================================================== */ - -/* Change the size of L->i and L->x, or allocate them if their current size - * is zero. L must be simplicial. - * - * workspace: none - */ - -int CHOLMOD(reallocate_factor) -( - /* ---- input ---- */ - size_t nznew, /* new # of entries in L */ - /* ---- in/out --- */ - cholmod_factor *L, /* factor to modify */ - /* --------------- */ - cholmod_common *Common -) -{ - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (FALSE) ; - RETURN_IF_NULL (L, FALSE) ; - RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; - PRINT1 (("realloc factor: xtype %d\n", L->xtype)) ; - if (L->is_super) - { - /* L must be simplicial, and not symbolic */ - ERROR (CHOLMOD_INVALID, "L invalid") ; - return (FALSE) ; - } - Common->status = CHOLMOD_OK ; - PRINT1 (("realloc factor %g to %g\n", (double) L->nzmax, (double) nznew)) ; - - /* ---------------------------------------------------------------------- */ - /* resize (or allocate) the L->i and L->x components of the factor */ - /* ---------------------------------------------------------------------- */ - - CHOLMOD(realloc_multiple) (nznew, 1, L->xtype, &(L->i), NULL, - &(L->x), &(L->z), &(L->nzmax), Common) ; - return (Common->status == CHOLMOD_OK) ; -} - - -/* ========================================================================== */ -/* === cholmod_reallocate_column =========================================== */ -/* ========================================================================== */ - -/* Column j needs more space, reallocate it at the end of L->i and L->x. - * If the reallocation fails, the factor is converted to a simplicial - * symbolic factor (no pattern, just L->Perm and L->ColCount). - * - * workspace: none - */ - -int CHOLMOD(reallocate_column) -( - /* ---- input ---- */ - size_t j, /* the column to reallocate */ - size_t need, /* required size of column j */ - /* ---- in/out --- */ - cholmod_factor *L, /* factor to modify */ - /* --------------- */ - cholmod_common *Common -) -{ - double xneed ; - double *Lx, *Lz ; - Int *Lp, *Lprev, *Lnext, *Li, *Lnz ; - Int n, pold, pnew, len, k, tail ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (FALSE) ; - RETURN_IF_NULL (L, FALSE) ; - RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; - if (L->is_super) - { - ERROR (CHOLMOD_INVALID, "L must be simplicial") ; - return (FALSE) ; - } - n = L->n ; - if (j >= L->n || need == 0) - { - ERROR (CHOLMOD_INVALID, "j invalid") ; - return (FALSE) ; /* j out of range */ - } - Common->status = CHOLMOD_OK ; - - DEBUG (CHOLMOD(dump_factor) (L, "start colrealloc", Common)) ; - - /* ---------------------------------------------------------------------- */ - /* increase the size of L if needed */ - /* ---------------------------------------------------------------------- */ - - /* head = n+1 ; */ - tail = n ; - Lp = L->p ; - Lnz = L->nz ; - Lprev = L->prev ; - Lnext = L->next ; - - ASSERT (Lnz != NULL) ; - ASSERT (Lnext != NULL && Lprev != NULL) ; - PRINT1 (("col %g need %g\n", (double) j, (double) need)) ; - - /* column j cannot have more than n-j entries if all entries are present */ - need = MIN (need, n-j) ; - - /* compute need in double to avoid integer overflow */ - if (Common->grow1 >= 1.0) - { - xneed = (double) need ; - xneed = Common->grow1 * xneed + Common->grow2 ; - xneed = MIN (xneed, n-j) ; - need = (Int) xneed ; - } - PRINT1 (("really new need %g current %g\n", (double) need, - (double) (Lp [Lnext [j]] - Lp [j]))) ; - ASSERT (need >= 1 && need <= n-j) ; - - if (Lp [Lnext [j]] - Lp [j] >= (Int) need) - { - /* no need to reallocate the column, it's already big enough */ - PRINT1 (("colrealloc: quick return %g %g\n", - (double) (Lp [Lnext [j]] - Lp [j]), (double) need)) ; - return (TRUE) ; - - } - - if (Lp [tail] + need > L->nzmax) - { - /* use double to avoid integer overflow */ - xneed = (double) need ; - if (Common->grow0 < 1.2) /* fl. pt. compare, false if NaN */ - { - /* if grow0 is less than 1.2 or NaN, don't use it */ - xneed = 1.2 * (((double) L->nzmax) + xneed + 1) ; - } - else - { - xneed = Common->grow0 * (((double) L->nzmax) + xneed + 1) ; - } - if (xneed > (double) SIZE_MAX || - !CHOLMOD(reallocate_factor) ((Int) xneed, L, Common)) - { - /* out of memory, convert to simplicial symbolic */ - CHOLMOD(change_factor) (CHOLMOD_PATTERN, L->is_ll, FALSE, TRUE, - TRUE, L, Common) ; - ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory; L now symbolic") ; - return (FALSE) ; /* out of memory */ - } - PRINT1 (("\n=== GROW L from %g to %g\n", - (double) L->nzmax, (double) xneed)) ; - /* pack all columns so that each column has at most grow2 free space */ - CHOLMOD(pack_factor) (L, Common) ; - ASSERT (Common->status == CHOLMOD_OK) ; - Common->nrealloc_factor++ ; - } - - /* ---------------------------------------------------------------------- */ - /* reallocate the column */ - /* ---------------------------------------------------------------------- */ - - Common->nrealloc_col++ ; - - Li = L->i ; - Lx = L->x ; - Lz = L->z ; - - /* remove j from its current position in the list */ - Lnext [Lprev [j]] = Lnext [j] ; - Lprev [Lnext [j]] = Lprev [j] ; - - /* place j at the end of the list */ - Lnext [Lprev [tail]] = j ; - Lprev [j] = Lprev [tail] ; - Lnext [j] = n ; - Lprev [tail] = j ; - - /* L is no longer monotonic; columns are out-of-order */ - L->is_monotonic = FALSE ; - - /* allocate space for column j */ - pold = Lp [j] ; - pnew = Lp [tail] ; - Lp [j] = pnew ; - Lp [tail] += need ; - - /* copy column j to the new space */ - len = Lnz [j] ; - for (k = 0 ; k < len ; k++) - { - Li [pnew + k] = Li [pold + k] ; - } - - if (L->xtype == CHOLMOD_REAL) - { - for (k = 0 ; k < len ; k++) - { - Lx [pnew + k] = Lx [pold + k] ; - } - } - else if (L->xtype == CHOLMOD_COMPLEX) - { - for (k = 0 ; k < len ; k++) - { - Lx [2*(pnew + k) ] = Lx [2*(pold + k) ] ; - Lx [2*(pnew + k)+1] = Lx [2*(pold + k)+1] ; - } - } - else if (L->xtype == CHOLMOD_ZOMPLEX) - { - for (k = 0 ; k < len ; k++) - { - Lx [pnew + k] = Lx [pold + k] ; - Lz [pnew + k] = Lz [pold + k] ; - } - } - - DEBUG (CHOLMOD(dump_factor) (L, "colrealloc done", Common)) ; - - /* successful reallocation of column j of L */ - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === cholmod_pack_factor ================================================== */ -/* ========================================================================== */ - -/* Pack the columns of a simplicial LDL' or LL' factor. This can be followed - * by a call to cholmod_reallocate_factor to reduce the size of L to the exact - * size required by the factor, if desired. Alternatively, you can leave the - * size of L->i and L->x the same, to allow space for future updates/rowadds. - * - * Each column is reduced in size so that it has at most Common->grow2 free - * space at the end of the column. - * - * Does nothing and returns silently if given any other type of factor. - * - * Does NOT force the columns of L to be monotonic. It thus differs from - * cholmod_change_factor (xtype, -, FALSE, TRUE, TRUE, L, Common), which - * packs the columns and ensures that they appear in monotonic order. - */ - -int CHOLMOD(pack_factor) -( - /* ---- in/out --- */ - cholmod_factor *L, /* factor to modify */ - /* --------------- */ - cholmod_common *Common -) -{ - double *Lx, *Lz ; - Int *Lp, *Li, *Lnz, *Lnext ; - Int pnew, j, k, pold, len, n, head, tail, grow2 ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (FALSE) ; - RETURN_IF_NULL (L, FALSE) ; - RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; - Common->status = CHOLMOD_OK ; - DEBUG (CHOLMOD(dump_factor) (L, "start pack", Common)) ; - PRINT1 (("PACK factor %d\n", L->is_super)) ; - - if (L->xtype == CHOLMOD_PATTERN || L->is_super) - { - /* nothing to do unless L is simplicial numeric */ - return (TRUE) ; - } - - /* ---------------------------------------------------------------------- */ - /* pack */ - /* ---------------------------------------------------------------------- */ - - grow2 = Common->grow2 ; - PRINT1 (("\nPACK grow2 "ID"\n", grow2)) ; - - pnew = 0 ; - n = L->n ; - Lp = L->p ; - Li = L->i ; - Lx = L->x ; - Lz = L->z ; - Lnz = L->nz ; - Lnext = L->next ; - - head = n+1 ; - tail = n ; - - for (j = Lnext [head] ; j != tail ; j = Lnext [j]) - { - /* pack column j */ - pold = Lp [j] ; - len = Lnz [j] ; - ASSERT (len > 0) ; - PRINT2 (("col "ID" pnew "ID" pold "ID"\n", j, pnew, pold)) ; - if (pnew < pold) - { - PRINT2 ((" pack this column\n")) ; - - for (k = 0 ; k < len ; k++) - { - Li [pnew + k] = Li [pold + k] ; - } - - if (L->xtype == CHOLMOD_REAL) - { - for (k = 0 ; k < len ; k++) - { - Lx [pnew + k] = Lx [pold + k] ; - } - } - else if (L->xtype == CHOLMOD_COMPLEX) - { - for (k = 0 ; k < len ; k++) - { - Lx [2*(pnew + k) ] = Lx [2*(pold + k) ] ; - Lx [2*(pnew + k)+1] = Lx [2*(pold + k)+1] ; - } - } - else if (L->xtype == CHOLMOD_ZOMPLEX) - { - for (k = 0 ; k < len ; k++) - { - Lx [pnew + k] = Lx [pold + k] ; - Lz [pnew + k] = Lz [pold + k] ; - } - } - - Lp [j] = pnew ; - } - len = MIN (len + grow2, n - j) ; - pnew = MIN (Lp [j] + len, Lp [Lnext [j]]) ; - } - PRINT2 (("final pnew = "ID"\n", pnew)) ; - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === cholmod_factor_to_sparse ============================================= */ -/* ========================================================================== */ - -/* Constructs a column-oriented sparse matrix containing the pattern and values - * of a simplicial or supernodal numerical factor, and then converts the factor - * into a simplicial symbolic factor. If L is already packed, monotonic, - * and simplicial (which is the case when cholmod_factorize uses the simplicial - * Cholesky factorization algorithm) then this routine requires only O(1) - * memory and takes O(1) time. - * - * Only operates on numeric factors (real, complex, or zomplex). Does not - * change the numeric L->xtype (the resulting sparse matrix has the same xtype - * as L). If this routine fails, L is left unmodified. - */ - -cholmod_sparse *CHOLMOD(factor_to_sparse) -( - /* ---- in/out --- */ - cholmod_factor *L, /* factor to copy, converted to symbolic on output */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_sparse *Lsparse ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - RETURN_IF_NULL (L, NULL) ; - RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, NULL) ; - Common->status = CHOLMOD_OK ; - DEBUG (CHOLMOD(dump_factor) (L, "start convert to matrix", Common)) ; - - /* ---------------------------------------------------------------------- */ - /* convert to packed, monotonic, simplicial, numeric */ - /* ---------------------------------------------------------------------- */ - - /* leave as LL or LDL' */ - if (!CHOLMOD(change_factor) (L->xtype, L->is_ll, FALSE, TRUE, TRUE, L, - Common)) - { - ERROR (CHOLMOD_INVALID, "cannot convert L") ; - return (NULL) ; - } - - /* ---------------------------------------------------------------------- */ - /* create Lsparse */ - /* ---------------------------------------------------------------------- */ - - /* allocate the header for Lsparse, the sparse matrix version of L */ - Lsparse = CHOLMOD(malloc) (sizeof (cholmod_sparse), 1, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - - /* transfer the contents from L to Lsparse */ - Lsparse->nrow = L->n ; - Lsparse->ncol = L->n ; - Lsparse->p = L->p ; - Lsparse->i = L->i ; - Lsparse->x = L->x ; - Lsparse->z = L->z ; - Lsparse->nz = NULL ; - Lsparse->stype = 0 ; - Lsparse->itype = L->itype ; - Lsparse->xtype = L->xtype ; - Lsparse->dtype = L->dtype ; - Lsparse->sorted = TRUE ; - Lsparse->packed = TRUE ; - Lsparse->nzmax = L->nzmax ; - ASSERT (CHOLMOD(dump_sparse) (Lsparse, "Lsparse", Common) >= 0) ; - - /* ---------------------------------------------------------------------- */ - /* convert L to symbolic, but do not free contents transfered to Lsparse */ - /* ---------------------------------------------------------------------- */ - - L->p = NULL ; - L->i = NULL ; - L->x = NULL ; - L->z = NULL ; - L->xtype = CHOLMOD_PATTERN ; - CHOLMOD(change_factor) (CHOLMOD_PATTERN, FALSE, FALSE, TRUE, TRUE, L, - Common) ; - - return (Lsparse) ; -} - - -/* ========================================================================== */ -/* === cholmod_copy_factor ================================================== */ -/* ========================================================================== */ - -/* Create an exact copy of a factor, with one exception: - * - * Entries in unused space are not copied (they might not be initialized, - * and copying them would cause program checkers such as purify and - * valgrind to complain). - * - * Note that a supernodal L cannot be zomplex. - */ - -cholmod_factor *CHOLMOD(copy_factor) -( - /* ---- input ---- */ - cholmod_factor *L, /* factor to copy */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_factor *L2 ; - double *Lx, *L2x, *Lz, *L2z ; - Int *Perm, *ColCount, *Lp, *Li, *Lnz, *Lnext, *Lprev, *Lsuper, *Lpi, *Lpx, - *Ls, *Perm2, *ColCount2, *L2p, *L2i, *L2nz, *L2next, *L2prev, *L2super, - *L2pi, *L2px, *L2s ; - Int n, j, p, pend, s, xsize, ssize, nsuper ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - RETURN_IF_NULL (L, NULL) ; - RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; - Common->status = CHOLMOD_OK ; - DEBUG (CHOLMOD(dump_factor) (L, "start copy", Common)) ; - - n = L->n ; - - /* ---------------------------------------------------------------------- */ - /* allocate a simplicial symbolic factor */ - /* ---------------------------------------------------------------------- */ - - /* allocates L2->Perm and L2->ColCount */ - L2 = CHOLMOD(allocate_factor) (n, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - ASSERT (L2->xtype == CHOLMOD_PATTERN && !(L2->is_super)) ; - - Perm = L->Perm ; - ColCount = L->ColCount ; - Perm2 = L2->Perm ; - ColCount2 = L2->ColCount ; - L2->ordering = L->ordering ; - - for (j = 0 ; j < n ; j++) - { - Perm2 [j] = Perm [j] ; - } - for (j = 0 ; j < n ; j++) - { - ColCount2 [j] = ColCount [j] ; - } - L2->is_ll = L->is_ll ; - - /* ---------------------------------------------------------------------- */ - /* copy the rest of the factor */ - /* ---------------------------------------------------------------------- */ - - if (L->xtype != CHOLMOD_PATTERN && !(L->super)) - { - - /* ------------------------------------------------------------------ */ - /* allocate a simplicial numeric factor */ - /* ------------------------------------------------------------------ */ - - /* allocate L2->p, L2->nz, L2->prev, L2->next, L2->i, and L2->x. - * packed = -1 so that cholmod_change_factor allocates space of - * size L2->nzmax */ - L2->nzmax = L->nzmax ; - if (!CHOLMOD(change_factor) (L->xtype, L->is_ll, FALSE, -1, TRUE, - L2, Common)) - { - CHOLMOD(free_factor) (&L2, Common) ; - return (NULL) ; /* out of memory */ - } - ASSERT (MAX (1, L->nzmax) == L2->nzmax) ; - - /* ------------------------------------------------------------------ */ - /* copy the contents of a simplicial numeric factor */ - /* ------------------------------------------------------------------ */ - - Lp = L->p ; - Li = L->i ; - Lx = L->x ; - Lz = L->z ; - Lnz = L->nz ; - Lnext = L->next ; - Lprev = L->prev ; - - L2p = L2->p ; - L2i = L2->i ; - L2x = L2->x ; - L2z = L2->z ; - L2nz = L2->nz ; - L2next = L2->next ; - L2prev = L2->prev ; - L2->xtype = L->xtype ; - L2->dtype = L->dtype ; - - for (j = 0 ; j <= n ; j++) - { - L2p [j] = Lp [j] ; - } - - for (j = 0 ; j < n+2 ; j++) - { - L2prev [j] = Lprev [j] ; - } - - for (j = 0 ; j < n+2 ; j++) - { - L2next [j] = Lnext [j] ; - } - - for (j = 0 ; j < n ; j++) - { - L2nz [j] = Lnz [j] ; - } - - for (j = 0 ; j < n ; j++) - { - p = Lp [j] ; - pend = p + Lnz [j] ; - for ( ; p < pend ; p++) - { - L2i [p] = Li [p] ; - } - p = Lp [j] ; - - if (L->xtype == CHOLMOD_REAL) - { - for ( ; p < pend ; p++) - { - L2x [p] = Lx [p] ; - } - } - else if (L->xtype == CHOLMOD_COMPLEX) - { - for ( ; p < pend ; p++) - { - L2x [2*p ] = Lx [2*p ] ; - L2x [2*p+1] = Lx [2*p+1] ; - } - } - else if (L->xtype == CHOLMOD_ZOMPLEX) - { - for ( ; p < pend ; p++) - { - L2x [p] = Lx [p] ; - L2z [p] = Lz [p] ; - } - } - - } - - } - else if (L->is_super) - { - - /* ------------------------------------------------------------------ */ - /* copy a supernodal factor */ - /* ------------------------------------------------------------------ */ - - xsize = L->xsize ; - ssize = L->ssize ; - nsuper = L->nsuper ; - - L2->xsize = xsize ; - L2->ssize = ssize ; - L2->nsuper = nsuper ; - - /* allocate L2->super, L2->pi, L2->px, and L2->s. Allocate L2->x if - * L is numeric */ - if (!CHOLMOD(change_factor) (L->xtype, TRUE, TRUE, TRUE, TRUE, L2, - Common)) - { - CHOLMOD(free_factor) (&L2, Common) ; - return (NULL) ; /* out of memory */ - } - - ASSERT (L2->s != NULL) ; - - /* ------------------------------------------------------------------ */ - /* copy the contents of a supernodal factor */ - /* ------------------------------------------------------------------ */ - - Lsuper = L->super ; - Lpi = L->pi ; - Lpx = L->px ; - Ls = L->s ; - Lx = L->x ; - - L2super = L2->super ; - L2pi = L2->pi ; - L2px = L2->px ; - L2s = L2->s ; - L2x = L2->x ; - - L2->maxcsize = L->maxcsize ; - L2->maxesize = L->maxesize ; - - for (s = 0 ; s <= nsuper ; s++) - { - L2super [s] = Lsuper [s] ; - } - for (s = 0 ; s <= nsuper ; s++) - { - L2pi [s] = Lpi [s] ; - } - for (s = 0 ; s <= nsuper ; s++) - { - L2px [s] = Lpx [s] ; - } - - L2s [0] = 0 ; - for (p = 0 ; p < ssize ; p++) - { - L2s [p] = Ls [p] ; - } - - if (L->xtype == CHOLMOD_REAL) - { - for (p = 0 ; p < xsize ; p++) - { - L2x [p] = Lx [p] ; - } - } - else if (L->xtype == CHOLMOD_COMPLEX) - { - for (p = 0 ; p < 2*xsize ; p++) - { - L2x [p] = Lx [p] ; - } - } - } - - L2->minor = L->minor ; - L2->is_monotonic = L->is_monotonic ; - - DEBUG (CHOLMOD(dump_factor) (L2, "L2 got copied", Common)) ; - ASSERT (L2->xtype == L->xtype && L2->is_super == L->is_super) ; - return (L2) ; -} diff --git a/CHOLMOD/Core/cholmod_l_common.c b/CHOLMOD/Core/cholmod_l_common.c deleted file mode 100644 index 9a062f870..000000000 --- a/CHOLMOD/Core/cholmod_l_common.c +++ /dev/null @@ -1,13 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_common.c: int64_t version of cholmod_common -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -#define DLONG -#include "cholmod_common.c" - diff --git a/CHOLMOD/Core/cholmod_l_complex.c b/CHOLMOD/Core/cholmod_l_complex.c deleted file mode 100644 index 8d93936a1..000000000 --- a/CHOLMOD/Core/cholmod_l_complex.c +++ /dev/null @@ -1,13 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_complex.c: int64_t version of cholmod_complex -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -#define DLONG -#include "cholmod_complex.c" - diff --git a/CHOLMOD/Core/cholmod_l_dense.c b/CHOLMOD/Core/cholmod_l_dense.c deleted file mode 100644 index bc354d98f..000000000 --- a/CHOLMOD/Core/cholmod_l_dense.c +++ /dev/null @@ -1,13 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_dense.c: int64_t version of cholmod_dense -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -#define DLONG -#include "cholmod_dense.c" - diff --git a/CHOLMOD/Core/cholmod_l_error.c b/CHOLMOD/Core/cholmod_l_error.c deleted file mode 100644 index 62090ca31..000000000 --- a/CHOLMOD/Core/cholmod_l_error.c +++ /dev/null @@ -1,13 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_error.c: int64_t version of cholmod_error -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -#define DLONG -#include "cholmod_error.c" - diff --git a/CHOLMOD/Core/cholmod_l_memory.c b/CHOLMOD/Core/cholmod_l_memory.c deleted file mode 100644 index 564303bad..000000000 --- a/CHOLMOD/Core/cholmod_l_memory.c +++ /dev/null @@ -1,13 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_memory.c: int64_t version of cholmod_memory -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -#define DLONG -#include "cholmod_memory.c" - diff --git a/CHOLMOD/Core/cholmod_l_sparse.c b/CHOLMOD/Core/cholmod_l_sparse.c deleted file mode 100644 index 1bb2f27a4..000000000 --- a/CHOLMOD/Core/cholmod_l_sparse.c +++ /dev/null @@ -1,13 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_sparse.c: int64_t version of cholmod_sparse -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -#define DLONG -#include "cholmod_sparse.c" - diff --git a/CHOLMOD/Core/cholmod_l_transpose.c b/CHOLMOD/Core/cholmod_l_transpose.c deleted file mode 100644 index 57fb11ed3..000000000 --- a/CHOLMOD/Core/cholmod_l_transpose.c +++ /dev/null @@ -1,13 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_transpose.c: int64_t version of cholmod_transpose -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -#define DLONG -#include "cholmod_transpose.c" - diff --git a/CHOLMOD/Core/cholmod_l_version.c b/CHOLMOD/Core/cholmod_l_version.c deleted file mode 100644 index 039e2abb8..000000000 --- a/CHOLMOD/Core/cholmod_l_version.c +++ /dev/null @@ -1,13 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_version.c: int64_t version of cholmod_version -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -#define DLONG -#include "cholmod_version.c" - diff --git a/CHOLMOD/Core/cholmod_memory.c b/CHOLMOD/Core/cholmod_memory.c deleted file mode 100644 index bc1b25f20..000000000 --- a/CHOLMOD/Core/cholmod_memory.c +++ /dev/null @@ -1,553 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_memory: memory management routines -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* Core memory management routines: - * - * Primary routines: - * ----------------- - * cholmod_malloc malloc wrapper - * cholmod_free free wrapper - * - * Secondary routines: - * ------------------- - * cholmod_calloc calloc wrapper - * cholmod_realloc realloc wrapper - * cholmod_realloc_multiple realloc wrapper for multiple objects - * - * The user may make use of these, just like malloc and free. You can even - * malloc an object and safely free it with cholmod_free, and visa versa - * (except that the memory usage statistics will be corrupted). These routines - * do differ from malloc and free. If cholmod_free is given a NULL pointer, - * for example, it does nothing (unlike the ANSI free). cholmod_realloc does - * not return NULL if given a non-NULL pointer and a nonzero size, even if it - * fails (it sets an error code in Common->status instead). - * - * CHOLMOD keeps track of the amount of memory it has allocated, and so the - * cholmod_free routine includes as a parameter the size of the object being - * freed. This is only used for memory usage statistics, which are very useful - * in finding memory leaks in your program. If you, the user of CHOLMOD, pass - * the wrong size, the only consequence is that the memory usage statistics - * will be invalid. This will causes assertions to fail if CHOLMOD is - * compiled with debugging enabled, but otherwise it will cause no errors. - * - * The cholmod_free_* routines for each CHOLMOD object keep track of the size - * of the blocks they free, so they do not require you to pass their sizes - * as a parameter. - * - * If a block of size zero is requested, these routines allocate a block of - * size one instead. - */ - -#include "cholmod_internal.h" - -/* ========================================================================== */ -/* === cholmod_add_size_t =================================================== */ -/* ========================================================================== */ - -/* Safely compute a+b, and check for integer overflow. If overflow occurs, - * return 0 and set OK to FALSE. Also return 0 if OK is FALSE on input. */ - -size_t CHOLMOD(add_size_t) (size_t a, size_t b, int *ok) -{ - size_t s = a + b ; - (*ok) = (*ok) && (s >= a) ; - return ((*ok) ? s : 0) ; -} - -/* ========================================================================== */ -/* === cholmod_mult_size_t ================================================== */ -/* ========================================================================== */ - -/* Safely compute a*k, where k should be small, and check for integer overflow. - * If overflow occurs, return 0 and set OK to FALSE. Also return 0 if OK is - * FALSE on input. */ - -size_t CHOLMOD(mult_size_t) (size_t a, size_t k, int *ok) -{ - size_t p = 0, s ; - while (*ok) - { - if (k % 2) - { - p = p + a ; - (*ok) = (*ok) && (p >= a) ; - } - k = k / 2 ; - if (!k) return (p) ; - s = a + a ; - (*ok) = (*ok) && (s >= a) ; - a = s ; - } - return (0) ; -} - - -/* ========================================================================== */ -/* === cholmod_malloc ======================================================= */ -/* ========================================================================== */ - -/* Wrapper around malloc routine. Allocates space of size MAX(1,n)*size, where - * size is normally a sizeof (...). - * - * This routine, cholmod_calloc, and cholmod_realloc do not set Common->status - * to CHOLMOD_OK on success, so that a sequence of cholmod_malloc's, _calloc's, - * or _realloc's can be used. If any of them fails, the Common->status will - * hold the most recent error status. - * - * Usage, for a pointer to int: - * - * p = cholmod_malloc (n, sizeof (int), Common) - * - * Uses a pointer to the malloc routine (or its equivalent) defined in Common. - */ - -void *CHOLMOD(malloc) /* returns pointer to the newly malloc'd block */ -( - /* ---- input ---- */ - size_t n, /* number of items */ - size_t size, /* size of each item */ - /* --------------- */ - cholmod_common *Common -) -{ - void *p ; - size_t s ; - /* - int ok = TRUE ; - */ - - RETURN_IF_NULL_COMMON (NULL) ; - if (size == 0) - { - ERROR (CHOLMOD_INVALID, "sizeof(item) must be > 0") ; - p = NULL ; - } - else if (n >= (SIZE_MAX / size) || (int64_t) n >= Int_max) - { - /* object is too big to allocate without causing integer overflow */ - ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; - p = NULL ; - } - else - { - /* call malloc, or its equivalent */ - p = SuiteSparse_malloc (n, size) ; - - if (p == NULL) - { - /* failure: out of memory */ - ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory") ; - } - else - { - /* success: increment the count of objects allocated */ - Common->malloc_count++ ; - Common->memory_inuse += (n * size) ; - Common->memory_usage = - MAX (Common->memory_usage, Common->memory_inuse) ; - PRINTM (("cholmod_malloc %p %g cnt: %g inuse %g\n", - p, (double) n*size, (double) Common->malloc_count, - (double) Common->memory_inuse)) ; - } - } - return (p) ; -} - - -/* ========================================================================== */ -/* === cholmod_free ========================================================= */ -/* ========================================================================== */ - -/* Wrapper around free routine. Returns NULL, which can be assigned to the - * pointer being freed, as in: - * - * p = cholmod_free (n, sizeof (int), p, Common) ; - * - * In CHOLMOD, the syntax: - * - * cholmod_free (n, sizeof (int), p, Common) ; - * - * is used if p is a local pointer and the routine is returning shortly. - * Uses a pointer to the free routine (or its equivalent) defined in Common. - * Nothing is freed if the pointer is NULL. - */ - -void *CHOLMOD(free) /* always returns NULL */ -( - /* ---- input ---- */ - size_t n, /* number of items */ - size_t size, /* size of each item */ - /* ---- in/out --- */ - void *p, /* block of memory to free */ - /* --------------- */ - cholmod_common *Common -) -{ - RETURN_IF_NULL_COMMON (NULL) ; - if (p != NULL) - { - /* only free the object if the pointer is not NULL */ - /* call free, or its equivalent */ - SuiteSparse_free (p) ; - - Common->malloc_count-- ; - Common->memory_inuse -= (n * size) ; - PRINTM (("cholmod_free %p %g cnt: %g inuse %g\n", - p, (double) n*size, (double) Common->malloc_count, - (double) Common->memory_inuse)) ; - /* This assertion will fail if the user calls cholmod_malloc and - * cholmod_free with mismatched memory sizes. It shouldn't fail - * otherwise. */ - ASSERT (IMPLIES (Common->malloc_count == 0, Common->memory_inuse == 0)); - } - /* return NULL, and the caller should assign this to p. This avoids - * freeing the same pointer twice. */ - return (NULL) ; -} - - -/* ========================================================================== */ -/* === cholmod_calloc ======================================================= */ -/* ========================================================================== */ - -/* Wrapper around calloc routine. - * - * Uses a pointer to the calloc routine (or its equivalent) defined in Common. - * This routine is identical to malloc, except that it zeros the newly allocated - * block to zero. - */ - -void *CHOLMOD(calloc) /* returns pointer to the newly calloc'd block */ -( - /* ---- input ---- */ - size_t n, /* number of items */ - size_t size, /* size of each item */ - /* --------------- */ - cholmod_common *Common -) -{ - void *p ; - - RETURN_IF_NULL_COMMON (NULL) ; - if (size == 0) - { - ERROR (CHOLMOD_INVALID, "sizeof(item) must be > 0") ; - p = NULL ; - } - else if (n >= (SIZE_MAX / size) || (int64_t) n >= Int_max) - { - /* object is too big to allocate without causing integer overflow */ - ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; - p = NULL ; - } - else - { - /* call calloc, or its equivalent */ - p = SuiteSparse_calloc (n, size) ; - - if (p == NULL) - { - /* failure: out of memory */ - ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory") ; - } - else - { - /* success: increment the count of objects allocated */ - Common->malloc_count++ ; - Common->memory_inuse += (n * size) ; - Common->memory_usage = - MAX (Common->memory_usage, Common->memory_inuse) ; - PRINTM (("cholmod_malloc %p %g cnt: %g inuse %g\n", - p, (double) n*size, (double) Common->malloc_count, - (double) Common->memory_inuse)) ; - } - } - return (p) ; -} - - -/* ========================================================================== */ -/* === cholmod_realloc ====================================================== */ -/* ========================================================================== */ - -/* Wrapper around realloc routine. Given a pointer p to a block of size - * (*n)*size memory, it changes the size of the block pointed to by p to be - * MAX(1,nnew)*size in size. It may return a pointer different than p. This - * should be used as (for a pointer to int): - * - * p = cholmod_realloc (nnew, sizeof (int), p, *n, Common) ; - * - * If p is NULL, this is the same as p = cholmod_malloc (...). - * A size of nnew=0 is treated as nnew=1. - * - * If the realloc fails, p is returned unchanged and Common->status is set - * to CHOLMOD_OUT_OF_MEMORY. If successful, Common->status is not modified, - * and p is returned (possibly changed) and pointing to a large block of memory. - * - * Uses a pointer to the realloc routine (or its equivalent) defined in Common. - */ - -void *CHOLMOD(realloc) /* returns pointer to reallocated block */ -( - /* ---- input ---- */ - size_t nnew, /* requested # of items in reallocated block */ - size_t size, /* size of each item */ - /* ---- in/out --- */ - void *p, /* block of memory to realloc */ - size_t *n, /* current size on input, nnew on output if successful*/ - /* --------------- */ - cholmod_common *Common -) -{ - size_t nold = (*n) ; - void *pnew ; - size_t s ; - int ok = TRUE ; - - RETURN_IF_NULL_COMMON (NULL) ; - if (size == 0) - { - ERROR (CHOLMOD_INVALID, "sizeof(item) must be > 0") ; - p = NULL ; - } - else if (p == NULL) - { - /* A fresh object is being allocated. */ - PRINT1 (("realloc fresh: %d %d\n", nnew, size)) ; - p = CHOLMOD(malloc) (nnew, size, Common) ; - *n = (p == NULL) ? 0 : nnew ; - } - else if (nold == nnew) - { - /* Nothing to do. Do not change p or n. */ - PRINT1 (("realloc nothing: %d %d\n", nnew, size)) ; - } - else if (nnew >= (SIZE_MAX / size) || (int64_t) nnew >= Int_max) - { - /* failure: nnew is too big. Do not change p or n. */ - ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; - } - else - { - /* The object exists, and is changing to some other nonzero size. */ - /* call realloc, or its equivalent */ - PRINT1 (("realloc : %d to %d, %d\n", nold, nnew, size)) ; - pnew = SuiteSparse_realloc (nnew, nold, size, p, &ok) ; - if (ok) - { - /* success: return revised p and change the size of the block */ - PRINTM (("cholmod_free %p %g cnt: %g inuse %g\n" - "cholmod_malloc %p %g cnt: %g inuse %g\n", - p, (double) nold*size, (double) Common->malloc_count-1, - (double) (Common->memory_inuse - nold*size), - pnew, (double) nnew*size, (double) Common->malloc_count, - (double) (Common->memory_inuse + (nnew-nold)*size))) ; - p = pnew ; - *n = nnew ; - Common->memory_inuse += ((nnew-nold) * size) ; - } - else - { - /* Increasing the size of the block has failed. - * Do not change n. */ - ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory") ; - } - - Common->memory_usage = MAX (Common->memory_usage, Common->memory_inuse); - } - - return (p) ; -} - - -/* ========================================================================== */ -/* === cholmod_realloc_multiple ============================================= */ -/* ========================================================================== */ - -/* reallocate multiple blocks of memory, all of the same size (up to two integer - * and two real blocks). Either reallocations all succeed, or all are returned - * in the original size (they are freed if the original size is zero). The nnew - * blocks are of size 1 or more. - */ - -int CHOLMOD(realloc_multiple) -( - /* ---- input ---- */ - size_t nnew, /* requested # of items in reallocated blocks */ - int nint, /* number of int32_t/int64_t blocks */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* ---- in/out --- */ - void **Iblock, /* int32_t or int64_t block */ - void **Jblock, /* int32_t or int64_t block */ - void **Xblock, /* complex or double block */ - void **Zblock, /* zomplex case only: double block */ - size_t *nold_p, /* current size of the I,J,X,Z blocks on input, - * nnew on output if successful */ - /* --------------- */ - cholmod_common *Common -) -{ - double *xx, *zz ; - size_t i, j, x, z, nold ; - - RETURN_IF_NULL_COMMON (FALSE) ; - - if (xtype < CHOLMOD_PATTERN || xtype > CHOLMOD_ZOMPLEX) - { - ERROR (CHOLMOD_INVALID, "invalid xtype") ; - return (FALSE) ; - } - - nold = *nold_p ; - - if (nint < 1 && xtype == CHOLMOD_PATTERN) - { - /* nothing to do */ - return (TRUE) ; - } - - i = nold ; - j = nold ; - x = nold ; - z = nold ; - - if (nint > 0) - { - *Iblock = CHOLMOD(realloc) (nnew, sizeof (Int), *Iblock, &i, Common) ; - } - if (nint > 1) - { - *Jblock = CHOLMOD(realloc) (nnew, sizeof (Int), *Jblock, &j, Common) ; - } - - switch (xtype) - { - case CHOLMOD_REAL: - *Xblock = CHOLMOD(realloc) (nnew, sizeof (double), *Xblock, &x, - Common) ; - break ; - - case CHOLMOD_COMPLEX: - *Xblock = CHOLMOD(realloc) (nnew, 2*sizeof (double), *Xblock, &x, - Common) ; - break ; - - case CHOLMOD_ZOMPLEX: - *Xblock = CHOLMOD(realloc) (nnew, sizeof (double), *Xblock, &x, - Common) ; - *Zblock = CHOLMOD(realloc) (nnew, sizeof (double), *Zblock, &z, - Common) ; - break ; - } - - if (Common->status < CHOLMOD_OK) - { - /* one or more realloc's failed. Resize all back down to nold. */ - - if (nold == 0) - { - - if (nint > 0) - { - *Iblock = CHOLMOD(free) (i, sizeof (Int), *Iblock, Common) ; - } - if (nint > 1) - { - *Jblock = CHOLMOD(free) (j, sizeof (Int), *Jblock, Common) ; - } - - switch (xtype) - { - case CHOLMOD_REAL: - *Xblock = CHOLMOD(free) (x, sizeof (double), *Xblock, - Common) ; - break ; - - case CHOLMOD_COMPLEX: - *Xblock = CHOLMOD(free) (x, 2*sizeof (double), *Xblock, - Common) ; - break ; - - case CHOLMOD_ZOMPLEX: - *Xblock = CHOLMOD(free) (x, sizeof (double), *Xblock, - Common) ; - *Zblock = CHOLMOD(free) (x, sizeof (double), *Zblock, - Common) ; - break ; - } - - } - else - { - if (nint > 0) - { - *Iblock = CHOLMOD(realloc) (nold, sizeof (Int), *Iblock, &i, - Common) ; - } - if (nint > 1) - { - *Jblock = CHOLMOD(realloc) (nold, sizeof (Int), *Jblock, &j, - Common) ; - } - - switch (xtype) - { - case CHOLMOD_REAL: - *Xblock = CHOLMOD(realloc) (nold, sizeof (double), - *Xblock, &x, Common) ; - break ; - - case CHOLMOD_COMPLEX: - *Xblock = CHOLMOD(realloc) (nold, 2*sizeof (double), - *Xblock, &x, Common) ; - break ; - - case CHOLMOD_ZOMPLEX: - *Xblock = CHOLMOD(realloc) (nold, sizeof (double), - *Xblock, &x, Common) ; - *Zblock = CHOLMOD(realloc) (nold, sizeof (double), - *Zblock, &z, Common) ; - break ; - } - - } - - return (FALSE) ; - } - - if (nold == 0) - { - /* New space was allocated. Clear the first entry so that valgrind - * doesn't complain about its access in change_complexity - * (Core/cholmod_complex.c). */ - xx = *Xblock ; - zz = *Zblock ; - switch (xtype) - { - case CHOLMOD_REAL: - xx [0] = 0 ; - break ; - - case CHOLMOD_COMPLEX: - xx [0] = 0 ; - xx [1] = 0 ; - break ; - - case CHOLMOD_ZOMPLEX: - xx [0] = 0 ; - zz [0] = 0 ; - break ; - } - } - - /* all realloc's succeeded, change size to reflect realloc'ed size. */ - *nold_p = nnew ; - return (TRUE) ; -} diff --git a/CHOLMOD/Core/cholmod_sparse.c b/CHOLMOD/Core/cholmod_sparse.c deleted file mode 100644 index 6fa9b8ddb..000000000 --- a/CHOLMOD/Core/cholmod_sparse.c +++ /dev/null @@ -1,649 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_sparse: core methods for the cholmod_sparse object -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* Core utility routines for the cholmod_sparse object: - * - * A sparse matrix is held in compressed column form. In the basic type - * ("packed", which corresponds to a MATLAB sparse matrix), an n-by-n matrix - * with nz entries is held in three arrays: p of size n+1, i of size nz, and x - * of size nz. Row indices of column j are held in i [p [j] ... p [j+1]-1] and - * in the same locations in x. There may be no duplicate entries in a column. - * Row indices in each column may be sorted or unsorted (CHOLMOD keeps track). - * - * Primary routines: - * ----------------- - * cholmod_allocate_sparse allocate a sparse matrix - * cholmod_free_sparse free a sparse matrix - * - * Secondary routines: - * ------------------- - * cholmod_reallocate_sparse change the size (# entries) of sparse matrix - * cholmod_nnz number of nonzeros in a sparse matrix - * cholmod_speye sparse identity matrix - * cholmod_spzeros sparse zero matrix - * cholmod_copy_sparse create a copy of a sparse matrix - * - * All xtypes are supported (pattern, real, complex, and zomplex) - */ - -#include "cholmod_internal.h" - -/* ========================================================================== */ -/* === cholmod_allocate_sparse ============================================== */ -/* ========================================================================== */ - -/* Allocate space for a matrix. A->i and A->x are not initialized. A->p - * (and A->nz if A is not packed) are set to zero, so a matrix containing no - * entries (all zero) is returned. See also cholmod_spzeros. - * - * workspace: none - */ - -cholmod_sparse *CHOLMOD(allocate_sparse) -( - /* ---- input ---- */ - size_t nrow, /* # of rows of A */ - size_t ncol, /* # of columns of A */ - size_t nzmax, /* max # of nonzeros of A */ - int sorted, /* TRUE if columns of A sorted, FALSE otherwise */ - int packed, /* TRUE if A will be packed, FALSE otherwise */ - int stype, /* stype of A */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_sparse *A ; - Int *Ap, *Anz ; - size_t nzmax0 ; - Int j ; - int ok = TRUE ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - if (stype != 0 && nrow != ncol) - { - ERROR (CHOLMOD_INVALID, "rectangular matrix with stype != 0 invalid") ; - return (NULL) ; - } - if (xtype < CHOLMOD_PATTERN || xtype > CHOLMOD_ZOMPLEX) - { - ERROR (CHOLMOD_INVALID, "xtype invalid") ; - return (NULL) ; - } - /* ensure the dimensions do not cause integer overflow */ - (void) CHOLMOD(add_size_t) (ncol, 2, &ok) ; - if (!ok || (int64_t) nrow >= Int_max - || (int64_t) ncol >= Int_max - || (int64_t) nzmax >= Int_max) - { - ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; - return (NULL) ; - } - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* allocate header */ - /* ---------------------------------------------------------------------- */ - - A = CHOLMOD(malloc) (sizeof (cholmod_sparse), 1, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - PRINT1 (("cholmod_allocate_sparse %d-by-%d nzmax %d sorted %d packed %d" - " xtype %d\n", nrow, ncol, nzmax, sorted, packed, xtype)) ; - - nzmax = MAX (1, nzmax) ; - - A->nrow = nrow ; - A->ncol = ncol ; - A->nzmax = nzmax ; - A->packed = packed ; /* default is packed (A->nz not present) */ - A->stype = stype ; - A->itype = ITYPE ; - A->xtype = xtype ; - A->dtype = DTYPE ; - - A->nz = NULL ; - A->p = NULL ; - A->i = NULL ; - A->x = NULL ; - A->z = NULL ; - - /* A 1-by-m matrix always has sorted columns */ - A->sorted = (nrow <= 1) ? TRUE : sorted ; - - /* ---------------------------------------------------------------------- */ - /* allocate the matrix itself */ - /* ---------------------------------------------------------------------- */ - - /* allocate O(ncol) space */ - A->p = CHOLMOD(malloc) (((size_t) ncol)+1, sizeof (Int), Common) ; - if (!packed) - { - A->nz = CHOLMOD(malloc) (ncol, sizeof (Int), Common) ; - } - - /* allocate O(nz) space */ - nzmax0 = 0 ; - CHOLMOD(realloc_multiple) (nzmax, 1, xtype, &(A->i), NULL, &(A->x), &(A->z), - &nzmax0, Common) ; - - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free_sparse) (&A, Common) ; - return (NULL) ; /* out of memory */ - } - - /* ---------------------------------------------------------------------- */ - /* initialize A->p and A->nz so that A is an empty matrix */ - /* ---------------------------------------------------------------------- */ - - Ap = A->p ; - for (j = 0 ; j <= (Int) ncol ; j++) - { - Ap [j] = 0 ; - } - if (!packed) - { - Anz = A->nz ; - for (j = 0 ; j < (Int) ncol ; j++) - { - Anz [j] = 0 ; - } - } - return (A) ; -} - - -/* ========================================================================== */ -/* === cholmod_free_sparse ================================================== */ -/* ========================================================================== */ - -/* free a sparse matrix - * - * workspace: none - */ - -int CHOLMOD(free_sparse) -( - /* ---- in/out --- */ - cholmod_sparse **AHandle, /* matrix to deallocate, NULL on output */ - /* --------------- */ - cholmod_common *Common -) -{ - Int n, nz ; - cholmod_sparse *A ; - - RETURN_IF_NULL_COMMON (FALSE) ; - - if (AHandle == NULL) - { - /* nothing to do */ - return (TRUE) ; - } - A = *AHandle ; - if (A == NULL) - { - /* nothing to do */ - return (TRUE) ; - } - n = A->ncol ; - nz = A->nzmax ; - A->p = CHOLMOD(free) (n+1, sizeof (Int), A->p, Common) ; - A->i = CHOLMOD(free) (nz, sizeof (Int), A->i, Common) ; - A->nz = CHOLMOD(free) (n, sizeof (Int), A->nz, Common) ; - - switch (A->xtype) - { - case CHOLMOD_REAL: - A->x = CHOLMOD(free) (nz, sizeof (double), A->x, Common) ; - break ; - - case CHOLMOD_COMPLEX: - A->x = CHOLMOD(free) (nz, 2*sizeof (double), A->x, Common) ; - break ; - - case CHOLMOD_ZOMPLEX: - A->x = CHOLMOD(free) (nz, sizeof (double), A->x, Common) ; - A->z = CHOLMOD(free) (nz, sizeof (double), A->z, Common) ; - break ; - } - - *AHandle = CHOLMOD(free) (1, sizeof (cholmod_sparse), (*AHandle), Common) ; - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === cholmod_reallocate_sparse ============================================ */ -/* ========================================================================== */ - -/* Change the size of A->i, A->x, and A->z, or allocate them if their current - * size is zero. A->x and A->z are not modified if A->xtype is CHOLMOD_PATTERN. - * A->z is not modified unless A->xtype is CHOLMOD_ZOMPLEX. - * - * workspace: none - */ - -int CHOLMOD(reallocate_sparse) -( - /* ---- input ---- */ - size_t nznew, /* new # of entries in A */ - /* ---- in/out --- */ - cholmod_sparse *A, /* matrix to reallocate */ - /* --------------- */ - cholmod_common *Common -) -{ - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (FALSE) ; - RETURN_IF_NULL (A, FALSE) ; - RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; - Common->status = CHOLMOD_OK ; - PRINT1 (("realloc matrix %d to %d, xtype: %d\n", - A->nzmax, nznew, A->xtype)) ; - - /* ---------------------------------------------------------------------- */ - /* resize the matrix */ - /* ---------------------------------------------------------------------- */ - - CHOLMOD(realloc_multiple) (MAX (1,nznew), 1, A->xtype, &(A->i), NULL, - &(A->x), &(A->z), &(A->nzmax), Common) ; - - return (Common->status == CHOLMOD_OK) ; -} - - -/* ========================================================================== */ -/* === cholmod_speye ======================================================== */ -/* ========================================================================== */ - -/* Return a sparse identity matrix. */ - -cholmod_sparse *CHOLMOD(speye) -( - /* ---- input ---- */ - size_t nrow, /* # of rows of A */ - size_t ncol, /* # of columns of A */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ - cholmod_common *Common -) -{ - double *Ax, *Az ; - cholmod_sparse *A ; - Int *Ap, *Ai ; - Int j, n ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* allocate the matrix */ - /* ---------------------------------------------------------------------- */ - - n = MIN (nrow, ncol) ; - A = CHOLMOD(allocate_sparse) (nrow, ncol, n, TRUE, TRUE, 0, xtype, - Common) ; - - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory or inputs invalid */ - } - - /* ---------------------------------------------------------------------- */ - /* create the identity matrix */ - /* ---------------------------------------------------------------------- */ - - Ap = A->p ; - Ai = A->i ; - Ax = A->x ; - Az = A->z ; - - for (j = 0 ; j < n ; j++) - { - Ap [j] = j ; - } - for (j = n ; j <= ((Int) ncol) ; j++) - { - Ap [j] = n ; - } - for (j = 0 ; j < n ; j++) - { - Ai [j] = j ; - } - - switch (xtype) - { - case CHOLMOD_REAL: - for (j = 0 ; j < n ; j++) - { - Ax [j] = 1 ; - } - break ; - - case CHOLMOD_COMPLEX: - for (j = 0 ; j < n ; j++) - { - Ax [2*j ] = 1 ; - Ax [2*j+1] = 0 ; - } - break ; - - case CHOLMOD_ZOMPLEX: - for (j = 0 ; j < n ; j++) - { - Ax [j] = 1 ; - } - for (j = 0 ; j < n ; j++) - { - Az [j] = 0 ; - } - break ; - } - - return (A) ; -} - - -/* ========================================================================== */ -/* === cholmod_spzeros ====================================================== */ -/* ========================================================================== */ - -/* Return a sparse zero matrix. */ - -cholmod_sparse *CHOLMOD(spzeros) -( - /* ---- input ---- */ - size_t nrow, /* # of rows of A */ - size_t ncol, /* # of columns of A */ - size_t nzmax, /* max # of nonzeros of A */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ - cholmod_common *Common -) -{ - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* allocate the matrix */ - /* ---------------------------------------------------------------------- */ - - return (CHOLMOD(allocate_sparse) (nrow, ncol, nzmax, TRUE, TRUE, 0, xtype, - Common)) ; -} - - -/* ========================================================================== */ -/* === cholmod_nnz ========================================================== */ -/* ========================================================================== */ - -/* Return the number of entries in a sparse matrix. - * - * workspace: none - * integer overflow cannot occur, since the matrix is already allocated. - */ - -int64_t CHOLMOD(nnz) -( - /* ---- input ---- */ - cholmod_sparse *A, - /* --------------- */ - cholmod_common *Common -) -{ - Int *Ap, *Anz ; - size_t nz ; - Int j, ncol ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (EMPTY) ; - RETURN_IF_NULL (A, EMPTY) ; - RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, EMPTY) ; - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* return nnz (A) */ - /* ---------------------------------------------------------------------- */ - - ncol = A->ncol ; - if (A->packed) - { - Ap = A->p ; - RETURN_IF_NULL (Ap, EMPTY) ; - nz = Ap [ncol] ; - } - else - { - Anz = A->nz ; - RETURN_IF_NULL (Anz, EMPTY) ; - nz = 0 ; - for (j = 0 ; j < ncol ; j++) - { - nz += MAX (0, Anz [j]) ; - } - } - return (nz) ; -} - - -/* ========================================================================== */ -/* === cholmod_copy_sparse ================================================== */ -/* ========================================================================== */ - -/* C = A. Create an exact copy of a sparse matrix, with one exception. - * Entries in unused space are not copied (they might not be initialized, - * and copying them would cause program checkers such as purify and - * valgrind to complain). The xtype of the resulting matrix C is the same as - * the xtype of the input matrix A. - * - * See also Core/cholmod_copy, which copies a matrix with possible changes - * in stype, presence of diagonal entries, pattern vs. numerical values, - * real and/or imaginary parts, and so on. - */ - -cholmod_sparse *CHOLMOD(copy_sparse) -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ - /* --------------- */ - cholmod_common *Common -) -{ - double *Ax, *Cx, *Az, *Cz ; - Int *Ap, *Ai, *Anz, *Cp, *Ci, *Cnz ; - cholmod_sparse *C ; - Int p, pend, j, ncol, packed, nzmax, nz, xtype ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - RETURN_IF_NULL (A, NULL) ; - RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; - if (A->stype != 0 && A->nrow != A->ncol) - { - ERROR (CHOLMOD_INVALID, "rectangular matrix with stype != 0 invalid") ; - return (NULL) ; - } - Common->status = CHOLMOD_OK ; - ASSERT (CHOLMOD(dump_sparse) (A, "A original", Common) >= 0) ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - ncol = A->ncol ; - nzmax = A->nzmax ; - packed = A->packed ; - Ap = A->p ; - Ai = A->i ; - Ax = A->x ; - Az = A->z ; - Anz = A->nz ; - xtype = A->xtype ; - - /* ---------------------------------------------------------------------- */ - /* allocate the copy */ - /* ---------------------------------------------------------------------- */ - - C = CHOLMOD(allocate_sparse) (A->nrow, A->ncol, A->nzmax, A->sorted, - A->packed, A->stype, A->xtype, Common) ; - - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - - Cp = C->p ; - Ci = C->i ; - Cx = C->x ; - Cz = C->z ; - Cnz = C->nz ; - - /* ---------------------------------------------------------------------- */ - /* copy the matrix */ - /* ---------------------------------------------------------------------- */ - - for (j = 0 ; j <= ncol ; j++) - { - Cp [j] = Ap [j] ; - } - - if (packed) - { - nz = Ap [ncol] ; - for (p = 0 ; p < nz ; p++) - { - Ci [p] = Ai [p] ; - } - - switch (xtype) - { - case CHOLMOD_REAL: - for (p = 0 ; p < nz ; p++) - { - Cx [p] = Ax [p] ; - } - break ; - - case CHOLMOD_COMPLEX: - for (p = 0 ; p < 2*nz ; p++) - { - Cx [p] = Ax [p] ; - } - break ; - - case CHOLMOD_ZOMPLEX: - for (p = 0 ; p < nz ; p++) - { - Cx [p] = Ax [p] ; - Cz [p] = Az [p] ; - } - break ; - } - - } - else - { - - for (j = 0 ; j < ncol ; j++) - { - Cnz [j] = Anz [j] ; - } - - switch (xtype) - { - case CHOLMOD_PATTERN: - for (j = 0 ; j < ncol ; j++) - { - p = Ap [j] ; - pend = p + Anz [j] ; - for ( ; p < pend ; p++) - { - Ci [p] = Ai [p] ; - } - } - break ; - - case CHOLMOD_REAL: - for (j = 0 ; j < ncol ; j++) - { - p = Ap [j] ; - pend = p + Anz [j] ; - for ( ; p < pend ; p++) - { - Ci [p] = Ai [p] ; - Cx [p] = Ax [p] ; - } - } - break ; - - case CHOLMOD_COMPLEX: - for (j = 0 ; j < ncol ; j++) - { - p = Ap [j] ; - pend = p + Anz [j] ; - for ( ; p < pend ; p++) - { - Ci [p] = Ai [p] ; - Cx [2*p ] = Ax [2*p ] ; - Cx [2*p+1] = Ax [2*p+1] ; - } - } - break ; - - case CHOLMOD_ZOMPLEX: - for (j = 0 ; j < ncol ; j++) - { - p = Ap [j] ; - pend = p + Anz [j] ; - for ( ; p < pend ; p++) - { - Ci [p] = Ai [p] ; - Cx [p] = Ax [p] ; - Cz [p] = Az [p] ; - } - } - break ; - } - } - - /* ---------------------------------------------------------------------- */ - /* return the result */ - /* ---------------------------------------------------------------------- */ - - ASSERT (CHOLMOD(dump_sparse) (C, "C copy", Common) >= 0) ; - return (C) ; -} diff --git a/CHOLMOD/Core/cholmod_transpose.c b/CHOLMOD/Core/cholmod_transpose.c deleted file mode 100644 index 8e3a1af4b..000000000 --- a/CHOLMOD/Core/cholmod_transpose.c +++ /dev/null @@ -1,1133 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_tranpose: transpose a matrix -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* Core utility routines for the cholmod_sparse object to - * compute the transpose or permuted transpose of a matrix: - * - * Primary routines: - * ----------------- - * cholmod_transpose transpose sparse matrix - * cholmod_ptranspose transpose and permute sparse matrix - * cholmod_sort sort row indices in each column of sparse matrix - * - * Secondary routines: - * ------------------- - * cholmod_transpose_unsym transpose unsymmetric sparse matrix - * cholmod_transpose_sym transpose symmetric sparse matrix - * - * All xtypes (pattern, real, complex, and zomplex) are supported. - * - * --------------------------------------- - * Unsymmetric case: A->stype is zero. - * --------------------------------------- - * - * Computes F = A', F = A (:,f)' or F = A (p,f)', except that the indexing by - * f does not work the same as the MATLAB notation (see below). A->stype - * is zero, which denotes that both the upper and lower triangular parts of - * A are present (and used). A may in fact be symmetric in pattern and/or - * value; A->stype just denotes which part of A are stored. A may be - * rectangular. - * - * p is a permutation of 0:m-1, and f is a subset of 0:n-1, where A is m-by-n. - * There can be no duplicate entries in p or f. - * - * The set f is held in fset and fsize. - * fset = NULL means ":" in MATLAB. fsize is ignored. - * fset != NULL means f = fset [0..fsize-1]. - * fset != NULL and fsize = 0 means f is the empty set. - * - * Columns not in the set f are considered to be zero. That is, - * if A is 5-by-10 then F = A (:,[3 4])' is not 2-by-5, but 10-by-5, and rows - * 3 and 4 of F are equal to columns 3 and 4 of A (the other rows of F are - * zero). More precisely, in MATLAB notation: - * - * [m n] = size (A) ; - * F = A ; - * notf = ones (1,n) ; - * notf (f) = 0 ; - * F (:, find (notf)) = 0 - * F = F' - * - * If you want the MATLAB equivalent F=A(p,f) operation, use cholmod_submatrix - * instead (which does not compute the transpose). - * - * F->nzmax must be large enough to hold the matrix F. It is not modified. - * If F->nz is present then F->nz [j] = # of entries in column j of F. - * - * A can be sorted or unsorted, with packed or unpacked columns. - * - * If f is present and not sorted in ascending order, then F is unsorted - * (that is, it may contain columns whose row indices do not appear in - * ascending order). Otherwise, F is sorted (the row indices in each - * column of F appear in strictly ascending order). - * - * F is returned in packed or unpacked form, depending on F->packed on input. - * If F->packed is false, then F is returned in unpacked form (F->nz must be - * present). Each row i of F is large enough to hold all the entries in row i - * of A, even if f is provided. That is, F->i and - * F->x [F->p [i] .. F->p [i] + F->nz [i] - 1] contain all entries in A (i,f), - * but F->p [i+1] - F->p [i] is equal to the number of nonzeros in A (i,:), - * not just A (i,f). - * - * The cholmod_transpose_unsym routine is the only operation in CHOLMOD that - * can produce an unpacked matrix. - * - * --------------------------------------- - * Symmetric case: A->stype is nonzero. - * --------------------------------------- - * - * Computes F = A' or F = A(p,p)', the transpose or permuted transpose, where - * A->stype is nonzero. - * - * If A->stype > 0, then A is a symmetric matrix where just the upper part - * of the matrix is stored. Entries in the lower triangular part may be - * present, but are ignored. A must be square. If F=A', then F is returned - * sorted; otherwise F is unsorted for the F=A(p,p)' case. - * - * There can be no duplicate entries in p. - * The fset and fsize parameters are not used. - * - * Three kinds of transposes are available, depending on the "values" parameter: - * 0: do not transpose the numerical values; create a CHOLMOD_PATTERN matrix - * 1: array transpose - * 2: complex conjugate transpose (same as 2 if input is real or pattern) - * - * ----------------------------------------------------------------------------- - * - * For cholmod_transpose_unsym and cholmod_transpose_sym, the output matrix - * F must already be pre-allocated by the caller, with the correct dimensions. - * If F is not valid or has the wrong dimensions, it is not modified. - * Otherwise, if F is too small, the transpose is not computed; the contents - * of F->p contain the column pointers of the resulting matrix, where - * F->p [F->ncol] > F->nzmax. In this case, the remaining contents of F are - * not modified. F can still be properly free'd with cholmod_free_sparse. - */ - -#include "cholmod_internal.h" - -/* ========================================================================== */ -/* === TEMPLATE ============================================================= */ -/* ========================================================================== */ - -#define PATTERN -#include "t_cholmod_transpose.c" -#define REAL -#include "t_cholmod_transpose.c" -#define COMPLEX -#include "t_cholmod_transpose.c" -#define COMPLEX -#define NCONJUGATE -#include "t_cholmod_transpose.c" -#define ZOMPLEX -#include "t_cholmod_transpose.c" -#define ZOMPLEX -#define NCONJUGATE -#include "t_cholmod_transpose.c" - -/* ========================================================================== */ -/* === cholmod_transpose_unsym ============================================== */ -/* ========================================================================== */ - -/* Compute F = A', A (:,f)', or A (p,f)', where A is unsymmetric and F is - * already allocated. See cholmod_transpose for a simpler routine. - * - * workspace: - * Iwork (MAX (nrow,ncol)) if fset is present - * Iwork (nrow) if fset is NULL - * - * The xtype of A and F must match, unless values is zero or F->xtype is - * CHOLMOD_PATTERN (in which case only the pattern of A is transpose into F). - */ - -int CHOLMOD(transpose_unsym) -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to transpose */ - int values, /* 2: complex conj. transpose, 1: array transpose, - 0: do not transpose the numerical values */ - Int *Perm, /* size nrow, if present (can be NULL) */ - Int *fset, /* subset of 0:(A->ncol)-1 */ - size_t fsize, /* size of fset */ - /* ---- output --- */ - cholmod_sparse *F, /* F = A', A(:,f)', or A(p,f)' */ - /* --------------- */ - cholmod_common *Common -) -{ - Int *Fp, *Fnz, *Ap, *Ai, *Anz, *Wi ; - Int nrow, ncol, permute, use_fset, Apacked, Fpacked, p, pend, - i, j, k, Fsorted, nf, jj, jlast ; - size_t s ; - int ok = TRUE ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (FALSE) ; - RETURN_IF_NULL (A, FALSE) ; - RETURN_IF_NULL (F, FALSE) ; - RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; - RETURN_IF_XTYPE_INVALID (F, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; - if (A->nrow != F->ncol || A->ncol != F->nrow) - { - ERROR (CHOLMOD_INVALID, "F has the wrong dimensions") ; - return (FALSE) ; - } - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - nf = fsize ; - use_fset = (fset != NULL) ; - nrow = A->nrow ; - ncol = A->ncol ; - - Ap = A->p ; /* size A->ncol+1, column pointers of A */ - Ai = A->i ; /* size nz = Ap [A->ncol], row indices of A */ - Anz = A->nz ; - Apacked = A->packed ; - ASSERT (IMPLIES (!Apacked, Anz != NULL)) ; - - permute = (Perm != NULL) ; - - Fp = F->p ; /* size A->nrow+1, row pointers of F */ - Fnz = F->nz ; - Fpacked = F->packed ; - ASSERT (IMPLIES (!Fpacked, Fnz != NULL)) ; - - nf = (use_fset) ? nf : ncol ; - - /* ---------------------------------------------------------------------- */ - /* allocate workspace */ - /* ---------------------------------------------------------------------- */ - - /* s = nrow + ((fset != NULL) ? ncol : 0) */ - s = CHOLMOD(add_size_t) (nrow, ((fset != NULL) ? ncol : 0), &ok) ; - if (!ok) - { - ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; - return (FALSE) ; - } - - CHOLMOD(allocate_work) (0, s, 0, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (FALSE) ; /* out of memory */ - } - - Wi = Common->Iwork ; /* size nrow (i/l/l) */ - - /* ---------------------------------------------------------------------- */ - /* check Perm and fset */ - /* ---------------------------------------------------------------------- */ - - if (permute) - { - for (i = 0 ; i < nrow ; i++) - { - Wi [i] = 1 ; - } - for (k = 0 ; k < nrow ; k++) - { - i = Perm [k] ; - if (i < 0 || i > nrow || Wi [i] == 0) - { - ERROR (CHOLMOD_INVALID, "invalid permutation") ; - return (FALSE) ; - } - Wi [i] = 0 ; - } - } - - if (use_fset) - { - for (j = 0 ; j < ncol ; j++) - { - Wi [j] = 1 ; - } - for (k = 0 ; k < nf ; k++) - { - j = fset [k] ; - if (j < 0 || j > ncol || Wi [j] == 0) - { - ERROR (CHOLMOD_INVALID, "invalid fset") ; - return (FALSE) ; - } - Wi [j] = 0 ; - } - } - - /* Perm and fset are now valid */ - ASSERT (CHOLMOD(dump_perm) (Perm, nrow, nrow, "Perm", Common)) ; - ASSERT (CHOLMOD(dump_perm) (fset, nf, ncol, "fset", Common)) ; - - /* ---------------------------------------------------------------------- */ - /* count the entries in each row of A or A(:,f) */ - /* ---------------------------------------------------------------------- */ - - for (i = 0 ; i < nrow ; i++) - { - Wi [i] = 0 ; - } - - jlast = EMPTY ; - Fsorted = TRUE ; - - if (use_fset) - { - /* count entries in each row of A(:,f) */ - for (jj = 0 ; jj < nf ; jj++) - { - j = fset [jj] ; - if (j <= jlast) - { - Fsorted = FALSE ; - } - p = Ap [j] ; - pend = (Apacked) ? (Ap [j+1]) : (p + Anz [j]) ; - for ( ; p < pend ; p++) - { - Wi [Ai [p]]++ ; - } - jlast = j ; - } - - /* save the nz counts if F is unpacked, and recount all of A */ - if (!Fpacked) - { - if (permute) - { - for (i = 0 ; i < nrow ; i++) - { - Fnz [i] = Wi [Perm [i]] ; - } - } - else - { - for (i = 0 ; i < nrow ; i++) - { - Fnz [i] = Wi [i] ; - } - } - for (i = 0 ; i < nrow ; i++) - { - Wi [i] = 0 ; - } - - /* count entries in each row of A */ - for (j = 0 ; j < ncol ; j++) - { - p = Ap [j] ; - pend = (Apacked) ? (Ap [j+1]) : (p + Anz [j]) ; - for ( ; p < pend ; p++) - { - Wi [Ai [p]]++ ; - } - } - } - - } - else - { - - /* count entries in each row of A */ - for (j = 0 ; j < ncol ; j++) - { - p = Ap [j] ; - pend = (Apacked) ? (Ap [j+1]) : (p + Anz [j]) ; - for ( ; p < pend ; p++) - { - Wi [Ai [p]]++ ; - } - } - - /* save the nz counts if F is unpacked */ - if (!Fpacked) - { - if (permute) - { - for (i = 0 ; i < nrow ; i++) - { - Fnz [i] = Wi [Perm [i]] ; - } - } - else - { - for (i = 0 ; i < nrow ; i++) - { - Fnz [i] = Wi [i] ; - } - } - } - } - - /* ---------------------------------------------------------------------- */ - /* compute the row pointers */ - /* ---------------------------------------------------------------------- */ - - p = 0 ; - if (permute) - { - for (i = 0 ; i < nrow ; i++) - { - Fp [i] = p ; - p += Wi [Perm [i]] ; - } - for (i = 0 ; i < nrow ; i++) - { - Wi [Perm [i]] = Fp [i] ; - } - } - else - { - for (i = 0 ; i < nrow ; i++) - { - Fp [i] = p ; - p += Wi [i] ; - } - for (i = 0 ; i < nrow ; i++) - { - Wi [i] = Fp [i] ; - } - } - Fp [nrow] = p ; - - if (p > (Int) (F->nzmax)) - { - ERROR (CHOLMOD_INVALID, "F is too small") ; - return (FALSE) ; - } - - /* ---------------------------------------------------------------------- */ - /* transpose matrix, using template routine */ - /* ---------------------------------------------------------------------- */ - - ok = FALSE ; - if (values == 0 || F->xtype == CHOLMOD_PATTERN) - { - ok = p_cholmod_transpose_unsym (A, Perm, fset, nf, F, Common) ; - } - else if (F->xtype == CHOLMOD_REAL) - { - ok = r_cholmod_transpose_unsym (A, Perm, fset, nf, F, Common) ; - } - else if (F->xtype == CHOLMOD_COMPLEX) - { - if (values == 1) - { - /* array transpose */ - ok = ct_cholmod_transpose_unsym (A, Perm, fset, nf, F, Common) ; - } - else - { - /* complex conjugate transpose */ - ok = c_cholmod_transpose_unsym (A, Perm, fset, nf, F, Common) ; - } - } - else if (F->xtype == CHOLMOD_ZOMPLEX) - { - if (values == 1) - { - /* array transpose */ - ok = zt_cholmod_transpose_unsym (A, Perm, fset, nf, F, Common) ; - } - else - { - /* complex conjugate transpose */ - ok = z_cholmod_transpose_unsym (A, Perm, fset, nf, F, Common) ; - } - } - - /* ---------------------------------------------------------------------- */ - /* finalize result F */ - /* ---------------------------------------------------------------------- */ - - if (ok) - { - F->sorted = Fsorted ; - } - ASSERT (CHOLMOD(dump_sparse) (F, "output F unsym", Common) >= 0) ; - return (ok) ; -} - - -/* ========================================================================== */ -/* === cholmod_transpose_sym ================================================ */ -/* ========================================================================== */ - -/* Compute F = A' or A (p,p)', where A is symmetric and F is already allocated. - * See cholmod_transpose for a simpler routine. - * - * workspace: Iwork (nrow) if Perm NULL, Iwork (2*nrow) if Perm non-NULL. - */ - -int CHOLMOD(transpose_sym) -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to transpose */ - int values, /* 2: complex conj. transpose, 1: array transpose, - 0: do not transpose the numerical values */ - Int *Perm, /* size nrow, if present (can be NULL) */ - /* ---- output --- */ - cholmod_sparse *F, /* F = A' or A(p,p)' */ - /* --------------- */ - cholmod_common *Common -) -{ - Int *Ap, *Anz, *Ai, *Fp, *Wi, *Pinv, *Iwork ; - Int p, pend, packed, upper, permute, jold, n, i, j, k, iold ; - size_t s ; - int ok = TRUE ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (FALSE) ; - RETURN_IF_NULL (A, FALSE) ; - RETURN_IF_NULL (F, FALSE) ; - RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; - RETURN_IF_XTYPE_INVALID (F, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; - if (A->nrow != A->ncol || A->stype == 0) - { - /* this routine handles square symmetric matrices only */ - ERROR (CHOLMOD_INVALID, "matrix must be symmetric") ; - return (FALSE) ; - } - if (A->nrow != F->ncol || A->ncol != F->nrow) - { - ERROR (CHOLMOD_INVALID, "F has the wrong dimensions") ; - return (FALSE) ; - } - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - permute = (Perm != NULL) ; - n = A->nrow ; - Ap = A->p ; /* size A->ncol+1, column pointers of A */ - Ai = A->i ; /* size nz = Ap [A->ncol], row indices of A */ - Anz = A->nz ; - packed = A->packed ; - ASSERT (IMPLIES (!packed, Anz != NULL)) ; - upper = (A->stype > 0) ; - - Fp = F->p ; /* size A->nrow+1, row pointers of F */ - - /* ---------------------------------------------------------------------- */ - /* allocate workspace */ - /* ---------------------------------------------------------------------- */ - - /* s = (Perm != NULL) ? 2*n : n */ - s = CHOLMOD(add_size_t) (n, ((Perm != NULL) ? n : 0), &ok) ; - if (!ok) - { - ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; - return (FALSE) ; - } - - CHOLMOD(allocate_work) (0, s, 0, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (FALSE) ; /* out of memory */ - } - - /* ---------------------------------------------------------------------- */ - /* get workspace */ - /* ---------------------------------------------------------------------- */ - - Iwork = Common->Iwork ; - Wi = Iwork ; /* size n (i/l/l) */ - Pinv = Iwork + n ; /* size n (i/i/l) , unused if Perm NULL */ - - /* ---------------------------------------------------------------------- */ - /* check Perm and construct inverse permutation */ - /* ---------------------------------------------------------------------- */ - - if (permute) - { - for (i = 0 ; i < n ; i++) - { - Pinv [i] = EMPTY ; - } - for (k = 0 ; k < n ; k++) - { - i = Perm [k] ; - if (i < 0 || i > n || Pinv [i] != EMPTY) - { - ERROR (CHOLMOD_INVALID, "invalid permutation") ; - return (FALSE) ; - } - Pinv [i] = k ; - } - } - - /* Perm is now valid */ - ASSERT (CHOLMOD(dump_perm) (Perm, n, n, "Perm", Common)) ; - - /* ---------------------------------------------------------------------- */ - /* count the entries in each row of F */ - /* ---------------------------------------------------------------------- */ - - for (i = 0 ; i < n ; i++) - { - Wi [i] = 0 ; - } - - if (packed) - { - if (permute) - { - if (upper) - { - /* packed, permuted, upper */ - for (j = 0 ; j < n ; j++) - { - jold = Perm [j] ; - pend = Ap [jold+1] ; - for (p = Ap [jold] ; p < pend ; p++) - { - iold = Ai [p] ; - if (iold <= jold) - { - i = Pinv [iold] ; - Wi [MIN (i, j)]++ ; - } - } - } - } - else - { - /* packed, permuted, lower */ - for (j = 0 ; j < n ; j++) - { - jold = Perm [j] ; - pend = Ap [jold+1] ; - for (p = Ap [jold] ; p < pend ; p++) - { - iold = Ai [p] ; - if (iold >= jold) - { - i = Pinv [iold] ; - Wi [MAX (i, j)]++ ; - } - } - } - } - } - else - { - if (upper) - { - /* packed, unpermuted, upper */ - for (j = 0 ; j < n ; j++) - { - pend = Ap [j+1] ; - for (p = Ap [j] ; p < pend ; p++) - { - i = Ai [p] ; - if (i <= j) - { - Wi [i]++ ; - } - } - } - } - else - { - /* packed, unpermuted, lower */ - for (j = 0 ; j < n ; j++) - { - pend = Ap [j+1] ; - for (p = Ap [j] ; p < pend ; p++) - { - i = Ai [p] ; - if (i >= j) - { - Wi [i]++ ; - } - } - } - } - } - } - else - { - if (permute) - { - if (upper) - { - /* unpacked, permuted, upper */ - for (j = 0 ; j < n ; j++) - { - jold = Perm [j] ; - p = Ap [jold] ; - pend = p + Anz [jold] ; - for ( ; p < pend ; p++) - { - iold = Ai [p] ; - if (iold <= jold) - { - i = Pinv [iold] ; - Wi [MIN (i, j)]++ ; - } - } - } - } - else - { - /* unpacked, permuted, lower */ - for (j = 0 ; j < n ; j++) - { - jold = Perm [j] ; - p = Ap [jold] ; - pend = p + Anz [jold] ; - for ( ; p < pend ; p++) - { - iold = Ai [p] ; - if (iold >= jold) - { - i = Pinv [iold] ; - Wi [MAX (i, j)]++ ; - } - } - } - } - } - else - { - if (upper) - { - /* unpacked, unpermuted, upper */ - for (j = 0 ; j < n ; j++) - { - p = Ap [j] ; - pend = p + Anz [j] ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (i <= j) - { - Wi [i]++ ; - } - } - } - } - else - { - /* unpacked, unpermuted, lower */ - for (j = 0 ; j < n ; j++) - { - p = Ap [j] ; - pend = p + Anz [j] ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (i >= j) - { - Wi [i]++ ; - } - } - } - } - } - } - - /* ---------------------------------------------------------------------- */ - /* compute the row pointers */ - /* ---------------------------------------------------------------------- */ - - p = 0 ; - for (i = 0 ; i < n ; i++) - { - Fp [i] = p ; - p += Wi [i] ; - } - Fp [n] = p ; - for (i = 0 ; i < n ; i++) - { - Wi [i] = Fp [i] ; - } - - if (p > (Int) (F->nzmax)) - { - ERROR (CHOLMOD_INVALID, "F is too small") ; - return (FALSE) ; - } - - /* ---------------------------------------------------------------------- */ - /* transpose matrix, using template routine */ - /* ---------------------------------------------------------------------- */ - - ok = FALSE ; - if (values == 0 || F->xtype == CHOLMOD_PATTERN) - { - PRINT2 (("\n:::: p_transpose_sym Perm %p\n", Perm)) ; - ok = p_cholmod_transpose_sym (A, Perm, F, Common) ; - } - else if (F->xtype == CHOLMOD_REAL) - { - PRINT2 (("\n:::: r_transpose_sym Perm %p\n", Perm)) ; - ok = r_cholmod_transpose_sym (A, Perm, F, Common) ; - } - else if (F->xtype == CHOLMOD_COMPLEX) - { - if (values == 1) - { - /* array transpose */ - PRINT2 (("\n:::: ct_transpose_sym Perm %p\n", Perm)) ; - ok = ct_cholmod_transpose_sym (A, Perm, F, Common) ; - } - else - { - /* complex conjugate transpose */ - PRINT2 (("\n:::: c_transpose_sym Perm %p\n", Perm)) ; - ok = c_cholmod_transpose_sym (A, Perm, F, Common) ; - } - } - else if (F->xtype == CHOLMOD_ZOMPLEX) - { - if (values == 1) - { - /* array transpose */ - PRINT2 (("\n:::: zt_transpose_sym Perm %p\n", Perm)) ; - ok = zt_cholmod_transpose_sym (A, Perm, F, Common) ; - } - else - { - /* complex conjugate transpose */ - PRINT2 (("\n:::: z_transpose_sym Perm %p\n", Perm)) ; - ok = z_cholmod_transpose_sym (A, Perm, F, Common) ; - } - } - - /* ---------------------------------------------------------------------- */ - /* finalize result F */ - /* ---------------------------------------------------------------------- */ - - /* F is sorted if there is no permutation vector */ - if (ok) - { - F->sorted = !permute ; - F->packed = TRUE ; - F->stype = - SIGN (A->stype) ; /* flip the stype */ - ASSERT (CHOLMOD(dump_sparse) (F, "output F sym", Common) >= 0) ; - } - return (ok) ; -} - - -/* ========================================================================== */ -/* === cholmod_transpose ==================================================== */ -/* ========================================================================== */ - -/* Returns A'. See also cholmod_ptranspose below. */ - -cholmod_sparse *CHOLMOD(transpose) -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to transpose */ - int values, /* 2: complex conj. transpose, 1: array transpose, - 0: do not transpose the numerical values - (returns its result as CHOLMOD_PATTERN) */ - /* --------------- */ - cholmod_common *Common -) -{ - return (CHOLMOD(ptranspose) (A, values, NULL, NULL, 0, Common)) ; -} - - -/* ========================================================================== */ -/* === cholmod_ptranspose =================================================== */ -/* ========================================================================== */ - -/* Return A' or A(p,p)' if A is symmetric. Return A', A(:,f)', or A(p,f)' if - * A is unsymmetric. - * - * workspace: - * Iwork (MAX (nrow,ncol)) if unsymmetric and fset is non-NULL - * Iwork (nrow) if unsymmetric and fset is NULL - * Iwork (2*nrow) if symmetric and Perm is non-NULL. - * Iwork (nrow) if symmetric and Perm is NULL. - * - * A simple worst-case upper bound on the workspace is nrow+ncol. - */ - -cholmod_sparse *CHOLMOD(ptranspose) -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to transpose */ - int values, /* 2: complex conj. transpose, 1: array transpose, - 0: do not transpose the numerical values */ - Int *Perm, /* if non-NULL, F = A(p,f) or A(p,p) */ - Int *fset, /* subset of 0:(A->ncol)-1 */ - size_t fsize, /* size of fset */ - /* --------------- */ - cholmod_common *Common -) -{ - Int *Ap, *Anz ; - cholmod_sparse *F ; - Int nrow, ncol, use_fset, j, jj, fnz, packed, stype, nf, xtype ; - size_t ineed ; - int ok = TRUE ; - - nf = fsize ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - RETURN_IF_NULL (A, FALSE) ; - RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; - stype = A->stype ; - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* allocate workspace */ - /* ---------------------------------------------------------------------- */ - - nrow = A->nrow ; - ncol = A->ncol ; - - if (stype != 0) - { - use_fset = FALSE ; - if (Perm != NULL) - { - ineed = CHOLMOD(mult_size_t) (A->nrow, 2, &ok) ; - } - else - { - ineed = A->nrow ; - } - } - else - { - use_fset = (fset != NULL) ; - if (use_fset) - { - ineed = MAX (A->nrow, A->ncol) ; - } - else - { - ineed = A->nrow ; - } - } - - if (!ok) - { - ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; - return (NULL) ; - } - - CHOLMOD(allocate_work) (0, ineed, 0, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - Ap = A->p ; - Anz = A->nz ; - packed = A->packed ; - ASSERT (IMPLIES (!packed, Anz != NULL)) ; - xtype = values ? A->xtype : CHOLMOD_PATTERN ; - - /* ---------------------------------------------------------------------- */ - /* allocate F */ - /* ---------------------------------------------------------------------- */ - - /* determine # of nonzeros in F */ - if (stype != 0) - { - /* F=A' or F=A(p,p)', fset is ignored */ - fnz = CHOLMOD(nnz) (A, Common) ; - } - else - { - nf = (use_fset) ? nf : ncol ; - if (use_fset) - { - fnz = 0 ; - /* F=A(:,f)' or F=A(p,f)' */ - for (jj = 0 ; jj < nf ; jj++) - { - /* The fset is not yet checked; it will be thoroughly checked - * in cholmod_transpose_unsym. For now, just make sure we don't - * access Ap and Anz out of bounds. */ - j = fset [jj] ; - if (j >= 0 && j < ncol) - { - fnz += packed ? (Ap [j+1] - Ap [j]) : MAX (0, Anz [j]) ; - } - } - } - else - { - /* F=A' or F=A(p,:)' */ - fnz = CHOLMOD(nnz) (A, Common) ; - } - } - - /* F is ncol-by-nrow, fnz nonzeros, sorted unless f is present and unsorted, - * packed, of opposite stype as A, and with/without numerical values */ - F = CHOLMOD(allocate_sparse) (ncol, nrow, fnz, TRUE, TRUE, -SIGN(stype), - xtype, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - - /* ---------------------------------------------------------------------- */ - /* transpose and optionally permute the matrix A */ - /* ---------------------------------------------------------------------- */ - - if (stype != 0) - { - /* F = A (p,p)', using upper or lower triangular part of A only */ - ok = CHOLMOD(transpose_sym) (A, values, Perm, F, Common) ; - } - else - { - /* F = A (p,f)' */ - ok = CHOLMOD(transpose_unsym) (A, values, Perm, fset, nf, F, Common) ; - } - - /* ---------------------------------------------------------------------- */ - /* return the matrix F, or NULL if an error occured */ - /* ---------------------------------------------------------------------- */ - - if (!ok) - { - CHOLMOD(free_sparse) (&F, Common) ; - } - return (F) ; -} - - -/* ========================================================================== */ -/* === cholmod_sort ========================================================= */ -/* ========================================================================== */ - -/* Sort the columns of A, in place. Returns A in packed form, even if it - * starts as unpacked. Removes entries in the ignored part of a symmetric - * matrix. - * - * workspace: Iwork (max (nrow,ncol)). Allocates additional workspace for a - * temporary copy of A'. - */ - -int CHOLMOD(sort) -( - /* ---- in/out --- */ - cholmod_sparse *A, /* matrix to sort */ - /* --------------- */ - cholmod_common *Common -) -{ - Int *Ap ; - cholmod_sparse *F ; - Int anz, ncol, nrow, stype ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (FALSE) ; - RETURN_IF_NULL (A, FALSE) ; - RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; - Common->status = CHOLMOD_OK ; - nrow = A->nrow ; - if (nrow <= 1) - { - /* a 1-by-n sparse matrix must be sorted */ - A->sorted = TRUE ; - return (TRUE) ; - } - - /* ---------------------------------------------------------------------- */ - /* allocate workspace */ - /* ---------------------------------------------------------------------- */ - - ncol = A->ncol ; - CHOLMOD(allocate_work) (0, MAX (nrow, ncol), 0, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (FALSE) ; /* out of memory */ - } - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - anz = CHOLMOD(nnz) (A, Common) ; - stype = A->stype ; - - /* ---------------------------------------------------------------------- */ - /* sort the columns of the matrix */ - /* ---------------------------------------------------------------------- */ - - /* allocate workspace for transpose: ncol-by-nrow, same # of nonzeros as A, - * sorted, packed, same stype as A, and of the same numeric type as A. */ - F = CHOLMOD(allocate_sparse) (ncol, nrow, anz, TRUE, TRUE, stype, - A->xtype, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (FALSE) ; /* out of memory */ - } - - if (stype != 0) - { - /* F = A', upper or lower triangular part only */ - CHOLMOD(transpose_sym) (A, 1, NULL, F, Common) ; - A->packed = TRUE ; - /* A = F' */ - CHOLMOD(transpose_sym) (F, 1, NULL, A, Common) ; - } - else - { - /* F = A' */ - CHOLMOD(transpose_unsym) (A, 1, NULL, NULL, 0, F, Common) ; - A->packed = TRUE ; - /* A = F' */ - CHOLMOD(transpose_unsym) (F, 1, NULL, NULL, 0, A, Common) ; - } - - ASSERT (A->sorted && A->packed) ; - ASSERT (CHOLMOD(dump_sparse) (A, "Asorted", Common) >= 0) ; - - /* ---------------------------------------------------------------------- */ - /* reduce A in size, if needed. This must succeed. */ - /* ---------------------------------------------------------------------- */ - - Ap = A->p ; - anz = Ap [ncol] ; - ASSERT ((size_t) anz <= A->nzmax) ; - CHOLMOD(reallocate_sparse) (anz, A, Common) ; - ASSERT (Common->status >= CHOLMOD_OK) ; - - /* ---------------------------------------------------------------------- */ - /* free workspace */ - /* ---------------------------------------------------------------------- */ - - CHOLMOD(free_sparse) (&F, Common) ; - return (TRUE) ; -} diff --git a/CHOLMOD/Core/cholmod_triplet.c b/CHOLMOD/Core/cholmod_triplet.c deleted file mode 100644 index 88beafffe..000000000 --- a/CHOLMOD/Core/cholmod_triplet.c +++ /dev/null @@ -1,769 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_triplet: core methods for the cholmod_triplet object -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* Core utility routines for the cholmod_triplet object: - * - * A sparse matrix held in triplet form is the simplest one for a user to - * create. It consists of a list of nz entries in arbitrary order, held in - * three arrays: i, j, and x, each of length nk. The kth entry is in row i[k], - * column j[k], with value x[k]. There may be duplicate values; if A(i,j) - * appears more than once, its value is the sum of the entries with those row - * and column indices. - * - * Primary routines: - * ----------------- - * cholmod_allocate_triplet allocate a triplet matrix - * cholmod_free_triplet free a triplet matrix - * - * Secondary routines: - * ------------------- - * cholmod_reallocate_triplet reallocate a triplet matrix - * cholmod_sparse_to_triplet create a triplet matrix copy of a sparse matrix - * cholmod_triplet_to_sparse create a sparse matrix copy of a triplet matrix - * cholmod_copy_triplet create a copy of a triplet matrix - * - * The relationship between an m-by-n cholmod_sparse matrix A and a - * cholmod_triplet matrix (i, j, and x) is identical to how they are used in - * the MATLAB "sparse" and "find" functions: - * - * [i j x] = find (A) - * [m n] = size (A) - * A = sparse (i,j,x,m,n) - * - * with the exception that the cholmod_sparse matrix may be "unpacked", may - * have either sorted or unsorted columns (depending on the option selected), - * and may be symmetric with just the upper or lower triangular part stored. - * Likewise, the cholmod_triplet matrix may contain just the entries in the - * upper or lower triangular part of a symmetric matrix. - * - * MATLAB sparse matrices are always "packed", always have sorted columns, - * and always store both parts of a symmetric matrix. In some cases, MATLAB - * behaves like CHOLMOD by ignoring entries in the upper or lower triangular - * part of a matrix that is otherwise assumed to be symmetric (such as the - * input to chol). In CHOLMOD, that option is a characteristic of the object. - * In MATLAB, that option is based on how a matrix is used as the input to - * a function. - * - * The triplet matrix is provided to give the user a simple way of constructing - * a sparse matrix. There are very few operations supported for triplet - * matrices. The assumption is that they will be converted to cholmod_sparse - * matrix form first. - * - * Adding two triplet matrices simply involves concatenating the contents of - * the three arrays (i, j, and x). To permute a triplet matrix, just replace - * the row and column indices with their permuted values. For example, if - * P is a permutation vector, then P [k] = j means row/column j is the kth - * row/column in C=P*A*P'. In MATLAB notation, C=A(p,p). If Pinv is an array - * of size n and T is the triplet form of A, then: - * - * Ti = T->i ; - * Tj = T->j ; - * for (k = 0 ; k < n ; k++) Pinv [P [k]] = k ; - * for (k = 0 ; k < nz ; k++) Ti [k] = Pinv [Ti [k]] ; - * for (k = 0 ; k < nz ; k++) Tj [k] = Pinv [Tj [k]] ; - * - * overwrites T with the triplet form of C=P*A*P'. The conversion - * - * C = cholmod_triplet_to_sparse (T, 0, &Common) ; - * - * will then return the matrix C = P*A*P'. - * - * Note that T->stype > 0 means that entries in the lower triangular part of - * T are transposed into the upper triangular part when T is converted to - * sparse matrix (cholmod_sparse) form with cholmod_triplet_to_sparse. The - * opposite is true for T->stype < 0. - * - * Since the triplet matrix T is so simple to generate, it's quite easy - * to remove entries that you do not want, prior to converting T to the - * cholmod_sparse form. So if you include these entries in T, CHOLMOD - * assumes that there must be a reason (such as the one above). Thus, - * no entry in a triplet matrix is ever ignored. - * - * Other operations, such as extacting a submatrix, horizontal and vertical - * concatenation, multiply a triplet matrix times a dense matrix, are also - * simple. Multiplying two triplet matrices is not trivial; the simplest - * method is to convert them to cholmod_sparse matrices first. - * - * Supports all xtypes (pattern, real, complex, and zomplex). - */ - -#include "cholmod_internal.h" - -/* ========================================================================== */ -/* === TEMPLATE ============================================================= */ -/* ========================================================================== */ - -#define PATTERN -#include "t_cholmod_triplet.c" -#define REAL -#include "t_cholmod_triplet.c" -#define COMPLEX -#include "t_cholmod_triplet.c" -#define ZOMPLEX -#include "t_cholmod_triplet.c" - -/* ========================================================================== */ -/* === cholmod_allocate_triplet ============================================= */ -/* ========================================================================== */ - -/* allocate space for a triplet matrix - * - * workspace: none - */ - -cholmod_triplet *CHOLMOD(allocate_triplet) -( - /* ---- input ---- */ - size_t nrow, /* # of rows of T */ - size_t ncol, /* # of columns of T */ - size_t nzmax, /* max # of nonzeros of T */ - int stype, /* stype of T */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_triplet *T ; - size_t nzmax0 ; - int ok = TRUE ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - if (xtype < CHOLMOD_PATTERN || xtype > CHOLMOD_ZOMPLEX) - { - ERROR (CHOLMOD_INVALID, "xtype invalid") ; - return (NULL) ; - } - /* ensure the dimensions do not cause integer overflow */ - (void) CHOLMOD(add_size_t) (ncol, 2, &ok) ; - if (!ok || (int64_t) nrow >= Int_max - || (int64_t) ncol >= Int_max - || (int64_t) nzmax >= Int_max) - { - ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; - return (NULL) ; - } - - Common->status = CHOLMOD_OK ; - - /* ---------------------------------------------------------------------- */ - /* allocate header */ - /* ---------------------------------------------------------------------- */ - - T = CHOLMOD(malloc) (sizeof (cholmod_triplet), 1, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - - PRINT1 (("cholmod_allocate_triplet %d-by-%d nzmax %d xtype %d\n", - nrow, ncol, nzmax, xtype)) ; - - nzmax = MAX (1, nzmax) ; - - T->nrow = nrow ; - T->ncol = ncol ; - T->nzmax = nzmax ; - T->nnz = 0 ; - T->stype = stype ; - T->itype = ITYPE ; - T->xtype = xtype ; - T->dtype = DTYPE ; - - T->j = NULL ; - T->i = NULL ; - T->x = NULL ; - T->z = NULL ; - - /* ---------------------------------------------------------------------- */ - /* allocate the matrix itself */ - /* ---------------------------------------------------------------------- */ - - nzmax0 = 0 ; - CHOLMOD(realloc_multiple) (nzmax, 2, xtype, &(T->i), &(T->j), - &(T->x), &(T->z), &nzmax0, Common) ; - - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free_triplet) (&T, Common) ; - return (NULL) ; /* out of memory */ - } - - return (T) ; -} - - -/* ========================================================================== */ -/* === cholmod_free_triplet ================================================= */ -/* ========================================================================== */ - -/* free a triplet matrix - * - * workspace: none - */ - -int CHOLMOD(free_triplet) -( - /* ---- in/out --- */ - cholmod_triplet **THandle, /* matrix to deallocate, NULL on output */ - /* --------------- */ - cholmod_common *Common -) -{ - Int nz ; - cholmod_triplet *T ; - - RETURN_IF_NULL_COMMON (FALSE) ; - - if (THandle == NULL) - { - /* nothing to do */ - return (TRUE) ; - } - T = *THandle ; - if (T == NULL) - { - /* nothing to do */ - return (TRUE) ; - } - nz = T->nzmax ; - T->j = CHOLMOD(free) (nz, sizeof (Int), T->j, Common) ; - T->i = CHOLMOD(free) (nz, sizeof (Int), T->i, Common) ; - if (T->xtype == CHOLMOD_REAL) - { - T->x = CHOLMOD(free) (nz, sizeof (double), T->x, Common) ; - } - else if (T->xtype == CHOLMOD_COMPLEX) - { - T->x = CHOLMOD(free) (nz, 2*sizeof (double), T->x, Common) ; - } - else if (T->xtype == CHOLMOD_ZOMPLEX) - { - T->x = CHOLMOD(free) (nz, sizeof (double), T->x, Common) ; - T->z = CHOLMOD(free) (nz, sizeof (double), T->z, Common) ; - } - *THandle = CHOLMOD(free) (1, sizeof (cholmod_triplet), (*THandle), Common) ; - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === cholmod_reallocate_triplet =========================================== */ -/* ========================================================================== */ - -/* Change the size of T->i, T->j, and T->x, or allocate them if their current - * size is zero. T->x is not modified if T->xtype is CHOLMOD_PATTERN. - * - * workspace: none - */ - -int CHOLMOD(reallocate_triplet) -( - /* ---- input ---- */ - size_t nznew, /* new # of entries in T */ - /* ---- in/out --- */ - cholmod_triplet *T, /* triplet matrix to modify */ - /* --------------- */ - cholmod_common *Common -) -{ - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (FALSE) ; - RETURN_IF_NULL (T, FALSE) ; - RETURN_IF_XTYPE_INVALID (T, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; - Common->status = CHOLMOD_OK ; - PRINT1 (("realloc triplet %d to %d, xtype: %d\n", - T->nzmax, nznew, T->xtype)) ; - - /* ---------------------------------------------------------------------- */ - /* resize the matrix */ - /* ---------------------------------------------------------------------- */ - - CHOLMOD(realloc_multiple) (MAX (1,nznew), 2, T->xtype, &(T->i), &(T->j), - &(T->x), &(T->z), &(T->nzmax), Common) ; - - return (Common->status == CHOLMOD_OK) ; -} - - -/* ========================================================================== */ -/* === cholmod_triplet_to_sparse ============================================ */ -/* ========================================================================== */ - -/* Convert a set of triplets into a cholmod_sparse matrix. In MATLAB notation, - * for unsymmetric matrices: - * - * A = sparse (Ti, Tj, Tx, nrow, ncol, nzmax) ; - * - * For the symmetric upper case: - * - * A = sparse (min(Ti,Tj), max(Ti,Tj), Tx, nrow, ncol, nzmax) ; - * - * For the symmetric lower case: - * - * A = sparse (max(Ti,Tj), min(Ti,Tj), Tx, nrow, ncol, nzmax) ; - * - * If Tx is NULL, then A->x is not allocated, and only the pattern of A is - * computed. A is returned in packed form, and can be of any stype - * (upper/lower/unsymmetric). It has enough space to hold the values in T, - * or nzmax, whichever is larger. - * - * workspace: Iwork (max (nrow,ncol)) - * allocates a temporary copy of its output matrix. - * - * The resulting sparse matrix has the same xtype as the input triplet matrix. - */ - -cholmod_sparse *CHOLMOD(triplet_to_sparse) -( - /* ---- input ---- */ - cholmod_triplet *T, /* matrix to copy */ - size_t nzmax, /* allocate at least this much space in output matrix */ - /* --------------- */ - cholmod_common *Common -) -{ - cholmod_sparse *R, *A = NULL ; - Int *Wj, *Rp, *Ri, *Rnz, *Ti, *Tj ; - Int i, j, p, k, stype, nrow, ncol, nz, ok ; - size_t anz = 0 ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - RETURN_IF_NULL (T, NULL) ; - Ti = T->i ; - Tj = T->j ; - RETURN_IF_NULL (Ti, NULL) ; - RETURN_IF_NULL (Tj, NULL) ; - RETURN_IF_XTYPE_INVALID (T, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; - stype = SIGN (T->stype) ; - if (stype && T->nrow != T->ncol) - { - /* inputs invalid */ - ERROR (CHOLMOD_INVALID, "matrix invalid") ; - return (NULL) ; - } - Common->status = CHOLMOD_OK ; - DEBUG (CHOLMOD(dump_triplet) (T, "T", Common)) ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - nrow = T->nrow ; - ncol = T->ncol ; - nz = T->nnz ; - - /* ---------------------------------------------------------------------- */ - /* allocate workspace */ - /* ---------------------------------------------------------------------- */ - - CHOLMOD(allocate_work) (0, MAX (nrow, ncol), 0, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - - /* ---------------------------------------------------------------------- */ - /* allocate temporary matrix R */ - /* ---------------------------------------------------------------------- */ - - R = CHOLMOD(allocate_sparse) (ncol, nrow, nz, FALSE, FALSE, -stype, - T->xtype, Common) ; - - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - - Rp = R->p ; - Ri = R->i ; - Rnz = R->nz ; - - /* ---------------------------------------------------------------------- */ - /* count the entries in each row of A (also counting duplicates) */ - /* ---------------------------------------------------------------------- */ - - for (i = 0 ; i < nrow ; i++) - { - Rnz [i] = 0 ; - } - - if (stype > 0) - { - for (k = 0 ; k < nz ; k++) - { - i = Ti [k] ; - j = Tj [k] ; - if (i < 0 || i >= nrow || j < 0 || j >= ncol) - { - ERROR (CHOLMOD_INVALID, "index out of range") ; - break ; - } - /* A will be symmetric with just the upper triangular part stored. - * Create a matrix R that is lower triangular. Entries in the - * upper part of R are transposed to the lower part. */ - Rnz [MIN (i,j)]++ ; - } - } - else if (stype < 0) - { - for (k = 0 ; k < nz ; k++) - { - i = Ti [k] ; - j = Tj [k] ; - if (i < 0 || i >= nrow || j < 0 || j >= ncol) - { - ERROR (CHOLMOD_INVALID, "index out of range") ; - break ; - } - /* A will be symmetric with just the lower triangular part stored. - * Create a matrix R that is upper triangular. Entries in the - * lower part of R are transposed to the upper part. */ - Rnz [MAX (i,j)]++ ; - } - } - else - { - for (k = 0 ; k < nz ; k++) - { - i = Ti [k] ; - j = Tj [k] ; - if (i < 0 || i >= nrow || j < 0 || j >= ncol) - { - ERROR (CHOLMOD_INVALID, "index out of range") ; - break ; - } - /* constructing an unsymmetric matrix */ - Rnz [i]++ ; - } - } - - if (Common->status < CHOLMOD_OK) - { - /* triplet matrix is invalid */ - CHOLMOD(free_sparse) (&R, Common) ; - return (NULL) ; - } - - /* ---------------------------------------------------------------------- */ - /* construct the row pointers */ - /* ---------------------------------------------------------------------- */ - - p = 0 ; - for (i = 0 ; i < nrow ; i++) - { - Rp [i] = p ; - p += Rnz [i] ; - } - Rp [nrow] = p ; - - /* use Wj (i/l/l) as temporary row pointers */ - Wj = Common->Iwork ; /* size MAX (nrow,ncol) FUTURE WORK: (i/l/l) */ - for (i = 0 ; i < nrow ; i++) - { - Wj [i] = Rp [i] ; - } - - /* ---------------------------------------------------------------------- */ - /* construct triplet matrix, using template routine */ - /* ---------------------------------------------------------------------- */ - - switch (T->xtype) - { - case CHOLMOD_PATTERN: - anz = p_cholmod_triplet_to_sparse (T, R, Common) ; - break ; - - case CHOLMOD_REAL: - anz = r_cholmod_triplet_to_sparse (T, R, Common) ; - break ; - - case CHOLMOD_COMPLEX: - anz = c_cholmod_triplet_to_sparse (T, R, Common) ; - break ; - - case CHOLMOD_ZOMPLEX: - anz = z_cholmod_triplet_to_sparse (T, R, Common) ; - break ; - } - - /* ---------------------------------------------------------------------- */ - /* A = R' (array transpose, not complex conjugate transpose) */ - /* ---------------------------------------------------------------------- */ - - /* workspace: Iwork (R->nrow), which is A->ncol */ - - ASSERT (CHOLMOD(dump_sparse) (R, "R", Common) >= 0) ; - - A = CHOLMOD(allocate_sparse) (nrow, ncol, MAX (anz, nzmax), TRUE, TRUE, - stype, T->xtype, Common) ; - - if (stype) - { - ok = CHOLMOD(transpose_sym) (R, 1, NULL, A, Common) ; - } - else - { - ok = CHOLMOD(transpose_unsym) (R, 1, NULL, NULL, 0, A, Common) ; - } - - CHOLMOD(free_sparse) (&R, Common) ; - if (Common->status < CHOLMOD_OK) - { - CHOLMOD(free_sparse) (&A, Common) ; - } - - /* ---------------------------------------------------------------------- */ - /* return result */ - /* ---------------------------------------------------------------------- */ - - ASSERT (CHOLMOD(dump_sparse) (A, "A = triplet(T) result", Common) >= 0) ; - return (A) ; -} - - -/* ========================================================================== */ -/* === cholmod_sparse_to_triplet ============================================ */ -/* ========================================================================== */ - -/* Converts a sparse column-oriented matrix to triplet form. - * The resulting triplet matrix has the same xtype as the sparse matrix. - * - * workspace: none - */ - -cholmod_triplet *CHOLMOD(sparse_to_triplet) -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ - /* --------------- */ - cholmod_common *Common -) -{ - double *Ax, *Az, *Tx, *Tz ; - Int *Ap, *Ai, *Ti, *Tj, *Anz ; - cholmod_triplet *T ; - Int i, xtype, p, pend, k, j, nrow, ncol, nz, stype, packed, up, lo, - both ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - RETURN_IF_NULL (A, NULL) ; - RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; - stype = SIGN (A->stype) ; - nrow = A->nrow ; - ncol = A->ncol ; - if (stype && nrow != ncol) - { - /* inputs invalid */ - ERROR (CHOLMOD_INVALID, "matrix invalid") ; - return (NULL) ; - } - Ax = A->x ; - Az = A->z ; - xtype = A->xtype ; - Common->status = CHOLMOD_OK ; - - ASSERT (CHOLMOD(dump_sparse) (A, "A", Common) >= 0) ; - - /* ---------------------------------------------------------------------- */ - /* allocate triplet matrix */ - /* ---------------------------------------------------------------------- */ - - nz = CHOLMOD(nnz) (A, Common) ; - T = CHOLMOD(allocate_triplet) (nrow, ncol, nz, A->stype, A->xtype, Common) ; - - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - - /* ---------------------------------------------------------------------- */ - /* convert to a sparse matrix */ - /* ---------------------------------------------------------------------- */ - - Ap = A->p ; - Ai = A->i ; - Anz = A->nz ; - packed = A->packed ; - - Ti = T->i ; - Tj = T->j ; - Tx = T->x ; - Tz = T->z ; - T->stype = A->stype ; - - both = (A->stype == 0) ; - up = (A->stype > 0) ; - lo = (A->stype < 0) ; - - k = 0 ; - - for (j = 0 ; j < ncol ; j++) - { - p = Ap [j] ; - pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (both || (up && i <= j) || (lo && i >= j)) - { - Ti [k] = Ai [p] ; - Tj [k] = j ; - - if (xtype == CHOLMOD_REAL) - { - Tx [k] = Ax [p] ; - } - else if (xtype == CHOLMOD_COMPLEX) - { - Tx [2*k ] = Ax [2*p ] ; - Tx [2*k+1] = Ax [2*p+1] ; - } - else if (xtype == CHOLMOD_ZOMPLEX) - { - Tx [k] = Ax [p] ; - Tz [k] = Az [p] ; - } - - k++ ; - ASSERT (k <= nz) ; - } - } - } - - T->nnz = k ; - - /* ---------------------------------------------------------------------- */ - /* return result */ - /* ---------------------------------------------------------------------- */ - - ASSERT (CHOLMOD(dump_triplet) (T, "T", Common)) ; - return (T) ; -} - - -/* ========================================================================== */ -/* === cholmod_copy_triplet ================================================= */ -/* ========================================================================== */ - -/* Create an exact copy of a triplet matrix, except that entries in unused - * space are not copied (they might not be initialized, and copying them would - * cause program checkers such as purify and valgrind to complain). - * The output triplet matrix has the same xtype as the input triplet matrix. - */ - -cholmod_triplet *CHOLMOD(copy_triplet) -( - /* ---- input ---- */ - cholmod_triplet *T, /* matrix to copy */ - /* --------------- */ - cholmod_common *Common -) -{ - double *Tx, *Tz, *Cx, *Cz ; - Int *Ci, *Cj, *Ti, *Tj ; - cholmod_triplet *C ; - Int xtype, k, nz ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - RETURN_IF_NULL_COMMON (NULL) ; - RETURN_IF_NULL (T, NULL) ; - RETURN_IF_XTYPE_INVALID (T, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ; - nz = T->nnz ; - Ti = T->i ; - Tj = T->j ; - Tx = T->x ; - Tz = T->z ; - xtype = T->xtype ; - RETURN_IF_NULL (Ti, NULL) ; - RETURN_IF_NULL (Tj, NULL) ; - Common->status = CHOLMOD_OK ; - DEBUG (CHOLMOD(dump_triplet) (T, "T input", Common)) ; - - /* ---------------------------------------------------------------------- */ - /* allocate copy */ - /* ---------------------------------------------------------------------- */ - - C = CHOLMOD(allocate_triplet) (T->nrow, T->ncol, T->nzmax, T->stype, - xtype, Common) ; - - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - - /* ---------------------------------------------------------------------- */ - /* copy the triplet matrix */ - /* ---------------------------------------------------------------------- */ - - Ci = C->i ; - Cj = C->j ; - Cx = C->x ; - Cz = C->z ; - C->nnz = nz ; - - for (k = 0 ; k < nz ; k++) - { - Ci [k] = Ti [k] ; - } - for (k = 0 ; k < nz ; k++) - { - Cj [k] = Tj [k] ; - } - - if (xtype == CHOLMOD_REAL) - { - for (k = 0 ; k < nz ; k++) - { - Cx [k] = Tx [k] ; - } - } - else if (xtype == CHOLMOD_COMPLEX) - { - for (k = 0 ; k < nz ; k++) - { - Cx [2*k ] = Tx [2*k ] ; - Cx [2*k+1] = Tx [2*k+1] ; - } - } - else if (xtype == CHOLMOD_ZOMPLEX) - { - for (k = 0 ; k < nz ; k++) - { - Cx [k] = Tx [k] ; - Cz [k] = Tz [k] ; - } - } - - /* ---------------------------------------------------------------------- */ - /* return the result */ - /* ---------------------------------------------------------------------- */ - - ASSERT (CHOLMOD(dump_triplet) (C, "C triplet copy", Common)) ; - return (C) ; -} diff --git a/CHOLMOD/Core/cholmod_version.c b/CHOLMOD/Core/cholmod_version.c deleted file mode 100644 index d78281dc9..000000000 --- a/CHOLMOD/Core/cholmod_version.c +++ /dev/null @@ -1,33 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_version: current version of CHOLMOD -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ -//------------------------------------------------------------------------------ - -/* Return the current version of CHOLMOD. Unlike all other functions in - CHOLMOD, this function does not require the CHOLMOD Common. */ - -#include "cholmod_internal.h" - -int CHOLMOD(version) /* returns CHOLMOD_VERSION */ -( - /* output, contents not defined on input. Not used if NULL. - version [0] = CHOLMOD_MAIN_VERSION ; - version [1] = CHOLMOD_SUB_VERSION ; - version [2] = CHOLMOD_SUBSUB_VERSION ; - */ - int version [3] -) -{ - if (version != NULL) - { - version [0] = CHOLMOD_MAIN_VERSION ; - version [1] = CHOLMOD_SUB_VERSION ; - version [2] = CHOLMOD_SUBSUB_VERSION ; - } - return (CHOLMOD_VERSION) ; -} - diff --git a/CHOLMOD/Core/t_cholmod_change_factor.c b/CHOLMOD/Core/t_cholmod_change_factor.c deleted file mode 100644 index 807f5ef48..000000000 --- a/CHOLMOD/Core/t_cholmod_change_factor.c +++ /dev/null @@ -1,658 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/t_cholmod_change_factor: template for cholmod_change_factor -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* Template routine for cholmod_change_factor. All xtypes supported. */ - -#include "cholmod_template.h" - -/* ========================================================================== */ -/* === t_change_simplicial_numeric ========================================== */ -/* ========================================================================== */ - -static void TEMPLATE (change_simplicial_numeric) -( - cholmod_factor *L, - Int to_ll, - Int to_packed, - Int *newLi, - double *newLx, - double *newLz, - Int lnz, - Int grow, - double grow1, - Int grow2, - Int make_ll, - Int make_monotonic, - Int make_ldl, - cholmod_common *Common -) -{ - double xlen, dj [1], ljj [1], lj2 [1] ; - double *Lx, *Lz ; - Int *Lp, *Li, *Lnz ; - Int n, j, len, pnew, pold, k, p, pend ; - - n = L->n ; - Lp = L->p ; - Li = L->i ; - Lx = L->x ; - Lz = L->z ; - Lnz = L->nz ; - - if (make_ll) - { - L->minor = n ; - } - - if (make_monotonic) - { - - /* ------------------------------------------------------------------ */ - /* reorder the columns to make them monotonic */ - /* ------------------------------------------------------------------ */ - - pnew = 0 ; - for (j = 0 ; j < n ; j++) - { - /* copy and pack column j */ - len = Lnz [j] ; - PRINT2 (("j: "ID" Lnz[j] "ID" len "ID" p "ID"\n", - j, Lnz [j], len, pnew)) ; - pold = Lp [j] ; - ASSERT (Li [pold] == j) ; - - if (make_ll) - { - - /* ---------------------------------------------------------- */ - /* copy and convert LDL' to LL' */ - /* ---------------------------------------------------------- */ - - /* dj = Lx [pold] ; */ - ASSIGN_REAL (dj,0, Lx,pold) ; - - if (IS_LE_ZERO (dj [0])) - { - /* Conversion has failed; matrix is not positive definite. - * Do not modify the column so that the LDL' factorization - * can be restored if desired, by converting back to LDL'. - * Continue the conversion, but flag the error. */ - if (L->minor == (size_t) n) - { - ERROR (CHOLMOD_NOT_POSDEF, "L not positive definite") ; - L->minor = j ; - } - for (k = 0 ; k < len ; k++) - { - newLi [pnew + k] = Li [pold + k] ; - /* newLx [pnew + k] = Lx [pold + k] ; */ - ASSIGN (newLx, newLz, pnew+k, Lx, Lz, pold+k) ; - } - } - else - { - ljj [0] = sqrt (dj [0]) ; - newLi [pnew] = j ; - /* newLx [pnew] = ljj ; */ - ASSIGN_REAL (newLx, pnew, ljj, 0) ; - CLEAR_IMAG (newLx, newLz, pnew) ; - - for (k = 1 ; k < len ; k++) - { - newLi [pnew + k] = Li [pold + k] ; - /* newLx [pnew + k] = Lx [pold + k] * ljj ; */ - MULT_REAL (newLx, newLz, pnew+k, Lx, Lz, pold+k, ljj,0); - } - } - - } - else if (make_ldl) - { - - /* ---------------------------------------------------------- */ - /* copy and convert LL' to LDL' */ - /* ---------------------------------------------------------- */ - - /* ljj = Lx [pold] ; */ - ASSIGN_REAL (ljj, 0, Lx, pold) ; - - if (ljj [0] <= 0) - { - /* matrix is not positive-definite; copy column as-is */ - for (k = 0 ; k < len ; k++) - { - newLi [pnew + k] = Li [pold + k] ; - /* newLx [pnew + k] = Lx [pold + k] ; */ - ASSIGN (newLx, newLz, pnew+k, Lx, Lz, pold+k) ; - } - } - else - { - newLi [pnew] = j ; - /* newLx [pnew] = ljj*ljj ; */ - lj2 [0] = ljj [0] * ljj [0] ; - ASSIGN_REAL (newLx, pnew, lj2, 0) ; - CLEAR_IMAG (newLx, newLz, pnew) ; - - for (k = 1 ; k < len ; k++) - { - newLi [pnew + k] = Li [pold + k] ; - /* newLx [pnew + k] = Lx [pold + k] / ljj ; */ - DIV_REAL (newLx, newLz, pnew+k, Lx, Lz, pold+k, ljj,0) ; - } - } - - } - else - { - - /* ---------------------------------------------------------- */ - /* copy and leave LL' or LDL' as-is */ - /* ---------------------------------------------------------- */ - - for (k = 0 ; k < len ; k++) - { - newLi [pnew + k] = Li [pold + k] ; - /* newLx [pnew + k] = Lx [pold + k] ; */ - ASSIGN (newLx, newLz, pnew+k, Lx, Lz, pold+k) ; - } - } - - Lp [j] = pnew ; - - /* compute len in double to avoid integer overflow */ - if (grow) - { - xlen = (double) len ; - xlen = grow1 * xlen + grow2 ; - xlen = MIN (xlen, n-j) ; - len = (Int) xlen ; - } - ASSERT (len >= Lnz [j] && len <= n-j) ; - pnew += len ; - ASSERT (pnew > 0) ; /* integer overflow case already covered */ - } - Lp [n] = pnew ; - PRINT1 (("final pnew = "ID", lnz "ID" lnzmax %g\n", - pnew, lnz, (double) L->nzmax)) ; - ASSERT (pnew <= lnz) ; - - /* free the old L->i and L->x and replace with the new ones */ - CHOLMOD(free) (L->nzmax, sizeof (Int), L->i, Common) ; - -#ifdef REAL - CHOLMOD(free) (L->nzmax, sizeof (double), L->x, Common) ; -#elif defined (COMPLEX) - CHOLMOD(free) (L->nzmax, 2*sizeof (double), L->x, Common) ; -#else - CHOLMOD(free) (L->nzmax, sizeof (double), L->x, Common) ; - CHOLMOD(free) (L->nzmax, sizeof (double), L->z, Common) ; -#endif - - L->i = newLi ; - L->x = newLx ; - L->z = newLz ; - L->nzmax = lnz ; - - /* reconstruct the link list */ - natural_list (L) ; - - } - else if (to_packed) - { - - /* ------------------------------------------------------------------ */ - /* already monotonic, just pack the columns of L */ - /* ------------------------------------------------------------------ */ - - pnew = 0 ; - - if (make_ll) - { - - /* -------------------------------------------------------------- */ - /* pack and convert LDL' to LL' */ - /* -------------------------------------------------------------- */ - - for (j = 0 ; j < n ; j++) - { - /* pack column j */ - pold = Lp [j] ; - len = Lnz [j] ; - ASSERT (len > 0) ; - ASSERT (Li [pold] == j) ; - PRINT2 (("col "ID" pnew "ID" pold "ID"\n", j, pnew, pold)) ; - - /* dj = Lx [pold] ; */ - ASSIGN_REAL (dj,0, Lx,pold) ; - - if (IS_LE_ZERO (dj [0])) - { - /* Conversion has failed; matrix is not positive definite. - * Do not modify the column so that the LDL' factorization - * can be restored if desired, by converting back to LDL'. - * Continue the conversion, but flag the error. */ - if (L->minor == (size_t) n) - { - ERROR (CHOLMOD_NOT_POSDEF, "L not positive definite") ; - L->minor = j ; - } - for (k = 0 ; k < len ; k++) - { - Li [pnew + k] = Li [pold + k] ; - /* Lx [pnew + k] = Lx [pold + k] ; */ - ASSIGN (Lx, Lz, pnew+k, Lx, Lz, pold+k) ; - } - } - else - { - ljj [0] = sqrt (dj [0]) ; - Li [pnew] = j ; - - /* Lx [pnew] = ljj ; */ - ASSIGN_REAL (Lx, pnew, ljj, 0) ; - CLEAR_IMAG (Lx, Lz, pnew) ; - - for (k = 1 ; k < len ; k++) - { - Li [pnew + k] = Li [pold + k] ; - /* Lx [pnew + k] = Lx [pold + k] * ljj ; */ - MULT_REAL (Lx, Lz, pnew+k, Lx, Lz, pold+k, ljj,0) ; - } - } - Lp [j] = pnew ; - pnew += len ; - } - - } - else if (make_ldl) - { - - /* -------------------------------------------------------------- */ - /* pack and convert LL' to LDL' */ - /* -------------------------------------------------------------- */ - - for (j = 0 ; j < n ; j++) - { - /* pack column j */ - pold = Lp [j] ; - len = Lnz [j] ; - - /* ljj = Lx [pold] ; */ - ASSIGN_REAL (ljj, 0, Lx, pold) ; - - ASSERT (len > 0) ; - PRINT2 (("col "ID" pnew "ID" pold "ID"\n", j, pnew, pold)) ; - if (ljj [0] <= 0) - { - /* matrix is not positive-definite; pack column as-is */ - for (k = 0 ; k < len ; k++) - { - Li [pnew + k] = Li [pold + k] ; - /* Lx [pnew + k] = Lx [pold + k] ; */ - ASSIGN (Lx, Lz, pnew+k, Lx, Lz, pold+k) ; - } - } - else - { - Li [pnew] = Li [pold] ; - - /* Lx [pnew] = ljj*ljj ; */ - lj2 [0] = ljj [0] * ljj [0] ; - ASSIGN_REAL (Lx, pnew, lj2, 0) ; - CLEAR_IMAG (Lx, Lz, pnew) ; - - for (k = 1 ; k < len ; k++) - { - Li [pnew + k] = Li [pold + k] ; - /* Lx [pnew + k] = Lx [pold + k] / ljj ; */ - DIV_REAL (Lx, Lz, pnew+k, Lx, Lz, pold+k, ljj,0) ; - } - } - Lp [j] = pnew ; - pnew += len ; - } - - } - else - { - - /* ---------------------------------------------------------- */ - /* pack and leave LL' or LDL' as-is */ - /* ---------------------------------------------------------- */ - - for (j = 0 ; j < n ; j++) - { - /* pack column j */ - pold = Lp [j] ; - len = Lnz [j] ; - ASSERT (len > 0) ; - PRINT2 (("col "ID" pnew "ID" pold "ID"\n", j, pnew, pold)) ; - if (pnew < pold) - { - PRINT2 ((" pack this column\n")) ; - for (k = 0 ; k < len ; k++) - { - Li [pnew + k] = Li [pold + k] ; - /* Lx [pnew + k] = Lx [pold + k] ; */ - ASSIGN (Lx, Lz, pnew+k, Lx, Lz, pold+k) ; - } - Lp [j] = pnew ; - } - pnew += len ; - } - } - - Lp [n] = pnew ; - PRINT2 (("Lp [n] = "ID"\n", pnew)) ; - - } - else if (make_ll) - { - - /* ------------------------------------------------------------------ */ - /* convert LDL' to LL', but do so in-place */ - /* ------------------------------------------------------------------ */ - - for (j = 0 ; j < n ; j++) - { - p = Lp [j] ; - pend = p + Lnz [j] ; - - /* dj = Lx [p] ; */ - ASSIGN_REAL (dj,0, Lx,p) ; - - if (IS_LE_ZERO (dj [0])) - { - /* Conversion has failed; matrix is not positive definite. - * Do not modify the column so that the LDL' factorization - * can be restored if desired, by converting back to LDL'. - * Continue the conversion, but flag the error. */ - if (L->minor == (size_t) n) - { - ERROR (CHOLMOD_NOT_POSDEF, "L not positive definite") ; - L->minor = j ; - } - } - else - { - ljj [0] = sqrt (dj [0]) ; - /* Lx [p] = ljj ; */ - ASSIGN_REAL (Lx,p, ljj,0) ; - CLEAR_IMAG (Lx, Lz, p) ; - - for (p++ ; p < pend ; p++) - { - /* Lx [p] *= ljj ; */ - MULT_REAL (Lx,Lz,p, Lx,Lz,p, ljj,0) ; - } - } - } - - } - else if (make_ldl) - { - - /* ------------------------------------------------------------------ */ - /* convert LL' to LDL', but do so in-place */ - /* ------------------------------------------------------------------ */ - - for (j = 0 ; j < n ; j++) - { - p = Lp [j] ; - pend = p + Lnz [j] ; - - /* ljj = Lx [p] ; */ - ASSIGN_REAL (ljj, 0, Lx, p) ; - - if (ljj [0] > 0) - { - /* Lx [p] = ljj*ljj ; */ - lj2 [0] = ljj [0] * ljj [0] ; - ASSIGN_REAL (Lx, p, lj2, 0) ; - CLEAR_IMAG (Lx, Lz, p) ; - - for (p++ ; p < pend ; p++) - { - /* Lx [p] /= ljj ; */ - DIV_REAL (Lx,Lz,p, Lx,Lz,p, ljj,0) ; - } - } - } - } - - L->is_ll = to_ll ; - - DEBUG (CHOLMOD(dump_factor) (L, "done change simplicial numeric", Common)) ; -} - - -/* ========================================================================== */ -/* === t_ll_super_to_simplicial_numeric ===================================== */ -/* ========================================================================== */ - -/* A supernodal L can only be real or complex, not zomplex */ - -#ifndef ZOMPLEX - -static void TEMPLATE (ll_super_to_simplicial_numeric) -( - cholmod_factor *L, - Int to_packed, - Int to_ll, - cholmod_common *Common -) -{ - double ljj [1], lj2 [1] ; - double *Lx ; - Int *Ls, *Lpi, *Lpx, *Super, *Lp, *Li, *Lnz ; - Int n, lnz, s, nsuper, p, psi, psx, psend, nsrow, nscol, ii, jj, j, k1, k2, - q ; - - L->is_ll = to_ll ; - - Lp = L->p ; - Li = L->i ; - Lx = L->x ; - Lnz = L->nz ; - lnz = L->nzmax ; - - n = L->n ; - nsuper = L->nsuper ; - Lpi = L->pi ; - Lpx = L->px ; - Ls = L->s ; - Super = L->super ; - - p = 0 ; - - for (s = 0 ; s < nsuper ; s++) - { - k1 = Super [s] ; - k2 = Super [s+1] ; - psi = Lpi [s] ; - psend = Lpi [s+1] ; - psx = Lpx [s] ; - nsrow = psend - psi ; - nscol = k2 - k1 ; - - for (jj = 0 ; jj < nscol ; jj++) - { - /* column j of L starts here */ - j = jj + k1 ; - - if (to_ll) - { - if (to_packed) - { - - /* ------------------------------------------------------ */ - /* convert to LL' packed */ - /* ------------------------------------------------------ */ - - Lp [j] = p ; - PRINT2 (("Col j "ID" p "ID"\n", j, p)) ; - for (ii = jj ; ii < nsrow ; ii++) - { - /* get L(i,j) from supernode and store in column j */ - ASSERT (p < (Int) (L->xsize) && p <= psx+ii+jj*nsrow) ; - Li [p] = Ls [psi + ii] ; - /* Lx [p] = Lx [psx + ii + jj*nsrow] ; */ - q = psx + ii + jj*nsrow ; - ASSIGN (Lx,-,p, Lx,-,q) ; - PRINT2 ((" i "ID" ", Li [p])) ; - XPRINT2 (Lx,-,q) ; - PRINT2 (("\n")) ; - p++ ; - } - Lnz [j] = p - Lp [j] ; - - } - else - { - - /* ------------------------------------------------------ */ - /* convert to LL' unpacked */ - /* ------------------------------------------------------ */ - - p = psx + jj + jj*nsrow ; - Lp [j] = p ; - Li [p] = j ; - Lnz [j] = nsrow - jj ; - p++ ; - for (ii = jj + 1 ; ii < nsrow ; ii++) - { - /* get L(i,j) from supernode and store in column j */ - Li [psx + ii + jj*nsrow] = Ls [psi + ii] ; - } - - } - } - else - { - if (to_packed) - { - - /* ------------------------------------------------------ */ - /* convert to LDL' packed */ - /* ------------------------------------------------------ */ - - Lp [j] = p ; - PRINT2 (("Col j "ID" p "ID"\n", Lp [j], p)) ; - /* ljj = Lx [psx + jj + jj*nsrow] ; */ - ASSIGN_REAL (ljj, 0, Lx, psx + jj + jj*nsrow) ; - - if (ljj [0] <= 0) - { - /* the matrix is not positive definite; do not divide */ - /* Lx [p] = ljj ; */ - ASSIGN_REAL (Lx, p, ljj, 0) ; - CLEAR_IMAG (Lx, Lz, p) ; - ljj [0] = 1 ; - } - else - { - lj2 [0] = ljj [0] * ljj [0] ; - /* Lx [p] = ljj*ljj ; */ - ASSIGN_REAL (Lx, p, lj2, 0) ; - CLEAR_IMAG (Lx, Lz, p) ; - } - Li [p] = j ; - p++ ; - for (ii = jj + 1 ; ii < nsrow ; ii++) - { - /* get L(i,j) from supernode and store in column j */ - ASSERT (p < (Int) (L->xsize) && p <= psx+ii+jj*nsrow) ; - Li [p] = Ls [psi + ii] ; - - /* Lx [p] = Lx [psx + ii + jj*nsrow] / ljj ; */ - q = psx + ii + jj*nsrow ; - DIV_REAL (Lx, Lz, p, Lx, Lz, q, ljj,0) ; - - PRINT2 ((" i "ID" %g\n", Li [p], Lx [p])) ; - p++ ; - } - Lnz [j] = p - Lp [j] ; - - } - else - { - - /* ------------------------------------------------------ */ - /* convert to LDL' unpacked */ - /* ------------------------------------------------------ */ - - p = psx + jj + jj*nsrow ; - Lp [j] = p ; - - /* ljj = Lx [p] ; */ - ASSIGN_REAL (ljj,0, Lx,p) ; - - if (ljj [0] <= 0) - { - /* the matrix is not positive definite; do not divide */ - /* Lx [p] = ljj ; */ - ASSIGN_REAL (Lx, p, ljj, 0) ; - CLEAR_IMAG (Lx, Lz, p) ; - ljj [0] = 1 ; - } - else - { - lj2 [0] = ljj [0] * ljj [0] ; - /* Lx [p] = ljj*ljj ; */ - ASSIGN_REAL (Lx, p, lj2, 0) ; - CLEAR_IMAG (Lx, Lz, p) ; - } - Li [p] = j ; - Lnz [j] = nsrow - jj ; - p++ ; - for (ii = jj + 1 ; ii < nsrow ; ii++) - { - /* get L(i,j) from supernode and store in column j */ - Li [psx + ii + jj*nsrow] = Ls [psi + ii] ; - - /* Lx [psx + ii + jj*nsrow] /= ljj ; */ - q = psx + ii + jj*nsrow ; - DIV_REAL (Lx, Lz, q, Lx, Lz, q, ljj,0) ; - } - } - } - } - } - - if (to_packed) - { - Lp [n] = p ; - PRINT1 (("Final Lp "ID" n "ID" lnz "ID"\n", p, n, lnz)) ; - ASSERT (Lp [n] == lnz) ; - ASSERT (lnz <= (Int) (L->xsize)) ; - /* reduce size of L->x to match L->i. This cannot fail. */ - L->x = CHOLMOD(realloc) (lnz, -#ifdef COMPLEX - 2 * -#endif - sizeof (double), L->x, &(L->xsize), Common) ; - ASSERT (lnz == (Int) (L->xsize)) ; - Common->status = CHOLMOD_OK ; - } - else - { - Lp [n] = Lpx [nsuper] ; - ASSERT (MAX (1,Lp [n]) == (Int) (L->xsize)) ; - ASSERT (MAX (1,Lp [n]) == (Int) (L->nzmax)) ; - } -} - -#endif - -#undef PATTERN -#undef REAL -#undef COMPLEX -#undef ZOMPLEX diff --git a/CHOLMOD/Core/t_cholmod_dense.c b/CHOLMOD/Core/t_cholmod_dense.c deleted file mode 100644 index 121098b10..000000000 --- a/CHOLMOD/Core/t_cholmod_dense.c +++ /dev/null @@ -1,263 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/t_cholmod_dense: template for cholmod_dense -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* Template routine for cholmod_dense. All xtypes supported, except that there - * are no dense matrices with an xtype of pattern. */ - -#include "cholmod_template.h" - -/* ========================================================================== */ -/* === t_cholmod_sparse_to_dense ============================================ */ -/* ========================================================================== */ - -static cholmod_dense *TEMPLATE (cholmod_sparse_to_dense) -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ - /* --------------- */ - cholmod_common *Common -) -{ - double *Ax, *Xx, *Az, *Xz ; - Int *Ap, *Ai, *Anz ; - cholmod_dense *X ; - Int i, j, p, pend, nrow, ncol, packed ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - nrow = A->nrow ; - ncol = A->ncol ; - packed = A->packed ; - Ap = A->p ; - Ai = A->i ; - Ax = A->x ; - Az = A->z ; - Anz = A->nz ; - - /* ---------------------------------------------------------------------- */ - /* allocate result */ - /* ---------------------------------------------------------------------- */ - - X = CHOLMOD(zeros) (nrow, ncol, XTYPE2, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - Xx = X->x ; - Xz = X->z ; - - /* ---------------------------------------------------------------------- */ - /* copy into dense matrix */ - /* ---------------------------------------------------------------------- */ - - if (A->stype < 0) - { - /* A is symmetric with lower stored, but both parts of X are present */ - for (j = 0 ; j < ncol ; j++) - { - p = Ap [j] ; - pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (i >= j) - { - ASSIGN2 (Xx, Xz, i+j*nrow, Ax, Az, p) ; - ASSIGN2_CONJ (Xx, Xz, j+i*nrow, Ax, Az, p) ; - } - } - } - } - else if (A->stype > 0) - { - /* A is symmetric with upper stored, but both parts of X are present */ - for (j = 0 ; j < ncol ; j++) - { - p = Ap [j] ; - pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (i <= j) - { - ASSIGN2 (Xx, Xz, i+j*nrow, Ax, Az, p) ; - ASSIGN2_CONJ (Xx, Xz, j+i*nrow, Ax, Az, p) ; - } - } - } - } - else - { - /* both parts of A and X are present */ - for (j = 0 ; j < ncol ; j++) - { - p = Ap [j] ; - pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - ASSIGN2 (Xx, Xz, i+j*nrow, Ax, Az, p) ; - } - } - } - - return (X) ; -} - - -#ifndef PATTERN - -/* There are no dense matrices of xtype CHOLMOD_PATTERN */ - -/* ========================================================================== */ -/* === t_cholmod_dense_to_sparse ============================================ */ -/* ========================================================================== */ - -static cholmod_sparse *TEMPLATE (cholmod_dense_to_sparse) -( - /* ---- input ---- */ - cholmod_dense *X, /* matrix to copy */ - int values, /* TRUE if values to be copied, FALSE otherwise */ - /* --------------- */ - cholmod_common *Common -) -{ - double *Xx, *Cx, *Xz, *Cz ; - Int *Ci, *Cp ; - cholmod_sparse *C ; - Int i, j, p, d, nrow, ncol, nz ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - nrow = X->nrow ; - ncol = X->ncol ; - d = X->d ; - Xx = X->x ; - Xz = X->z ; - - /* ---------------------------------------------------------------------- */ - /* count the number of nonzeros in the result */ - /* ---------------------------------------------------------------------- */ - - nz = 0 ; - for (j = 0 ; j < ncol ; j++) - { - for (i = 0 ; i < nrow ; i++) - { - if (ENTRY_IS_NONZERO (Xx, Xz, i+j*d)) - { - nz++ ; - } - } - } - - /* ---------------------------------------------------------------------- */ - /* allocate the result C */ - /* ---------------------------------------------------------------------- */ - - C = CHOLMOD(allocate_sparse) (nrow, ncol, nz, TRUE, TRUE, 0, - values ? XTYPE : CHOLMOD_PATTERN, Common) ; - if (Common->status < CHOLMOD_OK) - { - return (NULL) ; /* out of memory */ - } - Cp = C->p ; - Ci = C->i ; - Cx = C->x ; - Cz = C->z ; - - /* ---------------------------------------------------------------------- */ - /* copy the dense matrix X into the sparse matrix C */ - /* ---------------------------------------------------------------------- */ - - p = 0 ; - for (j = 0 ; j < ncol ; j++) - { - Cp [j] = p ; - for (i = 0 ; i < nrow ; i++) - { - if (ENTRY_IS_NONZERO (Xx, Xz, i+j*d)) - { - Ci [p] = i ; - if (values) - { - ASSIGN (Cx, Cz, p, Xx, Xz, i+j*d) ; - } - p++ ; - } - } - } - ASSERT (p == nz) ; - Cp [ncol] = nz ; - - /* ---------------------------------------------------------------------- */ - /* return result */ - /* ---------------------------------------------------------------------- */ - - ASSERT (CHOLMOD(dump_sparse) (C, "C", Common) >= 0) ; - return (C) ; -} - - -/* ========================================================================== */ -/* === t_cholmod_copy_dense2 ================================================ */ -/* ========================================================================== */ - -/* Y = X, where X and Y are both already allocated. */ - -static int TEMPLATE (cholmod_copy_dense2) -( - /* ---- input ---- */ - cholmod_dense *X, /* matrix to copy */ - /* ---- output --- */ - cholmod_dense *Y /* copy of matrix X */ -) -{ - double *Xx, *Xz, *Yx, *Yz ; - Int i, j, nrow, ncol, dy, dx ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - Xx = X->x ; - Xz = X->z ; - Yx = Y->x ; - Yz = Y->z ; - dx = X->d ; - dy = Y->d ; - nrow = X->nrow ; - ncol = X->ncol ; - - /* ---------------------------------------------------------------------- */ - /* copy */ - /* ---------------------------------------------------------------------- */ - - CLEAR (Yx, Yz, 0) ; - for (j = 0 ; j < ncol ; j++) - { - for (i = 0 ; i < nrow ; i++) - { - ASSIGN (Yx, Yz, i+j*dy, Xx, Xz, i+j*dx) ; - } - } - return (TRUE) ; -} - -#endif - -#undef PATTERN -#undef REAL -#undef COMPLEX -#undef ZOMPLEX diff --git a/CHOLMOD/Core/t_cholmod_transpose.c b/CHOLMOD/Core/t_cholmod_transpose.c deleted file mode 100644 index 9b91e16fc..000000000 --- a/CHOLMOD/Core/t_cholmod_transpose.c +++ /dev/null @@ -1,315 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/t_cholmod_tranpose: template for cholmod_transpose -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* Template routine for cholmod_transpose. All xtypes are supported. For - * complex matrices, either the array tranpose or complex conjugate transpose - * can be computed. */ - -#include "cholmod_template.h" - -/* ========================================================================== */ -/* === t_cholmod_transpose_unsym ============================================ */ -/* ========================================================================== */ - -/* Compute F = A', A (:,f)', or A (p,f)', where A is unsymmetric and F is - * already allocated. The complex case performs either the array transpose - * or complex conjugate transpose. - * - * workspace: - * Iwork (MAX (nrow,ncol)) if fset is present - * Iwork (nrow) if fset is NULL - */ - -static int TEMPLATE (cholmod_transpose_unsym) -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to transpose */ - Int *Perm, /* size nrow, if present (can be NULL) */ - Int *fset, /* subset of 0:(A->ncol)-1 */ - Int nf, /* size of fset */ - /* ---- output --- */ - cholmod_sparse *F, /* F = A', A(:,f)', or A(p,f)' */ - /* --------------- */ - cholmod_common *Common -) -{ - double *Ax, *Az, *Fx, *Fz ; - Int *Ap, *Anz, *Ai, *Fp, *Fnz, *Fj, *Wi, *Iwork ; - Int j, p, pend, nrow, ncol, Apacked, use_fset, fp, Fpacked, jj, permute ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - /* ensure the xtype of A and F match (ignored if this is pattern version) */ - if (!XTYPE_OK (A->xtype)) - { - ERROR (CHOLMOD_INVALID, "real/complex mismatch") ; - return (FALSE) ; - } - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - use_fset = (fset != NULL) ; - nrow = A->nrow ; - ncol = A->ncol ; - - Ap = A->p ; /* size A->ncol+1, column pointers of A */ - Ai = A->i ; /* size nz = Ap [A->ncol], row indices of A */ - Ax = A->x ; /* size nz, real values of A */ - Az = A->z ; /* size nz, imag values of A */ - Anz = A->nz ; - Apacked = A->packed ; - ASSERT (IMPLIES (!Apacked, Anz != NULL)) ; - - permute = (Perm != NULL) ; - - Fp = F->p ; /* size A->nrow+1, row pointers of F */ - Fj = F->i ; /* size nz, column indices of F */ - Fx = F->x ; /* size nz, real values of F */ - Fz = F->z ; /* size nz, imag values of F */ - Fnz = F->nz ; - Fpacked = F->packed ; - ASSERT (IMPLIES (!Fpacked, Fnz != NULL)) ; - - nf = (use_fset) ? nf : ncol ; - - /* ---------------------------------------------------------------------- */ - /* get workspace */ - /* ---------------------------------------------------------------------- */ - - Iwork = Common->Iwork ; - Wi = Iwork ; /* size nrow (i/l/l) */ - - /* ---------------------------------------------------------------------- */ - /* construct the transpose */ - /* ---------------------------------------------------------------------- */ - - for (jj = 0 ; jj < nf ; jj++) - { - j = (use_fset) ? (fset [jj]) : jj ; - p = Ap [j] ; - pend = (Apacked) ? (Ap [j+1]) : (p + Anz [j]) ; - for ( ; p < pend ; p++) - { - fp = Wi [Ai [p]]++ ; - Fj [fp] = j ; -#ifdef NCONJUGATE - ASSIGN (Fx, Fz, fp, Ax, Az, p) ; -#else - ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ; -#endif - } - } - - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === t_cholmod_transpose_sym ============================================== */ -/* ========================================================================== */ - -/* Compute F = A' or A (p,p)', where A is symmetric and F is already allocated. - * The complex case performs either the array transpose or complex conjugate - * transpose. - * - * workspace: Iwork (nrow) if Perm NULL, Iwork (2*nrow) if Perm non-NULL. - */ - -static int TEMPLATE (cholmod_transpose_sym) -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to transpose */ - Int *Perm, /* size n, if present (can be NULL) */ - /* ---- output --- */ - cholmod_sparse *F, /* F = A' or A(p,p)' */ - /* --------------- */ - cholmod_common *Common -) -{ - double *Ax, *Az, *Fx, *Fz ; - Int *Ap, *Anz, *Ai, *Fp, *Fj, *Wi, *Pinv, *Iwork ; - Int p, pend, packed, fp, upper, permute, jold, n, i, j, iold ; - - /* ---------------------------------------------------------------------- */ - /* check inputs */ - /* ---------------------------------------------------------------------- */ - - /* ensure the xtype of A and F match (ignored if this is pattern version) */ - if (!XTYPE_OK (A->xtype)) - { - ERROR (CHOLMOD_INVALID, "real/complex mismatch") ; - return (FALSE) ; - } - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - permute = (Perm != NULL) ; - n = A->nrow ; - Ap = A->p ; /* size A->ncol+1, column pointers of A */ - Ai = A->i ; /* size nz = Ap [A->ncol], row indices of A */ - Ax = A->x ; /* size nz, real values of A */ - Az = A->z ; /* size nz, imag values of A */ - Anz = A->nz ; - packed = A->packed ; - ASSERT (IMPLIES (!packed, Anz != NULL)) ; - upper = (A->stype > 0) ; - - Fp = F->p ; /* size A->nrow+1, row pointers of F */ - Fj = F->i ; /* size nz, column indices of F */ - Fx = F->x ; /* size nz, real values of F */ - Fz = F->z ; /* size nz, imag values of F */ - - /* ---------------------------------------------------------------------- */ - /* get workspace */ - /* ---------------------------------------------------------------------- */ - - Iwork = Common->Iwork ; - Wi = Iwork ; /* size n (i/l/l) */ - Pinv = Iwork + n ; /* size n (i/i/l) , unused if Perm NULL */ - - /* ---------------------------------------------------------------------- */ - /* construct the transpose */ - /* ---------------------------------------------------------------------- */ - - if (permute) - { - if (upper) - { - /* permuted, upper */ - for (j = 0 ; j < n ; j++) - { - jold = Perm [j] ; - p = Ap [jold] ; - pend = (packed) ? Ap [jold+1] : p + Anz [jold] ; - for ( ; p < pend ; p++) - { - iold = Ai [p] ; - if (iold <= jold) - { - i = Pinv [iold] ; - if (i < j) - { - fp = Wi [i]++ ; - Fj [fp] = j ; -#ifdef NCONJUGATE - ASSIGN (Fx, Fz, fp, Ax, Az, p) ; -#else - ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ; -#endif - } - else - { - fp = Wi [j]++ ; - Fj [fp] = i ; - ASSIGN (Fx, Fz, fp, Ax, Az, p) ; - } - } - } - } - } - else - { - /* permuted, lower */ - for (j = 0 ; j < n ; j++) - { - jold = Perm [j] ; - p = Ap [jold] ; - pend = (packed) ? Ap [jold+1] : p + Anz [jold] ; - for ( ; p < pend ; p++) - { - iold = Ai [p] ; - if (iold >= jold) - { - i = Pinv [iold] ; - if (i > j) - { - fp = Wi [i]++ ; - Fj [fp] = j ; -#ifdef NCONJUGATE - ASSIGN (Fx, Fz, fp, Ax, Az, p) ; -#else - ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ; -#endif - } - else - { - fp = Wi [j]++ ; - Fj [fp] = i ; - ASSIGN (Fx, Fz, fp, Ax, Az, p) ; - } - } - } - } - } - } - else - { - if (upper) - { - /* unpermuted, upper */ - for (j = 0 ; j < n ; j++) - { - p = Ap [j] ; - pend = (packed) ? Ap [j+1] : p + Anz [j] ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (i <= j) - { - fp = Wi [i]++ ; - Fj [fp] = j ; -#ifdef NCONJUGATE - ASSIGN (Fx, Fz, fp, Ax, Az, p) ; -#else - ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ; -#endif - } - } - } - } - else - { - /* unpermuted, lower */ - for (j = 0 ; j < n ; j++) - { - p = Ap [j] ; - pend = (packed) ? Ap [j+1] : p + Anz [j] ; - for ( ; p < pend ; p++) - { - i = Ai [p] ; - if (i >= j) - { - fp = Wi [i]++ ; - Fj [fp] = j ; -#ifdef NCONJUGATE - ASSIGN (Fx, Fz, fp, Ax, Az, p) ; -#else - ASSIGN_CONJ (Fx, Fz, fp, Ax, Az, p) ; -#endif - } - } - } - } - } - - return (TRUE) ; -} - -#undef PATTERN -#undef REAL -#undef COMPLEX -#undef ZOMPLEX -#undef NCONJUGATE diff --git a/CHOLMOD/Core/t_cholmod_triplet.c b/CHOLMOD/Core/t_cholmod_triplet.c deleted file mode 100644 index f342058fb..000000000 --- a/CHOLMOD/Core/t_cholmod_triplet.c +++ /dev/null @@ -1,173 +0,0 @@ -//------------------------------------------------------------------------------ -// CHOLMOD/Core/t_cholmod_triplet: template for cholmod_triplet -//------------------------------------------------------------------------------ - -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis -// SPDX-License-Identifier: LGPL-2.1+ - -//------------------------------------------------------------------------------ - -/* Template routine for cholmod_triplet. All xtypes supported */ - -#include "cholmod_template.h" - -/* ========================================================================== */ -/* === t_cholmod_triplet_to_sparse ========================================== */ -/* ========================================================================== */ - -static size_t TEMPLATE (cholmod_triplet_to_sparse) -( - /* ---- input ---- */ - cholmod_triplet *T, /* matrix to copy */ - /* ---- in/out --- */ - cholmod_sparse *R, /* output matrix */ - /* --------------- */ - cholmod_common *Common -) -{ - double *Rx, *Rz, *Tx, *Tz ; - Int *Wj, *Rp, *Ri, *Rnz, *Ti, *Tj ; - Int i, j, p, p1, p2, pdest, pj, k, stype, nrow, ncol, nz ; - size_t anz ; - - /* ---------------------------------------------------------------------- */ - /* get inputs */ - /* ---------------------------------------------------------------------- */ - - /* Wj contains a copy of Rp on input [ */ - Wj = Common->Iwork ; /* size MAX (nrow,ncol). (i/l/l) */ - - Rp = R->p ; - Ri = R->i ; - Rnz = R->nz ; - Rx = R->x ; - Rz = R->z ; - - Ti = T->i ; - Tj = T->j ; - Tx = T->x ; - Tz = T->z ; - nz = T->nnz ; - nrow = T->nrow ; - ncol = T->ncol ; - stype = SIGN (T->stype) ; - - /* ---------------------------------------------------------------------- */ - /* construct the row form */ - /* ---------------------------------------------------------------------- */ - - /* if Ti is jumbled, this part dominates the run time */ - - if (stype > 0) - { - for (k = 0 ; k < nz ; k++) - { - i = Ti [k] ; - j = Tj [k] ; - if (i < j) - { - /* place triplet (j,i,x) in column i of R */ - p = Wj [i]++ ; - Ri [p] = j ; - } - else - { - /* place triplet (i,j,x) in column j of R */ - p = Wj [j]++ ; - Ri [p] = i ; - } - ASSIGN (Rx, Rz, p, Tx, Tz, k) ; - } - } - else if (stype < 0) - { - for (k = 0 ; k < nz ; k++) - { - i = Ti [k] ; - j = Tj [k] ; - if (i > j) - { - /* place triplet (j,i,x) in column i of R */ - p = Wj [i]++ ; - Ri [p] = j ; - } - else - { - /* place triplet (i,j,x) in column j of R */ - p = Wj [j]++ ; - Ri [p] = i ; - } - ASSIGN (Rx, Rz, p, Tx, Tz, k) ; - } - } - else - { - for (k = 0 ; k < nz ; k++) - { - /* place triplet (i,j,x) in column i of R */ - p = Wj [Ti [k]]++ ; - Ri [p] = Tj [k] ; - ASSIGN (Rx, Rz, p, Tx, Tz, k) ; - } - } - - /* done using Wj (i/l/l) as temporary row pointers ] */ - - /* ---------------------------------------------------------------------- */ - /* sum up duplicates */ - /* ---------------------------------------------------------------------- */ - - /* use Wj (i/l/l) of size ncol to keep track of duplicates in each row [ */ - for (j = 0 ; j < ncol ; j++) - { - Wj [j] = EMPTY ; - } - - anz = 0 ; - for (i = 0 ; i < nrow ; i++) - { - p1 = Rp [i] ; - p2 = Rp [i+1] ; - pdest = p1 ; - /* at this point Wj [j] < p1 holds true for all columns j, because - * Ri/Rx is stored in row oriented manner */ - for (p = p1 ; p < p2 ; p++) - { - j = Ri [p] ; - pj = Wj [j] ; - if (pj >= p1) - { - /* this column index j is already in row i at position pj; - * sum up the duplicate entry */ - /* Rx [pj] += Rx [p] ; */ - ASSEMBLE (Rx, Rz, pj, Rx, Rz, p) ; - } - else - { - /* keep the entry and keep track in Wj [j] for case above */ - Wj [j] = pdest ; - if (pdest != p) - { - Ri [pdest] = j ; - ASSIGN (Rx, Rz, pdest, Rx, Rz, p) ; - } - pdest++ ; - } - } - Rnz [i] = pdest - p1 ; - anz += (pdest - p1) ; - } - /* done using Wj to keep track of duplicate entries in each row ] */ - - /* ---------------------------------------------------------------------- */ - /* return number of entries after summing up duplicates */ - /* ---------------------------------------------------------------------- */ - - return (anz) ; -} - -#undef PATTERN -#undef REAL -#undef COMPLEX -#undef ZOMPLEX diff --git a/CHOLMOD/Demo/cholmod_demo.c b/CHOLMOD/Demo/cholmod_demo.c index 9aad7c137..ad5dc8c64 100644 --- a/CHOLMOD/Demo/cholmod_demo.c +++ b/CHOLMOD/Demo/cholmod_demo.c @@ -23,7 +23,7 @@ * The matrix is assumed to be positive definite (a supernodal LL' or simplicial * LDL' factorization is used). * - * Requires the Core, Cholesky, MatrixOps, and Check Modules. + * Requires the Utility, Cholesky, MatrixOps, and Check Modules. * Optionally uses the Partition and Supernodal Modules. * Does not use the Modify Module. * diff --git a/CHOLMOD/Demo/cholmod_l_demo.c b/CHOLMOD/Demo/cholmod_l_demo.c index 71fb43e6a..40dd31dde 100644 --- a/CHOLMOD/Demo/cholmod_l_demo.c +++ b/CHOLMOD/Demo/cholmod_l_demo.c @@ -23,7 +23,7 @@ * The matrix is assumed to be positive definite (a supernodal LL' or simplicial * LDL' factorization is used). * - * Requires the Core, Cholesky, MatrixOps, and Check Modules. + * Requires the Utility, Cholesky, MatrixOps, and Check Modules. * Optionally uses the Partition and Supernodal Modules. * Does not use the Modify Module. * diff --git a/CHOLMOD/Doc/CHOLMOD_UserGuide.pdf b/CHOLMOD/Doc/CHOLMOD_UserGuide.pdf index 911dff297..766e961e3 100644 Binary files a/CHOLMOD/Doc/CHOLMOD_UserGuide.pdf and b/CHOLMOD/Doc/CHOLMOD_UserGuide.pdf differ diff --git a/CHOLMOD/Doc/CHOLMOD_UserGuide.tex b/CHOLMOD/Doc/CHOLMOD_UserGuide.tex index 184396fb6..cfa6e876f 100644 --- a/CHOLMOD/Doc/CHOLMOD_UserGuide.tex +++ b/CHOLMOD/Doc/CHOLMOD_UserGuide.tex @@ -50,7 +50,7 @@ CHOLMOD Copyright\copyright 2005-2023 by Timothy A. Davis, All Rights Reserved. Portions are also copyrighted by William W. Hager (the {\tt Modify} Module), -and the University of Florida (the {\tt Partition} and {\tt Core} Modules). +and the University of Florida (the {\tt Partition} Module). All Rights Reserved. See CHOLMOD/Doc/License.txt for the license. @@ -92,14 +92,14 @@ that can factorize symmetric indefinite matrices if all of their leading submatrices are well-conditioned ($\m{D}$ is diagonal). -A pair of articles on CHOLMOD has been submitted to the ACM Transactions +A pair of articles on CHOLMOD appears in the ACM Transactions on Mathematical Software: \cite{ChenDavisHagerRajamanickam06,DavisHager06}. -CHOLMOD 1.0 replaces {\tt chol} (the sparse case), {\tt symbfact}, and {\tt etree} -in MATLAB 7.2 (R2006a), and is used for {\tt x=A}$\backslash${\tt b} -when {\tt A} is symmetric positive definite \cite{GilbertMolerSchreiber}. -It will replace {\tt sparse} in a future version of MATLAB. +CHOLMOD 1.0 replaces {\tt chol} (the sparse case), {\tt symbfact}, and {\tt +etree} in MATLAB 7.2 (R2006a), and is used for {\tt x=A}$\backslash${\tt b} +when {\tt A} is symmetric positive definite \cite{GilbertMolerSchreiber}. It +will replace {\tt sparse} in a future version of MATLAB. The C-callable CHOLMOD library consists of 133 user-callable routines and one include file. Each routine comes in two versions, one for {\tt int} integers @@ -110,6 +110,18 @@ performance, comparing it with nearly a dozen or so other solvers \cite{GouldHuScott05,GouldHuScott05b}. Its performance was quite competitive. +%------------------------------------------------------------------------------- +\newpage \section{Single-precision sparse matrix support} +%------------------------------------------------------------------------------- + +{\bf CHOLMOD v5.0.0}: introduces the first part of support for single + precision sparse matrices, with the introduction of the new + CHOLMOD:Utility Module. The CHOLMOD:Utility Module replaces the + CHOLMOD:Core Module that appeared in prior versions of CHOLMOD. + Single precision is not yet incorporated into the remaining Modules, + however. This feature will be implemented soon in a later version + of CHOLMOD. + %------------------------------------------------------------------------------- \newpage \section{Primary routines and data structures} %------------------------------------------------------------------------------- @@ -708,7 +720,7 @@ \subsection{Adjustable parameters} \vspace{0.1in} \noindent There are seven Modules that provide user-callable routines for CHOLMOD. \begin{enumerate} - \item {\tt Core}: basic data structures and definitions + \item {\tt Utility}: basic data structures and definitions \item {\tt Check}: prints/checks each of CHOLMOD's objects \item {\tt Cholesky}: sparse Cholesky factorization \item {\tt Modify}: sparse Cholesky update/downdate and row-add/row-delete @@ -727,7 +739,6 @@ \subsection{Adjustable parameters} \item {\tt Doc}: documentation (including this document) \item {\tt MATLAB}: CHOLMOD's interface to MATLAB \item {\tt Tcov}: an exhaustive test coverage (requires Linux or Solaris) - \item {\tt Valgrind}: runs the {\tt Tcov} test under {\tt valgrind} (requires Linux) \item \verb'cmake_modules': how other packages can find CHOLMOD when using cmake. \item \verb'Config': a folder containing the input files to create the @@ -735,11 +746,11 @@ \subsection{Adjustable parameters} \end{enumerate} %------------------------------------------------------------------------------- -\newpage \subsection{{\tt Core} Module: basic data structures and definitions} +\newpage \subsection{{\tt Utility} Module: basic data structures and definitions} %------------------------------------------------------------------------------- -CHOLMOD includes five basic objects, defined in the {\tt Core} Module. -The {\tt Core Module} provides basic operations for these objects +CHOLMOD includes five basic objects, defined in the {\tt Utility} Module. +The {\tt Utility Module} provides basic operations for these objects and is required by all six other CHOLMOD library Modules: \subsubsection{{\tt cholmod\_common}: parameters, statistics, and workspace} @@ -949,7 +960,7 @@ \subsubsection{{\tt cholmod\_version:} Version control} basic objects in CHOLMOD, and three kinds of integer vectors (a set, a permutation, and a tree). It also provides a routine to read a sparse matrix from a file in Matrix Market format (http://www.nist.gov/MatrixMarket). - Requires the {\tt Core} Module. + Requires the {\tt Utility} Module. \vspace{0.1in} \noindent Primary routines: @@ -997,7 +1008,7 @@ \subsubsection{{\tt cholmod\_version:} Version control} The primary routines are all that a user requires to order, analyze, and factorize a sparse symmetric positive definite matrix $\m{A}$ (or $\m{AA}\tr$), and to solve $\m{Ax}=\m{b}$ (or $\m{AA}\tr\m{x}=\m{b}$). The primary routines rely on the secondary -routines, the {\tt Core} Module, and the AMD and COLAMD packages. They +routines, the {\tt Utility} Module, and the AMD and COLAMD packages. They make optional use of the {\tt Supernodal} and {\tt Partition} Modules, the METIS package, the CAMD package, and the CCOLAMD package. The {\tt Cholesky} Module is @@ -1044,9 +1055,9 @@ \subsubsection{{\tt cholmod\_version:} Version control} It can also modify a corresponding solution to $\m{Lx}=\m{b}$ when L is modified. This module is most useful when applied on a Cholesky factorization computed by the {\tt Cholesky} module, but it does not actually require the {\tt Cholesky} module. -The {\tt Core} module can create an identity Cholesky factorization ($\m{LDL}\tr$ where +The {\tt Utility} module can create an identity Cholesky factorization ($\m{LDL}\tr$ where $\m{L}=\m{D}=\m{I}$) that can then be modified by these routines. -Requires the {\tt Core} module. Not required by any other CHOLMOD Module. +Requires the {\tt Utility} module. Not required by any other CHOLMOD Module. \vspace{0.1in} \noindent Primary routine: @@ -1075,7 +1086,7 @@ \subsection{{\tt MatrixOps} Module: basic sparse matrix operations} The {\tt MatrixOps} Module provides basic operations on sparse and dense matrices. -Requires the {\tt Core} module. Not required by any other CHOLMOD module. +Requires the {\tt Utility} module. Not required by any other CHOLMOD module. In the descriptions below, {\tt A}, {\tt B}, and {\tt C:} are sparse matrices ({\tt cholmod\_sparse}), {\tt X} and {\tt Y} are dense matrices ({\tt cholmod\_dense}), @@ -1106,7 +1117,7 @@ \subsection{{\tt Supernodal} Module: supernodal sparse Cholesky factorization} fill-reducing orderings. It normally operates on matrices ordered by the {\tt Cholesky} Module. It does not require the {\tt Cholesky} Module itself, however. -Requires the {\tt Core} Module, and two external packages: LAPACK and the BLAS. +Requires the {\tt Utility} Module, and two external packages: LAPACK and the BLAS. Optionally used by the {\tt Cholesky} Module. All are secondary routines since these functions are more easily used via the {\tt Cholesky} Module. @@ -1129,7 +1140,7 @@ \subsection{{\tt Partition} Module: graph-partitioning-based orderings} interface to CAMD, CCOLAMD, and CSYMAMD, constrained minimum degree ordering methods which order a matrix following constraints determined via nested dissection. -Requires the {\tt Core} and {\tt Cholesky} Modules, and two packages: {\tt METIS 5.1.0}, CAMD, and CCOLAMD. +Requires the {\tt Utility} and {\tt Cholesky} Modules, and two packages: {\tt METIS 5.1.0}, CAMD, and CCOLAMD. Optionally used by the {\tt Cholesky} Module. All are secondary routines since these are more easily used by the {\tt Cholesky} Module. @@ -1208,7 +1219,7 @@ \subsection{{\tt Partition} Module: graph-partitioning-based orderings} the imaginary part is always ignored ({\tt cholmod\_factor\_p}, for example). %------------------------------------------------------------------------------- -\newpage \section{{\tt Core} Module: {\tt cholmod\_common} object} +\newpage \section{{\tt Utility} Module: {\tt cholmod\_common} object} \label{cholmod_common} %------------------------------------------------------------------------------- @@ -1268,7 +1279,7 @@ \subsection{{\tt cholmod\_allocate\_work}: allocate workspace} of the integer {\tt Head}, {\tt Flag}, and {\tt Iwork} arrays, of size {\tt nrow+1}, {\tt nrow}, and {\tt iworksize}, respectively, and a {\tt double} array {\tt Xwork} of size -{\tt xworksize}. The {\tt Head} array is normally equal to -1 +{\tt xworksize} entries. The {\tt Head} array is normally equal to -1 when it is cleared. If the {\tt Flag} array is cleared, all entries are less than {\tt Common->mark}. The {\tt Iwork} array is not kept in any particular state. @@ -1276,6 +1287,15 @@ \subsection{{\tt cholmod\_allocate\_work}: allocate workspace} on whether the {\tt cholmod\_} or {\tt cholmod\_l\_} routines are used. +%--------------------------------------- +% \subsection{{\tt cholmod\_alloc\_work}: allocate workspace} +%--------------------------------------- + +% \input{_alloc_work.tex} +% This is the same as {\tt cholmod\_allocate\_work}, except that +% the {\tt Xwork} array can be {\tt float} or {\tt double}, as +% determined by the {\tt dtype} input parameter. + %--------------------------------------- \subsection{{\tt cholmod\_free\_work}: free workspace} %--------------------------------------- @@ -1336,7 +1356,7 @@ \subsection{{\tt cholmod\_divcomplex}: complex divide} that is not a part of CHOLMOD, but can be used via the function pointer. %------------------------------------------------------------------------------- -\newpage \section{{\tt Core} Module: {\tt cholmod\_sparse} object} +\newpage \section{{\tt Utility} Module: {\tt cholmod\_sparse} object} \label{cholmod_sparse} %------------------------------------------------------------------------------- @@ -1652,7 +1672,7 @@ \subsection{{\tt cholmod\_sparse\_xtype}: change sparse xtype} Changing from complex or zomplex to real discards the imaginary part. %------------------------------------------------------------------------------- -\newpage \section{{\tt Core} Module: {\tt cholmod\_factor} object} +\newpage \section{{\tt Utility} Module: {\tt cholmod\_factor} object} \label{cholmod_factor} %------------------------------------------------------------------------------- @@ -1698,49 +1718,49 @@ \subsection{{\tt cholmod\_reallocate\_factor}: reallocate factor} There are four basic classes of factor types: \begin{enumerate} \item simplicial symbolic: Consists of two size-{\tt n} arrays: the fill-reducing -permutation ({\tt L->Perm}) and the nonzero count for each column of L -({\tt L->ColCount}). All other factor types also include this information. -{\tt L->ColCount} may be exact (obtained from the analysis routines), or -it may be a guess. During factorization, and certainly after update/downdate, -the columns of {\tt L} can have a different number of nonzeros. -{\tt L->ColCount} is used to allocate space. {\tt L->ColCount} is exact for the -supernodal factorizations. The nonzero pattern of {\tt L} is not kept. + permutation ({\tt L->Perm}) and the nonzero count for each column of L + ({\tt L->ColCount}). All other factor types also include this information. + {\tt L->ColCount} may be exact (obtained from the analysis routines), or it + may be a guess. During factorization, and certainly after update/downdate, + the columns of {\tt L} can have a different number of nonzeros. {\tt + L->ColCount} is used to allocate space. {\tt L->ColCount} is exact for the + supernodal factorizations. The nonzero pattern of {\tt L} is not kept. \item simplicial numeric: These represent {\tt L} in a compressed column form. The -variants of this type are: + variants of this type are: -\begin{itemize} -\item $\m{LDL}\tr$: {\tt L} is unit diagonal. Row indices in column {\tt j} are located in - {\tt L->i [L->p [j] ... L->p [j] + L->nz [j]]}, and corresponding numeric - values are in the same locations in {\tt L->x}. The total number of - entries is the sum of {\tt L->nz [j]}. The unit diagonal is not stored; - {\tt D} is stored on the diagonal of {\tt L} instead. {\tt L->p} may or may not be - monotonic. The order of storage of the columns in {\tt L->i} and {\tt L->x} is - given by a doubly-linked list ({\tt L->prev} and {\tt L->next}). {\tt L->p} is of - size {\tt n+1}, but only the first {\tt n} entries are used. - - For the complex case, {\tt L->x} is stored interleaved with real and imaginary - parts, and is of size {\tt 2*lnz*sizeof(double)}. For the zomplex case, - {\tt L->x} is of size {\tt lnz*sizeof(double)} and holds the real part; {\tt L->z} - is the same size and holds the imaginary part. - -\item $\m{LL}\tr$: This is identical to the $\m{LDL}\tr$ form, except that the non-unit - diagonal of {\tt L} is stored as the first entry in each column of {\tt L}. -\end{itemize} + \begin{itemize} + \item $\m{LDL}\tr$: {\tt L} is unit diagonal. Row indices in column {\tt j} are located in + {\tt L->i [L->p [j] ... L->p [j] + L->nz [j]]}, and corresponding numeric + values are in the same locations in {\tt L->x}. The total number of + entries is the sum of {\tt L->nz [j]}. The unit diagonal is not stored; + {\tt D} is stored on the diagonal of {\tt L} instead. {\tt L->p} may or may not be + monotonic. The order of storage of the columns in {\tt L->i} and {\tt L->x} is + given by a doubly-linked list ({\tt L->prev} and {\tt L->next}). {\tt L->p} is of + size {\tt n+1}, but only the first {\tt n} entries are used. + + For the complex case, {\tt L->x} is stored interleaved with real and imaginary + parts, and is of size {\tt 2*lnz*sizeof(double)}. For the zomplex case, + {\tt L->x} is of size {\tt lnz*sizeof(double)} and holds the real part; {\tt L->z} + is the same size and holds the imaginary part. + + \item $\m{LL}\tr$: This is identical to the $\m{LDL}\tr$ form, except that the non-unit + diagonal of {\tt L} is stored as the first entry in each column of {\tt L}. + \end{itemize} \item supernodal symbolic: A representation of the nonzero pattern of the -supernodes for a supernodal factorization. There are {\tt L->nsuper} -supernodes. Columns {\tt L->super [k]} to {\tt L->super [k+1]-1} are in the {\tt k}th -supernode. The row indices for the {\tt k}th supernode are in -{\tt L->s [L->pi [k] ... L->pi [k+1]-1]}. The numerical values are not -allocated ({\tt L->x}), but when they are they will be located in -{\tt L->x [L->px [k] ... L->px [k+1]-1]}, and the {\tt L->px} array is defined -in this factor type. - -For the complex case, {\tt L->x} is stored interleaved with real/imaginary parts, -and is of size \newline -{\tt 2*L->xsize*sizeof(double)}. The zomplex supernodal case -is not supported, since it is not compatible with LAPACK and the BLAS. + supernodes for a supernodal factorization. There are {\tt L->nsuper} + supernodes. Columns {\tt L->super [k]} to {\tt L->super [k+1]-1} are in the {\tt k}th + supernode. The row indices for the {\tt k}th supernode are in + {\tt L->s [L->pi [k] ... L->pi [k+1]-1]}. The numerical values are not + allocated ({\tt L->x}), but when they are they will be located in + {\tt L->x [L->px [k] ... L->px [k+1]-1]}, and the {\tt L->px} array is defined + in this factor type. + + For the complex case, {\tt L->x} is stored interleaved with real/imaginary parts, + and is of size \newline + {\tt 2*L->xsize*sizeof(double)}. The zomplex supernodal case + is not supported, since it is not compatible with LAPACK and the BLAS. \item supernodal numeric: Always an $\m{LL}\tr$ factorization. {\tt L} has a non-unit diagonal. {\tt L->x} contains the numerical values of the supernodes, as @@ -1845,7 +1865,7 @@ \subsection{{\tt cholmod\_factor\_xtype}: change factor xtype} You cannot change a supernodal factor to the zomplex xtype. %------------------------------------------------------------------------------- -\newpage \section{{\tt Core} Module: {\tt cholmod\_dense} object} +\newpage \section{{\tt Utility} Module: {\tt cholmod\_dense} object} \label{cholmod_dense} %------------------------------------------------------------------------------- @@ -1908,6 +1928,13 @@ \subsection{{\tt cholmod\_eye}: dense identity matrix} \input{_sparse_to_dense.tex} Returns a dense copy of a sparse matrix. +%--------------------------------------- +\subsection{{\tt cholmod\_dense\_nnz}: number of nonzeros in a dense matrix} +%--------------------------------------- + +\input{_dense_nnz.tex} +Returns a count of the number of nonzero entries in a dense matrix. + %--------------------------------------- \subsection{{\tt cholmod\_dense\_to\_sparse}: sparse matrix copy of a dense matrix} %--------------------------------------- @@ -1938,7 +1965,7 @@ \subsection{{\tt cholmod\_dense\_xtype}: change dense matrix xtype} Changing from complex or zomplex to real discards the imaginary part. %------------------------------------------------------------------------------- -\newpage \section{{\tt Core} Module: {\tt cholmod\_triplet} object} +\newpage \section{{\tt Utility} Module: {\tt cholmod\_triplet} object} \label{cholmod_triplet} %------------------------------------------------------------------------------- @@ -2007,7 +2034,7 @@ \subsection{{\tt cholmod\_triplet\_xtype}: change triplet xtype} Changing from complex or zomplex to real discards the imaginary part. %------------------------------------------------------------------------------- -\newpage \section{{\tt Core} Module: memory management} +\newpage \section{{\tt Utility} Module: memory management} %------------------------------------------------------------------------------- %--------------------------------------- @@ -2074,7 +2101,7 @@ \subsection{{\tt cholmod\_realloc}: reallocate memory} or all are returned to their original size. %------------------------------------------------------------------------------- -\newpage \section{{\tt Core} Module: version control} +\newpage \section{{\tt Utility} Module: version control} %------------------------------------------------------------------------------- \subsection{{\tt cholmod\_version}: return current CHOLMOD version} @@ -2508,30 +2535,32 @@ \subsection{{\tt cholmod\_analyze}: symbolic factorization} If you truly want the natural ordering with no postordering, you must set {\tt Common->postorder} to {\tt FALSE}. -The factor {\tt L} is returned as simplicial symbolic if -{\tt Common->supernodal} is {\tt CHOLMOD\_SIMPLICIAL} (zero) or as supernodal symbolic if -{\tt Common->supernodal} is {\tt CHOLMOD\_SUPERNODAL} (two). If \newline -{\tt Common->supernodal} is {\tt CHOLMOD\_AUTO} (one), -then {\tt L} is simplicial if the flop count per nonzero in {\tt L} is less than -{\tt Common->supernodal\_switch} (default: 40), and -supernodal otherwise. In both cases, {\tt L->xtype} is {\tt CHOLMOD\_PATTERN}. -A subsequent call to {\tt cholmod\_factorize} will perform a -simplicial or supernodal factorization, depending on the type of {\tt L}. - -For the simplicial case, {\tt L} contains the fill-reducing permutation ({\tt L->Perm}) -and the counts of nonzeros in each column of {\tt L} ({\tt L->ColCount}). For the -supernodal case, {\tt L} also contains the nonzero pattern of each supernode. - -If a simplicial factorization is selected, it will be $\m{LDL}\tr$ by default, since -this is the kind required by the {\tt Modify} Module. CHOLMOD does not include a -supernodal $\m{LDL}\tr$ factorization, so if a supernodal factorization is selected, -it will be in the form $\m{LL}\tr$. The $\m{LDL}\tr$ method can be used to -factorize positive definite matrices and indefinite matrices whose leading minors -are well-conditioned (2-by-2 pivoting is not supported). The $\m{LL}\tr$ method -is restricted to positive definite matrices. To factorize a large indefinite matrix, -set {\tt Common->supernodal} to {\tt CHOLMOD\_SIMPLICIAL}, and the simplicial -$\m{LDL}\tr$ method will always be used. This will be significantly slower than -a supernodal $\m{LL}\tr$ factorization, however. +The factor {\tt L} is returned as simplicial symbolic if {\tt +Common->supernodal} is {\tt CHOLMOD\_SIMPLICIAL} (zero) or as supernodal +symbolic if {\tt Common->supernodal} is {\tt CHOLMOD\_SUPERNODAL} (two). If +\newline {\tt Common->supernodal} is {\tt CHOLMOD\_AUTO} (one), then {\tt L} is +simplicial if the flop count per nonzero in {\tt L} is less than {\tt +Common->supernodal\_switch} (default: 40), and supernodal otherwise. In both +cases, {\tt L->xtype} is {\tt CHOLMOD\_PATTERN}. A subsequent call to {\tt +cholmod\_factorize} will perform a simplicial or supernodal factorization, +depending on the type of {\tt L}. + +For the simplicial case, {\tt L} contains the fill-reducing permutation ({\tt +L->Perm}) and the counts of nonzeros in each column of {\tt L} ({\tt +L->ColCount}). For the supernodal case, {\tt L} also contains the nonzero +pattern of each supernode. + +If a simplicial factorization is selected, it will be $\m{LDL}\tr$ by default, +since this is the kind required by the {\tt Modify} Module. CHOLMOD does not +include a supernodal $\m{LDL}\tr$ factorization, so if a supernodal +factorization is selected, it will be in the form $\m{LL}\tr$. The +$\m{LDL}\tr$ method can be used to factorize positive definite matrices and +indefinite matrices whose leading minors are well-conditioned (2-by-2 pivoting +is not supported). The $\m{LL}\tr$ method is restricted to positive definite +matrices. To factorize a large indefinite matrix, set {\tt Common->supernodal} +to {\tt CHOLMOD\_SIMPLICIAL}, and the simplicial $\m{LDL}\tr$ method will +always be used. This will be significantly slower than a supernodal +$\m{LL}\tr$ factorization, however. Refer to {\tt cholmod\_transpose\_unsym} for a description of {\tt f}. @@ -2539,24 +2568,22 @@ \subsection{{\tt cholmod\_analyze}: symbolic factorization} \subsection{{\tt cholmod\_factorize}: numeric factorization} %--------------------------------------- -\input{_factorize.tex} -Computes the numerical factorization of a symmetric matrix. The % primary -inputs to this routine are a sparse matrix {\tt A} and the symbolic factor {\tt L} from -{\tt cholmod\_analyze} or a prior numerical factor {\tt L}. If {\tt A} is symmetric, this -routine factorizes {\tt A(p,p)}. %+beta*I (beta can be zero), -where p is the fill-reducing permutation ({\tt L->Perm}). If {\tt A} is unsymmetric, -% either -{\tt A(p,:)*A(p,:)'} % +beta*I or A(p,f)*A(p,f)'+beta*I -is factorized. % The set f and -The nonzero pattern of the matrix {\tt A} must be the same as the matrix passed to -{\tt cholmod\_analyze} for the supernodal case. For the simplicial case, it can -be different, but it should be the same for best performance. % beta is real. - -A simplicial factorization or supernodal factorization is chosen, based on -the type of the factor {\tt L}. If {\tt L->is\_super} is {\tt TRUE}, a supernodal $\m{LL}\tr$ -factorization is computed. Otherwise, a simplicial numeric factorization -is computed, either $\m{LL}\tr$ or $\m{LDL}\tr$, depending on {\tt Common->final\_ll} -(the default for the simplicial case is to compute an $\m{LDL}\tr$ factorization). +\input{_factorize.tex} Computes the numerical factorization of a symmetric +matrix. The inputs to this routine are a sparse matrix {\tt A} and the +symbolic factor {\tt L} from {\tt cholmod\_analyze} or a prior numerical factor +{\tt L}. If {\tt A} is symmetric, this routine factorizes {\tt A(p,p)}. where +p is the fill-reducing permutation ({\tt L->Perm}). If {\tt A} is unsymmetric, +{\tt A(p,:)*A(p,:)'} is factorized. The nonzero pattern of the matrix {\tt A} +must be the same as the matrix passed to {\tt cholmod\_analyze} for the +supernodal case. For the simplicial case, it can be different, but it should +be the same for best performance. + +A simplicial factorization or supernodal factorization is chosen, based on the +type of the factor {\tt L}. If {\tt L->is\_super} is {\tt TRUE}, a supernodal +$\m{LL}\tr$ factorization is computed. Otherwise, a simplicial numeric +factorization is computed, either $\m{LL}\tr$ or $\m{LDL}\tr$, depending on +{\tt Common->final\_ll} (the default for the simplicial case is to compute an +$\m{LDL}\tr$ factorization). Once the factorization is complete, it can be left as is or optionally converted into any simplicial numeric type, depending on the @@ -2939,12 +2966,12 @@ \subsection{{\tt cholmod\_resymbol}: re-do symbolic factorization} If an entry in {\tt L} is kept, its numerical value does not change. -This routine is used after a supernodal factorization is converted into -a simplicial one, to remove zero entries that were added due to relaxed -supernode amalgamation. It can also be used after a series of downdates -to remove entries that would no longer be present if the matrix were -factorized from scratch. A downdate ({\tt cholmod\_updown}) does not remove any -entries from {\tt L}. +This routine is used after a supernodal factorization is converted into a +simplicial one, to remove zero entries that were added due to relaxed supernode +amalgamation. It can also be used after a series of downdates to remove +entries that would no longer be present if the matrix were factorized from +scratch. A downdate ({\tt cholmod\_updown}) does not remove any entries from +{\tt L}. %--------------------------------------- \subsection{{\tt cholmod\_resymbol\_noperm}: re-do symbolic factorization} diff --git a/CHOLMOD/Doc/ChangeLog b/CHOLMOD/Doc/ChangeLog index ae65f71f3..51996eace 100644 --- a/CHOLMOD/Doc/ChangeLog +++ b/CHOLMOD/Doc/ChangeLog @@ -1,6 +1,15 @@ -Oct 16, 2023: version 4.2.2 +Oct 23, 2023, version 5.0.0 - * bug fix: incorrect computation of work for nthreads in CHOLMOD/Supernodal + * CHOLMOD v5.0.0: introduces the first part of support for single + precision sparse matrices, with the introduction of the new + CHOLMOD:Utility Module. The CHOLMOD:Utility Module replaces + CHOLMOD:Core in prior versions. Single precision is not yet + incorporated into the remaining Modules, however. + +Oct 18, 2023: version 4.2.2 + + * CHOLMOD 4.2.2: bug fix to CHOLMOD/Supernodal (heuristic to determine + # threads to use for last supernode was incorrect) Sept 18, 2023: version 4.2.1 diff --git a/CHOLMOD/Doc/License.txt b/CHOLMOD/Doc/License.txt index ef860eb26..902cfa734 100644 --- a/CHOLMOD/Doc/License.txt +++ b/CHOLMOD/Doc/License.txt @@ -54,20 +54,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -------------------------------------------------------------------------------- -==> Core/License.txt <== +==> Utility/License.txt <== -------------------------------------------------------------------------------- - CHOLMOD/Core Module. Copyright (C) 2005-2022, Univ. of Florida. Author: - Timothy A. Davis. CHOLMOD is also available under other licenses; contact - authors for details. http://www.suitesparse.com - - Note that this license is for the CHOLMOD/Core module only. - All CHOLMOD modules are licensed separately. - + CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights + Reserved. CHOLMOD is also available under other licenses; contact authors + for details. http://www.suitesparse.com ---------------------------------------------------------------------------- - This Module is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -287,31 +282,3 @@ along with this Module; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. --------------------------------------------------------------------------------- -==> Valgrind/License.txt <== --------------------------------------------------------------------------------- - - CHOLMOD/Valgrind Module. Copyright (C) 2005-2022, Timothy A. Davis. - CHOLMOD is also available under other licenses; contact authors for details. - http://www.suitesparse.com - - Note that this license is for the CHOLMOD/Valgrind module only. - All CHOLMOD modules are licensed separately. - - - ---------------------------------------------------------------------------- - - - This Module is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This Module is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this Module; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/CHOLMOD/Doc/Makefile b/CHOLMOD/Doc/Makefile index ad540f114..178c4a305 100644 --- a/CHOLMOD/Doc/Makefile +++ b/CHOLMOD/Doc/Makefile @@ -66,7 +66,7 @@ CHOLMOD_UserGuide.pdf: CHOLMOD_UserGuide.tex UserGuide.bib $(I) $(C) $(M) Makefi ./getproto '/int cholmod_free_work/, /\*\) ;/' ../Include/cholmod.h > _free_work.tex ./getproto '/int64_t cholmod_clear_flag/, /\*\) ;/' ../Include/cholmod.h > _clear_flag.tex ./getproto '/int cholmod_error/, /\*\) ;/' ../Include/cholmod.h > _error.tex - ./getproto '/double cholmod_dbound/, /\*\) ;/' ../Include/cholmod.h > _dbound.tex + ./getproto '/double cholmod_dbound/, /l_sbound/' ../Include/cholmod.h > _dbound.tex ./getproto '/double cholmod_hypot/, /double\) ;/' ../Include/cholmod.h > _hypot.tex ./getproto '/int cholmod_divcomplex/, /\*\) ;/' ../Include/cholmod.h > _divcomplex.tex ./getproto '/typedef struct cholmod_sparse/, /^}/' ../Include/cholmod.h > _sparse.tex @@ -74,6 +74,7 @@ CHOLMOD_UserGuide.pdf: CHOLMOD_UserGuide.tex UserGuide.bib $(I) $(C) $(M) Makefi ./getproto '/int cholmod_free_sparse/, /\*\) ;/' ../Include/cholmod.h > _free_sparse.tex ./getproto '/int cholmod_reallocate_sparse/, /\*\) ;/' ../Include/cholmod.h > _reallocate_sparse.tex ./getproto '/int64_t cholmod_nnz/, /\*\) ;/' ../Include/cholmod.h > _nnz.tex + ./getproto '/int64_t cholmod_dense_nnz/, /\*\) ;/' ../Include/cholmod.h > _dense_nnz.tex ./getproto '/cholmod_sparse \*cholmod_speye/, /\*\) ;/' ../Include/cholmod.h > _speye.tex ./getproto '/cholmod_sparse \*cholmod_spzeros/, /\*\) ;/' ../Include/cholmod.h > _spzeros.tex ./getproto '/cholmod_sparse \*cholmod_transpose/, /\*\) ;/' ../Include/cholmod.h > _transpose.tex @@ -124,7 +125,7 @@ CHOLMOD_UserGuide.pdf: CHOLMOD_UserGuide.tex UserGuide.bib $(I) $(C) $(M) Makefi ./getproto '/void \*cholmod_realloc/, /\*\) ;/' ../Include/cholmod.h > _realloc.tex ./getproto '/int cholmod_realloc_multiple/, /\*\) ;/' ../Include/cholmod.h > _realloc_multiple.tex ./getproto '/int cholmod_version/, /l_version/' ../Include/cholmod.h > _version.tex - ./getproto '/itype defines the/, /define CHOLMOD_SUPERNODAL/' ../Include/cholmod.h > _defn.tex + ./getproto '/itype: integer sizes/, /define CHOLMOD_SUPERNODAL/' ../Include/cholmod.h > _defn.tex ./getproto '/int cholmod_check_common/, /\*\) ;/' ../Include/cholmod.h > _check_common.tex ./getproto '/int cholmod_print_common/, /\*\) ;/' ../Include/cholmod.h > _print_common.tex ./getproto '/int cholmod_check_sparse/, /\*\) ;/' ../Include/cholmod.h > _check_sparse.tex @@ -205,7 +206,7 @@ CHOLMOD_UserGuide.pdf: CHOLMOD_UserGuide.tex UserGuide.bib $(I) $(C) $(M) Makefi bibtex CHOLMOD_UserGuide pdflatex CHOLMOD_UserGuide pdflatex CHOLMOD_UserGuide - - $(RM) _temp.awk _*.tex + - $(RM) _temp.awk - $(RM) -r *.aux *.bbl *.blg *.log *.toc *.dvi *.lof *.lot distclean: purge @@ -213,6 +214,7 @@ distclean: purge purge: clean clean: - - $(RM) _temp.awk _*.tex + - $(RM) _*.tex + - $(RM) _temp.awk - $(RM) -r *.aux *.bbl *.blg *.log *.toc *.dvi *.lof *.lot diff --git a/CHOLMOD/Doc/cholmod_version.tex b/CHOLMOD/Doc/cholmod_version.tex index badf2150b..214516bbf 100644 --- a/CHOLMOD/Doc/cholmod_version.tex +++ b/CHOLMOD/Doc/cholmod_version.tex @@ -1,2 +1,2 @@ % version of SuiteSparse/CHOLMOD -\date{VERSION 4.2.2, Oct 15, 2023} +\date{VERSION 5.0.0, Oct 23, 2023} diff --git a/CHOLMOD/GPU/CMakeLists.txt b/CHOLMOD/GPU/CMakeLists.txt index f0194e978..4c11d2fa6 100644 --- a/CHOLMOD/GPU/CMakeLists.txt +++ b/CHOLMOD/GPU/CMakeLists.txt @@ -63,7 +63,7 @@ set ( CHOLMOD_CUDA_INCLUDES ../Check ../../SuiteSparse_config ../Cholesky - ../Core + ../Utility ../Supernodal ../Include ../GPU ) diff --git a/CHOLMOD/GPU/cholmod_gpu.c b/CHOLMOD/GPU/cholmod_gpu.c index e24376339..1deef66ec 100644 --- a/CHOLMOD/GPU/cholmod_gpu.c +++ b/CHOLMOD/GPU/cholmod_gpu.c @@ -78,7 +78,7 @@ int CHOLMOD(gpu_memorysize) /* returns 1 on error, 0 otherwise */ *total_mem = 0; *available_mem = 0; -#ifndef DLONG +#ifndef CHOLMOD_INT64 return 0; #endif diff --git a/CHOLMOD/GPU/cholmod_l_gpu.c b/CHOLMOD/GPU/cholmod_l_gpu.c index db4dc5bef..bb4cd6852 100644 --- a/CHOLMOD/GPU/cholmod_l_gpu.c +++ b/CHOLMOD/GPU/cholmod_l_gpu.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_gpu.c" diff --git a/CHOLMOD/Include/cholmod.h b/CHOLMOD/Include/cholmod.h index 7b6e70e7b..d397d7e77 100644 --- a/CHOLMOD/Include/cholmod.h +++ b/CHOLMOD/Include/cholmod.h @@ -2,14 +2,14 @@ // CHOLMOD/Include/cholmod.h: include file for CHOLMOD //------------------------------------------------------------------------------ -// CHOLMOD/Include/cholmod.h. Copyright (C) 2005-2022, Timothy A. Davis. +// CHOLMOD/Include/cholmod.h. Copyright (C) 2005-2023, Timothy A. Davis. // All Rights Reserved. // Each Module of CHOLMOD has its own license, and a shared cholmod.h file. // CHOLMOD/Check: SPDX-License-Identifier: LGPL-2.1+ // CHOLMOD/Cholesky: SPDX-License-Identifier: LGPL-2.1+ -// CHOLMOD/Core: SPDX-License-Identifier: LGPL-2.1+ +// CHOLMOD/Utility: SPDX-License-Identifier: LGPL-2.1+ // CHOLMOD/Partition: SPDX-License-Identifier: LGPL-2.1+ // CHOLMOD/Demo: SPDX-License-Identifier: GPL-2.0+ @@ -19,433 +19,203 @@ // CHOLMOD/Modify: SPDX-License-Identifier: GPL-2.0+ // CHOLMOD/Supernodal: SPDX-License-Identifier: GPL-2.0+ // CHOLMOD/Tcov: SPDX-License-Identifier: GPL-2.0+ -// CHOLMOD/Valgrind: SPDX-License-Identifier: GPL-2.0+ //------------------------------------------------------------------------------ - -/* CHOLMOD consists of a set of Modules, each with their own license: either - * LGPL-2.1+ or GPL-2.0+. This cholmod.h file includes defintions of the - * CHOLMOD API for all Modules, and this cholmod.h file itself is provided to - * you with a permissive license (Apache-2.0). You are permitted to provide - * the hooks for an optional interface to CHOLMOD in a non-GPL/non-LGPL code, - * without requiring you to agree to the GPL/LGPL license of the Modules, as - * long as you don't use the *.c files in the relevant Modules. The Modules - * themselves can only be functional if their GPL or LGPL licenses are used. - * - * Portions of CHOLMOD (the Core and Partition Modules) are copyrighted by the - * University of Florida. The Modify Module is co-authored by William W. - * Hager, Univ. of Florida. - * - * Acknowledgements: this work was supported in part by the National Science - * Foundation (NFS CCR-0203270 and DMS-9803599), and a grant from Sandia - * National Laboratories (Dept. of Energy) which supported the development of - * CHOLMOD's Partition Module. - * -------------------------------------------------------------------------- */ - -/* CHOLMOD include file, for inclusion user programs. - * - * The include files listed below include a short description of each user- - * callable routine. Each routine in CHOLMOD has a consistent interface. - * More details about the CHOLMOD data types is in the cholmod_core.h file. - * - * Naming convention: - * ------------------ - * - * All routine names, data types, and CHOLMOD library files use the - * cholmod_ prefix. All macros and other #define's use the CHOLMOD - * prefix. - * - * Return value: - * ------------- - * - * Most CHOLMOD routines return an int (TRUE (1) if successful, or FALSE - * (0) otherwise. An int32_t, int64_t, or double return value is >= 0 if - * successful, or -1 otherwise. A size_t return value is > 0 if - * successful, or 0 otherwise. - * - * If a routine returns a pointer, it is a pointer to a newly allocated - * object or NULL if a failure occured, with one exception. cholmod_free - * always returns NULL. - * - * "Common" parameter: - * ------------------ - * - * The last parameter in all CHOLMOD routines is a pointer to the CHOLMOD - * "Common" object. This contains control parameters, statistics, and - * workspace used between calls to CHOLMOD. It is always an input/output - * parameter. - * - * Input, Output, and Input/Output parameters: - * ------------------------------------------- - * - * Input parameters are listed first. They are not modified by CHOLMOD. - * - * Input/output are listed next. They must be defined on input, and - * are modified on output. - * - * Output parameters are listed next. If they are pointers, they must - * point to allocated space on input, but their contents are not defined - * on input. - * - * Workspace parameters appear next. They are used in only two routines - * in the Supernodal module. - * - * The cholmod_common *Common parameter always appears as the last - * parameter. It is always an input/output parameter. - */ +// CHOLMOD consists of a set of Modules, each with their own license: either +// LGPL-2.1+ or GPL-2.0+. This cholmod.h file includes defintions of the +// CHOLMOD API for all Modules, and this cholmod.h file itself is provided to +// you with a permissive license (Apache-2.0). You are permitted to provide +// the hooks for an optional interface to CHOLMOD in a non-GPL/non-LGPL code, +// without requiring you to agree to the GPL/LGPL license of the Modules, as +// long as you don't use the *.c files in the relevant Modules. The Modules +// themselves can only be functional if their GPL or LGPL licenses are used. +// +// The Modify Module is co-authored by William W. Hager. +// +// Acknowledgements: this work was supported in part by the National Science +// Foundation (NFS CCR-0203270 and DMS-9803599), and a grant from Sandia +// National Laboratories (Dept. of Energy) which supported the development of +// CHOLMOD's Partition Module. +// ----------------------------------------------------------------------------- + +// Each routine in CHOLMOD has a consistent interface. +// +// Naming convention: +// ------------------ +// +// All routine names, data types, and CHOLMOD library files use the +// cholmod_ prefix. All macros and other #define's use the CHOLMOD +// prefix. +// +// Return value: +// ------------- +// +// Most CHOLMOD routines return an int (TRUE (1) if successful, or FALSE +// (0) otherwise. An int32_t, int64_t, double, or float return value +// is >= 0 if successful, or -1 otherwise. A size_t return value +// is > 0 if successful, or 0 otherwise. +// +// If a routine returns a pointer, it is a pointer to a newly allocated +// object or NULL if a failure occured, with one exception. cholmod_free +// always returns NULL. +// +// "Common" parameter: +// ------------------ +// +// The last parameter in all CHOLMOD routines is a pointer to the CHOLMOD +// "Common" object. This contains control parameters, statistics, and +// workspace used between calls to CHOLMOD. It is always an input/output +// parameter. +// +// Input, Output, and Input/Output parameters: +// ------------------------------------------- +// +// Input parameters are listed first. They are not modified by CHOLMOD. +// +// Input/output are listed next. They must be defined on input, and +// are modified on output. +// +// Output parameters are listed next. If they are pointers, they must +// point to allocated space on input, but their contents are not defined +// on input. +// +// Workspace parameters appear next. They are used in only two routines +// in the Supernodal module. +// +// The cholmod_common *Common parameter always appears as the last +// parameter. It is always an input/output parameter. #ifndef CHOLMOD_H #define CHOLMOD_H -#define CHOLMOD_DATE "Oct 15, 2023" -#define CHOLMOD_MAIN_VERSION 4 -#define CHOLMOD_SUB_VERSION 2 -#define CHOLMOD_SUBSUB_VERSION 2 +//============================================================================== +// version control +//============================================================================== -/* ========================================================================== */ -/* === Include/cholmod_io64 ================================================= */ -/* ========================================================================== */ +#define CHOLMOD_DATE "Oct 23, 2023" +#define CHOLMOD_MAIN_VERSION 5 +#define CHOLMOD_SUB_VERSION 0 +#define CHOLMOD_SUBSUB_VERSION 0 -/* assume large file support. If problems occur, compile with -DNLARGEFILE */ - -/* Definitions required for large file I/O, which must come before any other - * #includes. These are not used if -DNLARGEFILE is defined at compile time. - * Large file support may not be portable across all platforms and compilers; - * if you encounter an error here, compile your code with -DNLARGEFILE. In - * particular, you must use -DNLARGEFILE for MATLAB 6.5 or earlier (which does - * not have the io64.h include file). - */ +#define CHOLMOD_VER_CODE(main,sub) ((main) * 1000 + (sub)) +#define CHOLMOD_VERSION \ + CHOLMOD_VER_CODE(CHOLMOD_MAIN_VERSION,CHOLMOD_SUB_VERSION) +#define CHOLMOD_HAS_VERSION_FUNCTION -/* skip all of this if NLARGEFILE is defined at the compiler command line */ -#ifndef NLARGEFILE +#ifdef __cplusplus +extern "C" { +#endif -#if defined(MATLAB_MEX_FILE) || defined(MATHWORKS) +int cholmod_version // returns CHOLMOD_VERSION, defined above +( + // if version is not NULL, then cholmod_version returns its contents as: + // version [0] = CHOLMOD_MAIN_VERSION + // version [1] = CHOLMOD_SUB_VERSION + // version [2] = CHOLMOD_SUBSUB_VERSION + int version [3] +) ; +int cholmod_l_version (int version [3]) ; -/* CHOLMOD is being compiled as a MATLAB mexFunction, or for use in MATLAB */ -#include "io64.h" +#ifdef __cplusplus +} +#endif -#else +//============================================================================== +// Large file support +//============================================================================== -/* CHOLMOD is being compiled in a stand-alone library */ -#undef _LARGEFILE64_SOURCE -#define _LARGEFILE64_SOURCE -#undef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 64 +// CHOLMOD assumes large file support. If problems occur, compile with +// -DNLARGEFILE -#endif +// Definitions required for large file I/O, which must come before any other +// #includes. These are not used if -DNLARGEFILE is defined at compile time. +// Large file support may not be portable across all platforms and compilers; +// if you encounter an error here, compile your code with -DNLARGEFILE. In +// particular, you must use -DNLARGEFILE for MATLAB 6.5 or earlier (which does +// not have the io64.h include file). +// skip all of this if NLARGEFILE is defined at the compiler command line +#ifndef NLARGEFILE + #if defined(MATLAB_MEX_FILE) || defined(MATHWORKS) + // CHOLMOD compiled as a MATLAB mexFunction, or for use in MATLAB + #include "io64.h" + #else + // CHOLMOD is being compiled in a stand-alone library + #undef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #undef _FILE_OFFSET_BITS + #define _FILE_OFFSET_BITS 64 + #endif #endif -/* ========================================================================== */ -/* === SuiteSparse_config.h ================================================= */ -/* ========================================================================== */ +//============================================================================== +// SuiteSparse_config +//============================================================================== #include "SuiteSparse_config.h" -/* ========================================================================== */ -/* === Include/cholmod_config.h ============================================= */ -/* ========================================================================== */ - -/* CHOLMOD configuration file, for inclusion in user programs. - * - * You do not have to edit any CHOLMOD files to compile and install CHOLMOD. - * However, if you do not use all of CHOLMOD's modules, you need to compile - * with the appropriate flag, or edit this file to add the appropriate #define. - * - * Compiler flags for CHOLMOD: - * - * -DNCHECK do not include the Check module. - * -DNCHOLESKY do not include the Cholesky module. - * -DNPARTITION do not include the Partition module. - * -DNCAMD do not include the interfaces to CAMD, - * CCOLAMD, CSYMAND in Partition module. - * -DNMATRIXOPS do not include the MatrixOps module. - * -DNMODIFY do not include the Modify module. - * -DNSUPERNODAL do not include the Supernodal module. - * - * -DNPRINT do not print anything - * - * The Core Module is always included in the CHOLMOD library. - */ - -/* Use the compiler flag, or uncomment the definition(s), if you want to use - * one or more non-default installation options: */ - -/* -#define NCHECK -#define NCHOLESKY -#define NCAMD -#define NPARTITION -#define NMATRIXOPS -#define NMODIFY -#define NSUPERNODAL -#define NPRINT -#define NGPL -*/ - -/* The NGPL option disables the MatrixOps, Modify, and Supernodal modules. The - existence of this #define here, and its use in these 3 modules, does not - affect the license itself; see CHOLMOD/Doc/License.txt for your actual - license. - */ +//============================================================================== +// CHOLMOD configuration +//============================================================================== + +// You do not have to edit any CHOLMOD files to compile and install CHOLMOD. +// However, if you do not use all of CHOLMOD's modules, you need to compile +// with the appropriate flag, or edit this file to add the appropriate #define. +// +// Compiler flags for CHOLMOD +// +// -DNCHECK do not include the Check module. +// -DNCHOLESKY do not include the Cholesky module. +// -DNPARTITION do not include the Partition module. +// -DNCAMD do not include the interfaces to CAMD, +// CCOLAMD, CSYMAND in Partition module. +// -DNMATRIXOPS do not include the MatrixOps module. +// -DNMODIFY do not include the Modify module. +// -DNSUPERNODAL do not include the Supernodal module. +// +// -DNPRINT do not print anything +// +// The Utility Module is always included in the CHOLMOD library. + +// Use the compiler flag, or uncomment the definition(s), if you want to use +// one or more non-default installation options: + +// #define NCHECK +// #define NCHOLESKY +// #define NCAMD +// #define NPARTITION +// #define NMATRIXOPS +// #define NMODIFY +// #define NSUPERNODAL +// #define NPRINT +// #define NGPL + +// The NGPL option disables the MatrixOps, Modify, and Supernodal modules. The +// existence of this #define here, and its use in these 3 modules, does not +// affect the license itself; see CHOLMOD/Doc/License.txt for your actual +// license. #ifdef NGPL -#undef NMATRIXOPS -#define NMATRIXOPS -#undef NMODIFY -#define NMODIFY -#undef NSUPERNODAL -#define NSUPERNODAL + #undef NMATRIXOPS + #define NMATRIXOPS + #undef NMODIFY + #define NMODIFY + #undef NSUPERNODAL + #define NSUPERNODAL #endif +//============================================================================== +// CHOLMOD:Utility Module +//============================================================================== -/* ========================================================================== */ -/* === Include/cholmod_core.h =============================================== */ -/* ========================================================================== */ - -/* CHOLMOD Core module: basic CHOLMOD objects and routines. - * Required by all CHOLMOD modules. Requires no other module or package. - * - * The CHOLMOD modules are: - * - * Core basic data structures and definitions - * Check check/print the 5 CHOLMOD objects, & 3 types of integer vectors - * Cholesky sparse Cholesky factorization - * Modify sparse Cholesky update/downdate/row-add/row-delete - * MatrixOps sparse matrix functions (add, multiply, norm, ...) - * Supernodal supernodal sparse Cholesky factorization - * Partition graph-partitioning based orderings - * - * The CHOLMOD objects: - * -------------------- - * - * cholmod_common parameters, statistics, and workspace - * cholmod_sparse a sparse matrix in compressed column form - * cholmod_factor an LL' or LDL' factorization - * cholmod_dense a dense matrix - * cholmod_triplet a sparse matrix in "triplet" form - * - * The Core module described here defines the CHOLMOD data structures, and - * basic operations on them. To create and solve a sparse linear system Ax=b, - * the user must create A and b, populate them with values, and then pass them - * to the routines in the CHOLMOD Cholesky module. There are two primary - * methods for creating A: (1) allocate space for a column-oriented sparse - * matrix and fill it with pattern and values, or (2) create a triplet form - * matrix and convert it to a sparse matrix. The latter option is simpler. - * - * The matrices b and x are typically dense matrices, but can also be sparse. - * You can allocate and free them as dense matrices with the - * cholmod_allocate_dense and cholmod_free_dense routines. - * - * The cholmod_factor object contains the symbolic and numeric LL' or LDL' - * factorization of sparse symmetric matrix. The matrix must be positive - * definite for an LL' factorization. It need only be symmetric and have well- - * conditioned leading submatrices for it to have an LDL' factorization - * (CHOLMOD does not pivot for numerical stability). It is typically created - * with the cholmod_factorize routine in the Cholesky module, but can also - * be initialized to L=D=I in the Core module and then modified by the Modify - * module. It must be freed with cholmod_free_factor, defined below. - * - * The Core routines for each object are described below. Each list is split - * into two parts: the primary routines and secondary routines. - * - * ============================================================================ - * === cholmod_common ========================================================= - * ============================================================================ - * - * The Common object contains control parameters, statistics, and - * You must call cholmod_start before calling any other CHOLMOD routine, and - * must call cholmod_finish as your last call to CHOLMOD, with two exceptions: - * you may call cholmod_print_common and cholmod_check_common in the Check - * module after calling cholmod_finish. - * - * cholmod_start first call to CHOLMOD - * cholmod_finish last call to CHOLMOD - * ----------------------------- - * cholmod_defaults restore default parameters - * cholmod_maxrank maximum rank for update/downdate - * cholmod_allocate_work allocate workspace in Common - * cholmod_free_work free workspace in Common - * cholmod_clear_flag clear Flag workspace in Common - * cholmod_error called when CHOLMOD encounters an error - * cholmod_dbound for internal use in CHOLMOD only - * cholmod_hypot compute sqrt (x*x + y*y) accurately - * cholmod_divcomplex complex division, c = a/b - * - * ============================================================================ - * === cholmod_sparse ========================================================= - * ============================================================================ - * - * A sparse matrix is held in compressed column form. In the basic type - * ("packed", which corresponds to a MATLAB sparse matrix), an n-by-n matrix - * with nz entries is held in three arrays: p of size n+1, i of size nz, and x - * of size nz. Row indices of column j are held in i [p [j] ... p [j+1]-1] and - * in the same locations in x. There may be no duplicate entries in a column. - * Row indices in each column may be sorted or unsorted (CHOLMOD keeps track). - * A->stype determines the storage mode: 0 if both upper/lower parts are stored, - * -1 if A is symmetric and just tril(A) is stored, +1 if symmetric and triu(A) - * is stored. - * - * cholmod_allocate_sparse allocate a sparse matrix - * cholmod_free_sparse free a sparse matrix - * ----------------------------- - * cholmod_reallocate_sparse change the size (# entries) of sparse matrix - * cholmod_nnz number of nonzeros in a sparse matrix - * cholmod_speye sparse identity matrix - * cholmod_spzeros sparse zero matrix - * cholmod_transpose transpose a sparse matrix - * cholmod_ptranspose transpose/permute a sparse matrix - * cholmod_transpose_unsym transpose/permute an unsymmetric sparse matrix - * cholmod_transpose_sym transpose/permute a symmetric sparse matrix - * cholmod_sort sort row indices in each column of sparse matrix - * cholmod_band C = tril (triu (A,k1), k2) - * cholmod_band_inplace A = tril (triu (A,k1), k2) - * cholmod_aat C = A*A' - * cholmod_copy_sparse C = A, create an exact copy of a sparse matrix - * cholmod_copy C = A, with possible change of stype - * cholmod_add C = alpha*A + beta*B - * cholmod_sparse_xtype change the xtype of a sparse matrix - * - * ============================================================================ - * === cholmod_factor ========================================================= - * ============================================================================ - * - * The data structure for an LL' or LDL' factorization is too complex to - * describe in one sentence. This object can hold the symbolic analysis alone, - * or in combination with a "simplicial" (similar to a sparse matrix) or - * "supernodal" form of the numerical factorization. Only the routine to free - * a factor is primary, since a factor object is created by the factorization - * routine (cholmod_factorize). It must be freed with cholmod_free_factor. - * - * cholmod_free_factor free a factor - * ----------------------------- - * cholmod_allocate_factor allocate a factor (LL' or LDL') - * cholmod_reallocate_factor change the # entries in a factor - * cholmod_change_factor change the type of factor (e.g., LDL' to LL') - * cholmod_pack_factor pack the columns of a factor - * cholmod_reallocate_column resize a single column of a factor - * cholmod_factor_to_sparse create a sparse matrix copy of a factor - * cholmod_copy_factor create a copy of a factor - * cholmod_factor_xtype change the xtype of a factor - * - * Note that there is no cholmod_sparse_to_factor routine to create a factor - * as a copy of a sparse matrix. It could be done, after a fashion, but a - * lower triangular sparse matrix would not necessarily have a chordal graph, - * which would break the many CHOLMOD routines that rely on this property. - * - * ============================================================================ - * === cholmod_dense ========================================================== - * ============================================================================ - * - * The solve routines and some of the MatrixOps and Modify routines use dense - * matrices as inputs. These are held in column-major order. With a leading - * dimension of d, the entry in row i and column j is held in x [i+j*d]. - * - * cholmod_allocate_dense allocate a dense matrix - * cholmod_free_dense free a dense matrix - * ----------------------------- - * cholmod_zeros allocate a dense matrix of all zeros - * cholmod_ones allocate a dense matrix of all ones - * cholmod_eye allocate a dense identity matrix - * cholmod_sparse_to_dense create a dense matrix copy of a sparse matrix - * cholmod_dense_to_sparse create a sparse matrix copy of a dense matrix - * cholmod_copy_dense create a copy of a dense matrix - * cholmod_copy_dense2 copy a dense matrix (pre-allocated) - * cholmod_dense_xtype change the xtype of a dense matrix - * cholmod_ensure_dense ensure a dense matrix has a given size and type - * - * ============================================================================ - * === cholmod_triplet ======================================================== - * ============================================================================ - * - * A sparse matrix held in triplet form is the simplest one for a user to - * create. It consists of a list of nz entries in arbitrary order, held in - * three arrays: i, j, and x, each of length nk. The kth entry is in row i[k], - * column j[k], with value x[k]. There may be duplicate values; if A(i,j) - * appears more than once, its value is the sum of the entries with those row - * and column indices. - * - * cholmod_allocate_triplet allocate a triplet matrix - * cholmod_triplet_to_sparse create a sparse matrix copy of a triplet matrix - * cholmod_free_triplet free a triplet matrix - * ----------------------------- - * cholmod_reallocate_triplet change the # of entries in a triplet matrix - * cholmod_sparse_to_triplet create a triplet matrix copy of a sparse matrix - * cholmod_copy_triplet create a copy of a triplet matrix - * cholmod_triplet_xtype change the xtype of a triplet matrix - * - * ============================================================================ - * === memory management ====================================================== - * ============================================================================ - * - * cholmod_malloc malloc wrapper - * cholmod_calloc calloc wrapper - * cholmod_free free wrapper - * cholmod_realloc realloc wrapper - * cholmod_realloc_multiple realloc wrapper for multiple objects - * - * ============================================================================ - * === Core CHOLMOD prototypes ================================================ - * ============================================================================ - * - * All CHOLMOD routines (in all modules) use the following protocol for return - * values, with one exception: - * - * int TRUE (1) if successful, or FALSE (0) otherwise. - * (exception: cholmod_divcomplex) - * int32_t a value >= 0 if successful, or -1 otherwise. - * int64_t a value >= 0 if successful, or -1 otherwise. - * double a value >= 0 if successful, or -1 otherwise. - * size_t a value > 0 if successful, or 0 otherwise. - * void * a non-NULL pointer to newly allocated memory if - * successful, or NULL otherwise. - * cholmod_sparse * a non-NULL pointer to a newly allocated matrix - * if successful, or NULL otherwise. - * cholmod_factor * a non-NULL pointer to a newly allocated factor - * if successful, or NULL otherwise. - * cholmod_triplet * a non-NULL pointer to a newly allocated triplet - * matrix if successful, or NULL otherwise. - * cholmod_dense * a non-NULL pointer to a newly allocated triplet - * matrix if successful, or NULL otherwise. - * - * The last parameter to all routines is always a pointer to the CHOLMOD - * Common object. - * - * TRUE and FALSE are not defined here, since they may conflict with the user - * program. A routine that described here returning TRUE or FALSE returns 1 - * or 0, respectively. Any TRUE/FALSE parameter is true if nonzero, false if - * zero. - */ - -/* ========================================================================== */ -/* === CHOLMOD version ====================================================== */ -/* ========================================================================== */ - -/* All versions of CHOLMOD will include the following definitions. - * As an example, to test if the version you are using is 1.3 or later: - * - * if (CHOLMOD_VERSION >= CHOLMOD_VER_CODE (1,3)) ... - * - * This also works during compile-time: - * - * #if CHOLMOD_VERSION >= CHOLMOD_VER_CODE (1,3) - * printf ("This is version 1.3 or later\n") ; - * #else - * printf ("This is version is earlier than 1.3\n") ; - * #endif - */ - -#define CHOLMOD_HAS_VERSION_FUNCTION -#define CHOLMOD_VER_CODE(main,sub) ((main) * 1000 + (sub)) -#define CHOLMOD_VERSION \ - CHOLMOD_VER_CODE(CHOLMOD_MAIN_VERSION,CHOLMOD_SUB_VERSION) - +// the CHOLMOD:Utility Module is always required +#if 1 -/* ========================================================================== */ -/* === CUDA BLAS for the GPU ================================================ */ -/* ========================================================================== */ +//------------------------------------------------------------------------------ +// CUDA BLAS +//------------------------------------------------------------------------------ -/* Define buffering parameters for GPU processing */ +// Define buffering parameters for GPU processing #ifndef SUITESPARSE_GPU_EXTERN_ON #ifdef SUITESPARSE_CUDA #include @@ -456,724 +226,529 @@ #define CHOLMOD_HOST_SUPERNODE_BUFFERS 8 #define CHOLMOD_DEVICE_STREAMS 2 -/* ========================================================================== */ -/* === CHOLMOD objects ====================================================== */ -/* ========================================================================== */ - -/* Each CHOLMOD object has its own type code. */ +//------------------------------------------------------------------------------ +// CHOLMOD objects +//------------------------------------------------------------------------------ +// CHOLMOD object enums #define CHOLMOD_COMMON 0 #define CHOLMOD_SPARSE 1 #define CHOLMOD_FACTOR 2 #define CHOLMOD_DENSE 3 #define CHOLMOD_TRIPLET 4 -/* ========================================================================== */ -/* === CHOLMOD Common ======================================================= */ -/* ========================================================================== */ - -/* itype defines the types of integer used: */ -#define CHOLMOD_INT 0 /* all integer arrays are int32_t */ -#define CHOLMOD_INTLONG 1 /* most are int32_t, some are int64_t */ -#define CHOLMOD_LONG 2 /* all integer arrays are int64_t */ - -/* The itype of all parameters for all CHOLMOD routines must match. - * FUTURE WORK: CHOLMOD_INTLONG is not yet supported. - */ - -/* dtype defines what the numerical type is (double or float): */ -#define CHOLMOD_DOUBLE 0 /* all numerical values are double */ -#define CHOLMOD_SINGLE 1 /* all numerical values are float */ +// enums used by cholmod_symmetry and cholmod_write +#define CHOLMOD_MM_RECTANGULAR 1 +#define CHOLMOD_MM_UNSYMMETRIC 2 +#define CHOLMOD_MM_SYMMETRIC 3 +#define CHOLMOD_MM_HERMITIAN 4 +#define CHOLMOD_MM_SKEW_SYMMETRIC 5 +#define CHOLMOD_MM_SYMMETRIC_POSDIAG 6 +#define CHOLMOD_MM_HERMITIAN_POSDIAG 7 -/* The dtype of all parameters for all CHOLMOD routines must match. - * - * Scalar floating-point values are always passed as double arrays of size 2 - * (for the real and imaginary parts). They are typecast to float as needed. - * FUTURE WORK: the float case is not supported yet. - */ +//------------------------------------------------------------------------------ +// CHOLMOD Common object +//------------------------------------------------------------------------------ -/* xtype defines the kind of numerical values used: */ -#define CHOLMOD_PATTERN 0 /* pattern only, no numerical values */ -#define CHOLMOD_REAL 1 /* a real matrix */ -#define CHOLMOD_COMPLEX 2 /* a complex matrix (ANSI C99 compatible) */ -#define CHOLMOD_ZOMPLEX 3 /* a complex matrix (MATLAB compatible) */ +// itype: integer sizes +// The itype is held in the Common object and must match the method used. +#define CHOLMOD_INT 0 /* int32, for cholmod_* methods (no _l_) */ +#define CHOLMOD_LONG 2 /* int64, for cholmod_l_* methods */ + +// dtype: floating point sizes (double or float) +// The dtype of all parameters for all CHOLMOD routines must match. +// NOTE: CHOLMOD_SINGLE is still under development. +#define CHOLMOD_DOUBLE 0 /* matrix or factorization is double precision */ +#define CHOLMOD_SINGLE 4 /* matrix or factorization is single precision */ + +// xtype: pattern, real, complex, or zomplex +#define CHOLMOD_PATTERN 0 /* no numerical values */ +#define CHOLMOD_REAL 1 /* real (double or single), not complex */ +#define CHOLMOD_COMPLEX 2 /* complex (double or single), interleaved */ +#define CHOLMOD_ZOMPLEX 3 /* complex (double or single), with real and imag */ + /* parts held in different arrays */ + +// xdtype is (xtype + dtype), which combines the two type parameters into +// a single number handling all 8 cases: +// +// (0) CHOLMOD_DOUBLE + CHOLMOD_PATTERN a pattern-only matrix +// (1) CHOLMOD_DOUBLE + CHOLMOD_REAL a double real matrix +// (2) CHOLMOD_DOUBLE + CHOLMOD_COMPLEX a double complex matrix +// (3) CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX a double zomplex matrix +// (4) CHOLMOD_SINGLE + CHOLMOD_PATTERN a pattern-only matrix +// (5) CHOLMOD_SINGLE + CHOLMOD_REAL a float real matrix +// (6) CHOLMOD_SINGLE + CHOLMOD_COMPLEX a float complex matrix +// (7) CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX a float zomplex matrix + +// max # of ordering methods in Common +#define CHOLMOD_MAXMETHODS 9 + +// Common->status for error handling: 0 is ok, negative is a fatal error, +// and positive is a warning +#define CHOLMOD_OK (0) +#define CHOLMOD_NOT_INSTALLED (-1) /* module not installed */ +#define CHOLMOD_OUT_OF_MEMORY (-2) /* malloc, calloc, or realloc failed */ +#define CHOLMOD_TOO_LARGE (-3) /* integer overflow */ +#define CHOLMOD_INVALID (-4) /* input invalid */ +#define CHOLMOD_GPU_PROBLEM (-5) /* CUDA error */ +#define CHOLMOD_NOT_POSDEF (1) /* matrix not positive definite */ +#define CHOLMOD_DSMALL (2) /* diagonal entry very small */ + +// ordering method +#define CHOLMOD_NATURAL 0 /* no preordering */ +#define CHOLMOD_GIVEN 1 /* user-provided permutation */ +#define CHOLMOD_AMD 2 /* AMD: approximate minimum degree */ +#define CHOLMOD_METIS 3 /* METIS: mested dissection */ +#define CHOLMOD_NESDIS 4 /* CHOLMOD's nested dissection */ +#define CHOLMOD_COLAMD 5 /* AMD for A, COLAMD for AA' or A'A */ +#define CHOLMOD_POSTORDERED 6 /* natural then postordered */ + +// supernodal strategy +#define CHOLMOD_SIMPLICIAL 0 /* always use simplicial method */ +#define CHOLMOD_AUTO 1 /* auto select simplicial vs supernodal */ +#define CHOLMOD_SUPERNODAL 2 /* always use supernoda method */ -/* The xtype of all parameters for all CHOLMOD routines must match. - * - * CHOLMOD_PATTERN: x and z are ignored. - * CHOLMOD_DOUBLE: x is non-null of size nzmax, z is ignored. - * CHOLMOD_COMPLEX: x is non-null of size 2*nzmax doubles, z is ignored. - * CHOLMOD_ZOMPLEX: x and z are non-null of size nzmax - * - * In the real case, z is ignored. The kth entry in the matrix is x [k]. - * There are two methods for the complex case. In the ANSI C99-compatible - * CHOLMOD_COMPLEX case, the real and imaginary parts of the kth entry - * are in x [2*k] and x [2*k+1], respectively. z is ignored. In the - * MATLAB-compatible CHOLMOD_ZOMPLEX case, the real and imaginary - * parts of the kth entry are in x [k] and z [k]. - * - * Scalar floating-point values are always passed as double arrays of size 2 - * (real and imaginary parts). The imaginary part of a scalar is ignored if - * the routine operates on a real matrix. - * - * These Modules support complex and zomplex matrices, with a few exceptions: - * - * Check all routines - * Cholesky all routines - * Core all except cholmod_aat, add, band, copy - * Demo all routines - * Partition all routines - * Supernodal all routines support any real, complex, or zomplex input. - * There will never be a supernodal zomplex L; a complex - * supernodal L is created if A is zomplex. - * Tcov all routines - * Valgrind all routines - * - * These Modules provide partial support for complex and zomplex matrices: - * - * MATLAB all routines support real and zomplex only, not complex, - * with the exception of ldlupdate, which supports - * real matrices only. This is a minor constraint since - * MATLAB's matrices are all real or zomplex. - * MatrixOps only norm_dense, norm_sparse, and sdmult support complex - * and zomplex - * - * These Modules do not support complex and zomplex matrices at all: - * - * Modify all routines support real matrices only - */ - -/* Definitions for cholmod_common: */ -#define CHOLMOD_MAXMETHODS 9 /* maximum number of different methods that */ - /* cholmod_analyze can try. Must be >= 9. */ - -/* Common->status values. zero means success, negative means a fatal error, - * positive is a warning. */ -#define CHOLMOD_OK 0 /* success */ -#define CHOLMOD_NOT_INSTALLED (-1) /* failure: method not installed */ -#define CHOLMOD_OUT_OF_MEMORY (-2) /* failure: out of memory */ -#define CHOLMOD_TOO_LARGE (-3) /* failure: integer overflow occured */ -#define CHOLMOD_INVALID (-4) /* failure: invalid input */ -#define CHOLMOD_GPU_PROBLEM (-5) /* failure: GPU fatal error */ -#define CHOLMOD_NOT_POSDEF (1) /* warning: matrix not pos. def. */ -#define CHOLMOD_DSMALL (2) /* warning: D for LDL' or diag(L) or */ - /* LL' has tiny absolute value */ - -/* ordering method (also used for L->ordering) */ -#define CHOLMOD_NATURAL 0 /* use natural ordering */ -#define CHOLMOD_GIVEN 1 /* use given permutation */ -#define CHOLMOD_AMD 2 /* use minimum degree (AMD) */ -#define CHOLMOD_METIS 3 /* use METIS' nested dissection */ -#define CHOLMOD_NESDIS 4 /* use CHOLMOD's version of nested dissection:*/ - /* node bisector applied recursively, followed - * by constrained minimum degree (CSYMAMD or - * CCOLAMD) */ -#define CHOLMOD_COLAMD 5 /* use AMD for A, COLAMD for A*A' */ - -/* POSTORDERED is not a method, but a result of natural ordering followed by a - * weighted postorder. It is used for L->ordering, not method [ ].ordering. */ -#define CHOLMOD_POSTORDERED 6 /* natural ordering, postordered. */ - -/* supernodal strategy (for Common->supernodal) */ -#define CHOLMOD_SIMPLICIAL 0 /* always do simplicial */ -#define CHOLMOD_AUTO 1 /* select simpl/super depending on matrix */ -#define CHOLMOD_SUPERNODAL 2 /* always do supernodal */ - -/* make it easy for C++ programs to include CHOLMOD */ #ifdef __cplusplus extern "C" { #endif typedef struct cholmod_common_struct { - /* ---------------------------------------------------------------------- */ - /* parameters for symbolic/numeric factorization and update/downdate */ - /* ---------------------------------------------------------------------- */ - - double dbound ; /* Smallest absolute value of diagonal entries of D - * for LDL' factorization and update/downdate/rowadd/ - * rowdel, or the diagonal of L for an LL' factorization. - * Entries in the range 0 to dbound are replaced with dbound. - * Entries in the range -dbound to 0 are replaced with -dbound. No - * changes are made to the diagonal if dbound <= 0. Default: zero */ - - double grow0 ; /* For a simplicial factorization, L->i and L->x can - * grow if necessary. grow0 is the factor by which - * it grows. For the initial space, L is of size MAX (1,grow0) times - * the required space. If L runs out of space, the new size of L is - * MAX(1.2,grow0) times the new required space. If you do not plan on - * modifying the LDL' factorization in the Modify module, set grow0 to - * zero (or set grow2 to 0, see below). Default: 1.2 */ - - double grow1 ; - - size_t grow2 ; /* For a simplicial factorization, each column j of L - * is initialized with space equal to - * grow1*L->ColCount[j] + grow2. If grow0 < 1, grow1 < 1, or grow2 == 0, - * then the space allocated is exactly equal to L->ColCount[j]. If the - * column j runs out of space, it increases to grow1*need + grow2 in - * size, where need is the total # of nonzeros in that column. If you do - * not plan on modifying the factorization in the Modify module, set - * grow2 to zero. Default: grow1 = 1.2, grow2 = 5. */ - - size_t maxrank ; /* rank of maximum update/downdate. Valid values: - * 2, 4, or 8. A value < 2 is set to 2, and a - * value > 8 is set to 8. It is then rounded up to the next highest - * power of 2, if not already a power of 2. Workspace (Xwork, below) of - * size nrow-by-maxrank double's is allocated for the update/downdate. - * If an update/downdate of rank-k is requested, with k > maxrank, - * it is done in steps of maxrank. Default: 8, which is fastest. - * Memory usage can be reduced by setting maxrank to 2 or 4. - */ - - double supernodal_switch ; /* supernodal vs simplicial factorization */ - int supernodal ; /* If Common->supernodal <= CHOLMOD_SIMPLICIAL - * (0) then cholmod_analyze performs a - * simplicial analysis. If >= CHOLMOD_SUPERNODAL (2), then a supernodal - * analysis is performed. If == CHOLMOD_AUTO (1) and - * flop/nnz(L) < Common->supernodal_switch, then a simplicial analysis - * is done. A supernodal analysis done otherwise. - * Default: CHOLMOD_AUTO. Default supernodal_switch = 40 */ - - int final_asis ; /* If TRUE, then ignore the other final_* parameters - * (except for final_pack). - * The factor is left as-is when done. Default: TRUE.*/ - - int final_super ; /* If TRUE, leave a factor in supernodal form when - * supernodal factorization is finished. If FALSE, - * then convert to a simplicial factor when done. - * Default: TRUE */ - - int final_ll ; /* If TRUE, leave factor in LL' form when done. - * Otherwise, leave in LDL' form. Default: FALSE */ - - int final_pack ; /* If TRUE, pack the columns when done. If TRUE, and - * cholmod_factorize is called with a symbolic L, L is - * allocated with exactly the space required, using L->ColCount. If you - * plan on modifying the factorization, set Common->final_pack to FALSE, - * and each column will be given a little extra slack space for future - * growth in fill-in due to updates. Default: TRUE */ - - int final_monotonic ; /* If TRUE, ensure columns are monotonic when done. - * Default: TRUE */ - - int final_resymbol ;/* if cholmod_factorize performed a supernodal - * factorization, final_resymbol is true, and - * final_super is FALSE (convert a simplicial numeric factorization), - * then numerically zero entries that resulted from relaxed supernodal - * amalgamation are removed. This does not remove entries that are zero - * due to exact numeric cancellation, since doing so would break the - * update/downdate rowadd/rowdel routines. Default: FALSE. */ - - /* supernodal relaxed amalgamation parameters: */ - double zrelax [3] ; - size_t nrelax [3] ; - - /* Let ns be the total number of columns in two adjacent supernodes. - * Let z be the fraction of zero entries in the two supernodes if they - * are merged (z includes zero entries from prior amalgamations). The - * two supernodes are merged if: - * (ns <= nrelax [0]) || (no new zero entries added) || - * (ns <= nrelax [1] && z < zrelax [0]) || - * (ns <= nrelax [2] && z < zrelax [1]) || (z < zrelax [2]) - * - * Default parameters result in the following rule: - * (ns <= 4) || (no new zero entries added) || - * (ns <= 16 && z < 0.8) || (ns <= 48 && z < 0.1) || (z < 0.05) - */ - - int prefer_zomplex ; /* X = cholmod_solve (sys, L, B, Common) computes - * x=A\b or solves a related system. If L and B are - * both real, then X is real. Otherwise, X is returned as - * CHOLMOD_COMPLEX if Common->prefer_zomplex is FALSE, or - * CHOLMOD_ZOMPLEX if Common->prefer_zomplex is TRUE. This parameter - * is needed because there is no supernodal zomplex L. Suppose the - * caller wants all complex matrices to be stored in zomplex form - * (MATLAB, for example). A supernodal L is returned in complex form - * if A is zomplex. B can be real, and thus X = cholmod_solve (L,B) - * should return X as zomplex. This cannot be inferred from the input - * arguments L and B. Default: FALSE, since all data types are - * supported in CHOLMOD_COMPLEX form and since this is the native type - * of LAPACK and the BLAS. Note that the MATLAB/cholmod.c mexFunction - * sets this parameter to TRUE, since MATLAB matrices are in - * CHOLMOD_ZOMPLEX form. - */ - - int prefer_upper ; /* cholmod_analyze and cholmod_factorize work - * fastest when a symmetric matrix is stored in - * upper triangular form when a fill-reducing ordering is used. In - * MATLAB, this corresponds to how x=A\b works. When the matrix is - * ordered as-is, they work fastest when a symmetric matrix is in lower - * triangular form. In MATLAB, R=chol(A) does the opposite. This - * parameter affects only how cholmod_read returns a symmetric matrix. - * If TRUE (the default case), a symmetric matrix is always returned in - * upper-triangular form (A->stype = 1). */ - - int quick_return_if_not_posdef ; /* if TRUE, the supernodal numeric - * factorization will return quickly if - * the matrix is not positive definite. Default: FALSE. */ - - int prefer_binary ; /* cholmod_read_triplet converts a symmetric - * pattern-only matrix into a real matrix. If - * prefer_binary is FALSE, the diagonal entries are set to 1 + the degree - * of the row/column, and off-diagonal entries are set to -1 (resulting - * in a positive definite matrix if the diagonal is zero-free). Most - * symmetric patterns are the pattern a positive definite matrix. If - * this parameter is TRUE, then the matrix is returned with a 1 in each - * entry, instead. Default: FALSE. Added in v1.3. */ - - /* ---------------------------------------------------------------------- */ - /* printing and error handling options */ - /* ---------------------------------------------------------------------- */ - - int print ; /* print level. Default: 3 */ - int precise ; /* if TRUE, print 16 digits. Otherwise print 5 */ - - /* CHOLMOD print_function replaced with SuiteSparse_config print_func */ - - int try_catch ; /* if TRUE, then ignore errors; CHOLMOD is in the middle - * of a try/catch block. No error message is printed - * and the Common->error_handler function is not called. */ - - void (*error_handler) (int status, const char *file, - int line, const char *message) ; - - /* Common->error_handler is the user's error handling routine. If not - * NULL, this routine is called if an error occurs in CHOLMOD. status - * can be CHOLMOD_OK (0), negative for a fatal error, and positive for - * a warning. file is a string containing the name of the source code - * file where the error occured, and line is the line number in that - * file. message is a string describing the error in more detail. */ - - /* ---------------------------------------------------------------------- */ - /* ordering options */ - /* ---------------------------------------------------------------------- */ - - /* The cholmod_analyze routine can try many different orderings and select - * the best one. It can also try one ordering method multiple times, with - * different parameter settings. The default is to use three orderings, - * the user's permutation (if provided), AMD which is the fastest ordering - * and generally gives good fill-in, and METIS. CHOLMOD's nested dissection - * (METIS with a constrained AMD) usually gives a better ordering than METIS - * alone (by about 5% to 10%) but it takes more time. - * - * If you know the method that is best for your matrix, set Common->nmethods - * to 1 and set Common->method [0] to the set of parameters for that method. - * If you set it to 1 and do not provide a permutation, then only AMD will - * be called. - * - * If METIS is not available, the default # of methods tried is 2 (the user - * permutation, if any, and AMD). - * - * To try other methods, set Common->nmethods to the number of methods you - * want to try. The suite of default methods and their parameters is - * described in the cholmod_defaults routine, and summarized here: - * - * Common->method [i]: - * i = 0: user-provided ordering (cholmod_analyze_p only) - * i = 1: AMD (for both A and A*A') - * i = 2: METIS - * i = 3: CHOLMOD's nested dissection (NESDIS), default parameters - * i = 4: natural - * i = 5: NESDIS with nd_small = 20000 - * i = 6: NESDIS with nd_small = 4, no constrained minimum degree - * i = 7: NESDIS with no dense node removal - * i = 8: AMD for A, COLAMD for A*A' - * - * You can modify the suite of methods you wish to try by modifying - * Common.method [...] after calling cholmod_start or cholmod_defaults. - * - * For example, to use AMD, followed by a weighted postordering: - * - * Common->nmethods = 1 ; - * Common->method [0].ordering = CHOLMOD_AMD ; - * Common->postorder = TRUE ; - * - * To use the natural ordering (with no postordering): - * - * Common->nmethods = 1 ; - * Common->method [0].ordering = CHOLMOD_NATURAL ; - * Common->postorder = FALSE ; - * - * If you are going to factorize hundreds or more matrices with the same - * nonzero pattern, you may wish to spend a great deal of time finding a - * good permutation. In this case, try setting Common->nmethods to 9. - * The time spent in cholmod_analysis will be very high, but you need to - * call it only once. - * - * cholmod_analyze sets Common->current to a value between 0 and nmethods-1. - * Each ordering method uses the set of options defined by this parameter. - */ - - int nmethods ; /* The number of ordering methods to try. Default: 0. - * nmethods = 0 is a special case. cholmod_analyze - * will try the user-provided ordering (if given) and AMD. Let fl and - * lnz be the flop count and nonzeros in L from AMD's ordering. Let - * anz be the number of nonzeros in the upper or lower triangular part - * of the symmetric matrix A. If fl/lnz < 500 or lnz/anz < 5, then this - * is a good ordering, and METIS is not attempted. Otherwise, METIS is - * tried. The best ordering found is used. If nmethods > 0, the - * methods used are given in the method[ ] array, below. The first - * three methods in the default suite of orderings is (1) use the given - * permutation (if provided), (2) use AMD, and (3) use METIS. Maximum - * allowed value is CHOLMOD_MAXMETHODS. */ - - int current ; /* The current method being tried. Default: 0. Valid - * range is 0 to nmethods-1. */ - - int selected ; /* The best method found. */ - - /* The suite of ordering methods and parameters: */ + //-------------------------------------------------------------------------- + // primary parameters for factorization and update/downdate + //-------------------------------------------------------------------------- + + double dbound ; // Bounds the diagonal entries of D for LDL' + // factorization and update/downdate/rowadd. Entries outside this + // bound are replaced with dbound. Default: 0. + // dbound is used for double precision factorization only. + // See sbound for single precision factorization. + + double grow0 ; // default: 1.2 + double grow1 ; // default: 1.2 + size_t grow2 ; // default: 5 + // Initial space for simplicial factorization is max(grow0,1) times the + // required space. If space is exhausted, L is grown by + // max(grow0,1.2) times the required space. grow1 and grow2 control + // how each column of L can grow in an update/downdate; if space runs + // out, then grow1*(required space) + grow2 is allocated. + + size_t maxrank ; // maximum rank for update/downdate. Valid values are + // 2, 4, and 8. Default is 8. If a larger update/downdate is done, + // it is done in steps of maxrank. + + double supernodal_switch ; // default: 40 + int supernodal ; // default: CHOLMOD_AUTO. + // Controls supernodal vs simplicial factorization. If + // Common->supernodal is CHOLMOD_SIMPLICIAL, a simplicial factorization + // is always done; if CHOLMOD_SUPERNODAL, a supernodal factorization is + // always done. If CHOLMOD_AUTO, then a simplicial factorization is + // down if flops/nnz(L) < Common->supernodal_switch. + + int final_asis ; // if true, other final_* parameters are ignored, + // except for final_pack and the factors are left as-is when done. + // Default: true. + + int final_super ; // if true, leave factor in supernodal form. + // if false, convert to simplicial. Default: true. + + int final_ll ; // if true, simplicial factors are converted to LL', + // otherwise left as LDL. Default: false. + + int final_pack ; // if true, the factorize are allocated with exactly + // the space required. Set this to false if you expect future + // updates/downdates (giving a little extra space for future growth), + // Default: true. + + int final_monotonic ; // if true, columns are sorted when done, by + // ascending row index. Default: true. + + int final_resymbol ; // if true, a supernodal factorization converted + // to simplicial is reanalyzed, to remove zeros added for relaxed + // amalgamation. Default: false. + + double zrelax [3] ; size_t nrelax [3] ; + // The zrelax and nrelax parameters control relaxed supernodal + // amalgamation, If ns is the # of columns in two adjacent supernodes, + // and z is the fraction of zeros in the two supernodes if merged, then + // the two supernodes are merged if any of the 5 following condition + // are true: + // + // no new zero entries added if the two supernodes are merged + // (ns <= nrelax [0]) + // (ns <= nrelax [1] && z < zrelax [0]) + // (ns <= nrelax [2] && z < zrelax [1]) + // (z < zrelax [2]) + // + // With the defaults, the rules become: + // + // no new zero entries added if the two supernodes are merged + // (ns <= 4) + // (ns <= 16 && z < 0.8) + // (ns <= 48 && z < 0.1) + // (z < 0.05) + + int prefer_zomplex ; // if true, and a complex system is solved, + // X is returned as zomplex (with two arrays, one for the real part + // and one for the imaginary part). If false, then X is returned as + // a single array with interleaved real and imaginary parts. + // Default: false. + + int prefer_upper ; // if true, then a preference is given for holding + // a symmetric matrix by just its upper triangular form. This gives + // the best performance by the CHOLMOD analysis and factorization + // methods. Only used by cholmod_read. Default: true. + + int quick_return_if_not_posdef ; // if true, a supernodal factorization + // returns immediately if it finds the matrix is not positive definite. + // If false, the failed supernode is refactorized, up to but not + // including the failed column (required by MATLAB). + + int prefer_binary ; // if true, cholmod_read_triplet converts a symmetric + // pattern-only matrix to a real matrix with all values set to 1. + // if false, diagonal entries A(k,k) are set to one plus the # of + // entries in row/column k, and off-diagonals are set to -1. + // Default: false. + + int print ; // print level. Default is 3. + int precise ; // if true, print 16 digits, otherwise 5. Default: false. + + int try_catch ; // if true, ignore errors (CHOLMOD is assumed to be inside + // a try/catch block. No error messages are printed and the + // error_handler function is not called. Default: false. + + void (*error_handler) (int status, const char *file, int line, + const char *message) ; + // User error handling routine; default is NULL. + // This function is called if an error occurs, with parameters: + // status: the Common->status result. + // file: filename where the error occurred. + // line: line number where the error occurred. + // message: a string that describes the error. + + //-------------------------------------------------------------------------- + // ordering options + //-------------------------------------------------------------------------- + + // CHOLMOD can try many ordering options and then pick the best result it + // finds. The default is to use one or two orderings: the user's + // permutation (if given), and AMD. + + // Common->nmethods is the number of methods to try. If the + // Common->method array is left unmodified, the methods are: + + // (0) given (skipped if no user permutation) + // (1) amd + // (2) metis + // (3) nesdis with defaults (CHOLMOD's nested dissection, based on METIS) + // (4) natural + // (5) nesdis: stop at subgraphs of 20000 nodes + // (6) nesdis: stop at subgraphs of 4 nodes, do not use CAMD + // (7) nesdis: no pruning on of dense rows/cols + // (8) colamd + + // To use all 9 of the above methods, set Common->nmethods to 9. The + // analysis will take a long time, but that might be worth it if the + // ordering will be reused many many times. + + // Common->nmethods and Common->methods can be revised to use a different + // set of orderings. For example, to use just a single method + // (AMD with a weighted postordering): + // + // Common->nmethods = 1 ; + // Common->method [0].ordering = CHOLMOD_AMD ; + // Common->postorder = TRUE ; + // + // + + int nmethods ; // Number of methods to try, default is 0. + // The value of 0 is a special case, and tells CHOLMOD to use the user + // permutation (if not NULL) and then AMD. Next, if fl is lnz are the + // flop counts and number of nonzeros in L as found by AMD, then the + // this ordering is used if fl/lnz < 500 or lnz/anz < 5, where anz is + // the number of entries in A. If this condition fails, METIS is tried + // as well. + // + // Otherwise, if Common->nmethods > 0, then the methods defined by + // Common->method [0 ... Common->nmethods-1] are used. + + int current ; // The current method being tried in the analysis. + int selected ; // The selected method: Common->method [Common->selected] + + // The Common->method parameter is an array of structs that defines up + // to 9 methods: struct cholmod_method_struct { - /* statistics for this method */ - double lnz ; /* nnz(L) excl. zeros from supernodal amalgamation, - * for a "pure" L */ - - double fl ; /* flop count for a "pure", real simplicial LL' - * factorization, with no extra work due to - * amalgamation. Subtract n to get the LDL' flop count. Multiply - * by about 4 if the matrix is complex or zomplex. */ - - /* ordering method parameters */ - double prune_dense ;/* dense row/col control for AMD, SYMAMD, CSYMAMD, - * and NESDIS (cholmod_nested_dissection). For a - * symmetric n-by-n matrix, rows/columns with more than - * MAX (16, prune_dense * sqrt (n)) entries are removed prior to - * ordering. They appear at the end of the re-ordered matrix. - * - * If prune_dense < 0, only completely dense rows/cols are removed. - * - * This paramater is also the dense column control for COLAMD and - * CCOLAMD. For an m-by-n matrix, columns with more than - * MAX (16, prune_dense * sqrt (MIN (m,n))) entries are removed prior - * to ordering. They appear at the end of the re-ordered matrix. - * CHOLMOD factorizes A*A', so it calls COLAMD and CCOLAMD with A', - * not A. Thus, this parameter affects the dense *row* control for - * CHOLMOD's matrix, and the dense *column* control for COLAMD and - * CCOLAMD. - * - * Removing dense rows and columns improves the run-time of the - * ordering methods. It has some impact on ordering quality - * (usually minimal, sometimes good, sometimes bad). - * - * Default: 10. */ - - double prune_dense2 ;/* dense row control for COLAMD and CCOLAMD. - * Rows with more than MAX (16, dense2 * sqrt (n)) - * for an m-by-n matrix are removed prior to ordering. CHOLMOD's - * matrix is transposed before ordering it with COLAMD or CCOLAMD, - * so this controls the dense *columns* of CHOLMOD's matrix, and - * the dense *rows* of COLAMD's or CCOLAMD's matrix. - * - * If prune_dense2 < 0, only completely dense rows/cols are removed. - * - * Default: -1. Note that this is not the default for COLAMD and - * CCOLAMD. -1 is best for Cholesky. 10 is best for LU. */ - - double nd_oksep ; /* in NESDIS, when a node separator is computed, it - * discarded if nsep >= nd_oksep*n, where nsep is - * the number of nodes in the separator, and n is the size of the - * graph being cut. Valid range is 0 to 1. If 1 or greater, the - * separator is discarded if it consists of the entire graph. - * Default: 1 */ - - double other_1 [4] ; /* future expansion */ - - size_t nd_small ; /* do not partition graphs with fewer nodes than - * nd_small, in NESDIS. Default: 200 (same as - * METIS) */ - - size_t other_2 [4] ; /* future expansion */ - - int aggressive ; /* Aggresive absorption in AMD, COLAMD, SYMAMD, - * CCOLAMD, and CSYMAMD. Default: TRUE */ - - int order_for_lu ; /* CCOLAMD can be optimized to produce an ordering - * for LU or Cholesky factorization. CHOLMOD only - * performs a Cholesky factorization. However, you may wish to use - * CHOLMOD as an interface for CCOLAMD but use it for your own LU - * factorization. In this case, order_for_lu should be set to FALSE. - * When factorizing in CHOLMOD itself, you should *** NEVER *** set - * this parameter FALSE. Default: TRUE. */ - - int nd_compress ; /* If TRUE, compress the graph and subgraphs before - * partitioning them in NESDIS. Default: TRUE */ - - int nd_camd ; /* If 1, follow the nested dissection ordering - * with a constrained minimum degree ordering that - * respects the partitioning just found (using CAMD). If 2, use - * CSYMAMD instead. If you set nd_small very small, you may not need - * this ordering, and can save time by setting it to zero (no - * constrained minimum degree ordering). Default: 1. */ - - int nd_components ; /* The nested dissection ordering finds a node - * separator that splits the graph into two parts, - * which may be unconnected. If nd_components is TRUE, each of - * these connected components is split independently. If FALSE, - * each part is split as a whole, even if it consists of more than - * one connected component. Default: FALSE */ - - /* fill-reducing ordering to use */ - int ordering ; - - size_t other_3 [4] ; /* future expansion */ - - } method [CHOLMOD_MAXMETHODS + 1] ; - - int postorder ; /* If TRUE, cholmod_analyze follows the ordering with a - * weighted postorder of the elimination tree. Improves - * supernode amalgamation. Does not affect fundamental nnz(L) and - * flop count. Default: TRUE. */ - - int default_nesdis ; /* Default: FALSE. If FALSE, then the default - * ordering strategy (when Common->nmethods == 0) - * is to try the given ordering (if present), AMD, and then METIS if AMD - * reports high fill-in. If Common->default_nesdis is TRUE then NESDIS - * is used instead in the default strategy. */ - - /* ---------------------------------------------------------------------- */ - /* memory management, complex divide, and hypot function pointers moved */ - /* ---------------------------------------------------------------------- */ - - /* Function pointers moved from here (in CHOLMOD 2.2.0) to - SuiteSparse_config.[ch]. See CHOLMOD/Include/cholmod_back.h - for a set of macros that can be #include'd or copied into your - application to define these function pointers on any version of CHOLMOD. - */ - - /* ---------------------------------------------------------------------- */ - /* METIS workarounds */ - /* ---------------------------------------------------------------------- */ - - /* These workarounds were put into place for METIS 4.0.1. They are safe - to use with METIS 5.1.0, but they might not longer be necessary. */ - - double metis_memory ; /* This is a parameter for CHOLMOD's interface to - * METIS, not a parameter to METIS itself. METIS - * uses an amount of memory that is difficult to estimate precisely - * beforehand. If it runs out of memory, it terminates your program. - * All routines in CHOLMOD except for CHOLMOD's interface to METIS - * return an error status and safely return to your program if they run - * out of memory. To mitigate this problem, the CHOLMOD interface - * can allocate a single block of memory equal in size to an empirical - * upper bound of METIS's memory usage times the Common->metis_memory - * parameter, and then immediately free it. It then calls METIS. If - * this pre-allocation fails, it is possible that METIS will fail as - * well, and so CHOLMOD returns with an out-of-memory condition without - * calling METIS. - * - * METIS_NodeND (used in the CHOLMOD_METIS ordering option) with its - * default parameter settings typically uses about (4*nz+40n+4096) - * times sizeof(int) memory, where nz is equal to the number of entries - * in A for the symmetric case or AA' if an unsymmetric matrix is - * being ordered (where nz includes both the upper and lower parts - * of A or AA'). The observed "upper bound" (with 2 exceptions), - * measured in an instrumented copy of METIS 4.0.1 on thousands of - * matrices, is (10*nz+50*n+4096) * sizeof(int). Two large matrices - * exceeded this bound, one by almost a factor of 2 (Gupta/gupta2). - * - * If your program is terminated by METIS, try setting metis_memory to - * 2.0, or even higher if needed. By default, CHOLMOD assumes that METIS - * does not have this problem (so that CHOLMOD will work correctly when - * this issue is fixed in METIS). Thus, the default value is zero. - * This work-around is not guaranteed anyway. - * - * If a matrix exceeds this predicted memory usage, AMD is attempted - * instead. It, too, may run out of memory, but if it does so it will - * not terminate your program. - */ - - double metis_dswitch ; /* METIS_NodeND in METIS 4.0.1 gives a seg */ - size_t metis_nswitch ; /* fault with one matrix of order n = 3005 and - * nz = 6,036,025. This is a very dense graph. - * The workaround is to use AMD instead of METIS for matrices of dimension - * greater than Common->metis_nswitch (default 3000) or more and with - * density of Common->metis_dswitch (default 0.66) or more. - * cholmod_nested_dissection has no problems with the same matrix, even - * though it uses METIS_ComputeVertexSeparator on this matrix. If this - * seg fault does not affect you, set metis_nswitch to zero or less, - * and CHOLMOD will not switch to AMD based just on the density of the - * matrix (it will still switch to AMD if the metis_memory parameter - * causes the switch). - */ - - /* ---------------------------------------------------------------------- */ - /* workspace */ - /* ---------------------------------------------------------------------- */ - - /* CHOLMOD has several routines that take less time than the size of - * workspace they require. Allocating and initializing the workspace would - * dominate the run time, unless workspace is allocated and initialized - * just once. CHOLMOD allocates this space when needed, and holds it here - * between calls to CHOLMOD. cholmod_start sets these pointers to NULL - * (which is why it must be the first routine called in CHOLMOD). - * cholmod_finish frees the workspace (which is why it must be the last - * call to CHOLMOD). - */ - - size_t nrow ; /* size of Flag and Head */ - int64_t mark ; /* mark value for Flag array */ - size_t iworksize ; /* size of Iwork. Upper bound: 6*nrow+ncol */ - size_t xworksize ; /* size of Xwork, in bytes. - * maxrank*nrow*sizeof(double) for update/downdate. - * 2*nrow*sizeof(double) otherwise */ - - /* initialized workspace: contents needed between calls to CHOLMOD */ - void *Flag ; /* size nrow, an integer array. Kept cleared between - * calls to cholmod rouines (Flag [i] < mark) */ - - void *Head ; /* size nrow+1, an integer array. Kept cleared between - * calls to cholmod routines (Head [i] = EMPTY) */ - - void *Xwork ; /* a double array. Its size varies. It is nrow for - * most routines (cholmod_rowfac, cholmod_add, - * cholmod_aat, cholmod_norm, cholmod_ssmult) for the real case, twice - * that when the input matrices are complex or zomplex. It is of size - * 2*nrow for cholmod_rowadd and cholmod_rowdel. For cholmod_updown, - * its size is maxrank*nrow where maxrank is 2, 4, or 8. Kept cleared - * between calls to cholmod (set to zero). */ - - /* uninitialized workspace, contents not needed between calls to CHOLMOD */ - void *Iwork ; /* size iworksize, 2*nrow+ncol for most routines, - * up to 6*nrow+ncol for cholmod_analyze. */ - - int itype ; /* If CHOLMOD_LONG, Flag, Head, and Iwork are - * int64_t. Otherwise all three are int. */ - - int dtype ; /* double or float */ - - /* Common->itype and Common->dtype are used to define the types of all - * sparse matrices, triplet matrices, dense matrices, and factors - * created using this Common struct. The itypes and dtypes of all - * parameters to all CHOLMOD routines must match. */ - - int no_workspace_reallocate ; /* this is an internal flag, used as a - * precaution by cholmod_analyze. It is normally false. If true, - * cholmod_allocate_work is not allowed to reallocate any workspace; - * they must use the existing workspace in Common (Iwork, Flag, Head, - * and Xwork). Added for CHOLMOD v1.1 */ - - /* ---------------------------------------------------------------------- */ - /* statistics */ - /* ---------------------------------------------------------------------- */ - - /* fl and lnz are set only in cholmod_analyze and cholmod_rowcolcounts, - * in the Cholesky modudle. modfl is set only in the Modify module. */ - - int status ; /* error code */ - double fl ; /* LL' flop count from most recent analysis */ - double lnz ; /* fundamental nz in L */ - double anz ; /* nonzeros in tril(A) if A is symmetric/lower, - * triu(A) if symmetric/upper, or tril(A*A') if - * unsymmetric, in last call to cholmod_analyze. */ - double modfl ; /* flop count from most recent update/downdate/ - * rowadd/rowdel (excluding flops to modify the - * solution to Lx=b, if computed) */ - size_t malloc_count ; /* # of objects malloc'ed minus the # free'd*/ - size_t memory_usage ; /* peak memory usage in bytes */ - size_t memory_inuse ; /* current memory usage in bytes */ - - double nrealloc_col ; /* # of column reallocations */ - double nrealloc_factor ;/* # of factor reallocations due to col. reallocs */ - double ndbounds_hit ; /* # of times diagonal modified by dbound */ - - double rowfacfl ; /* # of flops in last call to cholmod_rowfac */ - double aatfl ; /* # of flops to compute A(:,f)*A(:,f)' */ - - int called_nd ; /* TRUE if the last call to - * cholmod_analyze called NESDIS or METIS. */ - int blas_ok ; /* FALSE if SUITESPARSE_BLAS_INT overflow; - TRUE otherwise */ - - /* ---------------------------------------------------------------------- */ - /* SuiteSparseQR control parameters: */ - /* ---------------------------------------------------------------------- */ - - double SPQR_grain ; /* task size is >= max (total flops / grain) */ - double SPQR_small ; /* task size is >= small */ - int SPQR_shrink ; /* controls stack realloc method */ - int SPQR_nthreads ; /* number of TBB threads, 0 = auto */ - - /* ---------------------------------------------------------------------- */ - /* SuiteSparseQR statistics */ - /* ---------------------------------------------------------------------- */ - - /* was other1 [0:3] */ - double SPQR_flopcount ; /* flop count for SPQR */ - double SPQR_analyze_time ; /* analysis time in seconds for SPQR */ - double SPQR_factorize_time ; /* factorize time in seconds for SPQR */ - double SPQR_solve_time ; /* backsolve time in seconds */ - - /* was SPQR_xstat [0:3] */ - double SPQR_flopcount_bound ; /* upper bound on flop count */ - double SPQR_tol_used ; /* tolerance used */ - double SPQR_norm_E_fro ; /* Frobenius norm of dropped entries */ - - /* was SPQR_istat [0:9] */ - int64_t SPQR_istat [10] ; - - /* ---------------------------------------------------------------------- */ - /* GPU configuration and statistics */ - /* ---------------------------------------------------------------------- */ - - /* useGPU: 1 if gpu-acceleration is requested */ - /* 0 if gpu-acceleration is prohibited */ - /* -1 if gpu-acceleration is undefined in which case the */ - /* environment CHOLMOD_USE_GPU will be queried and used. */ - /* useGPU=-1 is only used by CHOLMOD and treated as 0 by SPQR */ - int useGPU; - - /* for CHOLMOD: */ - size_t maxGpuMemBytes; - double maxGpuMemFraction; - - /* for SPQR: */ - size_t gpuMemorySize; /* Amount of memory in bytes on the GPU */ - double gpuKernelTime; /* Time taken by GPU kernels */ - int64_t gpuFlops; /* Number of flops performed by the GPU */ - int gpuNumKernelLaunches; /* Number of GPU kernel launches */ - - /* If not using the GPU, these items are not used, but they should be - present so that the CHOLMOD Common has the same size whether the GPU - is used or not. This way, all packages will agree on the size of - the CHOLMOD Common, regardless of whether or not they are compiled - with the GPU libraries or not */ -#ifdef SUITESPARSE_CUDA - /* in CUDA, these three types are pointers */ - #define CHOLMOD_CUBLAS_HANDLE cublasHandle_t - #define CHOLMOD_CUDASTREAM cudaStream_t - #define CHOLMOD_CUDAEVENT cudaEvent_t -#else - /* ... so make them void * pointers if the GPU is not being used */ - #define CHOLMOD_CUBLAS_HANDLE void * - #define CHOLMOD_CUDASTREAM void * - #define CHOLMOD_CUDAEVENT void * -#endif + //---------------------------------------------------------------------- + // statistics from the ordering + //---------------------------------------------------------------------- + + double lnz ; // number of nonzeros in L + double fl ; // Cholesky flop count for this ordering (each + // multiply and each add counted once (doesn't count complex + // flops). + + //---------------------------------------------------------------------- + // ordering parameters: + //---------------------------------------------------------------------- + + double prune_dense ; // dense row/col control. Default: 10. + // Rows/cols with more than max (prune_dense*sqrt(n),16) are + // removed prior to orderingm and placed last. If negative, + // only completely dense rows/cols are removed. Removing these + // rows/cols with many entries can speed up the ordering, but + // removing too many can reduce the ordering quality. + // + // For AMD, SYMAMD, and CSYMAMD, this is the only dense row/col + // parameter. For COLAMD and CCOLAMD, this parameter controls + // how dense columns are handled. + + double prune_dense2 ; // dense row control for COLAMD and CCOLAMD. + // Default -1. When computing the Cholesky factorization of AA' + // rows with more than max(prune_dense2*sqrt(n),16) entries + // are removed prior to ordering. If negative, only completely + // dense rows are removed. + + double nd_oksep ; // for CHOLMOD's nesdis method. Default 1. + // A node separator with nsep nodes is discarded if + // nsep >= nd_oksep*n. + + double other_1 [4] ; // unused, for future expansion + + size_t nd_small ; // for CHOLMOD's nesdis method. Default 200. + // Subgraphs with fewer than nd_small nodes are not partitioned. + + double other_2 [4] ; // unused, for future expansion + + int aggressive ; // if true, AMD, COLAMD, SYMAMD, CCOLAMD, and + // CSYMAMD perform aggresive absorption. Default: true + + int order_for_lu ; // Default: false. If the CHOLMOD analysis/ + // ordering methods are used as an ordering method for an LU + // factorization, then set this to true. For use in a Cholesky + // factorization by CHOLMOD itself, never set this to true. + + int nd_compress ; // if true, then the graph and subgraphs are + // compressed before partitioning them in CHOLMOD's nesdis + // method. Default: true. + + int nd_camd ; // if 1, then CHOLMOD's nesdis is followed by + // CAMD. If 2: followed by CSYMAMD. If nd_small is very small, + // then use 0, which skips CAMD or CSYMAMD. Default: 1. + + int nd_components ; // CHOLMOD's nesdis can partition a graph and then + // find that the subgraphs are unconnected. If true, each of these + // components is partitioned separately. If false, the whole + // subgraph is partitioned. Default: false. + + int ordering ; // ordering method to use + + size_t other_3 [4] ; // unused, for future expansion + + } + method [CHOLMOD_MAXMETHODS + 1] ; + + int postorder ; // if true, CHOLMOD performs a weighted postordering + // after its fill-reducing ordering, which improves supernodal + // amalgamation. Has no effect on flop count or nnz(L). + // Default: true. + + int default_nesdis ; // If false, then the default ordering strategy + // when Common->nmethods is zero is to try the user's permutation + // if given, then AMD, and then METIS if the AMD ordering results in + // a lot of fill-in. If true, then nesdis is used instead of METIS. + // Default: false. + + //-------------------------------------------------------------------------- + // METIS workarounds + //-------------------------------------------------------------------------- + + // These workarounds were put into place for METIS 4.0.1. They are safe + // to use with METIS 5.1.0, but they might not longer be necessary. + + double metis_memory ; // default: 0. If METIS terminates your + // program when it runs out of memory, try 2, or higher. + double metis_dswitch ; // default: 0.66 + size_t metis_nswitch ; // default: 3000 + // If a matrix has n > metis_nswitch and a density (nnz(A)/n^2) > + // metis_dswitch, then METIS is not used. + + //-------------------------------------------------------------------------- + // workspace + //-------------------------------------------------------------------------- + + // This workspace is kept in the CHOLMOD Common object. cholmod_start + // sets these arrays to NULL, and cholmod_finish frees them. + + size_t nrow ; // Flag has size nrow, Head has size nrow+1 + int64_t mark ; // Flag is cleared if Flag [0..nrow-1] < mark. + size_t iworksize ; // size of Iwork, in Ints (int32 or int64). + // This is at most 6*nrow + ncol. + size_t xworkbytes ; // size of Xwork, in bytes. for update/downdate: + // maxrank*nrow*sizeof(double or float), 2*nrow*sizeof(double or float) + // otherwise. NOTE: in CHOLMOD v4 and earlier, xworkwise was in terms + // of # of doubles, not # of bytes. + + void *Flag ; // size nrow. If this is "cleared" then + // Flag [i] < mark for all i = 0:nrow-1. Flag is kept cleared between + // calls to CHOLMOD. + + void *Head ; // size nrow+1. If Head [i] = EMPTY (-1) then that + // entry is "cleared". Head is kept cleared between calls to CHOLMOD. + + void *Xwork ; // a double or float array. It has size nrow for most + // routines, or 2*nrow if complex matrices are being handled. + // It has size 2*nrow for cholmod_rowadd/rowdel, and maxrank*nrow for + // cholmod_updown, where maxrank is 2, 4, or 8. Xwork is kept all + // zero between calls to CHOLMOD. + + void *Iwork ; // size iworksize integers (int32's or int64's). + // Uninitialized integer workspace, of size at most 6*nrow+ncol. + + int itype ; // cholmod_start (for int32's) sets this to CHOLMOD_INT, + // and cholmod_l_start sets this to CHOLMOD_LONG. It defines the + // integer sizes for th Flag, Head, and Iwork arrays, and also + // defines the integers for all objects created by CHOLMOD. + // The itype of the Common object must match the function name + // and all objects passed to it. + + int other_5 ; // unused: for future expansion + + int no_workspace_reallocate ; // an internal flag, usually false. + // This is set true to disable any reallocation of the workspace + // in the Common object. + + //-------------------------------------------------------------------------- + // statistics + //-------------------------------------------------------------------------- + + int status ; // status code (0: ok, negative: error, pos: warning + double fl ; // flop count from last analysis + double lnz ; // nnz(L) from last analysis + double anz ; // in last analysis: nnz(tril(A)) or nnz(triu(A)) if A + // symmetric, or tril(A*A') if A is unsymmetric. + double modfl ; // flop count from last update/downdate/rowadd/rowdel, + // not included the flops to revise the solution to Lx=b, + // if that was performed. + + size_t malloc_count ; // # of malloc'd objects not yet freed + size_t memory_usage ; // peak memory usage in bytes + size_t memory_inuse ; // current memory usage in bytes + + double nrealloc_col ; // # of column reallocations + double nrealloc_factor ;// # of factor reallocations due to col. reallocs + double ndbounds_hit ; // # of times diagonal modified by dbound + + double rowfacfl ; // flop count of cholmod_rowfac + double aatfl ; // flop count to compute A(:,f)*A(:,f)' + + int called_nd ; // true if last analysis used nesdis or METIS. + int blas_ok ; // true if no integer overflow has occured when trying to + // call the BLAS. The typical BLAS library uses 32-bit integers for + // its input parameters, even on a 64-bit platform. CHOLMOD uses int64 + // in its cholmod_l_* methods, and these must be typecast to the BLAS + // integer. If integer overflow occurs, this is set false. + + //-------------------------------------------------------------------------- + // SuiteSparseQR control parameters and statistics + //-------------------------------------------------------------------------- + + // SPQR uses the CHOLMOD Common object for its control and statistics. + // These parameters are not used by CHOLMOD itself. + + // control parameters: + double SPQR_grain ; // task size is >= max (total flops / grain) + double SPQR_small ; // task size is >= small + int SPQR_shrink ; // controls stack realloc method + int SPQR_nthreads ; // number of TBB threads, 0 = auto + + // statistics: + double SPQR_flopcount ; // flop count for SPQR + double SPQR_analyze_time ; // analysis time in seconds for SPQR + double SPQR_factorize_time ; // factorize time in seconds for SPQR + double SPQR_solve_time ; // backsolve time in seconds + double SPQR_flopcount_bound ; // upper bound on flop count + double SPQR_tol_used ; // tolerance used + double SPQR_norm_E_fro ; // Frobenius norm of dropped entries + + //-------------------------------------------------------------------------- + // Revised for CHOLMOD v5.0 + //-------------------------------------------------------------------------- + + // was size 10 in CHOLMOD v4.2; reduced to 8 in CHOLMOD v5: + int64_t SPQR_istat [8] ; // other statistics + + //-------------------------------------------------------------------------- + // Added for CHOLMOD v5.0 + //-------------------------------------------------------------------------- + + // These terms have been added to the CHOLMOD Common struct for v5.0, and + // on most systems they will total 16 bytes. The preceding term, + // SPQR_istat, was reduced by 16 bytes, since those last 2 entries were + // unused in CHOLMOD v4.2. As a result, the Common struct in v5.0 has the + // same size as v4.0, and all entries would normally be in the same offset, + // as well. This mitigates any changes between v4.0 and v5.0, and may make + // it easier to upgrade from v4 to v5. + + double nsbounds_hit ; // # of times diagonal modified by sbound. This + // ought to be int64_t, but ndbounds_hit was double in v4 + // (see above), so nsbounds_hit is made the same type for + // consistency. + float sbound ; // Same as dbound, but for single precision factorization. + float other_6 ; // for future expansion + + //-------------------------------------------------------------------------- + // GPU configuration and statistics + //-------------------------------------------------------------------------- + + int useGPU ; // 1 if GPU is requested for CHOLMOD + // 0 if GPU is not requested for CHOLMOD + // -1 if the use of the GPU is in CHOLMOD controled by the + // CHOLMOD_USE_GPU environment variable. + + size_t maxGpuMemBytes ; // GPU control for CHOLMOD + double maxGpuMemFraction ; // GPU control for CHOLMOD + + // for SPQR: + size_t gpuMemorySize ; // Amount of memory in bytes on the GPU + double gpuKernelTime ; // Time taken by GPU kernels + int64_t gpuFlops ; // Number of flops performed by the GPU + int gpuNumKernelLaunches ; // Number of GPU kernel launches + + #ifdef SUITESPARSE_CUDA + // these three types are pointers defined by CUDA: + #define CHOLMOD_CUBLAS_HANDLE cublasHandle_t + #define CHOLMOD_CUDASTREAM cudaStream_t + #define CHOLMOD_CUDAEVENT cudaEvent_t + #else + // they are (void *) if CUDA is not in use: + #define CHOLMOD_CUBLAS_HANDLE void * + #define CHOLMOD_CUDASTREAM void * + #define CHOLMOD_CUDAEVENT void * + #endif CHOLMOD_CUBLAS_HANDLE cublasHandle ; - /* a set of streams for general use */ - CHOLMOD_CUDASTREAM gpuStream[CHOLMOD_HOST_SUPERNODE_BUFFERS]; + // a set of streams for general use + CHOLMOD_CUDASTREAM gpuStream [CHOLMOD_HOST_SUPERNODE_BUFFERS] ; - CHOLMOD_CUDAEVENT cublasEventPotrf [3] ; - CHOLMOD_CUDAEVENT updateCKernelsComplete; - CHOLMOD_CUDAEVENT updateCBuffersFree[CHOLMOD_HOST_SUPERNODE_BUFFERS]; + CHOLMOD_CUDAEVENT cublasEventPotrf [3] ; + CHOLMOD_CUDAEVENT updateCKernelsComplete ; + CHOLMOD_CUDAEVENT updateCBuffersFree [CHOLMOD_HOST_SUPERNODE_BUFFERS] ; - void *dev_mempool; /* pointer to single allocation of device memory */ - size_t dev_mempool_size; + void *dev_mempool ; // pointer to single allocation of device memory + size_t dev_mempool_size ; - void *host_pinned_mempool; /* pointer to single allocation of pinned mem */ - size_t host_pinned_mempool_size; + void *host_pinned_mempool ; // pointer to single alloc of pinned mem + size_t host_pinned_mempool_size ; - size_t devBuffSize; - int ibuffer; + size_t devBuffSize ; + int ibuffer ; + double syrkStart ; // time syrk started - double syrkStart ; /* time syrk started */ - - /* run times of the different parts of CHOLMOD (GPU and CPU) */ + // run times of the different parts of CHOLMOD (GPU and CPU): double cholmod_cpu_gemm_time ; double cholmod_cpu_syrk_time ; double cholmod_cpu_trsm_time ; @@ -1185,7 +760,7 @@ typedef struct cholmod_common_struct double cholmod_assemble_time ; double cholmod_assemble_time2 ; - /* number of times the BLAS are called on the CPU and the GPU */ + // number of times the BLAS are called on the CPU and the GPU: size_t cholmod_cpu_gemm_calls ; size_t cholmod_cpu_syrk_calls ; size_t cholmod_cpu_trsm_calls ; @@ -1195,15 +770,16 @@ typedef struct cholmod_common_struct size_t cholmod_gpu_trsm_calls ; size_t cholmod_gpu_potrf_calls ; - double chunk ; // chunksize for computing # of threads to use. - // Given nwork work to do, # of threads is - // max (1, min (floor (work / chunk), nthreads_max)) - int nthreads_max ; // max # of threads to use in CHOLMOD. Defaults to - // SUITESPARSE_OPENMP_MAX_THREADS. + double chunk ; // chunksize for computing # of OpenMP threads to use. + // Given nwork work to do, # of threads is + // max (1, min (floor (work / chunk), nthreads_max)) + + int nthreads_max ; // max # of OpenMP threads to use in CHOLMOD. + // Defaults to SUITESPARSE_OPENMP_MAX_THREADS. } cholmod_common ; -/* size_t BLAS statistcs in Common: */ +// size_t BLAS statistcs in Common: #define CHOLMOD_CPU_GEMM_CALLS cholmod_cpu_gemm_calls #define CHOLMOD_CPU_SYRK_CALLS cholmod_cpu_syrk_calls #define CHOLMOD_CPU_TRSM_CALLS cholmod_cpu_trsm_calls @@ -1213,7 +789,7 @@ typedef struct cholmod_common_struct #define CHOLMOD_GPU_TRSM_CALLS cholmod_gpu_trsm_calls #define CHOLMOD_GPU_POTRF_CALLS cholmod_gpu_potrf_calls -/* double BLAS statistics in Common: */ +// double BLAS statistics in Common: #define CHOLMOD_CPU_GEMM_TIME cholmod_cpu_gemm_time #define CHOLMOD_CPU_SYRK_TIME cholmod_cpu_syrk_time #define CHOLMOD_CPU_TRSM_TIME cholmod_cpu_trsm_time @@ -1225,1422 +801,1138 @@ typedef struct cholmod_common_struct #define CHOLMOD_ASSEMBLE_TIME cholmod_assemble_time #define CHOLMOD_ASSEMBLE_TIME2 cholmod_assemble_time2 -/* for supernodal analysis */ +// for supernodal analysis: #define CHOLMOD_ANALYZE_FOR_SPQR 0 #define CHOLMOD_ANALYZE_FOR_CHOLESKY 1 #define CHOLMOD_ANALYZE_FOR_SPQRGPU 2 -/* -------------------------------------------------------------------------- */ -/* cholmod_start: first call to CHOLMOD */ -/* -------------------------------------------------------------------------- */ - -int cholmod_start -( - cholmod_common *Common -) ; +//------------------------------------------------------------------------------ +// cholmod_start: first call to CHOLMOD +//------------------------------------------------------------------------------ +int cholmod_start (cholmod_common *Common) ; int cholmod_l_start (cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_finish: last call to CHOLMOD */ -/* -------------------------------------------------------------------------- */ - -int cholmod_finish -( - cholmod_common *Common -) ; +//------------------------------------------------------------------------------ +// cholmod_finish: last call to CHOLMOD +//------------------------------------------------------------------------------ +int cholmod_finish (cholmod_common *Common) ; int cholmod_l_finish (cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_defaults: restore default parameters */ -/* -------------------------------------------------------------------------- */ - -int cholmod_defaults -( - cholmod_common *Common -) ; +//------------------------------------------------------------------------------ +// cholmod_defaults: set default parameters +//------------------------------------------------------------------------------ +int cholmod_defaults (cholmod_common *Common) ; int cholmod_l_defaults (cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_maxrank: return valid maximum rank for update/downdate */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_maxrank: return valid maximum rank for update/downdate +//------------------------------------------------------------------------------ -size_t cholmod_maxrank /* returns validated value of Common->maxrank */ +size_t cholmod_maxrank // return validated Common->maxrank ( - /* ---- input ---- */ - size_t n, /* A and L will have n rows */ - /* --------------- */ + size_t n, // # of rows of L and A cholmod_common *Common ) ; - size_t cholmod_l_maxrank (size_t, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_allocate_work: allocate workspace in Common */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_allocate_work: allocate workspace in Common +//------------------------------------------------------------------------------ + +// This method always allocates Xwork as double, for backward compatibility +// with CHOLMOD v4 and earlier. See cholmod_alloc_work for CHOLMOD v5. int cholmod_allocate_work ( - /* ---- input ---- */ - size_t nrow, /* size: Common->Flag (nrow), Common->Head (nrow+1) */ - size_t iworksize, /* size of Common->Iwork */ - size_t xworksize, /* size of Common->Xwork */ - /* --------------- */ + size_t nrow, // size of Common->Flag (nrow int32's) + // and Common->Head (nrow+1 int32's) + size_t iworksize, // size of Common->Iwork (# of int32's) + size_t xworksize, // size of Common->Xwork (# of double's) cholmod_common *Common ) ; - int cholmod_l_allocate_work (size_t, size_t, size_t, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_free_work: free workspace in Common */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_alloc_work: allocate workspace in Common +//------------------------------------------------------------------------------ -int cholmod_free_work +// Added for CHOLMOD v5: allocates Xwork as either double or single. + +int cholmod_alloc_work ( + size_t nrow, // size of Common->Flag (nrow int32's) + // and Common->Head (nrow+1 int32's) + size_t iworksize, // size of Common->Iwork (# of int32's) + size_t xworksize, // size of Common->Xwork (# of entries) + int dtype, // CHOLMOD_DOUBLE or CHOLMOD_SINGLE cholmod_common *Common ) ; +int cholmod_l_alloc_work (size_t, size_t, size_t, int, cholmod_common *) ; +//------------------------------------------------------------------------------ +// cholmod_free_work: free workspace in Common +//------------------------------------------------------------------------------ + +int cholmod_free_work (cholmod_common *Common) ; int cholmod_l_free_work (cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_clear_flag: clear Flag workspace in Common */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_clear_flag: clear Flag workspace in Common +//------------------------------------------------------------------------------ -/* use a macro for speed */ -#define CHOLMOD_CLEAR_FLAG(Common) \ -{ \ - Common->mark++ ; \ - if (Common->mark <= 0) \ - { \ - Common->mark = EMPTY ; \ - CHOLMOD (clear_flag) (Common) ; \ - } \ +// This macro is deprecated; do not use it: +#define CHOLMOD_CLEAR_FLAG(Common) \ +{ \ + Common->mark++ ; \ + if (Common->mark <= 0 || Common->mark >= INT32_MAX) \ + { \ + Common->mark = EMPTY ; \ + CHOLMOD (clear_flag) (Common) ; \ + } \ } -int64_t cholmod_clear_flag -( - cholmod_common *Common -) ; - +int64_t cholmod_clear_flag (cholmod_common *Common) ; int64_t cholmod_l_clear_flag (cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_error: called when CHOLMOD encounters an error */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_error: called when CHOLMOD encounters an error +//------------------------------------------------------------------------------ int cholmod_error ( - /* ---- input ---- */ - int status, /* error status */ - const char *file, /* name of source code file where error occured */ - int line, /* line number in source code file where error occured*/ - const char *message,/* error message */ - /* --------------- */ + int status, // Common->status + const char *file, // source file where error occurred + int line, // line number where error occurred + const char *message, // error message to print cholmod_common *Common ) ; - int cholmod_l_error (int, const char *, int, const char *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_dbound: for internal use in CHOLMOD only */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_dbound and cholmod_sbound: for internal use in CHOLMOD only +//------------------------------------------------------------------------------ -double cholmod_dbound /* returns modified diagonal entry of D or L */ -( - /* ---- input ---- */ - double dj, /* diagonal entry of D for LDL' or L for LL' */ - /* --------------- */ - cholmod_common *Common -) ; +// These were once documented functions but no are no longer meant to be used +// by the user application. They remain here for backward compatibility. +double cholmod_dbound (double, cholmod_common *) ; double cholmod_l_dbound (double, cholmod_common *) ; +float cholmod_sbound (float, cholmod_common *) ; +float cholmod_l_sbound (float, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_hypot: compute sqrt (x*x + y*y) accurately */ -/* -------------------------------------------------------------------------- */ - -double cholmod_hypot -( - /* ---- input ---- */ - double x, double y -) ; +//------------------------------------------------------------------------------ +// cholmod_hypot: compute sqrt (x*x + y*y) accurately +//------------------------------------------------------------------------------ +double cholmod_hypot (double x, double y) ; double cholmod_l_hypot (double, double) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_divcomplex: complex division, c = a/b */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_divcomplex: complex division, c = a/b +//------------------------------------------------------------------------------ -int cholmod_divcomplex /* return 1 if divide-by-zero, 0 otherise */ +int cholmod_divcomplex // return 1 if divide-by-zero, 0 if OK ( - /* ---- input ---- */ - double ar, double ai, /* real and imaginary parts of a */ - double br, double bi, /* real and imaginary parts of b */ - /* ---- output --- */ - double *cr, double *ci /* real and imaginary parts of c */ + double ar, double ai, // a (real, imaginary) + double br, double bi, // b (real, imaginary) + double *cr, double *ci // c (real, imaginary) ) ; - int cholmod_l_divcomplex (double, double, double, double, double *, double *) ; - -/* ========================================================================== */ -/* === Core/cholmod_sparse ================================================== */ -/* ========================================================================== */ - -/* A sparse matrix stored in compressed-column form. */ +//============================================================================== +// cholmod_sparse: a sparse matrix in compressed-column (CSC) form +//============================================================================== typedef struct cholmod_sparse_struct { - size_t nrow ; /* the matrix is nrow-by-ncol */ - size_t ncol ; - size_t nzmax ; /* maximum number of entries in the matrix */ - - /* pointers to int32_t or int64_t: */ - void *p ; /* p [0..ncol], the column pointers */ - void *i ; /* i [0..nzmax-1], the row indices */ - - /* for unpacked matrices only: */ - void *nz ; /* nz [0..ncol-1], the # of nonzeros in each col. In - * packed form, the nonzero pattern of column j is in - * A->i [A->p [j] ... A->p [j+1]-1]. In unpacked form, column j is in - * A->i [A->p [j] ... A->p [j]+A->nz[j]-1] instead. In both cases, the - * numerical values (if present) are in the corresponding locations in - * the array x (or z if A->xtype is CHOLMOD_ZOMPLEX). */ - - /* pointers to double or float: */ - void *x ; /* size nzmax or 2*nzmax, if present */ - void *z ; /* size nzmax, if present */ - - int stype ; /* Describes what parts of the matrix are considered: - * - * 0: matrix is "unsymmetric": use both upper and lower triangular parts - * (the matrix may actually be symmetric in pattern and value, but - * both parts are explicitly stored and used). May be square or - * rectangular. - * >0: matrix is square and symmetric, use upper triangular part. - * Entries in the lower triangular part are ignored. - * <0: matrix is square and symmetric, use lower triangular part. - * Entries in the upper triangular part are ignored. - * - * Note that stype>0 and stype<0 are different for cholmod_sparse and - * cholmod_triplet. See the cholmod_triplet data structure for more - * details. - */ - - int itype ; /* CHOLMOD_INT: p, i, and nz are int32_t. - * CHOLMOD_INTLONG: p is int64_t, - * i and nz are int32_t. - * CHOLMOD_LONG: p, i, and nz are int64_t */ - - int xtype ; /* pattern, real, complex, or zomplex */ - int dtype ; /* x and z are double or float */ - int sorted ; /* TRUE if columns are sorted, FALSE otherwise */ - int packed ; /* TRUE if packed (nz ignored), FALSE if unpacked - * (nz is required) */ + size_t nrow ; // # of rows of the matrix + size_t ncol ; // # of colums of the matrix + size_t nzmax ; // max # of entries that can be held in the matrix + + // int32_t or int64_t arrays: + void *p ; // A->p [0..ncol], column "pointers" of the CSC matrix + void *i ; // A->i [0..nzmax-1], the row indices + + // for unpacked matrices only: + void *nz ; // A->nz [0..ncol-1], is the # of nonzeros in each col. + // This is NULL for a "packed" matrix (conventional CSC). + // For a packed matrix, the jth column is held in A->i and A->x in + // postions A->p [j] to A->p [j+1]-1, with no gaps between columns. + // For an "unpacked" matrix, there can be gaps between columns, so + // the jth columns appears in positions A-p [j] to + // A->p [j] + A->nz [j] - 1. + + // double or float arrays: + void *x ; // size nzmax or 2*nzmax, or NULL + void *z ; // size nzmax, or NULL + + int stype ; // A->stype defines what parts of the matrix is held: + // 0: the matrix is unsymmetric with both lower and upper parts stored. + // >0: the matrix is square and symmetric, with just the upper + // triangular part stored. + // <0: the matrix is square and symmetric, with just the lower + // triangular part stored. + + int itype ; // A->itype defines the integers used for A->p, A->i, and A->nz. + // if CHOLMOD_INT, these arrays are all of type int32_t. + // if CHOLMOD_LONG, these arrays are all of type int64_t. + int xtype ; // pattern, real, complex, or zomplex + int dtype ; // x and z are double or single + int sorted ; // true if columns are sorted, false otherwise + int packed ; // true if packed (A->nz ignored), false if unpacked } cholmod_sparse ; -typedef struct cholmod_descendant_score_t -{ - double score ; - int64_t d ; -} -descendantScore ; - -/* For sorting descendant supernodes with qsort */ -int cholmod_score_comp (struct cholmod_descendant_score_t *i, - struct cholmod_descendant_score_t *j) ; - -int cholmod_l_score_comp (struct cholmod_descendant_score_t *i, - struct cholmod_descendant_score_t *j) ; - -/* -------------------------------------------------------------------------- */ -/* cholmod_allocate_sparse: allocate a sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_allocate_sparse: allocate a sparse matrix +//------------------------------------------------------------------------------ cholmod_sparse *cholmod_allocate_sparse ( - /* ---- input ---- */ - size_t nrow, /* # of rows of A */ - size_t ncol, /* # of columns of A */ - size_t nzmax, /* max # of nonzeros of A */ - int sorted, /* TRUE if columns of A sorted, FALSE otherwise */ - int packed, /* TRUE if A will be packed, FALSE otherwise */ - int stype, /* stype of A */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t nzmax, // max # of entries the matrix can hold + int sorted, // true if columns are sorted + int packed, // true if A is be packed (A->nz NULL), false if unpacked + int stype, // the stype of the matrix (unsym, tril, or triu) + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_allocate_sparse (size_t, size_t, size_t, int, int, int, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_free_sparse: free a sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_free_sparse: free a sparse matrix +//------------------------------------------------------------------------------ int cholmod_free_sparse ( - /* ---- in/out --- */ - cholmod_sparse **A, /* matrix to deallocate, NULL on output */ - /* --------------- */ + cholmod_sparse **A, // handle of sparse matrix to free cholmod_common *Common ) ; - int cholmod_l_free_sparse (cholmod_sparse **, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_reallocate_sparse: change the size (# entries) of sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_reallocate_sparse: change max # of entries in a sparse matrix +//------------------------------------------------------------------------------ int cholmod_reallocate_sparse ( - /* ---- input ---- */ - size_t nznew, /* new # of entries in A */ - /* ---- in/out --- */ - cholmod_sparse *A, /* matrix to reallocate */ - /* --------------- */ + size_t nznew, // new max # of nonzeros the sparse matrix can hold + cholmod_sparse *A, // sparse matrix to reallocate cholmod_common *Common ) ; +int cholmod_l_reallocate_sparse (size_t, cholmod_sparse *, cholmod_common *) ; -int cholmod_l_reallocate_sparse ( size_t, cholmod_sparse *, cholmod_common *) ; - -/* -------------------------------------------------------------------------- */ -/* cholmod_nnz: return number of nonzeros in a sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_nnz: # of entries in a sparse matrix +//------------------------------------------------------------------------------ -int64_t cholmod_nnz +int64_t cholmod_nnz // return # of entries in the sparse matrix ( - /* ---- input ---- */ - cholmod_sparse *A, - /* --------------- */ + cholmod_sparse *A, // sparse matrix to query cholmod_common *Common ) ; - int64_t cholmod_l_nnz (cholmod_sparse *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_speye: sparse identity matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_speye: sparse identity matrix (possibly rectangular) +//------------------------------------------------------------------------------ cholmod_sparse *cholmod_speye ( - /* ---- input ---- */ - size_t nrow, /* # of rows of A */ - size_t ncol, /* # of columns of A */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_speye (size_t, size_t, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_spzeros: sparse zero matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_spzeros: sparse matrix with no entries +//------------------------------------------------------------------------------ + +// Identical to cholmod_allocate_sparse, with packed = true, sorted = true, +// and stype = 0. -cholmod_sparse *cholmod_spzeros +cholmod_sparse *cholmod_spzeros // return a sparse matrix with no entries ( - /* ---- input ---- */ - size_t nrow, /* # of rows of A */ - size_t ncol, /* # of columns of A */ - size_t nzmax, /* max # of nonzeros of A */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t nzmax, // max # of entries the matrix can hold + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_spzeros (size_t, size_t, size_t, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_transpose: transpose a sparse matrix */ -/* -------------------------------------------------------------------------- */ - -/* Return A' or A.' The "values" parameter is 0, 1, or 2 to denote the pattern - * transpose, the array transpose (A.'), and the complex conjugate transpose - * (A'). - */ +//------------------------------------------------------------------------------ +// cholmod_transpose: transpose a sparse matrix +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_transpose +cholmod_sparse *cholmod_transpose // return new sparse matrix C ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to transpose */ - int values, /* 0: pattern, 1: array transpose, 2: conj. transpose */ - /* --------------- */ + cholmod_sparse *A, // input matrix + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // <= 0: pattern (with diag) cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_transpose (cholmod_sparse *, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_transpose_unsym: transpose an unsymmetric sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_transpose_unsym: transpose an unsymmetric sparse matrix +//------------------------------------------------------------------------------ -/* Compute F = A', A (:,f)', or A (p,f)', where A is unsymmetric and F is - * already allocated. See cholmod_transpose for a simpler routine. */ +// Compute C = A', A (:,f)', or A (p,f)', where A is unsymmetric and C is +// already allocated. See cholmod_transpose for a routine with a simpler +// interface. int cholmod_transpose_unsym ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to transpose */ - int values, /* 0: pattern, 1: array transpose, 2: conj. transpose */ - int32_t *Perm, /* size nrow, if present (can be NULL) */ - int32_t *fset, /* subset of 0:(A->ncol)-1 */ - size_t fsize, /* size of fset */ - /* ---- output --- */ - cholmod_sparse *F, /* F = A', A(:,f)', or A(p,f)' */ - /* --------------- */ + cholmod_sparse *A, // input matrix + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // <= 0: pattern (with diag) + int32_t *Perm, // permutation for C=A(p,f)', or NULL + int32_t *fset, // a list of column indices in range 0:A->ncol-1 + size_t fsize, // # of entries in fset + cholmod_sparse *C, // output matrix, must be allocated on input cholmod_common *Common ) ; +int cholmod_l_transpose_unsym (cholmod_sparse *, int, int64_t *, int64_t *, + size_t, cholmod_sparse *, cholmod_common *) ; -int cholmod_l_transpose_unsym (cholmod_sparse *, int, int64_t *, - int64_t *, size_t, cholmod_sparse *, cholmod_common *) ; - -/* -------------------------------------------------------------------------- */ -/* cholmod_transpose_sym: transpose a symmetric sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_transpose_sym: symmetric permuted transpose +//------------------------------------------------------------------------------ -/* Compute F = A' or A (p,p)', where A is symmetric and F is already allocated. - * See cholmod_transpose for a simpler routine. */ +// C = A' or C = A(p,p)' where A and C are both symmetric and C is already +// allocated. See cholmod_transpose or cholmod_ptranspose for a routine with +// a simpler interface. int cholmod_transpose_sym ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to transpose */ - int values, /* 0: pattern, 1: array transpose, 2: conj. transpose */ - int32_t *Perm, /* size nrow, if present (can be NULL) */ - /* ---- output --- */ - cholmod_sparse *F, /* F = A' or A(p,p)' */ - /* --------------- */ + cholmod_sparse *A, // input matrix + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // <= 0: pattern (with diag) + int32_t *Perm, // permutation for C=A(p,p)', or NULL + cholmod_sparse *C, // output matrix, must be allocated on input cholmod_common *Common ) ; +int cholmod_l_transpose_sym (cholmod_sparse *, int, int64_t *, cholmod_sparse *, + cholmod_common *) ; -int cholmod_l_transpose_sym (cholmod_sparse *, int, int64_t *, - cholmod_sparse *, cholmod_common *) ; - -/* -------------------------------------------------------------------------- */ -/* cholmod_ptranspose: transpose a sparse matrix */ -/* -------------------------------------------------------------------------- */ - -/* Return A' or A(p,p)' if A is symmetric. Return A', A(:,f)', or A(p,f)' if - * A is unsymmetric. */ +//------------------------------------------------------------------------------ +// cholmod_ptranspose: C = A', A(:,f)', A(p,p)', or A(p,f)' +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_ptranspose +cholmod_sparse *cholmod_ptranspose // return new sparse matrix C ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to transpose */ - int values, /* 0: pattern, 1: array transpose, 2: conj. transpose */ - int32_t *Perm, /* if non-NULL, F = A(p,f) or A(p,p) */ - int32_t *fset, /* subset of 0:(A->ncol)-1 */ - size_t fsize, /* size of fset */ - /* --------------- */ + cholmod_sparse *A, // input matrix + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // <= 0: pattern (with diag) + int32_t *Perm, // permutation for C=A(p,f)', or NULL + int32_t *fset, // a list of column indices in range 0:A->ncol-1 + size_t fsize, // # of entries in fset cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_ptranspose (cholmod_sparse *, int, int64_t *, int64_t *, size_t, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_sort: sort row indices in each column of sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_sort: sort the indices of a sparse matrix +//------------------------------------------------------------------------------ int cholmod_sort ( - /* ---- in/out --- */ - cholmod_sparse *A, /* matrix to sort */ - /* --------------- */ + cholmod_sparse *A, // input/output matrix to sort cholmod_common *Common ) ; - int cholmod_l_sort (cholmod_sparse *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_band: C = tril (triu (A,k1), k2) */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_band_nnz: # of entries within a band of a sparse matrix +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_band +int64_t cholmod_band_nnz // return # of entries in a band (-1 if error) ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to extract band matrix from */ - int64_t k1, /* ignore entries below the k1-st diagonal */ - int64_t k2, /* ignore entries above the k2-nd diagonal */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ - /* --------------- */ + cholmod_sparse *A, // matrix to examine + int64_t k1, // count entries in k1:k2 diagonals + int64_t k2, + bool ignore_diag, // if true, exclude any diagonal entries cholmod_common *Common ) ; +int64_t cholmod_l_band_nnz (cholmod_sparse *, int64_t, int64_t, bool, + cholmod_common *) ; -cholmod_sparse *cholmod_l_band (cholmod_sparse *, int64_t, - int64_t, int, cholmod_common *) ; +//------------------------------------------------------------------------------ +// cholmod_band: C = tril (triu (A,k1), k2) +//------------------------------------------------------------------------------ -/* -------------------------------------------------------------------------- */ -/* cholmod_band_inplace: A = tril (triu (A,k1), k2) */ -/* -------------------------------------------------------------------------- */ +cholmod_sparse *cholmod_band // return a new matrix C +( + cholmod_sparse *A, // input matrix + int64_t k1, // count entries in k1:k2 diagonals + int64_t k2, + int mode, // >0: numerical, 0: pattern, <0: pattern (no diag) + cholmod_common *Common +) ; +cholmod_sparse *cholmod_l_band (cholmod_sparse *, int64_t, int64_t, int, + cholmod_common *) ; + +//------------------------------------------------------------------------------ +// cholmod_band_inplace: A = tril (triu (A,k1), k2) */ +//------------------------------------------------------------------------------ int cholmod_band_inplace ( - /* ---- input ---- */ - int64_t k1, /* ignore entries below the k1-st diagonal */ - int64_t k2, /* ignore entries above the k2-nd diagonal */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ - /* ---- in/out --- */ - cholmod_sparse *A, /* matrix from which entries not in band are removed */ - /* --------------- */ + int64_t k1, // count entries in k1:k2 diagonals + int64_t k2, + int mode, // >0: numerical, 0: pattern, <0: pattern (no diag) + cholmod_sparse *A, // input/output matrix cholmod_common *Common ) ; +int cholmod_l_band_inplace (int64_t, int64_t, int, cholmod_sparse *, + cholmod_common *) ; -int cholmod_l_band_inplace (int64_t, int64_t, int, - cholmod_sparse *, cholmod_common *) ; - -/* -------------------------------------------------------------------------- */ -/* cholmod_aat: C = A*A' or A(:,f)*A(:,f)' */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_aat: C = A*A' or A(:,f)*A(:,f)' +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_aat +cholmod_sparse *cholmod_aat // return sparse matrix C ( - /* ---- input ---- */ - cholmod_sparse *A, /* input matrix; C=A*A' is constructed */ - int32_t *fset, /* subset of 0:(A->ncol)-1 */ - size_t fsize, /* size of fset */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag), - * -2: pattern only, no diagonal, add 50%+n extra - * space to C */ - /* --------------- */ + cholmod_sparse *A, // input matrix + int32_t *fset, // a list of column indices in range 0:A->ncol-1 + size_t fsize, // # of entries in fset + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // 0: pattern (with diag), -1: pattern (remove diag), + // -2: pattern (remove diag; add ~50% extra space in C) cholmod_common *Common ) ; +cholmod_sparse *cholmod_l_aat (cholmod_sparse *, int64_t *, size_t, int, + cholmod_common *) ; -cholmod_sparse *cholmod_l_aat (cholmod_sparse *, int64_t *, size_t, - int, cholmod_common *) ; +//------------------------------------------------------------------------------ +// cholmod_copy_sparse: C = A, create an exact copy of a sparse matrix +//------------------------------------------------------------------------------ -/* -------------------------------------------------------------------------- */ -/* cholmod_copy_sparse: C = A, create an exact copy of a sparse matrix */ -/* -------------------------------------------------------------------------- */ +// Creates an exact copy of a sparse matrix. For making a copy with a change +// of stype and/or copying the pattern of a numerical matrix, see cholmod_copy. +// For changing the xtype and/or dtype, see cholmod_sparse_xtype. -cholmod_sparse *cholmod_copy_sparse +cholmod_sparse *cholmod_copy_sparse // return new sparse matrix ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ - /* --------------- */ + cholmod_sparse *A, // sparse matrix to copy cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_copy_sparse (cholmod_sparse *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_copy: C = A, with possible change of stype */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_copy: C = A, with possible change of stype +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_copy +cholmod_sparse *cholmod_copy // return new sparse matrix ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ - int stype, /* requested stype of C */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ - /* --------------- */ + cholmod_sparse *A, // input matrix, not modified + int stype, // stype of C + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // 0: pattern (with diag), -1: pattern (remove diag), + // -2: pattern (remove diag; add ~50% extra space in C) cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_copy (cholmod_sparse *, int, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_add: C = alpha*A + beta*B */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_add: C = alpha*A + beta*B +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_add +cholmod_sparse *cholmod_add // return C = alpha*A + beta*B ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to add */ - cholmod_sparse *B, /* matrix to add */ - double alpha [2], /* scale factor for A */ - double beta [2], /* scale factor for B */ - int values, /* if TRUE compute the numerical values of C */ - int sorted, /* if TRUE, sort columns of C */ - /* --------------- */ + cholmod_sparse *A, // input matrix + cholmod_sparse *B, // input matrix + double alpha [2], // scale factor for A (two entires used if complex) + double beta [2], // scale factor for A (two entires used if complex) + int values, // if TRUE compute the numerical values of C + int sorted, // ignored; C is now always returned as sorted cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_add (cholmod_sparse *, cholmod_sparse *, double *, double *, int, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_sparse_xtype: change the xtype of a sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_sparse_xtype: change the xtype and/or dtype of a sparse matrix +//------------------------------------------------------------------------------ int cholmod_sparse_xtype ( - /* ---- input ---- */ - int to_xtype, /* requested xtype (pattern, real, complex, zomplex) */ - /* ---- in/out --- */ - cholmod_sparse *A, /* sparse matrix to change */ - /* --------------- */ + int to_xdtype, // requested xtype and dtype + cholmod_sparse *A, // sparse matrix to change cholmod_common *Common ) ; - int cholmod_l_sparse_xtype (int, cholmod_sparse *, cholmod_common *) ; - -/* ========================================================================== */ -/* === Core/cholmod_factor ================================================== */ -/* ========================================================================== */ - -/* A symbolic and numeric factorization, either simplicial or supernodal. - * In all cases, the row indices in the columns of L are kept sorted. */ +//============================================================================== +// cholmod_factor: symbolic or numeric factorization (simplicial or supernodal) +//============================================================================== typedef struct cholmod_factor_struct { - /* ---------------------------------------------------------------------- */ - /* for both simplicial and supernodal factorizations */ - /* ---------------------------------------------------------------------- */ - - size_t n ; /* L is n-by-n */ - - size_t minor ; /* If the factorization failed, L->minor is the column - * at which it failed (in the range 0 to n-1). A value - * of n means the factorization was successful or - * the matrix has not yet been factorized. */ - - /* ---------------------------------------------------------------------- */ - /* symbolic ordering and analysis */ - /* ---------------------------------------------------------------------- */ - - void *Perm ; /* size n, permutation used */ - void *ColCount ; /* size n, column counts for simplicial L */ - - void *IPerm ; /* size n, inverse permutation. Only created by - * cholmod_solve2 if Bset is used. */ - - /* ---------------------------------------------------------------------- */ - /* simplicial factorization */ - /* ---------------------------------------------------------------------- */ - - size_t nzmax ; /* size of i and x */ - - void *p ; /* p [0..ncol], the column pointers */ - void *i ; /* i [0..nzmax-1], the row indices */ - void *x ; /* x [0..nzmax-1], the numerical values */ - void *z ; - void *nz ; /* nz [0..ncol-1], the # of nonzeros in each column. - * i [p [j] ... p [j]+nz[j]-1] contains the row indices, - * and the numerical values are in the same locatins - * in x. The value of i [p [k]] is always k. */ - - void *next ; /* size ncol+2. next [j] is the next column in i/x */ - void *prev ; /* size ncol+2. prev [j] is the prior column in i/x. - * head of the list is ncol+1, and the tail is ncol. */ - - /* ---------------------------------------------------------------------- */ - /* supernodal factorization */ - /* ---------------------------------------------------------------------- */ - - /* Note that L->x is shared with the simplicial data structure. L->x has - * size L->nzmax for a simplicial factor, and size L->xsize for a supernodal - * factor. */ - - size_t nsuper ; /* number of supernodes */ - size_t ssize ; /* size of s, integer part of supernodes */ - size_t xsize ; /* size of x, real part of supernodes */ - size_t maxcsize ; /* size of largest update matrix */ - size_t maxesize ; /* max # of rows in supernodes, excl. triangular part */ - - void *super ; /* size nsuper+1, first col in each supernode */ - void *pi ; /* size nsuper+1, pointers to integer patterns */ - void *px ; /* size nsuper+1, pointers to real parts */ - void *s ; /* size ssize, integer part of supernodes */ - - /* ---------------------------------------------------------------------- */ - /* factorization type */ - /* ---------------------------------------------------------------------- */ - - int ordering ; /* ordering method used */ - - int is_ll ; /* TRUE if LL', FALSE if LDL' */ - int is_super ; /* TRUE if supernodal, FALSE if simplicial */ - int is_monotonic ; /* TRUE if columns of L appear in order 0..n-1. - * Only applicable to simplicial numeric types. */ - - /* There are 8 types of factor objects that cholmod_factor can represent - * (only 6 are used): - * - * Numeric types (xtype is not CHOLMOD_PATTERN) - * -------------------------------------------- - * - * simplicial LDL': (is_ll FALSE, is_super FALSE). Stored in compressed - * column form, using the simplicial components above (nzmax, p, i, - * x, z, nz, next, and prev). The unit diagonal of L is not stored, - * and D is stored in its place. There are no supernodes. - * - * simplicial LL': (is_ll TRUE, is_super FALSE). Uses the same storage - * scheme as the simplicial LDL', except that D does not appear. - * The first entry of each column of L is the diagonal entry of - * that column of L. - * - * supernodal LDL': (is_ll FALSE, is_super TRUE). Not used. - * FUTURE WORK: add support for supernodal LDL' - * - * supernodal LL': (is_ll TRUE, is_super TRUE). A supernodal factor, - * using the supernodal components described above (nsuper, ssize, - * xsize, maxcsize, maxesize, super, pi, px, s, x, and z). - * - * - * Symbolic types (xtype is CHOLMOD_PATTERN) - * ----------------------------------------- - * - * simplicial LDL': (is_ll FALSE, is_super FALSE). Nothing is present - * except Perm and ColCount. - * - * simplicial LL': (is_ll TRUE, is_super FALSE). Identical to the - * simplicial LDL', except for the is_ll flag. - * - * supernodal LDL': (is_ll FALSE, is_super TRUE). Not used. - * FUTURE WORK: add support for supernodal LDL' - * - * supernodal LL': (is_ll TRUE, is_super TRUE). A supernodal symbolic - * factorization. The simplicial symbolic information is present - * (Perm and ColCount), as is all of the supernodal factorization - * except for the numerical values (x and z). - */ - - int itype ; /* The integer arrays are Perm, ColCount, p, i, nz, - * next, prev, super, pi, px, and s. If itype is - * CHOLMOD_INT, all of these are int arrays. - * CHOLMOD_INTLONG: p, pi, px are int64_t, others int. - * CHOLMOD_LONG: all integer arrays are int64_t. */ - int xtype ; /* pattern, real, complex, or zomplex */ - int dtype ; /* x and z double or float */ - - int useGPU; /* Indicates the symbolic factorization supports - * GPU acceleration */ + size_t n ; // L is n-by-n + + size_t minor ; // If the factorization failed because of numerical issues + // (the matrix being factorized is found to be singular or not positive + // definte), then L->minor is the column at which it failed. L->minor + // = n means the factorization was successful. + + //-------------------------------------------------------------------------- + // symbolic ordering and analysis + //-------------------------------------------------------------------------- + + void *Perm ; // int32/int64, size n, fill-reducing ordering + void *ColCount ;// int32/int64, size n, # entries in each column of L + void *IPerm ; // int32/int64, size n, created by cholmod_solve2; + // containing the inverse of L->Perm + + //-------------------------------------------------------------------------- + // simplicial factorization (not supernodal) + //-------------------------------------------------------------------------- + + size_t nzmax ; // # of entries that L->i, L->x, and L->z can hold + + void *p ; // int32/int64, size n+1, column pointers + void *i ; // int32/int64, size nzmax, row indices + void *x ; // float/double, size nzmax or 2*nzmax, numerical values + void *z ; // float/double, size nzmax or empty, imaginary values + void *nz ; // int32/int64, size ncol, # of entries in each column + + // The row indices of L(:,j) are held in + // L->i [L->p [j] ... L->p [j] + L->nz [j] - 1]. + + // The numeical values of L(:,j) are held in the same positions in L->x + // (and L->z if L is zomplex) + + // L->next and L->prev hold a link list of columns of L, that tracks the + // order they appear in the arrays L->i, L->x, and L->z. The head and tail + // of the list is n+1 and n, respectively. + + void *next ; // int32/int64, size n+2 + void *prev ; // int32/int64, size n+2 + + //-------------------------------------------------------------------------- + // supernodal factorization (not simplicial) + //-------------------------------------------------------------------------- + + // L->x is shared with the simplicial structure above. L->z is not used + // for the supernodal case since a supernodal factor cannot be zomplex. + + size_t nsuper ; // # of supernodes + size_t ssize ; // # of integers in L->s + size_t xsize ; // # of entries in L->x + size_t maxcsize ; // size of largest update matrix + size_t maxesize ; // max # of rows in supernodes, excl. triangular part + + // the following are int32/int64 and are size nsuper+1: + void *super ; // first column in each supernode + void *pi ; // index into L->s for integer part of a supernode + void *px ; // index into L->x for numeric part of a supernode + + void *s ; // int32/int64, ssize, integer part of supernodes + + //-------------------------------------------------------------------------- + // type of the factorization + //-------------------------------------------------------------------------- + + int ordering ; // the fill-reducing method used (CHOLMOD_NATURAL, + // CHOLMOD_GIVEN, CHOLMOD_AMD, CHOLMOD_METIS, CHOLMOD_NESDIS, + // CHOLMOD_COLAMD, or CHOLMOD_POSTORDERED). + + int is_ll ; // true: an LL' factorization; false: LDL' instead + int is_super ; // true: supernodal; false: simplicial + int is_monotonic ; // true: columns appear in order 0 to n-1 in L, for a + // simplicial factorization only + + // Two boolean values above (is_ll, is_super) and L->xtype (pattern or + // otherwise, define eight types of factorizations, but only 6 are used: + + // If L->xtype is CHOLMOD_PATTERN, then L is a symbolic factor: + // + // simplicial LDL': (is_ll false, is_super false). Nothing is present + // except Perm and ColCount. + // + // simplicial LL': (is_ll true, is_super false). Identical to the + // simplicial LDL', except for the is_ll flag. + // + // supernodal LL': (is_ll true, is_super true). A supernodal symbolic + // factorization. The simplicial symbolic information is present + // (Perm and ColCount), as is all of the supernodal factorization + // except for the numerical values (x and z). + // + // If L->xtype is CHOLMOD_REAL, CHOLMOD_COMPLEX, or CHOLMOD_ZOMPLEX, + // then L is a numeric factor: + // + // + // simplicial LDL': (is_ll false, is_super false). Stored in compressed + // column form, using the simplicial components above (nzmax, p, i, + // x, z, nz, next, and prev). The unit diagonal of L is not stored, + // and D is stored in its place. There are no supernodes. + // + // simplicial LL': (is_ll true, is_super false). Uses the same storage + // scheme as the simplicial LDL', except that D does not appear. + // The first entry of each column of L is the diagonal entry of + // that column of L. + // + // supernodal LL': (is_ll true, is_super true). A supernodal factor, + // using the supernodal components described above (nsuper, ssize, + // xsize, maxcsize, maxesize, super, pi, px, s, x, and z). + // A supernodal factorization is never zomplex. + + int itype ; // integer type for L->Perm, L->ColCount, L->p, L->i, L->nz, + // L->next, L->prev, L->super, L->pi, L->px, and L->s. + // These are all int32 if L->itype is CHOLMOD_INT, or all int64 + // if L->itype is CHOLMOD_LONG. + + int xtype ; // pattern, real, complex, or zomplex + int dtype ; // x and z are double or single + + int useGPU; // if true, symbolic factorization allows for use of the GPU } cholmod_factor ; +//------------------------------------------------------------------------------ +// cholmod_allocate_factor: allocate a numerical factor +//------------------------------------------------------------------------------ -/* -------------------------------------------------------------------------- */ -/* cholmod_allocate_factor: allocate a factor (symbolic LL' or LDL') */ -/* -------------------------------------------------------------------------- */ +// L is returned as double precision -cholmod_factor *cholmod_allocate_factor +cholmod_factor *cholmod_allocate_factor // return the new factor L ( - /* ---- input ---- */ - size_t n, /* L is n-by-n */ - /* --------------- */ + size_t n, // L is factorization of an n-by-n matrix cholmod_common *Common ) ; - cholmod_factor *cholmod_l_allocate_factor (size_t, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_free_factor: free a factor */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_alloc_factor: allocate a numerical factor (double or single) +//------------------------------------------------------------------------------ -int cholmod_free_factor +cholmod_factor *cholmod_alloc_factor // return the new factor L ( - /* ---- in/out --- */ - cholmod_factor **L, /* factor to free, NULL on output */ - /* --------------- */ + size_t n, // L is factorization of an n-by-n matrix + int dtype, // CHOLMOD_SINGLE or CHOLMOD_DOUBLE cholmod_common *Common ) ; +cholmod_factor *cholmod_l_alloc_factor (size_t, int, cholmod_common *) ; + +//------------------------------------------------------------------------------ +// cholmod_free_factor: free a factor +//------------------------------------------------------------------------------ +int cholmod_free_factor +( + cholmod_factor **L, // handle of sparse factorization to free + cholmod_common *Common +) ; int cholmod_l_free_factor (cholmod_factor **, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_reallocate_factor: change the # entries in a factor */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_reallocate_factor: change the # entries in a factor +//------------------------------------------------------------------------------ int cholmod_reallocate_factor ( - /* ---- input ---- */ - size_t nznew, /* new # of entries in L */ - /* ---- in/out --- */ - cholmod_factor *L, /* factor to modify */ - /* --------------- */ + size_t nznew, // new max # of nonzeros the factor matrix can hold + cholmod_factor *L, // factor to reallocate cholmod_common *Common ) ; - int cholmod_l_reallocate_factor (size_t, cholmod_factor *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_change_factor: change the type of factor (e.g., LDL' to LL') */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_change_factor: change the type of factor (e.g., LDL' to LL') +//------------------------------------------------------------------------------ int cholmod_change_factor ( - /* ---- input ---- */ - int to_xtype, /* to CHOLMOD_PATTERN, _REAL, _COMPLEX, _ZOMPLEX */ - int to_ll, /* TRUE: convert to LL', FALSE: LDL' */ - int to_super, /* TRUE: convert to supernodal, FALSE: simplicial */ - int to_packed, /* TRUE: pack simplicial columns, FALSE: do not pack */ - int to_monotonic, /* TRUE: put simplicial columns in order, FALSE: not */ - /* ---- in/out --- */ - cholmod_factor *L, /* factor to modify */ - /* --------------- */ + int to_xtype, // CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX + int to_ll, // if true: convert to LL'; else to LDL' + int to_super, // if true: convert to supernodal; else to simplicial + int to_packed, // if true: pack simplicial columns' else: do not pack + int to_monotonic, // if true, put simplicial columns in order + cholmod_factor *L, // factor to change. cholmod_common *Common ) ; - -int cholmod_l_change_factor ( int, int, int, int, int, cholmod_factor *, +int cholmod_l_change_factor (int, int, int, int, int, cholmod_factor *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_pack_factor: pack the columns of a factor */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_pack_factor: pack a factor +//------------------------------------------------------------------------------ -/* Pack the columns of a simplicial factor. Unlike cholmod_change_factor, - * it can pack the columns of a factor even if they are not stored in their - * natural order (non-monotonic). */ +// Removes all slack space from all columns in a factor. int cholmod_pack_factor ( - /* ---- in/out --- */ - cholmod_factor *L, /* factor to modify */ - /* --------------- */ + cholmod_factor *L, // factor to pack cholmod_common *Common ) ; - int cholmod_l_pack_factor (cholmod_factor *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_reallocate_column: resize a single column of a factor */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_reallocate_column: reallocate a single column L(:,j) +//------------------------------------------------------------------------------ int cholmod_reallocate_column ( - /* ---- input ---- */ - size_t j, /* the column to reallocate */ - size_t need, /* required size of column j */ - /* ---- in/out --- */ - cholmod_factor *L, /* factor to modify */ - /* --------------- */ + size_t j, // reallocate L(:,j) + size_t need, // space in L(:,j) for this # of entries + cholmod_factor *L, // L factor modified, L(:,j) resized cholmod_common *Common ) ; - int cholmod_l_reallocate_column (size_t, size_t, cholmod_factor *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_factor_to_sparse: create a sparse matrix copy of a factor */ -/* -------------------------------------------------------------------------- */ - -/* Only operates on numeric factors, not symbolic ones */ +//------------------------------------------------------------------------------ +// cholmod_factor_to_sparse: create a sparse matrix copy of a factor +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_factor_to_sparse +cholmod_sparse *cholmod_factor_to_sparse // return a new sparse matrix ( - /* ---- in/out --- */ - cholmod_factor *L, /* factor to copy, converted to symbolic on output */ - /* --------------- */ + cholmod_factor *L, // input: factor to convert; output: L is converted + // to a simplicial symbolic factor cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_factor_to_sparse (cholmod_factor *, - cholmod_common *) ; + cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_copy_factor: create a copy of a factor */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_copy_factor: create a copy of a factor +//------------------------------------------------------------------------------ -cholmod_factor *cholmod_copy_factor +cholmod_factor *cholmod_copy_factor // return a copy of the factor ( - /* ---- input ---- */ - cholmod_factor *L, /* factor to copy */ - /* --------------- */ + cholmod_factor *L, // factor to copy (not modified) cholmod_common *Common ) ; - cholmod_factor *cholmod_l_copy_factor (cholmod_factor *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_factor_xtype: change the xtype of a factor */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_factor_xtype: change the xtype and/or dtype of a factor +//------------------------------------------------------------------------------ int cholmod_factor_xtype ( - /* ---- input ---- */ - int to_xtype, /* requested xtype (real, complex, or zomplex) */ - /* ---- in/out --- */ - cholmod_factor *L, /* factor to change */ - /* --------------- */ + int to_xdtype, // requested xtype and dtype + cholmod_factor *L, // factor to change cholmod_common *Common ) ; - int cholmod_l_factor_xtype (int, cholmod_factor *, cholmod_common *) ; - -/* ========================================================================== */ -/* === Core/cholmod_dense =================================================== */ -/* ========================================================================== */ - -/* A dense matrix in column-oriented form. It has no itype since it contains - * no integers. Entry in row i and column j is located in x [i+j*d]. - */ +//============================================================================== +// cholmod_dense: a dense matrix, held by column +//============================================================================== typedef struct cholmod_dense_struct { - size_t nrow ; /* the matrix is nrow-by-ncol */ + size_t nrow ; // the matrix is nrow-by-ncol size_t ncol ; - size_t nzmax ; /* maximum number of entries in the matrix */ - size_t d ; /* leading dimension (d >= nrow must hold) */ - void *x ; /* size nzmax or 2*nzmax, if present */ - void *z ; /* size nzmax, if present */ - int xtype ; /* pattern, real, complex, or zomplex */ - int dtype ; /* x and z double or float */ + size_t nzmax ; // maximum number of entries in the matrix + size_t d ; // leading dimension (d >= nrow must hold) + void *x ; // size nzmax or 2*nzmax, if present + void *z ; // size nzmax, if present + int xtype ; // pattern, real, complex, or zomplex + int dtype ; // x and z double or single } cholmod_dense ; -/* -------------------------------------------------------------------------- */ -/* cholmod_allocate_dense: allocate a dense matrix (contents uninitialized) */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_allocate_dense: allocate a dense matrix (contents not initialized) +//------------------------------------------------------------------------------ cholmod_dense *cholmod_allocate_dense ( - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - size_t d, /* leading dimension */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t d, // leading dimension + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_dense *cholmod_l_allocate_dense (size_t, size_t, size_t, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_zeros: allocate a dense matrix and set it to zero */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_zeros: allocate a dense matrix and set it to zero +//------------------------------------------------------------------------------ cholmod_dense *cholmod_zeros ( - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_dense *cholmod_l_zeros (size_t, size_t, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_ones: allocate a dense matrix and set it to all ones */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_ones: allocate a dense matrix of all 1's +//------------------------------------------------------------------------------ cholmod_dense *cholmod_ones ( - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (_REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_dense *cholmod_l_ones (size_t, size_t, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_eye: allocate a dense matrix and set it to the identity matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_eye: allocate a dense identity matrix +//------------------------------------------------------------------------------ -cholmod_dense *cholmod_eye +cholmod_dense *cholmod_eye // return a dense identity matrix ( - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (_REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_dense *cholmod_l_eye (size_t, size_t, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_free_dense: free a dense matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_free_dense: free a dense matrix +//------------------------------------------------------------------------------ int cholmod_free_dense ( - /* ---- in/out --- */ - cholmod_dense **X, /* dense matrix to deallocate, NULL on output */ - /* --------------- */ + cholmod_dense **X, // handle of dense matrix to free cholmod_common *Common ) ; - int cholmod_l_free_dense (cholmod_dense **, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_ensure_dense: ensure a dense matrix has a given size and type */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_ensure_dense: ensure a dense matrix has a given size and type +//------------------------------------------------------------------------------ cholmod_dense *cholmod_ensure_dense ( - /* ---- input/output ---- */ - cholmod_dense **XHandle, /* matrix handle to check */ - /* ---- input ---- */ - size_t nrow, /* # of rows of matrix */ - size_t ncol, /* # of columns of matrix */ - size_t d, /* leading dimension */ - int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + cholmod_dense **X, // matrix to resize as needed (*X may be NULL) + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t d, // leading dimension + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; +cholmod_dense *cholmod_l_ensure_dense (cholmod_dense **, size_t, size_t, + size_t, int, cholmod_common *) ; -cholmod_dense *cholmod_l_ensure_dense (cholmod_dense **, size_t, size_t, size_t, - int, cholmod_common *) ; - -/* -------------------------------------------------------------------------- */ -/* cholmod_sparse_to_dense: create a dense matrix copy of a sparse matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_sparse_to_dense: create a dense matrix copy of a sparse matrix +//------------------------------------------------------------------------------ -cholmod_dense *cholmod_sparse_to_dense +cholmod_dense *cholmod_sparse_to_dense // return a dense matrix ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ - /* --------------- */ + cholmod_sparse *A, // input matrix cholmod_common *Common ) ; +cholmod_dense *cholmod_l_sparse_to_dense (cholmod_sparse *, cholmod_common *) ; -cholmod_dense *cholmod_l_sparse_to_dense (cholmod_sparse *, - cholmod_common *) ; - -/* -------------------------------------------------------------------------- */ -/* cholmod_dense_to_sparse: create a sparse matrix copy of a dense matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_dense_nnz: count # of nonzeros in a dense matrix +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_dense_to_sparse +int64_t cholmod_dense_nnz // return # of entries in the dense matrix ( - /* ---- input ---- */ - cholmod_dense *X, /* matrix to copy */ - int values, /* TRUE if values to be copied, FALSE otherwise */ - /* --------------- */ + cholmod_dense *X, // input matrix cholmod_common *Common ) ; +int64_t cholmod_l_dense_nnz (cholmod_dense *, cholmod_common *) ; + +//------------------------------------------------------------------------------ +// cholmod_dense_to_sparse: create a sparse matrix copy of a dense matrix +//------------------------------------------------------------------------------ +cholmod_sparse *cholmod_dense_to_sparse // return a sparse matrix C +( + cholmod_dense *X, // input matrix + int values, // if true, copy the values; if false, C is pattern + cholmod_common *Common +) ; cholmod_sparse *cholmod_l_dense_to_sparse (cholmod_dense *, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_copy_dense: create a copy of a dense matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_copy_dense: create a copy of a dense matrix +//------------------------------------------------------------------------------ -cholmod_dense *cholmod_copy_dense +cholmod_dense *cholmod_copy_dense // returns new dense matrix ( - /* ---- input ---- */ - cholmod_dense *X, /* matrix to copy */ - /* --------------- */ + cholmod_dense *X, // input dense matrix cholmod_common *Common ) ; - cholmod_dense *cholmod_l_copy_dense (cholmod_dense *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_copy_dense2: copy a dense matrix (pre-allocated) */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_copy_dense2: copy a dense matrix (pre-allocated) +//------------------------------------------------------------------------------ int cholmod_copy_dense2 ( - /* ---- input ---- */ - cholmod_dense *X, /* matrix to copy */ - /* ---- output --- */ - cholmod_dense *Y, /* copy of matrix X */ - /* --------------- */ + cholmod_dense *X, // input dense matrix + cholmod_dense *Y, // output dense matrix (already allocated on input) cholmod_common *Common ) ; - int cholmod_l_copy_dense2 (cholmod_dense *, cholmod_dense *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_dense_xtype: change the xtype of a dense matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_dense_xtype: change the xtype and/or dtype of a dense matrix +//------------------------------------------------------------------------------ int cholmod_dense_xtype ( - /* ---- input ---- */ - int to_xtype, /* requested xtype (real, complex,or zomplex) */ - /* ---- in/out --- */ - cholmod_dense *X, /* dense matrix to change */ - /* --------------- */ + int to_xdtype, // requested xtype and dtype + cholmod_dense *X, // dense matrix to change cholmod_common *Common ) ; - int cholmod_l_dense_xtype (int, cholmod_dense *, cholmod_common *) ; - -/* ========================================================================== */ -/* === Core/cholmod_triplet ================================================= */ -/* ========================================================================== */ - -/* A sparse matrix stored in triplet form. */ +//============================================================================= +// cholmod_triplet: a sparse matrix in triplet form +//============================================================================= typedef struct cholmod_triplet_struct { - size_t nrow ; /* the matrix is nrow-by-ncol */ - size_t ncol ; - size_t nzmax ; /* maximum number of entries in the matrix */ - size_t nnz ; /* number of nonzeros in the matrix */ - - void *i ; /* i [0..nzmax-1], the row indices */ - void *j ; /* j [0..nzmax-1], the column indices */ - void *x ; /* size nzmax or 2*nzmax, if present */ - void *z ; /* size nzmax, if present */ - - int stype ; /* Describes what parts of the matrix are considered: - * - * 0: matrix is "unsymmetric": use both upper and lower triangular parts - * (the matrix may actually be symmetric in pattern and value, but - * both parts are explicitly stored and used). May be square or - * rectangular. - * >0: matrix is square and symmetric. Entries in the lower triangular - * part are transposed and added to the upper triangular part when - * the matrix is converted to cholmod_sparse form. - * <0: matrix is square and symmetric. Entries in the upper triangular - * part are transposed and added to the lower triangular part when - * the matrix is converted to cholmod_sparse form. - * - * Note that stype>0 and stype<0 are different for cholmod_sparse and - * cholmod_triplet. The reason is simple. You can permute a symmetric - * triplet matrix by simply replacing a row and column index with their - * new row and column indices, via an inverse permutation. Suppose - * P = L->Perm is your permutation, and Pinv is an array of size n. - * Suppose a symmetric matrix A is represent by a triplet matrix T, with - * entries only in the upper triangular part. Then the following code: - * - * Ti = T->i ; - * Tj = T->j ; - * for (k = 0 ; k < n ; k++) Pinv [P [k]] = k ; - * for (k = 0 ; k < nz ; k++) Ti [k] = Pinv [Ti [k]] ; - * for (k = 0 ; k < nz ; k++) Tj [k] = Pinv [Tj [k]] ; - * - * creates the triplet form of C=P*A*P'. However, if T initially - * contains just the upper triangular entries (T->stype = 1), after - * permutation it has entries in both the upper and lower triangular - * parts. These entries should be transposed when constructing the - * cholmod_sparse form of A, which is what cholmod_triplet_to_sparse - * does. Thus: - * - * C = cholmod_triplet_to_sparse (T, 0, &Common) ; - * - * will return the matrix C = P*A*P'. - * - * Since the triplet matrix T is so simple to generate, it's quite easy - * to remove entries that you do not want, prior to converting T to the - * cholmod_sparse form. So if you include these entries in T, CHOLMOD - * assumes that there must be a reason (such as the one above). Thus, - * no entry in a triplet matrix is ever ignored. - */ - - int itype ; /* CHOLMOD_LONG: i and j are int64_t. Otherwise int */ - int xtype ; /* pattern, real, complex, or zomplex */ - int dtype ; /* x and z are double or float */ + size_t nrow ; // # of rows of the matrix + size_t ncol ; // # of colums of the matrix + size_t nzmax ; // max # of entries that can be held in the matrix + size_t nnz ; // current # of entries can be held in the matrix + + // int32 or int64 arrays (depending on T->itype) + void *i ; // i [0..nzmax-1], the row indices + void *j ; // j [0..nzmax-1], the column indices + + // double or float arrays: + void *x ; // size nzmax or 2*nzmax, or NULL + void *z ; // size nzmax, or NULL + + int stype ; // T->stype defines what parts of the matrix is held: + // 0: the matrix is unsymmetric with both lower and upper parts stored. + // >0: the matrix is square and symmetric, where entries in the lower + // triangular part are transposed and placed in the upper + // triangular part of A if T is converted into a sparse matrix A. + // <0: the matrix is square and symmetric, where entries in the upper + // triangular part are transposed and placed in the lower + // triangular part of A if T is converted into a sparse matrix A. + // + // Note that A->stype (for a sparse matrix) and T->stype (for a + // triplet matrix) are handled differently. In a triplet matrix T, + // no entry is ever ignored. For a sparse matrix A, if A->stype < 0 + // or A->stype > 0, then entries not in the correct triangular part + // are ignored. + + int itype ; // T->itype defines the integers used for T->i and T->j. + // if CHOLMOD_INT, these arrays are all of type int32_t. + // if CHOLMOD_LONG, these arrays are all of type int64_t. + int xtype ; // pattern, real, complex, or zomplex + int dtype ; // x and z are double or single } cholmod_triplet ; -/* -------------------------------------------------------------------------- */ -/* cholmod_allocate_triplet: allocate a triplet matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_allocate_triplet: allocate a triplet matrix +//------------------------------------------------------------------------------ -cholmod_triplet *cholmod_allocate_triplet +cholmod_triplet *cholmod_allocate_triplet // return triplet matrix T ( - /* ---- input ---- */ - size_t nrow, /* # of rows of T */ - size_t ncol, /* # of columns of T */ - size_t nzmax, /* max # of nonzeros of T */ - int stype, /* stype of T */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* --------------- */ + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t nzmax, // max # of entries the matrix can hold + int stype, // the stype of the matrix (unsym, tril, or triu) + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) cholmod_common *Common ) ; - cholmod_triplet *cholmod_l_allocate_triplet (size_t, size_t, size_t, int, int, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_free_triplet: free a triplet matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_free_triplet: free a triplet matrix +//------------------------------------------------------------------------------ int cholmod_free_triplet ( - /* ---- in/out --- */ - cholmod_triplet **T, /* triplet matrix to deallocate, NULL on output */ - /* --------------- */ + cholmod_triplet **T, // handle of triplet matrix to free cholmod_common *Common ) ; - int cholmod_l_free_triplet (cholmod_triplet **, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_reallocate_triplet: change the # of entries in a triplet matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_reallocate_triplet: change max # of entries in a triplet matrix +//------------------------------------------------------------------------------ int cholmod_reallocate_triplet ( - /* ---- input ---- */ - size_t nznew, /* new # of entries in T */ - /* ---- in/out --- */ - cholmod_triplet *T, /* triplet matrix to modify */ - /* --------------- */ + size_t nznew, // new max # of nonzeros the triplet matrix can hold + cholmod_triplet *T, // triplet matrix to reallocate cholmod_common *Common ) ; - int cholmod_l_reallocate_triplet (size_t, cholmod_triplet *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_sparse_to_triplet: create a triplet matrix copy of a sparse matrix*/ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_sparse_to_triplet: create a triplet matrix copy of a sparse matrix +//------------------------------------------------------------------------------ cholmod_triplet *cholmod_sparse_to_triplet ( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ - /* --------------- */ + cholmod_sparse *A, // matrix to copy into triplet form T cholmod_common *Common ) ; - cholmod_triplet *cholmod_l_sparse_to_triplet (cholmod_sparse *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_triplet_to_sparse: create a sparse matrix copy of a triplet matrix*/ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_triplet_to_sparse: create a sparse matrix from of triplet matrix +//------------------------------------------------------------------------------ -cholmod_sparse *cholmod_triplet_to_sparse +cholmod_sparse *cholmod_triplet_to_sparse // return sparse matrix A ( - /* ---- input ---- */ - cholmod_triplet *T, /* matrix to copy */ - size_t nzmax, /* allocate at least this much space in output matrix */ - /* --------------- */ + cholmod_triplet *T, // input triplet matrix + size_t nzmax, // allocate space for max(nzmax,nnz(A)) entries cholmod_common *Common ) ; - cholmod_sparse *cholmod_l_triplet_to_sparse (cholmod_triplet *, size_t, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_copy_triplet: create a copy of a triplet matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_copy_triplet: copy a triplet matrix +//------------------------------------------------------------------------------ -cholmod_triplet *cholmod_copy_triplet +cholmod_triplet *cholmod_copy_triplet // return new triplet matrix ( - /* ---- input ---- */ - cholmod_triplet *T, /* matrix to copy */ - /* --------------- */ + cholmod_triplet *T, // triplet matrix to copy cholmod_common *Common ) ; - cholmod_triplet *cholmod_l_copy_triplet (cholmod_triplet *, cholmod_common *) ; -/* -------------------------------------------------------------------------- */ -/* cholmod_triplet_xtype: change the xtype of a triplet matrix */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// cholmod_triplet_xtype: change the xtype and/or dtype of a triplet matrix +//------------------------------------------------------------------------------ int cholmod_triplet_xtype ( - /* ---- input ---- */ - int to_xtype, /* requested xtype (pattern, real, complex,or zomplex)*/ - /* ---- in/out --- */ - cholmod_triplet *T, /* triplet matrix to change */ - /* --------------- */ + int to_xdtype, // requested xtype and dtype + cholmod_triplet *T, // triplet matrix to change cholmod_common *Common ) ; - int cholmod_l_triplet_xtype (int, cholmod_triplet *, cholmod_common *) ; +//============================================================================== +// memory allocation +//============================================================================== -/* ========================================================================== */ -/* === Core/cholmod_memory ================================================== */ -/* ========================================================================== */ - -/* The user may make use of these, just like malloc and free. You can even - * malloc an object and safely free it with cholmod_free, and visa versa - * (except that the memory usage statistics will be corrupted). These routines - * do differ from malloc and free. If cholmod_free is given a NULL pointer, - * for example, it does nothing (unlike the ANSI free). cholmod_realloc does - * not return NULL if given a non-NULL pointer and a nonzero size, even if it - * fails (it returns the original pointer and sets an error code in - * Common->status instead). - * - * CHOLMOD keeps track of the amount of memory it has allocated, and so the - * cholmod_free routine also takes the size of the object being freed. This - * is only used for statistics. If you, the user of CHOLMOD, pass the wrong - * size, the only consequence is that the memory usage statistics will be - * corrupted. - */ +// These methods act like malloc/calloc/realloc/free, with some differences. +// They are simple wrappers around the memory management functions in +// SuiteSparse_config. cholmod_malloc and cholmod_calloc have the same +// signature, unlike malloc and calloc. If cholmod_free is given a NULL +// pointer, it safely does nothing. cholmod_free must be passed the size of +// the object being freed, but that is just to keep track of memory usage +// statistics. cholmod_realloc does not return NULL if it fails; instead, it +// returns the pointer to the unmodified block of memory. -void *cholmod_malloc /* returns pointer to the newly malloc'd block */ +void *cholmod_malloc // return pointer to newly allocated memory ( - /* ---- input ---- */ - size_t n, /* number of items */ - size_t size, /* size of each item */ - /* --------------- */ + size_t n, // number of items + size_t size, // size of each item cholmod_common *Common ) ; - void *cholmod_l_malloc (size_t, size_t, cholmod_common *) ; -void *cholmod_calloc /* returns pointer to the newly calloc'd block */ +void *cholmod_calloc // return pointer to newly allocated memory ( - /* ---- input ---- */ - size_t n, /* number of items */ - size_t size, /* size of each item */ - /* --------------- */ + size_t n, // number of items + size_t size, // size of each item cholmod_common *Common ) ; - void *cholmod_l_calloc (size_t, size_t, cholmod_common *) ; -void *cholmod_free /* always returns NULL */ +void *cholmod_free // returns NULL to simplify its usage ( - /* ---- input ---- */ - size_t n, /* number of items */ - size_t size, /* size of each item */ - /* ---- in/out --- */ - void *p, /* block of memory to free */ - /* --------------- */ + size_t n, // number of items + size_t size, // size of each item + void *p, // memory to free cholmod_common *Common ) ; - void *cholmod_l_free (size_t, size_t, void *, cholmod_common *) ; -void *cholmod_realloc /* returns pointer to reallocated block */ +void *cholmod_realloc // return newly reallocated block of memory ( - /* ---- input ---- */ - size_t nnew, /* requested # of items in reallocated block */ - size_t size, /* size of each item */ - /* ---- in/out --- */ - void *p, /* block of memory to realloc */ - size_t *n, /* current size on input, nnew on output if successful*/ - /* --------------- */ + size_t nnew, // # of items in newly reallocate memory + size_t size, // size of each item + void *p, // pointer to memory to reallocate (may be NULL) + size_t *n, // # of items in p on input; nnew on output if success cholmod_common *Common ) ; - void *cholmod_l_realloc (size_t, size_t, void *, size_t *, cholmod_common *) ; -int cholmod_realloc_multiple +int cholmod_realloc_multiple // returns true if successful, false otherwise ( - /* ---- input ---- */ - size_t nnew, /* requested # of items in reallocated blocks */ - int nint, /* number of int32_t/int64_t blocks */ - int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */ - /* ---- in/out --- */ - void **Iblock, /* int32_t or int64_t block */ - void **Jblock, /* int32_t or int64_t block */ - void **Xblock, /* complex, double, or float block */ - void **Zblock, /* zomplex case only: double or float block */ - size_t *n, /* current size of the I,J,X,Z blocks on input, - * nnew on output if successful */ - /* --------------- */ + size_t nnew, // # of items in newly reallocate memory + int nint, // 0: do not allocate I or J, 1: just I, 2: both I and J + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) + // input/output: + void **I, // integer block of memory (int32_t or int64_t) + void **J, // integer block of memory (int32_t or int64_t) + void **X, // real or complex, double or single, block + void **Z, // zomplex only: double or single block + size_t *n, // current size of I, J, X, and/or Z blocks on input, + // changed to nnew on output, if successful cholmod_common *Common ) ; - int cholmod_l_realloc_multiple (size_t, int, int, void **, void **, void **, void **, size_t *, cholmod_common *) ; -/* ========================================================================== */ -/* === version control ====================================================== */ -/* ========================================================================== */ - -int cholmod_version /* returns CHOLMOD_VERSION */ -( - /* output, contents not defined on input. Not used if NULL. - version [0] = CHOLMOD_MAIN_VERSION - version [1] = CHOLMOD_SUB_VERSION - version [2] = CHOLMOD_SUBSUB_VERSION - */ - int version [3] -) ; - -int cholmod_l_version (int version [3]) ; - -/* Versions prior to 2.1.1 do not have the above function. The following - code fragment will work with any version of CHOLMOD: - #ifdef CHOLMOD_HAS_VERSION_FUNCTION - v = cholmod_version (NULL) ; - #else - v = CHOLMOD_VERSION ; - #endif -*/ - -/* ========================================================================== */ -/* === symmetry types ======================================================= */ -/* ========================================================================== */ - -#define CHOLMOD_MM_RECTANGULAR 1 -#define CHOLMOD_MM_UNSYMMETRIC 2 -#define CHOLMOD_MM_SYMMETRIC 3 -#define CHOLMOD_MM_HERMITIAN 4 -#define CHOLMOD_MM_SKEW_SYMMETRIC 5 -#define CHOLMOD_MM_SYMMETRIC_POSDIAG 6 -#define CHOLMOD_MM_HERMITIAN_POSDIAG 7 +//============================================================================== +// numerical comparisons +//============================================================================== -/* ========================================================================== */ -/* === Numerical relop macros =============================================== */ -/* ========================================================================== */ - -/* These macros correctly handle the NaN case. - * - * CHOLMOD_IS_NAN(x): - * True if x is NaN. False otherwise. The commonly-existing isnan(x) - * function could be used, but it's not in Kernighan & Ritchie 2nd edition - * (ANSI C89). It may appear in , but I'm not certain about - * portability. The expression x != x is true if and only if x is NaN, - * according to the IEEE 754 floating-point standard. - * - * CHOLMOD_IS_ZERO(x): - * True if x is zero. False if x is nonzero, NaN, or +/- Inf. - * This is (x == 0) if the compiler is IEEE 754 compliant. - * - * CHOLMOD_IS_NONZERO(x): - * True if x is nonzero, NaN, or +/- Inf. False if x zero. - * This is (x != 0) if the compiler is IEEE 754 compliant. - * - * CHOLMOD_IS_LT_ZERO(x): - * True if x is < zero or -Inf. False if x is >= 0, NaN, or +Inf. - * This is (x < 0) if the compiler is IEEE 754 compliant. - * - * CHOLMOD_IS_GT_ZERO(x): - * True if x is > zero or +Inf. False if x is <= 0, NaN, or -Inf. - * This is (x > 0) if the compiler is IEEE 754 compliant. - * - * CHOLMOD_IS_LE_ZERO(x): - * True if x is <= zero or -Inf. False if x is > 0, NaN, or +Inf. - * This is (x <= 0) if the compiler is IEEE 754 compliant. - */ +// These macros were different on Windows for older versions of CHOLMOD. +// They are no longer needed but are kept for backward compatibility. -#ifdef CHOLMOD_WINDOWS - -/* Yes, this is exceedingly ugly. Blame Microsoft, which hopelessly */ -/* violates the IEEE 754 floating-point standard in a bizarre way. */ -/* If you're using an IEEE 754-compliant compiler, then x != x is true */ -/* iff x is NaN. For Microsoft, (x < x) is true iff x is NaN. */ -/* So either way, this macro safely detects a NaN. */ -#define CHOLMOD_IS_NAN(x) (((x) != (x)) || (((x) < (x)))) -#define CHOLMOD_IS_ZERO(x) (((x) == 0.) && !CHOLMOD_IS_NAN(x)) -#define CHOLMOD_IS_NONZERO(x) (((x) != 0.) || CHOLMOD_IS_NAN(x)) -#define CHOLMOD_IS_LT_ZERO(x) (((x) < 0.) && !CHOLMOD_IS_NAN(x)) -#define CHOLMOD_IS_GT_ZERO(x) (((x) > 0.) && !CHOLMOD_IS_NAN(x)) -#define CHOLMOD_IS_LE_ZERO(x) (((x) <= 0.) && !CHOLMOD_IS_NAN(x)) - -#else - -/* These all work properly, according to the IEEE 754 standard ... except on */ -/* a PC with windows. Works fine in Linux on the same PC... */ -#define CHOLMOD_IS_NAN(x) ((x) != (x)) -#define CHOLMOD_IS_ZERO(x) ((x) == 0.) -#define CHOLMOD_IS_NONZERO(x) ((x) != 0.) -#define CHOLMOD_IS_LT_ZERO(x) ((x) < 0.) -#define CHOLMOD_IS_GT_ZERO(x) ((x) > 0.) -#define CHOLMOD_IS_LE_ZERO(x) ((x) <= 0.) +#define CHOLMOD_IS_NAN(x) isnan (x) +#define CHOLMOD_IS_ZERO(x) ((x) == 0.) +#define CHOLMOD_IS_NONZERO(x) ((x) != 0.) +#define CHOLMOD_IS_LT_ZERO(x) ((x) < 0.) +#define CHOLMOD_IS_GT_ZERO(x) ((x) > 0.) +#define CHOLMOD_IS_LE_ZERO(x) ((x) <= 0.) #endif +//============================================================================== +// CHOLMOD:Check Module +//============================================================================== +#ifndef NCHECK - -/* ========================================================================== */ -/* === Include/cholmod_check.h ============================================== */ -/* ========================================================================== */ - -/* CHOLMOD Check module. - * - * Routines that check and print the 5 basic data types in CHOLMOD, and 3 kinds +/* Routines that check and print the 5 basic data types in CHOLMOD, and 3 kinds * of integer vectors (subset, perm, and parent), and read in matrices from a * file: * @@ -2684,15 +1976,13 @@ int cholmod_l_version (int version [3]) ; * cholmod_print_common and cholmod_check_common are the only two routines that * you may call after calling cholmod_finish. * - * Requires the Core module. Not required by any CHOLMOD module, except when + * Requires the Utility module. Not required by any CHOLMOD module, except when * debugging is enabled (in which case all modules require the Check module). * * See cholmod_read.c for a description of the file formats supported by the * cholmod_read_* routines. */ -#ifndef NCHECK - /* -------------------------------------------------------------------------- */ /* cholmod_check_common: check the Common object */ /* -------------------------------------------------------------------------- */ @@ -2839,7 +2129,8 @@ int cholmod_print_triplet cholmod_common *Common ) ; -int cholmod_l_print_triplet (cholmod_triplet *, const char *, cholmod_common *); +int cholmod_l_print_triplet (cholmod_triplet *, const char *, + cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_check_subset: check a subset */ @@ -2982,7 +2273,7 @@ cholmod_dense *cholmod_read_dense cholmod_common *Common ) ; -cholmod_dense *cholmod_l_read_dense (FILE *, cholmod_common *) ; +cholmod_dense *cholmod_l_read_dense (FILE *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_read_matrix: read a sparse or dense matrix from a file */ @@ -3018,7 +2309,7 @@ void *cholmod_l_read_matrix (FILE *, int, int *, cholmod_common *) ; /* cholmod_write_sparse: write a sparse matrix to a file */ /* -------------------------------------------------------------------------- */ -int cholmod_write_sparse +int cholmod_write_sparse // returns the same result as cholmod_symmetry ( /* ---- input ---- */ FILE *f, /* file to write to, must already be open */ @@ -3048,25 +2339,21 @@ int cholmod_write_dense int cholmod_l_write_dense (FILE *, cholmod_dense *, const char *, cholmod_common *) ; -#endif - - - +#endif +//============================================================================== +// CHOLMOD:Cholesky Module +//============================================================================== -/* ========================================================================== */ -/* === Include/cholmod_cholesky.h =========================================== */ -/* ========================================================================== */ +#ifndef NCHOLESKY -/* CHOLMOD Cholesky module. - * - * Sparse Cholesky routines: analysis, factorization, and solve. +/* Sparse Cholesky routines: analysis, factorization, and solve. * * The primary routines are all that a user requires to order, analyze, and * factorize a sparse symmetric positive definite matrix A (or A*A'), and * to solve Ax=b (or A*A'x=b). The primary routines rely on the secondary - * routines, the CHOLMOD Core module, and the AMD and COLAMD packages. They + * routines, the CHOLMOD Utility module, and the AMD and COLAMD packages. They * make optional use of the CHOLMOD Supernodal and Partition modules, the * METIS package, and the CCOLAMD package. * @@ -3097,13 +2384,11 @@ int cholmod_l_write_dense (FILE *, cholmod_dense *, const char *, * cholmod_resymbol_noperm recompute the symbolic pattern of L, no L->Perm * cholmod_postorder postorder a tree * - * Requires the Core module, and two packages: AMD and COLAMD. + * Requires the Utility module, and two packages: AMD and COLAMD. * Optionally uses the Supernodal and Partition modules. * Required by the Partition module. */ -#ifndef NCHOLESKY - /* -------------------------------------------------------------------------- */ /* cholmod_analyze: order and analyze (simplicial or supernodal) */ /* -------------------------------------------------------------------------- */ @@ -3111,7 +2396,7 @@ int cholmod_l_write_dense (FILE *, cholmod_dense *, const char *, /* Orders and analyzes A, AA', PAP', or PAA'P' and returns a symbolic factor * that can later be passed to cholmod_factorize. */ -cholmod_factor *cholmod_analyze +cholmod_factor *cholmod_analyze // order and analyze ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to order and analyze */ @@ -3174,7 +2459,7 @@ cholmod_factor *cholmod_l_analyze_p2 (int, cholmod_sparse *, int64_t *, * routine a second time with another matrix. A must have the same nonzero * pattern as that passed to cholmod_analyze. */ -int cholmod_factorize +int cholmod_factorize // simplicial or superodal Cholesky factorization ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to factorize */ @@ -3550,7 +2835,7 @@ int cholmod_l_row_lsubtree (cholmod_sparse *, int64_t *, size_t, * first permutes A according to L->Perm. A can be upper/lower/unsymmetric, * in contrast to cholmod_resymbol_noperm (which can be lower or unsym). */ -int cholmod_resymbol +int cholmod_resymbol // recompute symbolic pattern of L ( /* ---- input ---- */ cholmod_sparse *A, /* matrix to analyze */ @@ -3619,19 +2904,18 @@ int32_t cholmod_postorder /* return # of nodes postordered */ cholmod_common *Common ) ; -int64_t cholmod_l_postorder (int64_t *, size_t, - int64_t *, int64_t *, cholmod_common *) ; +int64_t cholmod_l_postorder (int64_t *, size_t, int64_t *, int64_t *, + cholmod_common *) ; #endif +//============================================================================== +// CHOLMOD:MatrixOps Module +//============================================================================== -/* ========================================================================== */ -/* === Include/cholmod_matrixops.h ========================================== */ -/* ========================================================================== */ +#ifndef NMATRIXOPS -/* CHOLMOD MatrixOps module. - * - * Basic operations on sparse and dense matrices. +/* Basic operations on sparse and dense matrices. * * cholmod_drop A = entries in A with abs. value >= tol * cholmod_norm_dense s = norm (X), 1-norm, inf-norm, or 2-norm @@ -3647,11 +2931,9 @@ int64_t cholmod_l_postorder (int64_t *, size_t, * X, Y: dense matrices (cholmod_dense) * s: scalar or vector * - * Requires the Core module. Not required by any other CHOLMOD module. + * Requires the Utility module. Not required by any other CHOLMOD module. */ -#ifndef NMATRIXOPS - /* -------------------------------------------------------------------------- */ /* cholmod_drop: drop entries with small absolute value */ /* -------------------------------------------------------------------------- */ @@ -3807,8 +3089,7 @@ cholmod_sparse *cholmod_submatrix ) ; cholmod_sparse *cholmod_l_submatrix (cholmod_sparse *, int64_t *, - int64_t, int64_t *, int64_t, int, int, - cholmod_common *) ; + int64_t, int64_t *, int64_t, int, int, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_vertcat: C = [A ; B] */ @@ -3845,18 +3126,16 @@ int cholmod_symmetry cholmod_common *Common ) ; -int cholmod_l_symmetry (cholmod_sparse *, int, int64_t *, - int64_t *, int64_t *, int64_t *, - cholmod_common *) ; +int cholmod_l_symmetry (cholmod_sparse *, int, int64_t *, int64_t *, int64_t *, + int64_t *, cholmod_common *) ; #endif +//============================================================================== +// CHOLMOD:Modify Module +//============================================================================== - - -/* ========================================================================== */ -/* === Include/cholmod_modify.h ============================================= */ -/* ========================================================================== */ +#ifndef NMODIFY /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_modify.h. @@ -3864,13 +3143,11 @@ int cholmod_l_symmetry (cholmod_sparse *, int, int64_t *, * http://www.suitesparse.com * -------------------------------------------------------------------------- */ -/* CHOLMOD Modify module. - * - * Sparse Cholesky modification routines: update / downdate / rowadd / rowdel. +/* Sparse Cholesky modification routines: update / downdate / rowadd / rowdel. * Can also modify a corresponding solution to Lx=b when L is modified. This * module is most useful when applied on a Cholesky factorization computed by * the Cholesky module, but it does not actually require the Cholesky module. - * The Core module can create an identity Cholesky factorization (LDL' where + * The Utility module can create an identity Cholesky factorization (LDL' where * L=D=I) that can then by modified by these routines. * * Primary routines: @@ -3892,12 +3169,9 @@ int cholmod_l_symmetry (cholmod_sparse *, int, int64_t *, * cholmod_rowdel_solve delete a row, and downdate Lx=b * cholmod_rowdel_mark delete a row, and downdate solution to partial Lx=b * - * Requires the Core module. Not required by any other CHOLMOD module. + * Requires the Utility module. Not required by any other CHOLMOD module. */ - -#ifndef NMODIFY - /* -------------------------------------------------------------------------- */ /* cholmod_updown: multiple rank update/downdate */ /* -------------------------------------------------------------------------- */ @@ -3906,7 +3180,7 @@ int cholmod_l_symmetry (cholmod_sparse *, int, int64_t *, * (a downdate). The factor object L need not be an LDL' factorization; it * is converted to one if it isn't. */ -int cholmod_updown +int cholmod_updown // update/downdate ( /* ---- input ---- */ int update, /* TRUE for update, FALSE for downdate */ @@ -3916,9 +3190,8 @@ int cholmod_updown /* --------------- */ cholmod_common *Common ) ; +int cholmod_l_updown (int, cholmod_sparse *, cholmod_factor *, cholmod_common *) ; -int cholmod_l_updown (int, cholmod_sparse *, cholmod_factor *, - cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_updown_solve: update/downdate, and modify solution to Lx=b */ @@ -4030,7 +3303,7 @@ int cholmod_l_updown_mask2 (int, cholmod_sparse *, int64_t *, * computed as the factorization of the kth row/column of the matrix to * factorize, which is provided as a single n-by-1 sparse matrix R. */ -int cholmod_rowadd +int cholmod_rowadd // add a row to an LDL' factorization ( /* ---- input ---- */ size_t k, /* row/column index to add */ @@ -4108,7 +3381,7 @@ int cholmod_l_rowadd_mark (size_t, cholmod_sparse *, double *, * a little more time. */ -int cholmod_rowdel +int cholmod_rowdel // delete a rw from an LDL' factorization ( /* ---- input ---- */ size_t k, /* row/column index to delete */ @@ -4177,11 +3450,11 @@ int cholmod_l_rowdel_mark (size_t, cholmod_sparse *, double *, #endif +//============================================================================== +// CHOLMOD:Partition Module (CAMD, CCOLAMD, and CSYMAMD) +//============================================================================== - -/* ========================================================================== */ -/* === Include/cholmod_camd.h =============================================== */ -/* ========================================================================== */ +#ifndef NCAMD /* CHOLMOD Partition module, interface to CAMD, CCOLAMD, and CSYMAMD * @@ -4195,12 +3468,10 @@ int cholmod_l_rowdel_mark (size_t, cholmod_sparse *, double *, * cholmod_csymamd interface to CSYMAMD ordering * cholmod_camd interface to CAMD ordering * - * Requires the Core and Cholesky modules, and two packages: CAMD, + * Requires the Utility and Cholesky modules, and two packages: CAMD, * and CCOLAMD. Used by functions in the Partition Module. */ -#ifndef NCAMD - /* -------------------------------------------------------------------------- */ /* cholmod_ccolamd */ /* -------------------------------------------------------------------------- */ @@ -4271,9 +3542,13 @@ int cholmod_l_camd (cholmod_sparse *, int64_t *, size_t, #endif -/* ========================================================================== */ -/* === Include/cholmod_partition.h ========================================== */ -/* ========================================================================== */ +//============================================================================== +// CHOLMOD:Partition Module (graph partition methods) +//============================================================================== + +// These routines still exist if CHOLMOD is compiled with -DNPARTITION, +// but they return Common->status = CHOLMOD_NOT_INSTALLED in that case. +#if 1 /* ----------------------------------------------------------------------------- * CHOLMOD/Include/cholmod_partition.h. @@ -4293,7 +3568,7 @@ int cholmod_l_camd (cholmod_sparse *, int64_t *, size_t, * cholmod_bisect graph partitioner (currently based on METIS) * cholmod_metis_bisector direct interface to METIS_ComputeVertexSeparator * - * Requires the Core and Cholesky modules, and three packages: METIS, CAMD, + * Requires the Utility and Cholesky modules, and three packages: METIS, CAMD, * and CCOLAMD. Optionally used by the Cholesky module. * * Note that METIS does not have a version that uses int64_t integers. If you @@ -4304,9 +3579,6 @@ int cholmod_l_camd (cholmod_sparse *, int64_t *, size_t, * idxtype. */ -// These routines still exist if CHOLMOD is compiled with -DNPARTITION, -// but they return Common->status = CHOLMOD_NOT_INSTALLED. - /* -------------------------------------------------------------------------- */ /* cholmod_nested_dissection */ /* -------------------------------------------------------------------------- */ @@ -4334,9 +3606,8 @@ int64_t cholmod_nested_dissection /* returns # of components */ cholmod_common *Common ) ; -int64_t cholmod_l_nested_dissection (cholmod_sparse *, - int64_t *, size_t, int64_t *, int64_t *, - int64_t *, cholmod_common *) ; +int64_t cholmod_l_nested_dissection (cholmod_sparse *, int64_t *, size_t, + int64_t *, int64_t *, int64_t *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_metis */ @@ -4357,8 +3628,8 @@ int cholmod_metis cholmod_common *Common ) ; -int cholmod_l_metis (cholmod_sparse *, int64_t *, size_t, int, - int64_t *, cholmod_common *) ; +int cholmod_l_metis (cholmod_sparse *, int64_t *, size_t, int, int64_t *, + cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_bisect */ @@ -4381,8 +3652,8 @@ int64_t cholmod_bisect /* returns # of nodes in separator */ cholmod_common *Common ) ; -int64_t cholmod_l_bisect (cholmod_sparse *, int64_t *, - size_t, int, int64_t *, cholmod_common *) ; +int64_t cholmod_l_bisect (cholmod_sparse *, int64_t *, size_t, int, int64_t *, + cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_metis_bisector */ @@ -4396,7 +3667,7 @@ int64_t cholmod_metis_bisector /* returns separator size */ /* ---- input ---- */ cholmod_sparse *A, /* matrix to bisect */ int32_t *Anw, /* size A->nrow, node weights, can be NULL, */ - /* which means the graph is unweighted. */ + /* which means the graph is unweighted. */ int32_t *Aew, /* size nz, edge weights (silently ignored). */ /* This option was available with METIS 4, but not */ /* in METIS 5. This argument is now unused, but */ @@ -4408,9 +3679,8 @@ int64_t cholmod_metis_bisector /* returns separator size */ cholmod_common *Common ) ; -int64_t cholmod_l_metis_bisector (cholmod_sparse *, - int64_t *, int64_t *, int64_t *, - cholmod_common *) ; +int64_t cholmod_l_metis_bisector (cholmod_sparse *, int64_t *, int64_t *, + int64_t *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_collapse_septree */ @@ -4432,16 +3702,18 @@ int64_t cholmod_collapse_septree cholmod_common *Common ) ; -int64_t cholmod_l_collapse_septree (size_t, size_t, double, size_t, - int64_t *, int64_t *, cholmod_common *) ; +int64_t cholmod_l_collapse_septree (size_t, size_t, double, size_t, int64_t *, + int64_t *, cholmod_common *) ; + +#endif -/* ========================================================================== */ -/* === Include/cholmod_supernodal.h ========================================= */ -/* ========================================================================== */ +//============================================================================== +// CHOLMOD:Supernodal Module +//============================================================================== -/* CHOLMOD Supernodal module. - * - * Supernodal analysis, factorization, and solve. The simplest way to use +#ifndef NSUPERNODAL + +/* Supernodal analysis, factorization, and solve. The simplest way to use * these routines is via the Cholesky module. It does not provide any * fill-reducing orderings, but does accept the orderings computed by the * Cholesky module. It does not require the Cholesky module itself, however. @@ -4468,12 +3740,10 @@ int64_t cholmod_l_collapse_septree (size_t, size_t, double, size_t, * ---------------- * dpotrf LAPACK: A=chol(tril(A)) * - * Requires the Core module, and two external packages: LAPACK and the BLAS. + * Requires the Utility module, and two external packages: LAPACK and the BLAS. * Optionally used by the Cholesky module. */ -#ifndef NSUPERNODAL - /* -------------------------------------------------------------------------- */ /* cholmod_super_symbolic */ /* -------------------------------------------------------------------------- */ @@ -4496,8 +3766,8 @@ int cholmod_super_symbolic cholmod_common *Common ) ; -int cholmod_l_super_symbolic (cholmod_sparse *, cholmod_sparse *, - int64_t *, cholmod_factor *, cholmod_common *) ; +int cholmod_l_super_symbolic (cholmod_sparse *, cholmod_sparse *, int64_t *, + cholmod_factor *, cholmod_common *) ; /* -------------------------------------------------------------------------- */ /* cholmod_super_symbolic2 */ @@ -4600,19 +3870,37 @@ int cholmod_l_super_ltsolve (cholmod_factor *, cholmod_dense *, cholmod_dense *, } #endif +//============================================================================== +// CHOLMOD:SupernodalGPU Module +//============================================================================== -/* ========================================================================== */ -/* === Include/cholmod_gpu.h ================================================ */ -/* ========================================================================== */ +//------------------------------------------------------------------------------ +// cholmod_score_comp: for sorting descendant supernodes with qsort +//------------------------------------------------------------------------------ -/* ----------------------------------------------------------------------------- - * CHOLMOD/Include/cholmod_gpu.h. - * Copyright (C) 2014, Timothy A. Davis - * http://www.suitesparse.com - * -------------------------------------------------------------------------- */ +#ifdef __cplusplus +extern "C" { +#endif -/* CHOLMOD GPU module - */ +typedef struct cholmod_descendant_score_t +{ + double score ; + int64_t d ; +} +descendantScore ; + +int cholmod_score_comp (struct cholmod_descendant_score_t *i, + struct cholmod_descendant_score_t *j) ; +int cholmod_l_score_comp (struct cholmod_descendant_score_t *i, + struct cholmod_descendant_score_t *j) ; + +#ifdef __cplusplus +} +#endif + +//------------------------------------------------------------------------------ +// remainder of SupernodalGPU Module +//------------------------------------------------------------------------------ #ifdef SUITESPARSE_CUDA @@ -4635,11 +3923,10 @@ int cholmod_l_super_ltsolve (cholmod_factor *, cholmod_dense *, cholmod_dense *, #define CHOLMOD_POTRF_LIMIT 512 /* required cols for POTRF & TRSM on GPU */ /* # of host supernodes to perform before checking for free pinned buffers */ -#define CHOLMOD_GPU_SKIP 3 +#define CHOLMOD_GPU_SKIP 3 #define CHOLMOD_HANDLE_CUDA_ERROR(e,s) {if (e) {ERROR(CHOLMOD_GPU_PROBLEM,s);}} -/* make it easy for C++ programs to include CHOLMOD */ #ifdef __cplusplus extern "C" { #endif @@ -4669,7 +3956,7 @@ int cholmod_l_gpu_memorysize /* GPU memory size available, 1 if no GPU */ size_t *available_mem, cholmod_common *Common ) ; - + int cholmod_gpu_probe ( cholmod_common *Common ) ; int cholmod_l_gpu_probe ( cholmod_common *Common ) ; @@ -4689,3 +3976,4 @@ int cholmod_l_gpu_allocate ( cholmod_common *Common ) ; #endif #endif + diff --git a/CHOLMOD/Include/cholmod_internal.h b/CHOLMOD/Include/cholmod_internal.h index e14eeb48c..04ffcbbb0 100644 --- a/CHOLMOD/Include/cholmod_internal.h +++ b/CHOLMOD/Include/cholmod_internal.h @@ -18,7 +18,7 @@ * * Required by all CHOLMOD routines. Not required by any user routine that * uses CHOLMOMD. Unless debugging is enabled, this file does not require any - * CHOLMOD module (not even the Core module). + * CHOLMOD module (not even the Utility module). * * If debugging is enabled, all CHOLMOD modules require the Check module. * Enabling debugging requires that this file be editted. Debugging cannot be @@ -55,7 +55,6 @@ #undef FALSE #define TRUE 1 #define FALSE 0 -#define BOOLEAN(x) ((x) ? TRUE : FALSE) /* NULL should already be defined, but ensure it is here. */ #ifndef NULL @@ -77,6 +76,11 @@ #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define IMPLIES(p,q) (!(p) || (q)) +// RANGE (k, lo, hi): ensures k is in range lo:hi +#define RANGE(k,lo,hi) \ + (((k) < (lo)) ? (lo) : \ + (((k) > (hi)) ? (hi) : (k))) + /* find the sign: -1 if x < 0, 1 if x > 0, zero otherwise. * Not safe for NaN's */ #define SIGN(x) (((x) < 0) ? (-1) : (((x) > 0) ? 1 : 0)) @@ -93,11 +97,11 @@ { \ if ((A) == NULL) \ { \ - if (Common->status != CHOLMOD_OUT_OF_MEMORY) \ - { \ - ERROR (CHOLMOD_INVALID, "argument missing") ; \ - } \ - return (result) ; \ + if (Common->status != CHOLMOD_OUT_OF_MEMORY) \ + { \ + ERROR (CHOLMOD_INVALID, "argument missing") ; \ + } \ + return (result) ; \ } \ } @@ -106,22 +110,15 @@ { \ if (Common == NULL) \ { \ - return (result) ; \ + return (result) ; \ } \ - if (Common->itype != ITYPE || Common->dtype != DTYPE) \ + if (Common->itype != ITYPE) \ { \ - Common->status = CHOLMOD_INVALID ; \ - return (result) ; \ + Common->status = CHOLMOD_INVALID ; \ + return (result) ; \ } \ } -#define IS_NAN(x) CHOLMOD_IS_NAN(x) -#define IS_ZERO(x) CHOLMOD_IS_ZERO(x) -#define IS_NONZERO(x) CHOLMOD_IS_NONZERO(x) -#define IS_LT_ZERO(x) CHOLMOD_IS_LT_ZERO(x) -#define IS_GT_ZERO(x) CHOLMOD_IS_GT_ZERO(x) -#define IS_LE_ZERO(x) CHOLMOD_IS_LE_ZERO(x) - /* 1e308 is a huge number that doesn't take many characters to print in a * file, in CHOLMOD/Check/cholmod_read and _write. Numbers larger than this * are interpretted as Inf, since sscanf doesn't read in Inf's properly. @@ -129,25 +126,72 @@ * better, except that it takes too many digits to print in a file. */ #define HUGE_DOUBLE 1e308 -/* ========================================================================== */ -/* === int/long and double/float definitions ================================ */ -/* ========================================================================== */ +//============================================================================== +// int32/int64 and double/single definitions +//============================================================================== #include "cholmod_types.h" -#ifndef DLONG -// GPU acceleration only available for the DLONG case (double, int64) +#ifndef CHOLMOD_INT64 +// GPU acceleration only available for the CHOLMOD_INT64 case (int64) #undef SUITESPARSE_CUDA #endif -/* -------------------------------------------------------------------------- */ -/* routines for doing arithmetic on size_t, and checking for overflow */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// internal routines +//------------------------------------------------------------------------------ + +bool cholmod_mult_uint64_t // c = a*b, return true if ok +( + uint64_t *restrict c, + const uint64_t a, + const uint64_t b +) ; + +size_t cholmod_add_size_t (size_t a, size_t b, int *ok) ; +size_t cholmod_mult_size_t (size_t a, size_t b, int *ok) ; +size_t cholmod_l_add_size_t (size_t a, size_t b, int *ok) ; +size_t cholmod_l_mult_size_t (size_t a, size_t b, int *ok) ; + +int64_t cholmod_cumsum // return sum (Cnz), or -1 if int32_t overflow +( + int32_t *Cp, // size n+1, output array, the cumsum of Cnz + int32_t *Cnz, // size n, input array + size_t n // size of Cp and Cnz +) ; + +int64_t cholmod_l_cumsum // return sum (Cnz), or -1 if int64_t overflow +( + int64_t *Cp, // size n+1, output array, the cumsum of Cnz + int64_t *Cnz, // size n, input array + size_t n // size of Cp and Cnz +) ; + +void cholmod_set_empty +( + int32_t *S, // int32 array of size n + size_t n +) ; + +void cholmod_l_set_empty +( + int64_t *S, // int64 array of size n + size_t n +) ; + +void cholmod_to_simplicial_sym +( + cholmod_factor *L, // sparse factorization to modify + int to_ll, // change L to hold a LL' or LDL' factorization + cholmod_common *Common +) ; -size_t cholmod_add_size_t (size_t a, size_t b, int *ok) ; -size_t cholmod_mult_size_t (size_t a, size_t k, int *ok) ; -size_t cholmod_l_add_size_t (size_t a, size_t b, int *ok) ; -size_t cholmod_l_mult_size_t (size_t a, size_t k, int *ok) ; +void cholmod_l_to_simplicial_sym +( + cholmod_factor *L, // sparse factorization to modify + int to_ll, // change L to hold a LL' or LDL' factorization + cholmod_common *Common +) ; /* ========================================================================== */ /* === Include/cholmod_complexity.h ========================================= */ @@ -168,51 +212,58 @@ size_t cholmod_l_mult_size_t (size_t a, size_t k, int *ok) ; * XTYPE and XTYPE2 are defined in cholmod_template.h. */ -/* -------------------------------------------------------------------------- */ -/* pattern */ -/* -------------------------------------------------------------------------- */ - -#define P_TEMPLATE(name) p_ ## name -#define P_ASSIGN2(x,z,p,ax,az,q) x [p] = 1 -#define P_PRINT(k,x,z,p) PRK(k, ("1")) - -/* -------------------------------------------------------------------------- */ -/* real */ -/* -------------------------------------------------------------------------- */ - -#define R_TEMPLATE(name) r_ ## name -#define R_ASSEMBLE(x,z,p,ax,az,q) x [p] += ax [q] -#define R_ASSIGN(x,z,p,ax,az,q) x [p] = ax [q] -#define R_ASSIGN_CONJ(x,z,p,ax,az,q) x [p] = ax [q] -#define R_ASSIGN_REAL(x,p,ax,q) x [p] = ax [q] -#define R_XTYPE_OK(type) ((type) == CHOLMOD_REAL) -#define R_IS_NONZERO(ax,az,q) IS_NONZERO (ax [q]) -#define R_IS_ZERO(ax,az,q) IS_ZERO (ax [q]) -#define R_IS_ONE(ax,az,q) (ax [q] == 1) -#define R_MULT(x,z,p, ax,az,q, bx,bz,r) x [p] = ax [q] * bx [r] -#define R_MULTADD(x,z,p, ax,az,q, bx,bz,r) x [p] += ax [q] * bx [r] -#define R_MULTSUB(x,z,p, ax,az,q, bx,bz,r) x [p] -= ax [q] * bx [r] -#define R_MULTADDCONJ(x,z,p, ax,az,q, bx,bz,r) x [p] += ax [q] * bx [r] -#define R_MULTSUBCONJ(x,z,p, ax,az,q, bx,bz,r) x [p] -= ax [q] * bx [r] -#define R_ADD(x,z,p, ax,az,q, bx,bz,r) x [p] = ax [q] + bx [r] -#define R_ADD_REAL(x,p, ax,q, bx,r) x [p] = ax [q] + bx [r] -#define R_CLEAR(x,z,p) x [p] = 0 +//------------------------------------------------------------------------------ +// pattern: single or double +//------------------------------------------------------------------------------ + +#define P_TEMPLATE(name) p_ ## name +#define P_S_TEMPLATE(name) p_s_ ## name + +#define P_ASSIGN2(x,z,p,ax,az,q) x [p] = 1 +#define P_PRINT(k,x,z,p) PRK(k, ("1")) + +//------------------------------------------------------------------------------ +// real: single or double +//------------------------------------------------------------------------------ + +#define R_TEMPLATE(name) r_ ## name +#define R_S_TEMPLATE(name) r_s_ ## name + +#define R_ASSEMBLE(x,z,p,ax,az,q) x [p] += ax [q] +#define R_ASSIGN(x,z,p,ax,az,q) x [p] = ax [q] +#define R_ASSIGN_CONJ(x,z,p,ax,az,q) x [p] = ax [q] +#define R_ASSIGN_REAL(x,p,ax,q) x [p] = ax [q] +#define R_XTYPE_OK(type) ((type) == CHOLMOD_REAL) +#define R_IS_NONZERO(ax,az,q) (ax [q] != 0) +#define R_IS_ZERO(ax,az,q) (ax [q] == 0) +#define R_IS_ONE(ax,az,q) (ax [q] == 1) +#define R_MULT(x,z,p, ax,az,q, bx,bz,r) x [p] = ax [q] * bx [r] +#define R_MULTADD(x,z,p, ax,az,q, bx,bz,r) x [p] += ax [q] * bx [r] +#define R_MULTSUB(x,z,p, ax,az,q, bx,bz,r) x [p] -= ax [q] * bx [r] +#define R_MULTADDCONJ(x,z,p, ax,az,q, bx,bz,r) x [p] += ax [q] * bx [r] +#define R_MULTSUBCONJ(x,z,p, ax,az,q, bx,bz,r) x [p] -= ax [q] * bx [r] +#define R_ADD(x,z,p, ax,az,q, bx,bz,r) x [p] = ax [q] + bx [r] +#define R_ADD_REAL(x,p, ax,q, bx,r) x [p] = ax [q] + bx [r] +#define R_CLEAR(x,z,p) x [p] = 0 #define R_CLEAR_IMAG(x,z,p) -#define R_DIV(x,z,p,ax,az,q) x [p] /= ax [q] -#define R_LLDOT(x,p, ax,az,q) x [p] -= ax [q] * ax [q] -#define R_PRINT(k,x,z,p) PRK(k, ("%24.16e", x [p])) +#define R_DIV(x,z,p,ax,az,q) x [p] /= ax [q] +#define R_LLDOT(x,p, ax,az,q) x [p] -= ax [q] * ax [q] +#define R_PRINT(k,x,z,p) PRK(k, ("%24.16e", x [p])) -#define R_DIV_REAL(x,z,p, ax,az,q, bx,r) x [p] = ax [q] / bx [r] -#define R_MULT_REAL(x,z,p, ax,az,q, bx,r) x [p] = ax [q] * bx [r] +#define R_DIV_REAL(x,z,p, ax,az,q, bx,r) x [p] = ax [q] / bx [r] +#define R_MULT_REAL(x,z,p, ax,az,q, bx,r) x [p] = ax [q] * bx [r] -#define R_LDLDOT(x,p, ax,az,q, bx,r) x [p] -=(ax[q] * ax[q])/ bx[r] +#define R_LDLDOT(x,p, ax,az,q, bx,r) x [p] -=(ax[q] * ax[q])/ bx[r] -/* -------------------------------------------------------------------------- */ -/* complex */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// complex: single or double +//------------------------------------------------------------------------------ + +#define C_TEMPLATE(name) c_ ## name +#define CT_TEMPLATE(name) ct_ ## name -#define C_TEMPLATE(name) c_ ## name -#define CT_TEMPLATE(name) ct_ ## name +#define C_S_TEMPLATE(name) c_s_ ## name +#define CT_S_TEMPLATE(name) ct_s_ ## name #define C_ASSEMBLE(x,z,p,ax,az,q) \ x [2*(p) ] += ax [2*(q) ] ; \ @@ -222,46 +273,44 @@ size_t cholmod_l_mult_size_t (size_t a, size_t k, int *ok) ; x [2*(p) ] = ax [2*(q) ] ; \ x [2*(p)+1] = ax [2*(q)+1] -#define C_ASSIGN_REAL(x,p,ax,q) x [2*(p)] = ax [2*(q)] +#define C_ASSIGN_REAL(x,p,ax,q) x [2*(p)] = ax [2*(q)] #define C_ASSIGN_CONJ(x,z,p,ax,az,q) \ x [2*(p) ] = ax [2*(q) ] ; \ x [2*(p)+1] = -ax [2*(q)+1] -#define C_XTYPE_OK(type) ((type) == CHOLMOD_COMPLEX) +#define C_XTYPE_OK(type) ((type) == CHOLMOD_COMPLEX) -#define C_IS_NONZERO(ax,az,q) \ - (IS_NONZERO (ax [2*(q)]) || IS_NONZERO (ax [2*(q)+1])) +#define C_IS_NONZERO(ax,az,q) ((ax [2*(q)] != 0) || (ax [2*(q)+1] != 0)) -#define C_IS_ZERO(ax,az,q) \ - (IS_ZERO (ax [2*(q)]) && IS_ZERO (ax [2*(q)+1])) +#define C_IS_ZERO(ax,az,q) ((ax [2*(q)] == 0) && (ax [2*(q)+1] == 0)) #define C_IS_ONE(ax,az,q) \ - ((ax [2*(q)] == 1) && IS_ZERO (ax [2*(q)+1])) + ((ax [2*(q)] == 1) && (ax [2*(q)+1]) == 0) -#define C_IMAG_IS_NONZERO(ax,az,q) (IS_NONZERO (ax [2*(q)+1])) +#define C_IMAG_IS_NONZERO(ax,az,q) (ax [2*(q)+1] != 0) #define C_MULT(x,z,p, ax,az,q, bx,bz,r) \ -x [2*(p) ] = ax [2*(q) ] * bx [2*(r)] - ax [2*(q)+1] * bx [2*(r)+1] ; \ -x [2*(p)+1] = ax [2*(q)+1] * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] + x [2*(p) ] = ax [2*(q) ] * bx [2*(r)] - ax [2*(q)+1] * bx [2*(r)+1] ; \ + x [2*(p)+1] = ax [2*(q)+1] * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] #define C_MULTADD(x,z,p, ax,az,q, bx,bz,r) \ -x [2*(p) ] += ax [2*(q) ] * bx [2*(r)] - ax [2*(q)+1] * bx [2*(r)+1] ; \ -x [2*(p)+1] += ax [2*(q)+1] * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] + x [2*(p) ] += ax [2*(q) ] * bx [2*(r)] - ax [2*(q)+1] * bx [2*(r)+1] ; \ + x [2*(p)+1] += ax [2*(q)+1] * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] #define C_MULTSUB(x,z,p, ax,az,q, bx,bz,r) \ -x [2*(p) ] -= ax [2*(q) ] * bx [2*(r)] - ax [2*(q)+1] * bx [2*(r)+1] ; \ -x [2*(p)+1] -= ax [2*(q)+1] * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] + x [2*(p) ] -= ax [2*(q) ] * bx [2*(r)] - ax [2*(q)+1] * bx [2*(r)+1] ; \ + x [2*(p)+1] -= ax [2*(q)+1] * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] /* s += conj(a)*b */ #define C_MULTADDCONJ(x,z,p, ax,az,q, bx,bz,r) \ -x [2*(p) ] += ax [2*(q) ] * bx [2*(r)] + ax [2*(q)+1] * bx [2*(r)+1] ; \ -x [2*(p)+1] += (-ax [2*(q)+1]) * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] + x [2*(p) ] += ax [2*(q) ] * bx [2*(r)] + ax [2*(q)+1] * bx [2*(r)+1] ;\ + x [2*(p)+1] += (-ax [2*(q)+1]) * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] /* s -= conj(a)*b */ #define C_MULTSUBCONJ(x,z,p, ax,az,q, bx,bz,r) \ -x [2*(p) ] -= ax [2*(q) ] * bx [2*(r)] + ax [2*(q)+1] * bx [2*(r)+1] ; \ -x [2*(p)+1] -= (-ax [2*(q)+1]) * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] + x [2*(p) ] -= ax [2*(q) ] * bx [2*(r)] + ax [2*(q)+1] * bx [2*(r)+1] ;\ + x [2*(p)+1] -= (-ax [2*(q)+1]) * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] #define C_ADD(x,z,p, ax,az,q, bx,bz,r) \ x [2*(p) ] = ax [2*(q) ] + bx [2*(r) ] ; \ @@ -277,12 +326,24 @@ x [2*(p)+1] -= (-ax [2*(q)+1]) * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] #define C_CLEAR_IMAG(x,z,p) \ x [2*(p)+1] = 0 -/* s = s / a */ +// s = s / a (complex double case) #define C_DIV(x,z,p,ax,az,q) \ SuiteSparse_config_divcomplex ( \ - x [2*(p)], x [2*(p)+1], \ - ax [2*(q)], ax [2*(q)+1], \ - &x [2*(p)], &x [2*(p)+1]) + x [2*(p)], x [2*(p)+1], \ + ax [2*(q)], ax [2*(q)+1], \ + &x [2*(p)], &x [2*(p)+1]) + +// s = s / a (complex single case) +#define C_S_DIV(x,z,p,ax,az,q) \ +{ \ + double cr, ci ; \ + SuiteSparse_config_divcomplex ( \ + (double) x [2*(p)], (double) x [2*(p)+1], \ + (double) ax [2*(q)], (double) ax [2*(q)+1], \ + &cr, &ci) ; \ + x [2*(p) ] = (float) cr ; \ + x [2*(p)+1] = (float) ci ; \ +} /* s -= conj(a)*a ; note that the result of conj(a)*a is real */ #define C_LLDOT(x,p, ax,az,q) \ @@ -302,12 +363,15 @@ x [2*(p)+1] -= (-ax [2*(q)+1]) * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] #define C_LDLDOT(x,p, ax,az,q, bx,r) \ x [2*(p)] -= (ax [2*(q)] * ax [2*(q)] + ax [2*(q)+1] * ax [2*(q)+1]) / bx[r] -/* -------------------------------------------------------------------------- */ -/* zomplex */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// zomplex: single or double +//------------------------------------------------------------------------------ -#define Z_TEMPLATE(name) z_ ## name -#define ZT_TEMPLATE(name) zt_ ## name +#define Z_TEMPLATE(name) z_ ## name +#define ZT_TEMPLATE(name) zt_ ## name + +#define Z_S_TEMPLATE(name) z_s_ ## name +#define ZT_S_TEMPLATE(name) zt_s_ ## name #define Z_ASSEMBLE(x,z,p,ax,az,q) \ x [p] += ax [q] ; \ @@ -317,24 +381,21 @@ x [2*(p)+1] -= (-ax [2*(q)+1]) * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] x [p] = ax [q] ; \ z [p] = az [q] -#define Z_ASSIGN_REAL(x,p,ax,q) x [p] = ax [q] +#define Z_ASSIGN_REAL(x,p,ax,q) x [p] = ax [q] #define Z_ASSIGN_CONJ(x,z,p,ax,az,q) \ x [p] = ax [q] ; \ z [p] = -az [q] -#define Z_XTYPE_OK(type) ((type) == CHOLMOD_ZOMPLEX) +#define Z_XTYPE_OK(type) ((type) == CHOLMOD_ZOMPLEX) -#define Z_IS_NONZERO(ax,az,q) \ - (IS_NONZERO (ax [q]) || IS_NONZERO (az [q])) +#define Z_IS_NONZERO(ax,az,q) ((ax [q] != 0) || (az [q] != 0)) -#define Z_IS_ZERO(ax,az,q) \ - (IS_ZERO (ax [q]) && IS_ZERO (az [q])) +#define Z_IS_ZERO(ax,az,q) ((ax [q] == 0) && (az [q] == 0)) -#define Z_IS_ONE(ax,az,q) \ - ((ax [q] == 1) && IS_ZERO (az [q])) +#define Z_IS_ONE(ax,az,q) ((ax [q] == 1) && (az [q] == 0)) -#define Z_IMAG_IS_NONZERO(ax,az,q) (IS_NONZERO (az [q])) +#define Z_IMAG_IS_NONZERO(ax,az,q) (az [q] != 0) #define Z_MULT(x,z,p, ax,az,q, bx,bz,r) \ x [p] = ax [q] * bx [r] - az [q] * bz [r] ; \ @@ -357,11 +418,11 @@ x [2*(p)+1] -= (-ax [2*(q)+1]) * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] z [p] -= (-az [q]) * bx [r] + ax [q] * bz [r] #define Z_ADD(x,z,p, ax,az,q, bx,bz,r) \ - x [p] = ax [q] + bx [r] ; \ - z [p] = az [q] + bz [r] + x [p] = ax [q] + bx [r] ; \ + z [p] = az [q] + bz [r] #define Z_ADD_REAL(x,p, ax,q, bx,r) \ - x [p] = ax [q] + bx [r] + x [p] = ax [q] + bx [r] #define Z_CLEAR(x,z,p) \ x [p] = 0 ; \ @@ -370,16 +431,28 @@ x [2*(p)+1] -= (-ax [2*(q)+1]) * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] #define Z_CLEAR_IMAG(x,z,p) \ z [p] = 0 -/* s = s / a */ +// s = s / a (zomplex double case) #define Z_DIV(x,z,p,ax,az,q) \ SuiteSparse_config_divcomplex \ (x [p], z [p], ax [q], az [q], &x [p], &z [p]) +// s = s / a (zomplex single case) +#define Z_S_DIV(x,z,p,ax,az,q) \ +{ \ + double cr, ci ; \ + SuiteSparse_config_divcomplex ( \ + (double) x [p], (double) z [p], \ + (double) ax [q], (double) az [q], \ + &cr, &ci) ; \ + x [p] = (float) cr ; \ + z [p] = (float) ci ; \ +} + /* s -= conj(a)*a ; note that the result of conj(a)*a is real */ #define Z_LLDOT(x,p, ax,az,q) \ x [p] -= ax [q] * ax [q] + az [q] * az [q] -#define Z_PRINT(k,x,z,p) PRK(k, ("(%24.16e,%24.16e)", x [p], z [p])) +#define Z_PRINT(k,x,z,p) PRK(k, ("(%24.16e,%24.16e)", x [p], z [p])) #define Z_DIV_REAL(x,z,p, ax,az,q, bx,r) \ x [p] = ax [q] / bx [r] ; \ @@ -393,76 +466,141 @@ x [2*(p)+1] -= (-ax [2*(q)+1]) * bx [2*(r)] + ax [2*(q) ] * bx [2*(r)+1] #define Z_LDLDOT(x,p, ax,az,q, bx,r) \ x [p] -= (ax [q] * ax [q] + az [q] * az [q]) / bx[r] -/* -------------------------------------------------------------------------- */ -/* all classes */ -/* -------------------------------------------------------------------------- */ - -/* Check if A->xtype and the two arrays A->x and A->z are valid. Set status to - * invalid, unless status is already "out of memory". A can be a sparse matrix, - * dense matrix, factor, or triplet. */ +//------------------------------------------------------------------------------ +// all classes +//------------------------------------------------------------------------------ -#define RETURN_IF_XTYPE_INVALID(A,xtype1,xtype2,result) \ -{ \ - if ((A)->xtype < (xtype1) || (A)->xtype > (xtype2) || \ - ((A)->xtype != CHOLMOD_PATTERN && ((A)->x) == NULL) || \ - ((A)->xtype == CHOLMOD_ZOMPLEX && ((A)->z) == NULL)) \ - { \ - if (Common->status != CHOLMOD_OUT_OF_MEMORY) \ - { \ - ERROR (CHOLMOD_INVALID, "invalid xtype") ; \ - } \ - return (result) ; \ - } \ +// Check if A->xtype and the two arrays A->x and A->z are valid. Set status to +// invalid, unless status is already "out of memory". A can be a sparse matrix, +// dense matrix, factor, or triplet. + +#define RETURN_IF_XTYPE_IS_INVALID(xtype,xtype1,xtype2,result) \ + if (xtype < (xtype1) || xtype > (xtype2)) \ + { \ + if (Common->status != CHOLMOD_OUT_OF_MEMORY) \ + { \ + ERROR (CHOLMOD_INVALID, "invalid xtype") ; \ + } \ + return (result) ; \ + } \ + +#define RETURN_IF_XTYPE_INVALID(A,xtype1,xtype2,result) \ +{ \ + if ((A)->xtype < (xtype1) || (A)->xtype > (xtype2) || \ + ((A)->xtype != CHOLMOD_PATTERN && ((A)->x) == NULL) || \ + ((A)->xtype == CHOLMOD_ZOMPLEX && ((A)->z) == NULL) || \ + !(((A)->dtype == CHOLMOD_DOUBLE) || ((A)->dtype == CHOLMOD_SINGLE))) \ + { \ + if (Common->status != CHOLMOD_OUT_OF_MEMORY) \ + { \ + ERROR (CHOLMOD_INVALID, "invalid xtype or dtype") ; \ + } \ + return (result) ; \ + } \ } -/* ========================================================================== */ -/* === Architecture and BLAS ================================================ */ -/* ========================================================================== */ +#define RETURN_IF_DENSE_MATRIX_INVALID(X,result) \ + RETURN_IF_NULL (X, result) ; \ + RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, result) ; \ + if ((X)->d < (X)->nrow) \ + { \ + if (Common->status != CHOLMOD_OUT_OF_MEMORY) \ + { \ + ERROR (CHOLMOD_INVALID, "dense matrix invalid") ; \ + } \ + return (result) ; \ + } + +#define RETURN_IF_SPARSE_MATRIX_INVALID(A,result) \ + RETURN_IF_NULL (A, result) ; \ + RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, result) ; \ + if ((A)->p == NULL || (!(A)->packed && ((A)->nz == NULL)) || \ + (A->stype != 0 && A->nrow != A->ncol)) \ + { \ + if (Common->status != CHOLMOD_OUT_OF_MEMORY) \ + { \ + ERROR (CHOLMOD_INVALID, "sparse matrix invalid") ; \ + } \ + return (result) ; \ + } + +#define RETURN_IF_TRIPLET_MATRIX_INVALID(T,result) \ + RETURN_IF_NULL (T, result) ; \ + RETURN_IF_XTYPE_INVALID (T, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, result) ; \ + if ((T)->nnz > 0 && ((T)->i == NULL || (T)->j == NULL || \ + ((T)->xtype != CHOLMOD_PATTERN && (T)->x == NULL) || \ + ((T)->xtype == CHOLMOD_ZOMPLEX && (T)->z == NULL))) \ + { \ + if (Common->status != CHOLMOD_OUT_OF_MEMORY) \ + { \ + ERROR (CHOLMOD_INVALID, "triplet matrix invalid") ; \ + } \ + return (result) ; \ + } + +#define RETURN_IF_FACTOR_INVALID(L,result) \ + RETURN_IF_NULL (L, result) ; \ + RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, result) ; + +//============================================================================== +// Architecture and BLAS +//============================================================================== #if defined (__sun) || defined (MSOL2) || defined (ARCH_SOL2) -#define CHOLMOD_SOL2 -#define CHOLMOD_ARCHITECTURE "Sun Solaris" + + #define CHOLMOD_SOL2 + #define CHOLMOD_ARCHITECTURE "Sun Solaris" #elif defined (__sgi) || defined (MSGI) || defined (ARCH_SGI) -#define CHOLMOD_SGI -#define CHOLMOD_ARCHITECTURE "SGI Irix" + + #define CHOLMOD_SGI + #define CHOLMOD_ARCHITECTURE "SGI Irix" #elif defined (__linux) || defined (MGLNX86) || defined (ARCH_GLNX86) -#define CHOLMOD_LINUX -#define CHOLMOD_ARCHITECTURE "Linux" + + #define CHOLMOD_LINUX + #define CHOLMOD_ARCHITECTURE "Linux" #elif defined (__APPLE__) -#define CHOLMOD_MAC -#define CHOLMOD_ARCHITECTURE "Mac" + + #define CHOLMOD_MAC + #define CHOLMOD_ARCHITECTURE "Mac" #elif defined (_AIX) || defined (MIBM_RS) || defined (ARCH_IBM_RS) -#define CHOLMOD_AIX -#define CHOLMOD_ARCHITECTURE "IBM AIX" + + #define CHOLMOD_AIX + #define CHOLMOD_ARCHITECTURE "IBM AIX" #elif defined (__alpha) || defined (MALPHA) || defined (ARCH_ALPHA) -#define CHOLMOD_ALPHA -#define CHOLMOD_ARCHITECTURE "Compaq Alpha" + + #define CHOLMOD_ALPHA + #define CHOLMOD_ARCHITECTURE "Compaq Alpha" #elif defined (_WIN32) || defined (WIN32) || defined (_WIN64) || defined (WIN64) -#if defined (__MINGW32__) || defined (__MINGW32__) -#define CHOLMOD_MINGW -#elif defined (__CYGWIN32__) || defined (__CYGWIN32__) -#define CHOLMOD_CYGWIN -#else -#define CHOLMOD_WINDOWS -#endif -#define CHOLMOD_ARCHITECTURE "Microsoft Windows" + + #if defined (__MINGW32__) || defined (__MINGW32__) + #define CHOLMOD_MINGW + #elif defined (__CYGWIN32__) || defined (__CYGWIN32__) + #define CHOLMOD_CYGWIN + #else + #define CHOLMOD_WINDOWS + #endif + #define CHOLMOD_ARCHITECTURE "Microsoft Windows" #elif defined (__hppa) || defined (__hpux) || defined (MHPUX) || defined (ARCH_HPUX) -#define CHOLMOD_HP -#define CHOLMOD_ARCHITECTURE "HP Unix" + + #define CHOLMOD_HP + #define CHOLMOD_ARCHITECTURE "HP Unix" #elif defined (__hp700) || defined (MHP700) || defined (ARCH_HP700) -#define CHOLMOD_HP -#define CHOLMOD_ARCHITECTURE "HP 700 Unix" + + #define CHOLMOD_HP + #define CHOLMOD_ARCHITECTURE "HP 700 Unix" #else -#define CHOLMOD_ARCHITECTURE "unknown" + + #define CHOLMOD_ARCHITECTURE "unknown" + #endif //============================================================================== @@ -525,7 +663,7 @@ int cholmod_dump_perm (int *, size_t, size_t, const char *, cholmod_common *) ; int cholmod_dump_parent (int *, size_t, const char *, cholmod_common *) ; void cholmod_dump_init (const char *, cholmod_common *) ; int cholmod_dump_mem (const char *, int64_t, cholmod_common *) ; -void cholmod_dump_real (const char *, Real *, int64_t, +void cholmod_dump_real (const char *, double *, int64_t, int64_t, int, int, cholmod_common *) ; void cholmod_dump_super (int64_t, int *, int *, int *, int *, double *, int, cholmod_common *) ; @@ -549,7 +687,7 @@ int cholmod_l_dump_parent (int64_t *, size_t, const char *, cholmod_common *) ; void cholmod_l_dump_init (const char *, cholmod_common *) ; int cholmod_l_dump_mem (const char *, int64_t, cholmod_common *) ; -void cholmod_l_dump_real (const char *, Real *, int64_t, +void cholmod_l_dump_real (const char *, double *, int64_t, int64_t, int, int, cholmod_common *) ; void cholmod_l_dump_super (int64_t, int64_t *, int64_t *, int64_t *, int64_t *, @@ -580,11 +718,19 @@ int cholmod_l_dump_work(int, int, int64_t, cholmod_common *) ; #define PRINT2(params) PRK (2, params) #define PRINT3(params) PRK (3, params) +void CM_memtable_dump (void) ; +int CM_memtable_n (void) ; +void CM_memtable_clear (void) ; +void CM_memtable_add (void *p, size_t size) ; +size_t CM_memtable_size (void *p) ; +bool CM_memtable_find (void *p) ; +void CM_memtable_remove (void *p) ; + #define PRINTM(params) \ { \ if (CHOLMOD(dump_malloc) > 0) \ { \ - printf params ; \ + printf params ; \ } \ } @@ -604,4 +750,28 @@ int cholmod_l_dump_work(int, int, int64_t, cholmod_common *) ; #define DEBUG(statement) #endif +static bool check_flag (cholmod_common *Common) +{ + int64_t mark = Common->mark ; + size_t n = Common->nrow ; + if (Common->itype == CHOLMOD_LONG) + { + int64_t *Flag = Common->Flag ; + for (int64_t i = 0 ; i < n ; i++) + { + if (Flag [i] >= mark) return (false) ; + } + } + else + { + ASSERT (mark <= INT32_MAX) ; + int32_t *Flag = Common->Flag ; + for (int32_t i = 0 ; i < n ; i++) + { + if (Flag [i] >= mark) return (false) ; + } + } + return (true) ; +} + #endif diff --git a/CHOLMOD/Include/cholmod_template.h b/CHOLMOD/Include/cholmod_template.h index 77cd84d63..8ec528354 100644 --- a/CHOLMOD/Include/cholmod_template.h +++ b/CHOLMOD/Include/cholmod_template.h @@ -8,9 +8,23 @@ //------------------------------------------------------------------------------ -/* -------------------------------------------------------------------------- */ -/* undefine current xtype macros, and then define macros for current type */ -/* -------------------------------------------------------------------------- */ +// The #including file must #define the following: +// +// Floating-point value, one of the following (default is DOUBLE): +// +// #define DOUBLE +// #define SINGLE +// +// pattern/real/complex/zomplex, one of (no default): +// +// #define PATTERN +// #define REAL +// #define COMPLEX +// #define ZOMPLEX + +//------------------------------------------------------------------------------ +// undefine current xtype macros, and then define macros for current type +//------------------------------------------------------------------------------ #undef TEMPLATE #undef TEMPLATE2 @@ -28,6 +42,8 @@ #undef ASSIGN2 #undef ASSIGN2_CONJ #undef ASSIGN_REAL +#undef ASSIGN_CONJ_OR_NCONJ + #undef MULT #undef MULTADD #undef ADD @@ -51,201 +67,285 @@ #undef XPRINT2 #undef XPRINT3 -/* -------------------------------------------------------------------------- */ -/* pattern */ -/* -------------------------------------------------------------------------- */ +#undef Real + +//------------------------------------------------------------------------------ +// single/double +//------------------------------------------------------------------------------ + +#ifdef SINGLE + // single precision + #define Real float +#else + // double precision + #ifndef DOUBLE + #define DOUBLE + #endif + #define Real double +#endif +//------------------------------------------------------------------------------ +// pattern: both double and single +//------------------------------------------------------------------------------ #ifdef PATTERN -#define PREFIX p_ -#define TEMPLATE(name) P_TEMPLATE(name) -#define TEMPLATE2(name) P_TEMPLATE(name) -#define XTYPE CHOLMOD_PATTERN -#define XTYPE2 CHOLMOD_REAL -#define XTYPE_OK(type) (TRUE) -#define ENTRY_IS_NONZERO(ax,az,q) (TRUE) -#define ENTRY_IS_ZERO(ax,az,q) (FALSE) -#define ENTRY_IS_ONE(ax,az,q) (TRUE) -#define IMAG_IS_NONZERO(ax,az,q) (FALSE) -#define ENTRY_SIZE 0 - -#define ASSEMBLE(x,z,p,ax,az,q) -#define ASSIGN(x,z,p,ax,az,q) -#define ASSIGN_CONJ(x,z,p,ax,az,q) -#define ASSIGN2(x,z,p,ax,az,q) P_ASSIGN2(x,z,p,ax,az,q) -#define ASSIGN2_CONJ(x,z,p,ax,az,q) P_ASSIGN2(x,z,p,ax,az,q) -#define ASSIGN_REAL(x,p,ax,q) -#define MULT(x,z,p,ax,az,q,bx,bz,pb) -#define MULTADD(x,z,p,ax,az,q,bx,bz,pb) -#define ADD(x,z,p,ax,az,q,bx,bz,pb) -#define ADD_REAL(x,p, ax,q, bx,r) -#define MULTSUB(x,z,p,ax,az,q,bx,bz,pb) -#define MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) -#define MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) -#define LLDOT(x,p,ax,az,q) -#define CLEAR(x,z,p) -#define CLEAR_IMAG(x,z,p) -#define DIV(x,z,p,ax,az,q) -#define DIV_REAL(x,z,p, ax,az,q, bx,r) -#define MULT_REAL(x,z,p, ax,az,q, bx,r) -#define LDLDOT(x,p, ax,az,q, bx,r) - -#define XPRINT0(x,z,p) P_PRINT(0,x,z,p) -#define XPRINT1(x,z,p) P_PRINT(1,x,z,p) -#define XPRINT2(x,z,p) P_PRINT(2,x,z,p) -#define XPRINT3(x,z,p) P_PRINT(3,x,z,p) - -/* -------------------------------------------------------------------------- */ -/* real */ -/* -------------------------------------------------------------------------- */ + #ifdef SINGLE + #define PREFIX p_s_ + #define TEMPLATE(name) P_S_TEMPLATE(name) + #define TEMPLATE2(name) P_S_TEMPLATE(name) + #else + #define PREFIX p_ + #define TEMPLATE(name) P_TEMPLATE(name) + #define TEMPLATE2(name) P_TEMPLATE(name) + #endif + + #define XTYPE CHOLMOD_PATTERN + #define XTYPE2 CHOLMOD_REAL + #define XTYPE_OK(type) (TRUE) + #define ENTRY_IS_NONZERO(ax,az,q) (TRUE) + #define ENTRY_IS_ZERO(ax,az,q) (FALSE) + #define ENTRY_IS_ONE(ax,az,q) (TRUE) + #define IMAG_IS_NONZERO(ax,az,q) (FALSE) + #define ENTRY_SIZE 0 + + #define ASSEMBLE(x,z,p,ax,az,q) + #define ASSIGN(x,z,p,ax,az,q) + #define ASSIGN_CONJ(x,z,p,ax,az,q) + #define ASSIGN2(x,z,p,ax,az,q) P_ASSIGN2(x,z,p,ax,az,q) + #define ASSIGN2_CONJ(x,z,p,ax,az,q) P_ASSIGN2(x,z,p,ax,az,q) + #define ASSIGN_REAL(x,p,ax,q) + + #define MULT(x,z,p,ax,az,q,bx,bz,pb) + #define MULTADD(x,z,p,ax,az,q,bx,bz,pb) + #define ADD(x,z,p,ax,az,q,bx,bz,pb) + #define ADD_REAL(x,p, ax,q, bx,r) + #define MULTSUB(x,z,p,ax,az,q,bx,bz,pb) + #define MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) + #define MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) + #define LLDOT(x,p,ax,az,q) + #define CLEAR(x,z,p) + #define CLEAR_IMAG(x,z,p) + #define DIV(x,z,p,ax,az,q) + #define DIV_REAL(x,z,p, ax,az,q, bx,r) + #define MULT_REAL(x,z,p, ax,az,q, bx,r) + #define LDLDOT(x,p, ax,az,q, bx,r) + + #define XPRINT0(x,z,p) P_PRINT(0,x,z,p) + #define XPRINT1(x,z,p) P_PRINT(1,x,z,p) + #define XPRINT2(x,z,p) P_PRINT(2,x,z,p) + #define XPRINT3(x,z,p) P_PRINT(3,x,z,p) + +//------------------------------------------------------------------------------ +// real: double and single +//------------------------------------------------------------------------------ #elif defined (REAL) -#define PREFIX r_ -#define TEMPLATE(name) R_TEMPLATE(name) -#define TEMPLATE2(name) R_TEMPLATE(name) -#define XTYPE CHOLMOD_REAL -#define XTYPE2 CHOLMOD_REAL -#define XTYPE_OK(type) R_XTYPE_OK(type) -#define ENTRY_IS_NONZERO(ax,az,q) R_IS_NONZERO(ax,az,q) -#define ENTRY_IS_ZERO(ax,az,q) R_IS_ZERO(ax,az,q) -#define ENTRY_IS_ONE(ax,az,q) R_IS_ONE(ax,az,q) -#define IMAG_IS_NONZERO(ax,az,q) (FALSE) -#define ENTRY_SIZE 1 - -#define ASSEMBLE(x,z,p,ax,az,q) R_ASSEMBLE(x,z,p,ax,az,q) -#define ASSIGN(x,z,p,ax,az,q) R_ASSIGN(x,z,p,ax,az,q) -#define ASSIGN_CONJ(x,z,p,ax,az,q) R_ASSIGN(x,z,p,ax,az,q) -#define ASSIGN2(x,z,p,ax,az,q) R_ASSIGN(x,z,p,ax,az,q) -#define ASSIGN2_CONJ(x,z,p,ax,az,q) R_ASSIGN(x,z,p,ax,az,q) -#define ASSIGN_REAL(x,p,ax,q) R_ASSIGN_REAL(x,p,ax,q) -#define MULT(x,z,p,ax,az,q,bx,bz,pb) R_MULT(x,z,p,ax,az,q,bx,bz,pb) -#define MULTADD(x,z,p,ax,az,q,bx,bz,pb) R_MULTADD(x,z,p,ax,az,q,bx,bz,pb) -#define ADD(x,z,p,ax,az,q,bx,bz,pb) R_ADD(x,z,p,ax,az,q,bx,bz,pb) -#define ADD_REAL(x,p, ax,q, bx,r) R_ADD_REAL(x,p, ax,q, bx,r) -#define MULTSUB(x,z,p,ax,az,q,bx,bz,pb) R_MULTSUB(x,z,p,ax,az,q,bx,bz,pb) -#define MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) \ - R_MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) -#define MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) \ - R_MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) -#define LLDOT(x,p,ax,az,q) R_LLDOT(x,p,ax,az,q) -#define CLEAR(x,z,p) R_CLEAR(x,z,p) -#define CLEAR_IMAG(x,z,p) R_CLEAR_IMAG(x,z,p) -#define DIV(x,z,p,ax,az,q) R_DIV(x,z,p,ax,az,q) -#define DIV_REAL(x,z,p, ax,az,q, bx,r) R_DIV_REAL(x,z,p, ax,az,q, bx,r) -#define MULT_REAL(x,z,p, ax,az,q, bx,r) R_MULT_REAL(x,z,p, ax,az,q, bx,r) -#define LDLDOT(x,p, ax,az,q, bx,r) R_LDLDOT(x,p, ax,az,q, bx,r) - -#define XPRINT0(x,z,p) R_PRINT(0,x,z,p) -#define XPRINT1(x,z,p) R_PRINT(1,x,z,p) -#define XPRINT2(x,z,p) R_PRINT(2,x,z,p) -#define XPRINT3(x,z,p) R_PRINT(3,x,z,p) - -/* -------------------------------------------------------------------------- */ -/* complex */ -/* -------------------------------------------------------------------------- */ + #ifdef SINGLE + #define PREFIX r_s_ + #define TEMPLATE(name) R_S_TEMPLATE(name) + #define TEMPLATE2(name) R_S_TEMPLATE(name) + #else + #define PREFIX r_ + #define TEMPLATE(name) R_TEMPLATE(name) + #define TEMPLATE2(name) R_TEMPLATE(name) + #endif + + #define XTYPE CHOLMOD_REAL + #define XTYPE2 CHOLMOD_REAL + #define XTYPE_OK(type) R_XTYPE_OK(type) + #define ENTRY_IS_NONZERO(ax,az,q) R_IS_NONZERO(ax,az,q) + #define ENTRY_IS_ZERO(ax,az,q) R_IS_ZERO(ax,az,q) + #define ENTRY_IS_ONE(ax,az,q) R_IS_ONE(ax,az,q) + #define IMAG_IS_NONZERO(ax,az,q) (FALSE) + #define ENTRY_SIZE 1 + + #define ASSEMBLE(x,z,p,ax,az,q) R_ASSEMBLE(x,z,p,ax,az,q) + #define ASSIGN(x,z,p,ax,az,q) R_ASSIGN(x,z,p,ax,az,q) + #define ASSIGN_CONJ(x,z,p,ax,az,q) R_ASSIGN(x,z,p,ax,az,q) + #define ASSIGN2(x,z,p,ax,az,q) R_ASSIGN(x,z,p,ax,az,q) + #define ASSIGN2_CONJ(x,z,p,ax,az,q) R_ASSIGN(x,z,p,ax,az,q) + #define ASSIGN_REAL(x,p,ax,q) R_ASSIGN_REAL(x,p,ax,q) + + #define MULT(x,z,p,ax,az,q,bx,bz,pb) R_MULT(x,z,p,ax,az,q,bx,bz,pb) + #define MULTADD(x,z,p,ax,az,q,bx,bz,pb) R_MULTADD(x,z,p,ax,az,q,bx,bz,pb) + #define ADD(x,z,p,ax,az,q,bx,bz,pb) R_ADD(x,z,p,ax,az,q,bx,bz,pb) + #define ADD_REAL(x,p, ax,q, bx,r) R_ADD_REAL(x,p, ax,q, bx,r) + #define MULTSUB(x,z,p,ax,az,q,bx,bz,pb) R_MULTSUB(x,z,p,ax,az,q,bx,bz,pb) + #define MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) \ + R_MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) + #define MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) \ + R_MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) + #define LLDOT(x,p,ax,az,q) R_LLDOT(x,p,ax,az,q) + #define CLEAR(x,z,p) R_CLEAR(x,z,p) + #define CLEAR_IMAG(x,z,p) R_CLEAR_IMAG(x,z,p) + + #define DIV(x,z,p,ax,az,q) R_DIV(x,z,p,ax,az,q) + + #define DIV_REAL(x,z,p, ax,az,q, bx,r) R_DIV_REAL(x,z,p, ax,az,q, bx,r) + #define MULT_REAL(x,z,p, ax,az,q, bx,r) R_MULT_REAL(x,z,p, ax,az,q, bx,r) + #define LDLDOT(x,p, ax,az,q, bx,r) R_LDLDOT(x,p, ax,az,q, bx,r) + + #define XPRINT0(x,z,p) R_PRINT(0,x,z,p) + #define XPRINT1(x,z,p) R_PRINT(1,x,z,p) + #define XPRINT2(x,z,p) R_PRINT(2,x,z,p) + #define XPRINT3(x,z,p) R_PRINT(3,x,z,p) -#elif defined (COMPLEX) +//------------------------------------------------------------------------------ +// complex: both double and single +//------------------------------------------------------------------------------ -#define PREFIX c_ +#elif defined (COMPLEX) -#ifdef NCONJUGATE -#define TEMPLATE(name) CT_TEMPLATE(name) -#define TEMPLATE2(name) CT_TEMPLATE(name) -#else -#define TEMPLATE(name) C_TEMPLATE(name) -#define TEMPLATE2(name) C_TEMPLATE(name) -#endif + #ifdef SINGLE + #define PREFIX c_s_ + #ifdef NCONJUGATE + // non-conjugate + #define TEMPLATE(name) CT_S_TEMPLATE(name) + #define TEMPLATE2(name) CT_S_TEMPLATE(name) + #else + // conjugate + #define TEMPLATE(name) C_S_TEMPLATE(name) + #define TEMPLATE2(name) C_S_TEMPLATE(name) + #endif + #else + #define PREFIX c_ + #ifdef NCONJUGATE + // non-conjugate + #define TEMPLATE(name) CT_TEMPLATE(name) + #define TEMPLATE2(name) CT_TEMPLATE(name) + #else + // conjugate + #define TEMPLATE(name) C_TEMPLATE(name) + #define TEMPLATE2(name) C_TEMPLATE(name) + #endif + #endif + + #define ASSEMBLE(x,z,p,ax,az,q) C_ASSEMBLE(x,z,p,ax,az,q) + #define ASSIGN(x,z,p,ax,az,q) C_ASSIGN(x,z,p,ax,az,q) + #define ASSIGN_CONJ(x,z,p,ax,az,q) C_ASSIGN_CONJ(x,z,p,ax,az,q) + #define ASSIGN2(x,z,p,ax,az,q) C_ASSIGN(x,z,p,ax,az,q) + #define ASSIGN2_CONJ(x,z,p,ax,az,q) C_ASSIGN_CONJ(x,z,p,ax,az,q) + #define ASSIGN_REAL(x,p,ax,q) C_ASSIGN_REAL(x,p,ax,q) + + #define XTYPE CHOLMOD_COMPLEX + #define XTYPE2 CHOLMOD_COMPLEX + #define XTYPE_OK(type) C_XTYPE_OK(type) + #define ENTRY_IS_NONZERO(ax,az,q) C_IS_NONZERO(ax,az,q) + #define ENTRY_IS_ZERO(ax,az,q) C_IS_ZERO(ax,az,q) + #define ENTRY_IS_ONE(ax,az,q) C_IS_ONE(ax,az,q) + #define IMAG_IS_NONZERO(ax,az,q) C_IMAG_IS_NONZERO(ax,az,q) + #define ENTRY_SIZE 2 + + #define MULTADD(x,z,p,ax,az,q,bx,bz,pb) C_MULTADD(x,z,p,ax,az,q,bx,bz,pb) + #define MULT(x,z,p,ax,az,q,bx,bz,pb) C_MULT(x,z,p,ax,az,q,bx,bz,pb) + #define ADD(x,z,p,ax,az,q,bx,bz,pb) C_ADD(x,z,p,ax,az,q,bx,bz,pb) + #define ADD_REAL(x,p, ax,q, bx,r) C_ADD_REAL(x,p, ax,q, bx,r) + #define MULTSUB(x,z,p,ax,az,q,bx,bz,pb) C_MULTSUB(x,z,p,ax,az,q,bx,bz,pb) + #define MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) \ + C_MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) + #define MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) \ + C_MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) + #define LLDOT(x,p,ax,az,q) C_LLDOT(x,p,ax,az,q) + #define CLEAR(x,z,p) C_CLEAR(x,z,p) + #define CLEAR_IMAG(x,z,p) C_CLEAR_IMAG(x,z,p) + + #ifdef SINGLE + #define DIV(x,z,p,ax,az,q) C_S_DIV(x,z,p,ax,az,q) + #else + #define DIV(x,z,p,ax,az,q) C_DIV(x,z,p,ax,az,q) + #endif + + #define DIV_REAL(x,z,p, ax,az,q, bx,r) C_DIV_REAL(x,z,p, ax,az,q, bx,r) + #define MULT_REAL(x,z,p, ax,az,q, bx,r) C_MULT_REAL(x,z,p, ax,az,q, bx,r) + #define LDLDOT(x,p, ax,az,q, bx,r) C_LDLDOT(x,p, ax,az,q, bx,r) + + #define XPRINT0(x,z,p) C_PRINT(0,x,z,p) + #define XPRINT1(x,z,p) C_PRINT(1,x,z,p) + #define XPRINT2(x,z,p) C_PRINT(2,x,z,p) + #define XPRINT3(x,z,p) C_PRINT(3,x,z,p) -#define ASSEMBLE(x,z,p,ax,az,q) C_ASSEMBLE(x,z,p,ax,az,q) -#define ASSIGN(x,z,p,ax,az,q) C_ASSIGN(x,z,p,ax,az,q) -#define ASSIGN_CONJ(x,z,p,ax,az,q) C_ASSIGN_CONJ(x,z,p,ax,az,q) -#define ASSIGN2(x,z,p,ax,az,q) C_ASSIGN(x,z,p,ax,az,q) -#define ASSIGN2_CONJ(x,z,p,ax,az,q) C_ASSIGN_CONJ(x,z,p,ax,az,q) -#define ASSIGN_REAL(x,p,ax,q) C_ASSIGN_REAL(x,p,ax,q) -#define XTYPE CHOLMOD_COMPLEX -#define XTYPE2 CHOLMOD_COMPLEX -#define XTYPE_OK(type) C_XTYPE_OK(type) -#define ENTRY_IS_NONZERO(ax,az,q) C_IS_NONZERO(ax,az,q) -#define ENTRY_IS_ZERO(ax,az,q) C_IS_ZERO(ax,az,q) -#define ENTRY_IS_ONE(ax,az,q) C_IS_ONE(ax,az,q) -#define IMAG_IS_NONZERO(ax,az,q) C_IMAG_IS_NONZERO(ax,az,q) -#define ENTRY_SIZE 2 - -#define MULTADD(x,z,p,ax,az,q,bx,bz,pb) C_MULTADD(x,z,p,ax,az,q,bx,bz,pb) -#define MULT(x,z,p,ax,az,q,bx,bz,pb) C_MULT(x,z,p,ax,az,q,bx,bz,pb) -#define ADD(x,z,p,ax,az,q,bx,bz,pb) C_ADD(x,z,p,ax,az,q,bx,bz,pb) -#define ADD_REAL(x,p, ax,q, bx,r) C_ADD_REAL(x,p, ax,q, bx,r) -#define MULTSUB(x,z,p,ax,az,q,bx,bz,pb) C_MULTSUB(x,z,p,ax,az,q,bx,bz,pb) -#define MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) \ - C_MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) -#define MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) \ - C_MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) -#define LLDOT(x,p,ax,az,q) C_LLDOT(x,p,ax,az,q) -#define CLEAR(x,z,p) C_CLEAR(x,z,p) -#define CLEAR_IMAG(x,z,p) C_CLEAR_IMAG(x,z,p) -#define DIV(x,z,p,ax,az,q) C_DIV(x,z,p,ax,az,q) -#define DIV_REAL(x,z,p, ax,az,q, bx,r) C_DIV_REAL(x,z,p, ax,az,q, bx,r) -#define MULT_REAL(x,z,p, ax,az,q, bx,r) C_MULT_REAL(x,z,p, ax,az,q, bx,r) -#define LDLDOT(x,p, ax,az,q, bx,r) C_LDLDOT(x,p, ax,az,q, bx,r) - -#define XPRINT0(x,z,p) C_PRINT(0,x,z,p) -#define XPRINT1(x,z,p) C_PRINT(1,x,z,p) -#define XPRINT2(x,z,p) C_PRINT(2,x,z,p) -#define XPRINT3(x,z,p) C_PRINT(3,x,z,p) - -/* -------------------------------------------------------------------------- */ -/* zomplex */ -/* -------------------------------------------------------------------------- */ +//------------------------------------------------------------------------------ +// zomplex: both double and single +//------------------------------------------------------------------------------ #elif defined (ZOMPLEX) -#define PREFIX z_ + #ifdef SINGLE + #define PREFIX z_s_ + #ifdef NCONJUGATE + // non-conjugate + #define TEMPLATE(name) ZT_S_TEMPLATE(name) + #define TEMPLATE2(name) CT_S_TEMPLATE(name) + #else + // conjugate + #define TEMPLATE(name) Z_S_TEMPLATE(name) + #define TEMPLATE2(name) C_S_TEMPLATE(name) + #endif + #else + #define PREFIX z_ + #ifdef NCONJUGATE + // non-conjugate + #define TEMPLATE(name) ZT_TEMPLATE(name) + #define TEMPLATE2(name) CT_TEMPLATE(name) + #else + #define TEMPLATE(name) Z_TEMPLATE(name) + #define TEMPLATE2(name) C_TEMPLATE(name) + #endif + #endif + + #define ASSEMBLE(x,z,p,ax,az,q) Z_ASSEMBLE(x,z,p,ax,az,q) + #define ASSIGN(x,z,p,ax,az,q) Z_ASSIGN(x,z,p,ax,az,q) + #define ASSIGN_CONJ(x,z,p,ax,az,q) Z_ASSIGN_CONJ(x,z,p,ax,az,q) + #define ASSIGN2(x,z,p,ax,az,q) Z_ASSIGN(x,z,p,ax,az,q) + #define ASSIGN2_CONJ(x,z,p,ax,az,q) Z_ASSIGN_CONJ(x,z,p,ax,az,q) + #define ASSIGN_REAL(x,p,ax,q) Z_ASSIGN_REAL(x,p,ax,q) + + #define XTYPE CHOLMOD_ZOMPLEX + #define XTYPE2 CHOLMOD_ZOMPLEX + #define XTYPE_OK(type) Z_XTYPE_OK(type) + #define ENTRY_IS_NONZERO(ax,az,q) Z_IS_NONZERO(ax,az,q) + #define ENTRY_IS_ZERO(ax,az,q) Z_IS_ZERO(ax,az,q) + #define ENTRY_IS_ONE(ax,az,q) Z_IS_ONE(ax,az,q) + #define IMAG_IS_NONZERO(ax,az,q) Z_IMAG_IS_NONZERO(ax,az,q) + #define ENTRY_SIZE 1 + + #define MULTADD(x,z,p,ax,az,q,bx,bz,pb) Z_MULTADD(x,z,p,ax,az,q,bx,bz,pb) + #define MULT(x,z,p,ax,az,q,bx,bz,pb) Z_MULT(x,z,p,ax,az,q,bx,bz,pb) + #define ADD(x,z,p,ax,az,q,bx,bz,pb) Z_ADD(x,z,p,ax,az,q,bx,bz,pb) + #define ADD_REAL(x,p, ax,q, bx,r) Z_ADD_REAL(x,p, ax,q, bx,r) + #define MULTSUB(x,z,p,ax,az,q,bx,bz,pb) Z_MULTSUB(x,z,p,ax,az,q,bx,bz,pb) + #define MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) \ + Z_MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) + #define MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) \ + Z_MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) + #define LLDOT(x,p,ax,az,q) Z_LLDOT(x,p,ax,az,q) + #define CLEAR(x,z,p) Z_CLEAR(x,z,p) + #define CLEAR_IMAG(x,z,p) Z_CLEAR_IMAG(x,z,p) + + #ifdef SINGLE + #define DIV(x,z,p,ax,az,q) Z_S_DIV(x,z,p,ax,az,q) + #else + #define DIV(x,z,p,ax,az,q) Z_DIV(x,z,p,ax,az,q) + #endif + + #define DIV_REAL(x,z,p, ax,az,q, bx,r) Z_DIV_REAL(x,z,p, ax,az,q, bx,r) + #define MULT_REAL(x,z,p, ax,az,q, bx,r) Z_MULT_REAL(x,z,p, ax,az,q, bx,r) + #define LDLDOT(x,p, ax,az,q, bx,r) Z_LDLDOT(x,p, ax,az,q, bx,r) + + #define XPRINT0(x,z,p) Z_PRINT(0,x,z,p) + #define XPRINT1(x,z,p) Z_PRINT(1,x,z,p) + #define XPRINT2(x,z,p) Z_PRINT(2,x,z,p) + #define XPRINT3(x,z,p) Z_PRINT(3,x,z,p) + +#endif #ifdef NCONJUGATE -#define TEMPLATE(name) ZT_TEMPLATE(name) -#define TEMPLATE2(name) CT_TEMPLATE(name) + // non-conjugate assign + #define ASSIGN_CONJ_OR_NCONJ(x,z,p,ax,az,q) ASSIGN(x,z,p,ax,az,q) #else -#define TEMPLATE(name) Z_TEMPLATE(name) -#define TEMPLATE2(name) C_TEMPLATE(name) + // conjugate assign + #define ASSIGN_CONJ_OR_NCONJ(x,z,p,ax,az,q) ASSIGN_CONJ(x,z,p,ax,az,q) #endif -#define ASSEMBLE(x,z,p,ax,az,q) Z_ASSEMBLE(x,z,p,ax,az,q) -#define ASSIGN(x,z,p,ax,az,q) Z_ASSIGN(x,z,p,ax,az,q) -#define ASSIGN_CONJ(x,z,p,ax,az,q) Z_ASSIGN_CONJ(x,z,p,ax,az,q) -#define ASSIGN2(x,z,p,ax,az,q) Z_ASSIGN(x,z,p,ax,az,q) -#define ASSIGN2_CONJ(x,z,p,ax,az,q) Z_ASSIGN_CONJ(x,z,p,ax,az,q) -#define ASSIGN_REAL(x,p,ax,q) Z_ASSIGN_REAL(x,p,ax,q) -#define XTYPE CHOLMOD_ZOMPLEX -#define XTYPE2 CHOLMOD_ZOMPLEX -#define XTYPE_OK(type) Z_XTYPE_OK(type) -#define ENTRY_IS_NONZERO(ax,az,q) Z_IS_NONZERO(ax,az,q) -#define ENTRY_IS_ZERO(ax,az,q) Z_IS_ZERO(ax,az,q) -#define ENTRY_IS_ONE(ax,az,q) Z_IS_ONE(ax,az,q) -#define IMAG_IS_NONZERO(ax,az,q) Z_IMAG_IS_NONZERO(ax,az,q) -#define ENTRY_SIZE 1 - -#define MULTADD(x,z,p,ax,az,q,bx,bz,pb) Z_MULTADD(x,z,p,ax,az,q,bx,bz,pb) -#define MULT(x,z,p,ax,az,q,bx,bz,pb) Z_MULT(x,z,p,ax,az,q,bx,bz,pb) -#define ADD(x,z,p,ax,az,q,bx,bz,pb) Z_ADD(x,z,p,ax,az,q,bx,bz,pb) -#define ADD_REAL(x,p, ax,q, bx,r) Z_ADD_REAL(x,p, ax,q, bx,r) -#define MULTSUB(x,z,p,ax,az,q,bx,bz,pb) Z_MULTSUB(x,z,p,ax,az,q,bx,bz,pb) -#define MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) \ - Z_MULTADDCONJ(x,z,p,ax,az,q,bx,bz,pb) -#define MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) \ - Z_MULTSUBCONJ(x,z,p,ax,az,q,bx,bz,pb) -#define LLDOT(x,p,ax,az,q) Z_LLDOT(x,p,ax,az,q) -#define CLEAR(x,z,p) Z_CLEAR(x,z,p) -#define CLEAR_IMAG(x,z,p) Z_CLEAR_IMAG(x,z,p) -#define DIV(x,z,p,ax,az,q) Z_DIV(x,z,p,ax,az,q) -#define DIV_REAL(x,z,p, ax,az,q, bx,r) Z_DIV_REAL(x,z,p, ax,az,q, bx,r) -#define MULT_REAL(x,z,p, ax,az,q, bx,r) Z_MULT_REAL(x,z,p, ax,az,q, bx,r) -#define LDLDOT(x,p, ax,az,q, bx,r) Z_LDLDOT(x,p, ax,az,q, bx,r) - -#define XPRINT0(x,z,p) Z_PRINT(0,x,z,p) -#define XPRINT1(x,z,p) Z_PRINT(1,x,z,p) -#define XPRINT2(x,z,p) Z_PRINT(2,x,z,p) -#define XPRINT3(x,z,p) Z_PRINT(3,x,z,p) - -#endif diff --git a/CHOLMOD/Include/cholmod_types.h b/CHOLMOD/Include/cholmod_types.h index e82f783d7..ab6dde04f 100644 --- a/CHOLMOD/Include/cholmod_types.h +++ b/CHOLMOD/Include/cholmod_types.h @@ -8,132 +8,75 @@ //------------------------------------------------------------------------------ -// CHOLMOD internal include file: defining integer and floating-point types. -// This file is suitable for inclusion in C and C++ codes. It can be -// #include'd more than once. - -// The #include'ing file defines one of four macros (DINT, DLONG, SINT, or -// SLONG) before #include'ing this file. - -/* ========================================================================== */ -/* === int/long and double/float definitions ================================ */ -/* ========================================================================== */ - -/* CHOLMOD is designed for 3 types of integer variables: - * - * (1) all integers are int - * (2) most integers are int, some are int64_t - * (3) all integers are int64_t - * - * and two kinds of floating-point values: - * - * (1) double - * (2) float - * - * the complex types (ANSI-compatible complex, and MATLAB-compatable zomplex) - * are based on the double or float type, and are not selected here. They - * are typically selected via template routines. - * - * This gives 6 different modes in which CHOLMOD can be compiled (only the - * first two are currently supported): - * - * DINT double, int prefix: cholmod_ - * DLONG double, int64_t prefix: cholmod_l_ - * DMIX double, mixed int/int64_t prefix: cholmod_m_ - * SINT float, int prefix: cholmod_si_ - * SLONG float, int64_t prefix: cholmod_sl_ - * SMIX float, mixed int/log prefix: cholmod_sm_ - * - * These are selected with compile time flags (-DDLONG, for example). If no - * flag is selected, the default is DINT. - * - * All six versions use the same include files. The user-visible include files - * are completely independent of which int/long/double/float version is being - * used. The integer / real types in all data structures (sparse, triplet, - * dense, common, and triplet) are defined at run-time, not compile-time, so - * there is only one "cholmod_sparse" data type. Void pointers are used inside - * that data structure to point to arrays of the proper type. Each data - * structure has an itype and dtype field which determines the kind of basic - * types used. These are defined in Include/cholmod_core.h. - * - * FUTURE WORK: support all six types (float, and mixed int/long) - * SINT and SLONG are in progress. - */ +// CHOLMOD internal include file for defining integer types. This file is +// suitable for inclusion in C and C++ codes. It can be #include'd more than +// once. The #include'ing file defines one of two macros (CHOLMOD_INT32 or +// CHOLMOD_INT64). CHOLMOD is designed for 2 types of integer variables: +// int32_t or int64_t. +// +// The complex types (ANSI-compatible complex, and MATLAB-compatable zomplex) +// are based on the double or float type, and are not selected here. They are +// typically selected via template routines. // ----------------------------------------------------------------------------- -#undef Real #undef Int #undef UInt #undef Int_max #undef CHOLMOD #undef ITYPE -#undef DTYPE #undef ID +#undef CLEAR_FLAG -#if defined ( SLONG ) +#if defined ( CHOLMOD_INT64 ) //-------------------------------------------------------------------------- - // SLONG: float (also complex float), int64_t + // CHOLMOD_INT64: int64_t //-------------------------------------------------------------------------- - #define Real float - #define Int int64_t - #define UInt uint64_t - #define Int_max INT64_MAX - #define CHOLMOD(name) cholmod_sl_ ## name - #define ITYPE CHOLMOD_LONG - #define DTYPE CHOLMOD_SINGLE - #define ID "%" PRId64 - -#elif defined ( SINT ) - - //-------------------------------------------------------------------------- - // SINT: float (also complex float), int32_t - //-------------------------------------------------------------------------- - - #define Real float - #define Int int32_t - #define UInt uint32_t - #define Int_max INT32_MAX - #define CHOLMOD(name) cholmod_si_ ## name - #define ITYPE CHOLMOD_INT - #define DTYPE CHOLMOD_SINGLE - #define ID "%d" - -#elif defined ( DLONG ) - - //-------------------------------------------------------------------------- - // DLONG: double (also complex double), int64_t - //-------------------------------------------------------------------------- - - #define Real double #define Int int64_t #define UInt uint64_t #define Int_max INT64_MAX #define CHOLMOD(name) cholmod_l_ ## name #define ITYPE CHOLMOD_LONG - #define DTYPE CHOLMOD_DOUBLE #define ID "%" PRId64 + #define CLEAR_FLAG(Common) \ + { \ + Common->mark++ ; \ + if (Common->mark <= 0) \ + { \ + Common->mark = EMPTY ; \ + cholmod_l_clear_flag (Common) ; \ + } \ + } + #else //-------------------------------------------------------------------------- - // DINT: double (also complex double), int32 + // CHOLMOD_INT32: int32 //-------------------------------------------------------------------------- - #ifndef DINT - #define DINT + #ifndef CHOLMOD_INT32 + #define CHOLMOD_INT32 #endif - #define Real double #define Int int32_t #define UInt uint32_t #define Int_max INT32_MAX #define CHOLMOD(name) cholmod_ ## name #define ITYPE CHOLMOD_INT - #define DTYPE CHOLMOD_DOUBLE #define ID "%d" + #define CLEAR_FLAG(Common) \ + { \ + Common->mark++ ; \ + if (Common->mark <= 0 || Common->mark > INT32_MAX) \ + { \ + Common->mark = EMPTY ; \ + cholmod_clear_flag (Common) ; \ + } \ + } + #endif diff --git a/CHOLMOD/MATLAB/analyze.c b/CHOLMOD/MATLAB/analyze.c index 32e8fa7ee..641c1035b 100644 --- a/CHOLMOD/MATLAB/analyze.c +++ b/CHOLMOD/MATLAB/analyze.c @@ -71,7 +71,7 @@ void mexFunction if (nargin == 3) { cm->nmethods = mxGetScalar (pargin [2]) ; - if (cm->nmethods == -1) + if (cm->nmethods == -1 || cm->nmethods == 1 || cm->nmethods == 2) { /* use AMD only */ cm->nmethods = 1 ; diff --git a/CHOLMOD/MATLAB/cholmod_make.m b/CHOLMOD/MATLAB/cholmod_make.m index 715c37f6b..a8c3a1e26 100644 --- a/CHOLMOD/MATLAB/cholmod_make.m +++ b/CHOLMOD/MATLAB/cholmod_make.m @@ -141,20 +141,76 @@ cholmod_matlab = { 'cholmod_matlab' } ; cholmod_src = { - '../Core/cholmod_l_aat', ... - '../Core/cholmod_l_add', ... - '../Core/cholmod_l_band', ... - '../Core/cholmod_l_change_factor', ... - '../Core/cholmod_l_common', ... - '../Core/cholmod_l_complex', ... - '../Core/cholmod_l_copy', ... - '../Core/cholmod_l_dense', ... - '../Core/cholmod_l_error', ... - '../Core/cholmod_l_factor', ... - '../Core/cholmod_l_memory', ... - '../Core/cholmod_l_sparse', ... - '../Core/cholmod_l_transpose', ... - '../Core/cholmod_l_triplet', ... + '../Utility/cholmod_l_aat', ... + '../Utility/cholmod_l_add', ... + '../Utility/cholmod_l_add_size_t', ... + '../Utility/cholmod_l_allocate_dense', ... + '../Utility/cholmod_l_allocate_factor', ... + '../Utility/cholmod_l_allocate_sparse', ... + '../Utility/cholmod_l_allocate_triplet', ... + '../Utility/cholmod_l_allocate_work', ... + '../Utility/cholmod_l_alloc_factor', ... + '../Utility/cholmod_l_alloc_work', ... + '../Utility/cholmod_l_band', ... + '../Utility/cholmod_l_band_nnz', ... + '../Utility/cholmod_l_calloc', ... + '../Utility/cholmod_l_change_factor', ... + '../Utility/cholmod_l_clear_flag', ... + '../Utility/cholmod_l_copy', ... + '../Utility/cholmod_l_copy_dense2', ... + '../Utility/cholmod_l_copy_dense', ... + '../Utility/cholmod_l_copy_factor', ... + '../Utility/cholmod_l_copy_sparse', ... + '../Utility/cholmod_l_copy_triplet', ... + '../Utility/cholmod_l_cumsum', ... + '../Utility/cholmod_l_dbound', ... + '../Utility/cholmod_l_defaults', ... + '../Utility/cholmod_l_dense_nnz', ... + '../Utility/cholmod_l_dense_to_sparse', ... + '../Utility/cholmod_l_divcomplex', ... + '../Utility/cholmod_l_ensure_dense', ... + '../Utility/cholmod_l_error', ... + '../Utility/cholmod_l_eye', ... + '../Utility/cholmod_l_factor_to_sparse', ... + '../Utility/cholmod_l_finish', ... + '../Utility/cholmod_l_free', ... + '../Utility/cholmod_l_free_dense', ... + '../Utility/cholmod_l_free_factor', ... + '../Utility/cholmod_l_free_sparse', ... + '../Utility/cholmod_l_free_triplet', ... + '../Utility/cholmod_l_free_work', ... + '../Utility/cholmod_l_hypot', ... + '../Utility/cholmod_l_malloc', ... + '../Utility/cholmod_l_maxrank', ... + '../Utility/cholmod_l_mult_size_t', ... + '../Utility/cholmod_l_nnz', ... + '../Utility/cholmod_l_ones', ... + '../Utility/cholmod_l_pack_factor', ... + '../Utility/cholmod_l_ptranspose', ... + '../Utility/cholmod_l_reallocate_column', ... + '../Utility/cholmod_l_reallocate_factor', ... + '../Utility/cholmod_l_reallocate_sparse', ... + '../Utility/cholmod_l_reallocate_triplet', ... + '../Utility/cholmod_l_realloc', ... + '../Utility/cholmod_l_realloc_multiple', ... + '../Utility/cholmod_l_sbound', ... + '../Utility/cholmod_l_score_comp', ... + '../Utility/cholmod_l_set_empty', ... + '../Utility/cholmod_l_sort', ... + '../Utility/cholmod_l_sparse_to_dense', ... + '../Utility/cholmod_l_sparse_to_triplet', ... + '../Utility/cholmod_l_speye', ... + '../Utility/cholmod_l_spzeros', ... + '../Utility/cholmod_l_start', ... + '../Utility/cholmod_l_transpose', ... + '../Utility/cholmod_l_transpose_sym', ... + '../Utility/cholmod_l_transpose_unsym', ... + '../Utility/cholmod_l_triplet_to_sparse', ... + '../Utility/cholmod_l_version', ... + '../Utility/cholmod_l_xtype', ... + '../Utility/cholmod_l_zeros', ... + '../Utility/cholmod_mult_uint64_t', ... + '../Utility/cholmod_memdebug', ... '../Check/cholmod_l_check', ... '../Check/cholmod_l_read', ... '../Check/cholmod_l_write', ... diff --git a/CHOLMOD/MATLAB/cholmod_matlab.c b/CHOLMOD/MATLAB/cholmod_matlab.c index 31a377bde..cb86ca5e7 100644 --- a/CHOLMOD/MATLAB/cholmod_matlab.c +++ b/CHOLMOD/MATLAB/cholmod_matlab.c @@ -718,8 +718,8 @@ cholmod_sparse *sputil_extract_zeros { for (p = Ap [j] ; p < Ap [j+1] ; p++) { - if (CHOLMOD_IS_ZERO (Ax [p]) && - ((is_complex) ? CHOLMOD_IS_ZERO (Az [p]) : TRUE)) + if ((Ax [p] == 0) && + ((is_complex) ? (Az [p] == 0) : TRUE)) { nzeros++ ; } @@ -741,8 +741,8 @@ cholmod_sparse *sputil_extract_zeros Zp [j] = pz ; for (p = Ap [j] ; p < Ap [j+1] ; p++) { - if (CHOLMOD_IS_ZERO (Ax [p]) && - ((is_complex) ? CHOLMOD_IS_ZERO (Az [p]) : TRUE)) + if ((Ax [p] == 0) && + ((is_complex) ? (Az [p] == 0) : TRUE)) { Zi [pz] = Ai [p] ; Zx [pz] = 1 ; @@ -803,7 +803,7 @@ int64_t sputil_drop_zeros { sik = Sx [p] ; zik = Sz [p] ; - if (CHOLMOD_IS_NONZERO (sik) || CHOLMOD_IS_NONZERO (zik)) + if ((sik != 0) || (zik != 0)) { if (p != pdest) { @@ -826,7 +826,7 @@ int64_t sputil_drop_zeros for ( ; p < pend ; p++) { sik = Sx [p] ; - if (CHOLMOD_IS_NONZERO (sik)) + if ((sik != 0)) { if (p != pdest) { @@ -1078,7 +1078,7 @@ int64_t sputil_copy_ij /* returns the dimension, n */ for (i = 0 ; i < nrow ; i++) \ { \ xij = X [i + j*nrow] ; \ - if (CHOLMOD_IS_NONZERO (xij)) \ + if (xij != 0) \ { \ nz++ ; \ } \ @@ -1099,7 +1099,7 @@ int64_t sputil_copy_ij /* returns the dimension, n */ for (i = 0 ; i < nrow ; i++) \ { \ xij = X [i + j*nrow] ; \ - if (CHOLMOD_IS_NONZERO (xij)) \ + if (xij != 0) \ { \ Si [nz] = i ; \ Sx [nz] = (stype) xij ; \ @@ -1155,7 +1155,7 @@ mxArray *sputil_dense_to_sparse (const mxArray *arg) { xij = X [i + j*nrow] ; zij = Z [i + j*nrow] ; - if (CHOLMOD_IS_NONZERO (xij) || CHOLMOD_IS_NONZERO (zij)) + if ((xij != 0) || (zij != 0)) { nz++ ; } @@ -1174,7 +1174,7 @@ mxArray *sputil_dense_to_sparse (const mxArray *arg) { xij = X [i + j*nrow] ; zij = Z [i + j*nrow] ; - if (CHOLMOD_IS_NONZERO (xij) || CHOLMOD_IS_NONZERO (zij)) + if ((xij != 0) || (zij != 0)) { Si [nz] = i ; Sx [nz] = xij ; @@ -1606,7 +1606,7 @@ mxArray *sputil_copy_sparse (const mxArray *A) { aij = Ax [p] ; zij = Az [p] ; - if (CHOLMOD_IS_NONZERO (aij) || CHOLMOD_IS_NONZERO (zij)) + if ((aij != 0) || (zij != 0)) { snz++ ; } @@ -1629,7 +1629,7 @@ mxArray *sputil_copy_sparse (const mxArray *A) { aij = Ax [p] ; zij = Az [p] ; - if (CHOLMOD_IS_NONZERO (aij) || CHOLMOD_IS_NONZERO (zij)) + if ((aij != 0) || (zij != 0)) { Si [snz] = Ai [p] ; Sx [snz] = aij ; @@ -1652,7 +1652,7 @@ mxArray *sputil_copy_sparse (const mxArray *A) for (p = 0 ; p < anz ; p++) { aij = Ax [p] ; - if (CHOLMOD_IS_NONZERO (aij)) + if (aij != 0) { snz++ ; } @@ -1673,7 +1673,7 @@ mxArray *sputil_copy_sparse (const mxArray *A) for (p = Ap [j] ; p < pend ; p++) { aij = Ax [p] ; - if (CHOLMOD_IS_NONZERO (aij)) + if (aij != 0) { Si [snz] = Ai [p] ; Sx [snz] = aij ; diff --git a/CHOLMOD/MATLAB/mread.c b/CHOLMOD/MATLAB/mread.c index 6783ef62f..e0cb677d5 100644 --- a/CHOLMOD/MATLAB/mread.c +++ b/CHOLMOD/MATLAB/mread.c @@ -89,7 +89,7 @@ void mexFunction mexErrMsgTxt ("could not read file") ; } - /* get the specific matrix (A or X), and change to ZOMPLEX if needed */ + /* get the specific matrix (A or X), and change to zomplex if needed */ if (mtype == CHOLMOD_SPARSE) { A = (cholmod_sparse *) G ; @@ -100,7 +100,7 @@ void mexFunction Ai = A->i ; if (is_complex) { - /* if complex, ensure A is ZOMPLEX */ + /* if complex, ensure A is zomplex */ cholmod_l_sparse_xtype (CHOLMOD_ZOMPLEX, A, cm) ; } Ax = A->x ; @@ -114,7 +114,7 @@ void mexFunction is_complex = (X->xtype == CHOLMOD_COMPLEX) ; if (is_complex) { - /* if complex, ensure X is ZOMPLEX */ + /* if complex, ensure X is zomplex */ cholmod_l_dense_xtype (CHOLMOD_ZOMPLEX, X, cm) ; } Ax = X->x ; diff --git a/CHOLMOD/MatrixOps/cholmod_drop.c b/CHOLMOD/MatrixOps/cholmod_drop.c index 005c0ee90..eceb86a7c 100644 --- a/CHOLMOD/MatrixOps/cholmod_drop.c +++ b/CHOLMOD/MatrixOps/cholmod_drop.c @@ -88,7 +88,7 @@ int CHOLMOD(drop) { i = Ai [p] ; aij = Ax [p] ; - if (i <= j && (fabs (aij) > tol || IS_NAN (aij))) + if (i <= j && (fabs (aij) > tol || isnan (aij))) { Ai [nz] = i ; Ax [nz] = aij ; @@ -114,7 +114,7 @@ int CHOLMOD(drop) { i = Ai [p] ; aij = Ax [p] ; - if (i >= j && (fabs (aij) > tol || IS_NAN (aij))) + if (i >= j && (fabs (aij) > tol || isnan (aij))) { Ai [nz] = i ; Ax [nz] = aij ; @@ -139,7 +139,7 @@ int CHOLMOD(drop) { i = Ai [p] ; aij = Ax [p] ; - if (fabs (aij) > tol || IS_NAN (aij)) + if (fabs (aij) > tol || isnan (aij)) { Ai [nz] = i ; Ax [nz] = aij ; diff --git a/CHOLMOD/MatrixOps/cholmod_l_drop.c b/CHOLMOD/MatrixOps/cholmod_l_drop.c index 1cfd378d6..da5ab9e09 100644 --- a/CHOLMOD/MatrixOps/cholmod_l_drop.c +++ b/CHOLMOD/MatrixOps/cholmod_l_drop.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_drop.c" diff --git a/CHOLMOD/MatrixOps/cholmod_l_horzcat.c b/CHOLMOD/MatrixOps/cholmod_l_horzcat.c index 7172b3052..a8f9cac9d 100644 --- a/CHOLMOD/MatrixOps/cholmod_l_horzcat.c +++ b/CHOLMOD/MatrixOps/cholmod_l_horzcat.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_horzcat.c" diff --git a/CHOLMOD/MatrixOps/cholmod_l_norm.c b/CHOLMOD/MatrixOps/cholmod_l_norm.c index c25c2dc28..b3bb886ba 100644 --- a/CHOLMOD/MatrixOps/cholmod_l_norm.c +++ b/CHOLMOD/MatrixOps/cholmod_l_norm.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_norm.c" diff --git a/CHOLMOD/MatrixOps/cholmod_l_scale.c b/CHOLMOD/MatrixOps/cholmod_l_scale.c index 89cc869fe..8c56e00e1 100644 --- a/CHOLMOD/MatrixOps/cholmod_l_scale.c +++ b/CHOLMOD/MatrixOps/cholmod_l_scale.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_scale.c" diff --git a/CHOLMOD/MatrixOps/cholmod_l_sdmult.c b/CHOLMOD/MatrixOps/cholmod_l_sdmult.c index 02b950cae..94cce9891 100644 --- a/CHOLMOD/MatrixOps/cholmod_l_sdmult.c +++ b/CHOLMOD/MatrixOps/cholmod_l_sdmult.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_sdmult.c" diff --git a/CHOLMOD/MatrixOps/cholmod_l_ssmult.c b/CHOLMOD/MatrixOps/cholmod_l_ssmult.c index ce613099e..521771f2d 100644 --- a/CHOLMOD/MatrixOps/cholmod_l_ssmult.c +++ b/CHOLMOD/MatrixOps/cholmod_l_ssmult.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_ssmult.c" diff --git a/CHOLMOD/MatrixOps/cholmod_l_submatrix.c b/CHOLMOD/MatrixOps/cholmod_l_submatrix.c index d7797fd94..0ceb8037b 100644 --- a/CHOLMOD/MatrixOps/cholmod_l_submatrix.c +++ b/CHOLMOD/MatrixOps/cholmod_l_submatrix.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_submatrix.c" diff --git a/CHOLMOD/MatrixOps/cholmod_l_symmetry.c b/CHOLMOD/MatrixOps/cholmod_l_symmetry.c index d95ede094..b42176247 100644 --- a/CHOLMOD/MatrixOps/cholmod_l_symmetry.c +++ b/CHOLMOD/MatrixOps/cholmod_l_symmetry.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_symmetry.c" diff --git a/CHOLMOD/MatrixOps/cholmod_l_vertcat.c b/CHOLMOD/MatrixOps/cholmod_l_vertcat.c index 2507a141a..c567f5c94 100644 --- a/CHOLMOD/MatrixOps/cholmod_l_vertcat.c +++ b/CHOLMOD/MatrixOps/cholmod_l_vertcat.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_vertcat.c" diff --git a/CHOLMOD/MatrixOps/cholmod_norm.c b/CHOLMOD/MatrixOps/cholmod_norm.c index 73d205712..e4a2b55b7 100644 --- a/CHOLMOD/MatrixOps/cholmod_norm.c +++ b/CHOLMOD/MatrixOps/cholmod_norm.c @@ -144,7 +144,7 @@ double CHOLMOD(norm_dense) for (i = 0 ; i < nrow ; i++) { s = W [i] ; - if ((IS_NAN (s) || s > xnorm) && !IS_NAN (xnorm)) + if ((isnan (s) || s > xnorm) && !isnan (xnorm)) { xnorm = s ; } @@ -166,7 +166,7 @@ double CHOLMOD(norm_dense) { s += abs_value (xtype, Xx, Xz, i+j*d, Common) ; } - if ((IS_NAN (s) || s > xnorm) && !IS_NAN (xnorm)) + if ((isnan (s) || s > xnorm) && !isnan (xnorm)) { xnorm = s ; } @@ -187,7 +187,7 @@ double CHOLMOD(norm_dense) { s += abs_value (xtype, Xx, Xz, i+j*d, Common) ; } - if ((IS_NAN (s) || s > xnorm) && !IS_NAN (xnorm)) + if ((isnan (s) || s > xnorm) && !isnan (xnorm)) { xnorm = s ; } @@ -416,7 +416,7 @@ double CHOLMOD(norm_sparse) s += abs_value (xtype, Ax, Az, p, Common) ; } } - if ((IS_NAN (s) || s > anorm) && !IS_NAN (anorm)) + if ((isnan (s) || s > anorm) && !isnan (anorm)) { anorm = s ; } @@ -432,7 +432,7 @@ double CHOLMOD(norm_sparse) for (i = 0 ; i < nrow ; i++) { s = W [i] ; - if ((IS_NAN (s) || s > anorm) && !IS_NAN (anorm)) + if ((isnan (s) || s > anorm) && !isnan (anorm)) { anorm = s ; } diff --git a/CHOLMOD/MatrixOps/cholmod_sdmult.c b/CHOLMOD/MatrixOps/cholmod_sdmult.c index 0a5bf5443..6e66448fd 100644 --- a/CHOLMOD/MatrixOps/cholmod_sdmult.c +++ b/CHOLMOD/MatrixOps/cholmod_sdmult.c @@ -115,8 +115,8 @@ int CHOLMOD(sdmult) ASSERT (CHOLMOD(dump_sparse) (A, "A", Common) >= 0) ; DEBUG (CHOLMOD(dump_dense) (X, "X", Common)) ; - DEBUG (if (IS_NONZERO (beta [0]) - || (IS_NONZERO (beta [1]) && A->xtype != CHOLMOD_REAL)) + DEBUG (if ((beta [0] != 0) + || ((beta [1] != 0) && A->xtype != CHOLMOD_REAL)) CHOLMOD(dump_dense) (Y, "Y", Common)) ; switch (A->xtype) diff --git a/CHOLMOD/MatrixOps/cholmod_ssmult.c b/CHOLMOD/MatrixOps/cholmod_ssmult.c index 2257851cb..17a40a60a 100644 --- a/CHOLMOD/MatrixOps/cholmod_ssmult.c +++ b/CHOLMOD/MatrixOps/cholmod_ssmult.c @@ -178,7 +178,7 @@ cholmod_sparse *CHOLMOD(ssmult) { /* clear the Flag array */ /* mark = CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; mark = Common->mark ; /* for each nonzero B(t,j) in column j, do: */ @@ -209,7 +209,8 @@ cholmod_sparse *CHOLMOD(ssmult) } /* mark = CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; + ASSERT (check_flag (Common)) ; mark = Common->mark ; /* ---------------------------------------------------------------------- */ @@ -330,7 +331,7 @@ cholmod_sparse *CHOLMOD(ssmult) { /* clear the Flag array */ /* mark = CHOLMOD(clear_flag (Common)) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; mark = Common->mark ; /* start column j of C */ @@ -379,7 +380,7 @@ cholmod_sparse *CHOLMOD(ssmult) { /* clear the Flag array */ /* mark = CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; mark = Common->mark ; /* start column j of C */ @@ -419,7 +420,8 @@ cholmod_sparse *CHOLMOD(ssmult) CHOLMOD(free_sparse) (&A2, Common) ; CHOLMOD(free_sparse) (&B2, Common) ; /* CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; + ASSERT (check_flag (Common)) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)) ; /* ---------------------------------------------------------------------- */ @@ -477,7 +479,7 @@ cholmod_sparse *CHOLMOD(ssmult) /* return result */ /* ---------------------------------------------------------------------- */ - DEBUG (CHOLMOD(dump_sparse) (C, "ssmult", Common) >= 0) ; + ASSERT (CHOLMOD(dump_sparse) (C, "ssmult", Common) >= 0) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)) ; return (C) ; } diff --git a/CHOLMOD/MatrixOps/cholmod_submatrix.c b/CHOLMOD/MatrixOps/cholmod_submatrix.c index dcb2942f4..9d0127c7b 100644 --- a/CHOLMOD/MatrixOps/cholmod_submatrix.c +++ b/CHOLMOD/MatrixOps/cholmod_submatrix.c @@ -107,6 +107,13 @@ cholmod_sparse *CHOLMOD(submatrix) ERROR (CHOLMOD_INVALID, "symmetric upper or lower case not supported") ; return (NULL) ; } + + if (rsize > Int_max || csize > Int_max) + { + ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; + return (NULL) ; + } + Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ @@ -115,8 +122,9 @@ cholmod_sparse *CHOLMOD(submatrix) ancol = A->ncol ; anrow = A->nrow ; - nr = rsize ; - nc = csize ; + nr = (Int) rsize ; + nc = (Int) csize ; + if (rset == NULL) { /* nr = 0 denotes rset = [ ], nr < 0 denotes rset = 0:anrow-1 */ @@ -147,6 +155,7 @@ cholmod_sparse *CHOLMOD(submatrix) } return (C) ; } + PRINT1 (("submatrix nr "ID" nc "ID" Cnrow "ID" Cncol "ID"" " Anrow "ID" Ancol "ID"\n", nr, nc, cnrow, cncol, anrow, ancol)) ; diff --git a/CHOLMOD/Modify/cholmod_l_rowadd.c b/CHOLMOD/Modify/cholmod_l_rowadd.c index 49408762b..86bcd9cf4 100644 --- a/CHOLMOD/Modify/cholmod_l_rowadd.c +++ b/CHOLMOD/Modify/cholmod_l_rowadd.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_rowadd.c" diff --git a/CHOLMOD/Modify/cholmod_l_rowdel.c b/CHOLMOD/Modify/cholmod_l_rowdel.c index 0268ec114..c8839bc11 100644 --- a/CHOLMOD/Modify/cholmod_l_rowdel.c +++ b/CHOLMOD/Modify/cholmod_l_rowdel.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_rowdel.c" diff --git a/CHOLMOD/Modify/cholmod_l_updown.c b/CHOLMOD/Modify/cholmod_l_updown.c index 9debeffd1..a37713cb7 100644 --- a/CHOLMOD/Modify/cholmod_l_updown.c +++ b/CHOLMOD/Modify/cholmod_l_updown.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_updown.c" diff --git a/CHOLMOD/Modify/cholmod_rowadd.c b/CHOLMOD/Modify/cholmod_rowadd.c index df21326a8..32811db1b 100644 --- a/CHOLMOD/Modify/cholmod_rowadd.c +++ b/CHOLMOD/Modify/cholmod_rowadd.c @@ -344,7 +344,8 @@ int CHOLMOD(rowadd_mark) { /* out of memory, L is now simplicial symbolic */ /* CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; + ASSERT (check_flag (Common)) ; for (i = 0 ; i < n ; i++) { W [i] = 0 ; @@ -530,7 +531,7 @@ int CHOLMOD(rowadd_mark) /* ensure abs (dk) >= dbound, if dbound is given */ /* ---------------------------------------------------------------------- */ - dk = (IS_GT_ZERO (Common->dbound)) ? (CHOLMOD(dbound) (dk, Common)) : dk ; + dk = (Common->dbound > 0) ? (CHOLMOD(dbound) (dk, Common)) : dk ; PRINT2 (("D [k = "ID"] = %g\n", k, dk)) ; @@ -620,7 +621,7 @@ int CHOLMOD(rowadd_mark) PRINT1 (("rowadd update lnz = "ID"\n", lnz)) ; if (lnz > 0) { - do_update = IS_LT_ZERO (dk) ; + do_update = (dk < 0) ; if (do_update) { dk = -dk ; diff --git a/CHOLMOD/Modify/cholmod_rowdel.c b/CHOLMOD/Modify/cholmod_rowdel.c index d040df076..d33af94a1 100644 --- a/CHOLMOD/Modify/cholmod_rowdel.c +++ b/CHOLMOD/Modify/cholmod_rowdel.c @@ -395,7 +395,7 @@ int CHOLMOD(rowdel_mark) } } - do_update = IS_GT_ZERO (dk) ; + do_update = (dk > 0) ; if (!do_update) { dk = -dk ; diff --git a/CHOLMOD/Modify/cholmod_updown.c b/CHOLMOD/Modify/cholmod_updown.c index c2ded58bd..ce1a1141d 100644 --- a/CHOLMOD/Modify/cholmod_updown.c +++ b/CHOLMOD/Modify/cholmod_updown.c @@ -541,7 +541,8 @@ int CHOLMOD(updown_mask2) /* ---------------------------------------------------------------------- */ /* mark = CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; + ASSERT (check_flag (Common)) ; mark = Common->mark ; PRINT1 (("updown, rank %g update %d\n", (double) C->ncol, update)) ; @@ -735,7 +736,7 @@ int CHOLMOD(updown_mask2) if (do_solve) { xj = Xx [j] ; - if (IS_NONZERO (xj)) + if (xj != 0) { xj = Xx [j] ; /* This is first time column j has been seen for entire */ diff --git a/CHOLMOD/Modify/t_cholmod_updown_numkr.c b/CHOLMOD/Modify/t_cholmod_updown_numkr.c index 482a8ffbc..62c9b75c2 100644 --- a/CHOLMOD/Modify/t_cholmod_updown_numkr.c +++ b/CHOLMOD/Modify/t_cholmod_updown_numkr.c @@ -345,7 +345,7 @@ static void NUMERIC (WDIM, RANK) double *Lx ; Int *Li, *Lp, *Lnz ; Int p, k ; - Int use_dbound = IS_GT_ZERO (Common->dbound) ; + Int use_dbound = (Common->dbound > 0) ; Li = L->i ; Lx = L->x ; @@ -386,7 +386,7 @@ static void NUMERIC (WDIM, RANK) double *W0, *W1, *W2, *W3, *Lx ; Int *Li, *Lp, *Lnz ; Int j1, j2, j3, p0, p1, p2, p3, parent, lnz, pend, k ; - Int use_dbound = IS_GT_ZERO (Common->dbound) ; + Int use_dbound = (Common->dbound > 0) ; Li = L->i ; Lx = L->x ; diff --git a/CHOLMOD/Partition/cholmod_camd.c b/CHOLMOD/Partition/cholmod_camd.c index 40747391b..716410df7 100644 --- a/CHOLMOD/Partition/cholmod_camd.c +++ b/CHOLMOD/Partition/cholmod_camd.c @@ -177,7 +177,7 @@ int CHOLMOD(camd) Control [CAMD_AGGRESSIVE] = Common->method [Common->current].aggressive; } -#if ( ITYPE == CHOLMOD_LONG ) +#if defined ( CHOLMOD_INT64 ) /* DEBUG (camd_l_debug_init ("cholmod_l_camd")) ; */ camd_l2 (n, C->p, C->i, Len, C->nzmax, cnz, Nv, Next, Perm, Head, Elen, Degree, Wi, Control, Info, Cmember, BucketSet) ; diff --git a/CHOLMOD/Partition/cholmod_ccolamd.c b/CHOLMOD/Partition/cholmod_ccolamd.c index 08b79c9b5..7251abd7d 100644 --- a/CHOLMOD/Partition/cholmod_ccolamd.c +++ b/CHOLMOD/Partition/cholmod_ccolamd.c @@ -67,7 +67,7 @@ static int ccolamd_interface /* ---------------------------------------------------------------------- */ /* get parameters */ -#if ( ITYPE == CHOLMOD_LONG ) +#if defined ( CHOLMOD_INT64 ) ccolamd_l_set_defaults (knobs) ; #else ccolamd_set_defaults (knobs) ; @@ -90,7 +90,7 @@ static int ccolamd_interface if (ok) { -#if ( ITYPE == CHOLMOD_LONG ) +#if defined ( CHOLMOD_INT64 ) ccolamd_l (ncol, nrow, alen, C->i, C->p, knobs, stats, Cmember) ; #else ccolamd (ncol, nrow, alen, C->i, C->p, knobs, stats, Cmember) ; @@ -164,7 +164,7 @@ int CHOLMOD(ccolamd) /* allocate workspace */ /* ---------------------------------------------------------------------- */ -#if ( ITYPE == CHOLMOD_LONG ) +#if defined ( CHOLMOD_INT64 ) alen = ccolamd_l_recommended (A->nzmax, ncol, nrow) ; #else alen = ccolamd_recommended (A->nzmax, ncol, nrow) ; diff --git a/CHOLMOD/Partition/cholmod_csymamd.c b/CHOLMOD/Partition/cholmod_csymamd.c index 03d46e1f7..6990d3499 100644 --- a/CHOLMOD/Partition/cholmod_csymamd.c +++ b/CHOLMOD/Partition/cholmod_csymamd.c @@ -86,7 +86,7 @@ int CHOLMOD(csymamd) perm = Common->Head ; /* size nrow+1 (i/l/l) */ /* get parameters */ -#if ( ITYPE == CHOLMOD_LONG ) +#if defined ( CHOLMOD_INT64 ) ccolamd_l_set_defaults (knobs) ; #else ccolamd_set_defaults (knobs) ; @@ -103,7 +103,7 @@ int CHOLMOD(csymamd) calloc_func = SuiteSparse_config_calloc_func_get ( ) ; free_func = SuiteSparse_config_free_func_get ( ) ; -#if ( ITYPE == CHOLMOD_LONG ) +#if defined ( CHOLMOD_INT64 ) csymamd_l (nrow, A->i, A->p, perm, knobs, stats, calloc_func, free_func, diff --git a/CHOLMOD/Partition/cholmod_l_camd.c b/CHOLMOD/Partition/cholmod_l_camd.c index 6926e41b3..d4c380980 100644 --- a/CHOLMOD/Partition/cholmod_l_camd.c +++ b/CHOLMOD/Partition/cholmod_l_camd.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_camd.c" diff --git a/CHOLMOD/Partition/cholmod_l_ccolamd.c b/CHOLMOD/Partition/cholmod_l_ccolamd.c index cfe317c54..56faa504d 100644 --- a/CHOLMOD/Partition/cholmod_l_ccolamd.c +++ b/CHOLMOD/Partition/cholmod_l_ccolamd.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_ccolamd.c" diff --git a/CHOLMOD/Partition/cholmod_l_csymamd.c b/CHOLMOD/Partition/cholmod_l_csymamd.c index 4b816b588..2ffd4dd50 100644 --- a/CHOLMOD/Partition/cholmod_l_csymamd.c +++ b/CHOLMOD/Partition/cholmod_l_csymamd.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_csymamd.c" diff --git a/CHOLMOD/Partition/cholmod_l_metis.c b/CHOLMOD/Partition/cholmod_l_metis.c index ad2c7467a..f529e47cc 100644 --- a/CHOLMOD/Partition/cholmod_l_metis.c +++ b/CHOLMOD/Partition/cholmod_l_metis.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_metis.c" diff --git a/CHOLMOD/Partition/cholmod_l_nesdis.c b/CHOLMOD/Partition/cholmod_l_nesdis.c index 51896c5f1..60572c9cb 100644 --- a/CHOLMOD/Partition/cholmod_l_nesdis.c +++ b/CHOLMOD/Partition/cholmod_l_nesdis.c @@ -8,6 +8,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_nesdis.c" diff --git a/CHOLMOD/Partition/cholmod_nesdis.c b/CHOLMOD/Partition/cholmod_nesdis.c index 46cb8a135..43c990079 100644 --- a/CHOLMOD/Partition/cholmod_nesdis.c +++ b/CHOLMOD/Partition/cholmod_nesdis.c @@ -1007,7 +1007,8 @@ int64_t CHOLMOD(bisect) /* returns # of nodes in separator */ B->ncol = n ; /* restore size for memory usage statistics */ CHOLMOD(free_sparse) (&B, Common) ; Common->mark = EMPTY ; - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; + ASSERT (check_flag (Common)) ; CHOLMOD(free) (csize, sizeof (Int), Bew, Common) ; return (sepsize) ; #else @@ -1199,7 +1200,8 @@ int64_t CHOLMOD(nested_dissection) /* returns # of components, or -1 if error */ /* all nodes start out unmarked and unordered (Type 4, see below) */ Common->mark = EMPTY ; - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; + ASSERT (check_flag (Common)) ; ASSERT (Flag == Common->Flag) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; @@ -1209,7 +1211,7 @@ int64_t CHOLMOD(nested_dissection) /* returns # of components, or -1 if error */ } /* prune dense nodes from B */ - if (IS_NAN (prune_dense) || prune_dense < 0) + if (isnan (prune_dense) || prune_dense < 0) { /* only remove completely dense nodes */ threshold = n-2 ; @@ -1260,7 +1262,8 @@ int64_t CHOLMOD(nested_dissection) /* returns # of components, or -1 if error */ CHOLMOD(free_sparse) (&B, Common) ; CHOLMOD(free) (3*n, sizeof (Int), Work3n, Common) ; Common->mark = EMPTY ; - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; + ASSERT (check_flag (Common)) ; return (1) ; } @@ -1277,7 +1280,8 @@ int64_t CHOLMOD(nested_dissection) /* returns # of components, or -1 if error */ CHOLMOD(free) (csize, sizeof (Int), Cew, Common) ; CHOLMOD(free) (3*n, sizeof (Int), Work3n, Common) ; Common->mark = EMPTY ; - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; + ASSERT (check_flag (Common)) ; PRINT2 (("out of memory for C, etc\n")) ; return (EMPTY) ; } @@ -1503,7 +1507,8 @@ int64_t CHOLMOD(nested_dissection) /* returns # of components, or -1 if error */ CHOLMOD(free) (csize, sizeof (Int), Cew, Common) ; CHOLMOD(free) (3*n, sizeof (Int), Work3n, Common) ; Common->mark = EMPTY ; - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; + ASSERT (check_flag (Common)) ; return (EMPTY) ; } @@ -1831,7 +1836,8 @@ int64_t CHOLMOD(nested_dissection) /* returns # of components, or -1 if error */ /* ---------------------------------------------------------------------- */ Common->mark = EMPTY ; - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; + ASSERT (check_flag (Common)) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; /* ---------------------------------------------------------------------- */ @@ -2037,6 +2043,7 @@ int64_t CHOLMOD(collapse_septree) /* find the first descendant of each node of the separator tree */ /* ---------------------------------------------------------------------- */ + ASSERT (ncomponents >= 1 && ncomponents <= n) ; for (c = 0 ; c < nc ; c++) { First [c] = EMPTY ; diff --git a/CHOLMOD/README.txt b/CHOLMOD/README.txt index 2103a52d7..43ed5956c 100644 --- a/CHOLMOD/README.txt +++ b/CHOLMOD/README.txt @@ -1,4 +1,4 @@ -CHOLMOD: a sparse CHOLesky MODification package, Copyright (c) 2005-2020. +CHOLMOD: a sparse CHOLesky MODification package, Copyright (c) 2005-2023. http://www.suitesparse.com ----------------------------------------------- @@ -13,9 +13,12 @@ http://www.suitesparse.com C and MATLAB interfaces. This code works on Microsoft Windows and many versions of Unix and Linux. +CHOLMOD v5.0.0 introduces the first part of support for single precision +sparse matrices, with the introduction of the new CHOLMOD:Utility Module. +Single precision is not yet incorporated into the remaining Modules, however. -Some Modules of CHOLMOD are copyrighted by the University of Florida (the -Core and Partition Modules). The rest are copyrighted by the authors: +One CHOLMOD Module is copyrighted by the University of Florida (the +Partition Module). The rest are copyrighted by the authors: Timothy A. Davis (all of them), and William W. Hager (the Modify Module). CHOLMOD relies on several other packages: AMD, CAMD, COLAMD, CCOLAMD, diff --git a/CHOLMOD/SuiteSparse_metis/GKlib/gkregex.c b/CHOLMOD/SuiteSparse_metis/GKlib/gkregex.c index 8a09caab7..093505bf1 100644 --- a/CHOLMOD/SuiteSparse_metis/GKlib/gkregex.c +++ b/CHOLMOD/SuiteSparse_metis/GKlib/gkregex.c @@ -10135,7 +10135,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx, { if (char_len <= 1) return 0; - /* FIXME: I don't think this if is needed, as both '\n' + /* fixme: I don't think this if is needed, as both '\n' and '\0' are char_len == 1. */ /* '.' accepts any one character except the following two cases. */ if ((!(dfa->syntax & RE_DOT_NEWLINE) && diff --git a/CHOLMOD/Supernodal/cholmod_l_super_numeric.c b/CHOLMOD/Supernodal/cholmod_l_super_numeric.c index 3b0c6a261..2f83c3388 100644 --- a/CHOLMOD/Supernodal/cholmod_l_super_numeric.c +++ b/CHOLMOD/Supernodal/cholmod_l_super_numeric.c @@ -9,6 +9,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_super_numeric.c" diff --git a/CHOLMOD/Supernodal/cholmod_l_super_solve.c b/CHOLMOD/Supernodal/cholmod_l_super_solve.c index 515fe4c26..a1ff3b286 100644 --- a/CHOLMOD/Supernodal/cholmod_l_super_solve.c +++ b/CHOLMOD/Supernodal/cholmod_l_super_solve.c @@ -9,6 +9,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_super_solve.c" diff --git a/CHOLMOD/Supernodal/cholmod_l_super_symbolic.c b/CHOLMOD/Supernodal/cholmod_l_super_symbolic.c index 34e45b648..8a9cd46ad 100644 --- a/CHOLMOD/Supernodal/cholmod_l_super_symbolic.c +++ b/CHOLMOD/Supernodal/cholmod_l_super_symbolic.c @@ -9,6 +9,6 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cholmod_super_symbolic.c" diff --git a/CHOLMOD/Supernodal/cholmod_super_numeric.c b/CHOLMOD/Supernodal/cholmod_super_numeric.c index 1148d19e5..fd8f413fa 100644 --- a/CHOLMOD/Supernodal/cholmod_super_numeric.c +++ b/CHOLMOD/Supernodal/cholmod_super_numeric.c @@ -63,7 +63,7 @@ /* === TEMPLATE codes for GPU and regular numeric factorization ============= */ /* ========================================================================== */ -#ifdef DLONG +#ifdef CHOLMOD_INT64 #ifdef SUITESPARSE_CUDA #include "cholmod_gpu_kernels.h" #define REAL @@ -218,7 +218,7 @@ int CHOLMOD(super_numeric) return (FALSE) ; } } - ASSERT (L->dtype == DTYPE) ; + ASSERT (L->dtype == CHOLMOD_DOUBLE) ; // FIXME ASSERT (L->xtype == CHOLMOD_REAL || L->xtype == CHOLMOD_COMPLEX) ; /* supernodal LDL' is not supported */ @@ -298,7 +298,8 @@ int CHOLMOD(super_numeric) /* Flag array was used as workspace, clear it */ Common->mark = EMPTY ; /* CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; + ASSERT (check_flag (Common)) ; ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; CHOLMOD(free_dense) (&C, Common) ; return (ok) ; diff --git a/CHOLMOD/Supernodal/cholmod_super_symbolic.c b/CHOLMOD/Supernodal/cholmod_super_symbolic.c index c8e1dfc4c..a41b0dea8 100644 --- a/CHOLMOD/Supernodal/cholmod_super_symbolic.c +++ b/CHOLMOD/Supernodal/cholmod_super_symbolic.c @@ -130,15 +130,15 @@ static void subtree /* clear workspace used by cholmod_super_symbolic */ -#define FREE_WORKSPACE \ -{ \ - /* CHOLMOD(clear_flag) (Common) ; */ \ - CHOLMOD_CLEAR_FLAG (Common) ; \ - for (k = 0 ; k <= nfsuper ; k++) \ - { \ - Head [k] = EMPTY ; \ - } \ - ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; \ +#define FREE_WORKSPACE \ +{ \ + CLEAR_FLAG (Common) ; \ + ASSERT (check_flag (Common)) ; \ + for (k = 0 ; k <= nfsuper ; k++) \ + { \ + Head [k] = EMPTY ; \ + } \ + ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ; \ } \ @@ -249,7 +249,7 @@ int CHOLMOD(super_symbolic2) max_bytes = 0; max_fraction = 0; -#ifdef DLONG +#ifdef CHOLMOD_INT64 if ( Common->useGPU == EMPTY ) { /* useGPU not explicity requested by the user, but not explicitly @@ -363,9 +363,9 @@ int CHOLMOD(super_symbolic2) zrelax1 = Common->zrelax [1] ; zrelax2 = Common->zrelax [2] ; - zrelax0 = IS_NAN (zrelax0) ? 0 : zrelax0 ; - zrelax1 = IS_NAN (zrelax1) ? 0 : zrelax1 ; - zrelax2 = IS_NAN (zrelax2) ? 0 : zrelax2 ; + zrelax0 = isnan (zrelax0) ? 0 : zrelax0 ; + zrelax1 = isnan (zrelax1) ? 0 : zrelax1 ; + zrelax2 = isnan (zrelax2) ? 0 : zrelax2 ; ASSERT (CHOLMOD(dump_parent) (Parent, n, "Parent", Common)) ; @@ -805,7 +805,7 @@ int CHOLMOD(super_symbolic2) /* clear the Flag array and mark the current supernode */ /* mark = CHOLMOD(clear_flag) (Common) ; */ - CHOLMOD_CLEAR_FLAG (Common) ; + CLEAR_FLAG (Common) ; mark = Common->mark ; Flag [s] = mark ; ASSERT (s == SuperMap [k]) ; diff --git a/CHOLMOD/Tcov/.gitignore b/CHOLMOD/Tcov/.gitignore index dc83e742c..3259887a4 100644 --- a/CHOLMOD/Tcov/.gitignore +++ b/CHOLMOD/Tcov/.gitignore @@ -7,3 +7,8 @@ l_*.cu *.gcno *.gcov timelog.m +u_*.c +n_*.c +ui_*.c +ul_*.c +o* diff --git a/CHOLMOD/Tcov/Makefile b/CHOLMOD/Tcov/Makefile index 59baf1cfe..012e8fc5e 100644 --- a/CHOLMOD/Tcov/Makefile +++ b/CHOLMOD/Tcov/Makefile @@ -75,15 +75,16 @@ default: go ################################################################################ -# valgrind is not used +# without valgrind V = - -# covall is used COVER = ./covall - -# with test coverage and 32-bit BLAS CF = -O0 -g --coverage -fprofile-abs-path -DTEST_COVERAGE -DBLAS32 -fopenmp +# with valgrind +# V = valgrind --suppressions=suppress --quiet +# COVER = +# CF = -O0 -g + # Temp directory T = $(TCOV_TMP)/CHOLMOD_TCOV_TMP @@ -99,8 +100,10 @@ C = $(CC) $(CF) $(CHOLMOD_CONFIG) $(NANTESTS) # no test coverage CN = $(CC) -O0 -g -fopenmp $(CHOLMOD_CONFIG) $(NANTESTS) -LDLIBS = -L$(SUITESPARSE)/lib -lsuitesparseconfig \ - -lm $(LAPACK) $(BLAS) -lrt -Wl,-rpath=$(SUITESPARSE)/lib +# LDLIBS = -L$(SUITESPARSE)/lib -lsuitesparseconfig \ +# -lm $(LAPACK) $(BLAS) -lrt -Wl,-rpath=$(SUITESPARSE)/lib + +LDLIBS = -lm $(LAPACK) $(BLAS) #------------------------------------------------------------------------------- # With the CUDA BLAS: @@ -113,20 +116,22 @@ I = -I.. -I../../AMD/Include -I../../COLAMD/Include \ -I../SuiteSparse_metis/include -I../../CCOLAMD/Include \ -I../../CAMD/Include \ -I../Include -I../../SuiteSparse_config $(CUDA_INC) \ - -I../Core -I../Check -I../Cholesky -I../Demo -I../Supernodal \ + -I../Check -I../Cholesky -I../Demo -I../Supernodal \ -I../Partition -I../Modify -I../MatrixOps -I../GPU \ -I../SuiteSparse_metis \ -I../SuiteSparse_metis/GKlib \ -I../SuiteSparse_metis/libmetis \ -I../../AMD/Source -I../../CAMD/Source \ - -I../../COLAMD/Source -I../../CCOLAMD/Source + -I../../COLAMD/Source -I../../CCOLAMD/Source \ + -I../Utility I += $(GPU_CONFIG) ccode: cm cl zdemo ldemo cmread clread -TEST = cm.c test_ops.c null.c null2.c lpdemo.c memory.c solve.c aug.c unpack.c \ - raw_factor.c cctest.c ctest.c amdtest.c camdtest.c huge.c +TEST = cm.c \ + test_ops.c null.c null2.c lpdemo.c memory.c solve.c aug.c unpack.c \ + raw_factor.c cctest.c ctest.c amdtest.c camdtest.c huge.c LTEST = cl.c amdtest_l.c camdtest_l.c huge_l.c @@ -204,7 +209,7 @@ IPARTITION_OBJ = \ z_csymamd.o \ z_camd.o \ z_metis.o \ - z_metis_wrapper.o \ + n_metis_wrapper.o \ z_nesdis.o LPARTITION_OBJ = \ @@ -212,7 +217,7 @@ LPARTITION_OBJ = \ l_csymamd.o \ l_camd.o \ l_metis.o \ - z_metis_wrapper.o \ + n_metis_wrapper.o \ l_nesdis.o CAMDSRC = ../../CAMD/Source/camd_1.c \ @@ -274,22 +279,147 @@ $(LCAMDOBJ): $(CAMDSRC) # LCAMDOBJ = #------------------------------------------------------------------------------- -IOBJ = \ - z_common.o \ - z_version.o \ - z_dense.o \ - z_factor.o \ - z_change_factor.o \ - z_memory.o \ - z_sparse.o \ - z_complex.o \ - z_transpose.o \ - z_band.o \ - z_copy.o \ - z_triplet.o \ - z_error.o \ - z_aat.o \ - z_add.o \ +IUTIL_OBJ = \ + ui_change_factor.o \ + ui_transpose_unsym.o \ + ui_transpose_sym.o \ + ui_transpose.o \ + ui_ptranspose.o \ + ui_sort.o \ + ui_aat.o \ + ui_factor_to_sparse.o \ + ui_reallocate_column.o \ + ui_copy_factor.o \ + ui_pack_factor.o \ + ui_reallocate_factor.o \ + ui_free_factor.o \ + ui_alloc_factor.o \ + ui_allocate_factor.o \ + ui_copy.o \ + ui_add.o \ + ui_add_size_t.o \ + ui_alloc_work.o \ + ui_allocate_dense.o \ + ui_allocate_sparse.o \ + ui_allocate_triplet.o \ + ui_allocate_work.o \ + ui_band.o \ + ui_band_nnz.o \ + ui_calloc.o \ + ui_clear_flag.o \ + ui_copy_dense.o \ + ui_copy_dense2.o \ + ui_copy_sparse.o \ + ui_copy_triplet.o \ + ui_cumsum.o \ + ui_dbound.o \ + ui_defaults.o \ + ui_dense_nnz.o \ + ui_dense_to_sparse.o \ + ui_divcomplex.o \ + ui_ensure_dense.o \ + ui_error.o \ + ui_eye.o \ + ui_finish.o \ + ui_free.o \ + ui_free_dense.o \ + ui_free_sparse.o \ + ui_free_triplet.o \ + ui_free_work.o \ + ui_hypot.o \ + ui_malloc.o \ + ui_maxrank.o \ + ui_mult_size_t.o \ + ui_nnz.o \ + ui_ones.o \ + ui_realloc.o \ + ui_realloc_multiple.o \ + ui_reallocate_sparse.o \ + ui_reallocate_triplet.o \ + ui_sbound.o \ + ui_score_comp.o \ + ui_set_empty.o \ + ui_sparse_to_dense.o \ + ui_sparse_to_triplet.o \ + ui_speye.o \ + ui_spzeros.o \ + ui_start.o \ + ui_triplet_to_sparse.o \ + ui_version.o \ + ui_xtype.o \ + ui_zeros.o + +LUTIL_OBJ = \ + ul_change_factor.o \ + ul_transpose_unsym.o \ + ul_transpose_sym.o \ + ul_transpose.o \ + ul_ptranspose.o \ + ul_sort.o \ + ul_aat.o \ + ul_factor_to_sparse.o \ + ul_reallocate_column.o \ + ul_copy_factor.o \ + ul_pack_factor.o \ + ul_reallocate_factor.o \ + ul_free_factor.o \ + ul_alloc_factor.o \ + ul_allocate_factor.o \ + ul_copy.o \ + ul_add.o \ + ul_add_size_t.o \ + ul_alloc_work.o \ + ul_allocate_dense.o \ + ul_allocate_sparse.o \ + ul_allocate_triplet.o \ + ul_allocate_work.o \ + ul_band.o \ + ul_band_nnz.o \ + ul_calloc.o \ + ul_clear_flag.o \ + ul_copy_dense.o \ + ul_copy_dense2.o \ + ul_copy_sparse.o \ + ul_copy_triplet.o \ + ul_cumsum.o \ + ul_dbound.o \ + ul_defaults.o \ + ul_dense_nnz.o \ + ul_dense_to_sparse.o \ + ul_divcomplex.o \ + ul_ensure_dense.o \ + ul_error.o \ + ul_eye.o \ + ul_finish.o \ + ul_free.o \ + ul_free_dense.o \ + ul_free_sparse.o \ + ul_free_triplet.o \ + ul_free_work.o \ + ul_hypot.o \ + ul_malloc.o \ + ul_maxrank.o \ + ul_mult_size_t.o \ + ul_nnz.o \ + ul_ones.o \ + ul_realloc.o \ + ul_realloc_multiple.o \ + ul_reallocate_sparse.o \ + ul_reallocate_triplet.o \ + ul_sbound.o \ + ul_score_comp.o \ + ul_set_empty.o \ + ul_sparse_to_dense.o \ + ul_sparse_to_triplet.o \ + ul_speye.o \ + ul_spzeros.o \ + ul_start.o \ + ul_triplet_to_sparse.o \ + ul_version.o \ + ul_xtype.o \ + ul_zeros.o + +IOBJ = $(IUTIL_OBJ) \ z_check.o \ z_read.o \ z_write.o \ @@ -322,22 +452,7 @@ IOBJ = \ z_super_symbolic.o \ $(IPARTITION_OBJ) -LOBJ = \ - l_common.o \ - l_version.o \ - l_dense.o \ - l_factor.o \ - l_change_factor.o \ - l_memory.o \ - l_sparse.o \ - l_complex.o \ - l_transpose.o \ - l_band.o \ - l_copy.o \ - l_triplet.o \ - l_error.o \ - l_aat.o \ - l_add.o \ +LOBJ = $(LUTIL_OBJ) \ l_check.o \ l_read.o \ l_write.o \ @@ -378,18 +493,22 @@ else LGPU = endif -# CONFIG = zz_SuiteSparse_config.o -CONFIG = +CONFIG = zz_SuiteSparse_config.o +# CONFIG = + +ILOBJ = u_mult_uint64_t.o u_memdebug.o -IALL = $(IOBJ) $(AMDOBJ) $(COLAMDOBJ) $(CCOLAMDOBJ) $(CAMDOBJ) $(CONFIG) $(IGPU) +IALL = $(IOBJ) $(AMDOBJ) $(COLAMDOBJ) $(CCOLAMDOBJ) $(CAMDOBJ) $(CONFIG) $(ILOBJ) $(IGPU) -LALL = $(LOBJ) $(LAMDOBJ) $(LCOLAMDOBJ) $(LCCOLAMDOBJ) $(LCAMDOBJ) $(CONFIG) $(LGPU) +LALL = $(LOBJ) $(LAMDOBJ) $(LCOLAMDOBJ) $(LCCOLAMDOBJ) $(LCAMDOBJ) $(CONFIG) $(ILOBJ) $(LGPU) cm: $(IALL) $(TEST) cm.h Makefile $(C) $(I) $(TEST) -o cm $(IALL) $(LDLIBS) -cl: $(LALL) $(LTEST) cm.h Makefile +cl: $(LALL) $(LTEST) cm.h Makefile cm.c \ + test_ops.c null.c null2.c lpdemo.c memory.c solve.c aug.c unpack.c \ + raw_factor.c cctest.c ctest.c amdtest.c camdtest.c huge.c $(C) $(I) $(LTEST) -o cl $(LALL) $(LDLIBS) cmread: $(IALL) cmread.c Makefile @@ -603,7 +722,7 @@ go: zdemo ldemo cmread clread cm cl $(V) ./cl -n < Matrix/galenet > $(T)/l_galenet_nan.out - $(COVER) $(V) ./cm < Matrix/zero > $(T)/zero.out - $(V) ./cl < Matrix/zero > $(T)/zero.out + $(V) ./cl < Matrix/zero > $(T)/l_zero.out - $(COVER) cov: @@ -630,6 +749,7 @@ clean: - $(RM) -r cm.profile cmread.profile zdemo.profile $(T) - $(RM) -r cl.profile clread.profile ldemo.profile - $(RM) temp*.mtx timelog.m l_*.cu + - $(RM) ui_*.c ul_*.c u_*.c n_*.c - $(RM) -r $(PURGE) - $(RM) -r $(CLEAN) @@ -884,66 +1004,568 @@ z_write.o: ../Check/cholmod_write.c $(C) -c $(I) z_write.c #------------------------------------------------------------------------------- +# Utility, int32 +#------------------------------------------------------------------------------- + +ui_change_factor.o: ../Utility/cholmod_change_factor.c + - ln -s $< ui_change_factor.c + $(C) -c $(I) ui_change_factor.c + +ui_transpose_unsym.o: ../Utility/cholmod_transpose_unsym.c + - ln -s $< ui_transpose_unsym.c + $(C) -c $(I) ui_transpose_unsym.c + +ui_transpose_sym.o: ../Utility/cholmod_transpose_sym.c + - ln -s $< ui_transpose_sym.c + $(C) -c $(I) ui_transpose_sym.c + +ui_transpose.o: ../Utility/cholmod_transpose.c + - ln -s $< ui_transpose.c + $(C) -c $(I) ui_transpose.c + +ui_ptranspose.o: ../Utility/cholmod_ptranspose.c + - ln -s $< ui_ptranspose.c + $(C) -c $(I) ui_ptranspose.c + +ui_sort.o: ../Utility/cholmod_sort.c + - ln -s $< ui_sort.c + $(C) -c $(I) ui_sort.c + +ui_aat.o: ../Utility/cholmod_aat.c + - ln -s $< ui_aat.c + $(C) -c $(I) ui_aat.c + +ui_factor_to_sparse.o: ../Utility/cholmod_factor_to_sparse.c + - ln -s $< ui_factor_to_sparse.c + $(C) -c $(I) ui_factor_to_sparse.c + +ui_reallocate_column.o: ../Utility/cholmod_reallocate_column.c + - ln -s $< ui_reallocate_column.c + $(C) -c $(I) ui_reallocate_column.c + +ui_copy_factor.o: ../Utility/cholmod_copy_factor.c + - ln -s $< ui_copy_factor.c + $(C) -c $(I) ui_copy_factor.c + +ui_pack_factor.o: ../Utility/cholmod_pack_factor.c + - ln -s $< ui_pack_factor.c + $(C) -c $(I) ui_pack_factor.c + +ui_reallocate_factor.o: ../Utility/cholmod_reallocate_factor.c + - ln -s $< ui_reallocate_factor.c + $(C) -c $(I) ui_reallocate_factor.c + +ui_free_factor.o: ../Utility/cholmod_free_factor.c + - ln -s $< ui_free_factor.c + $(C) -c $(I) ui_free_factor.c + +ui_alloc_factor.o: ../Utility/cholmod_alloc_factor.c + - ln -s $< ui_alloc_factor.c + $(C) -c $(I) ui_alloc_factor.c + +ui_allocate_factor.o: ../Utility/cholmod_allocate_factor.c + - ln -s $< ui_allocate_factor.c + $(C) -c $(I) ui_allocate_factor.c + +ui_copy.o: ../Utility/cholmod_copy.c + - ln -s $< ui_copy.c + $(C) -c $(I) ui_copy.c + +ui_add.o: ../Utility/cholmod_add.c + - ln -s $< ui_add.c + $(C) -c $(I) ui_add.c + +ui_add_size_t.o: ../Utility/cholmod_add_size_t.c + - ln -s $< ui_add_size_t.c + $(C) -c $(I) ui_add_size_t.c + +ui_alloc_work.o: ../Utility/cholmod_alloc_work.c + - ln -s $< ui_alloc_work.c + $(C) -c $(I) ui_alloc_work.c + +ui_allocate_dense.o: ../Utility/cholmod_allocate_dense.c + - ln -s $< ui_allocate_dense.c + $(C) -c $(I) ui_allocate_dense.c + +ui_allocate_sparse.o: ../Utility/cholmod_allocate_sparse.c + - ln -s $< ui_allocate_sparse.c + $(C) -c $(I) ui_allocate_sparse.c + +ui_allocate_triplet.o: ../Utility/cholmod_allocate_triplet.c + - ln -s $< ui_allocate_triplet.c + $(C) -c $(I) ui_allocate_triplet.c + +ui_allocate_work.o: ../Utility/cholmod_allocate_work.c + - ln -s $< ui_allocate_work.c + $(C) -c $(I) ui_allocate_work.c + +ui_band.o: ../Utility/cholmod_band.c + - ln -s $< ui_band.c + $(C) -c $(I) ui_band.c + +ui_band_nnz.o: ../Utility/cholmod_band_nnz.c + - ln -s $< ui_band_nnz.c + $(C) -c $(I) ui_band_nnz.c + +ui_calloc.o: ../Utility/cholmod_calloc.c + - ln -s $< ui_calloc.c + $(C) -c $(I) ui_calloc.c + +ui_clear_flag.o: ../Utility/cholmod_clear_flag.c + - ln -s $< ui_clear_flag.c + $(C) -c $(I) ui_clear_flag.c + +ui_copy_dense.o: ../Utility/cholmod_copy_dense.c + - ln -s $< ui_copy_dense.c + $(C) -c $(I) ui_copy_dense.c + +ui_copy_dense2.o: ../Utility/cholmod_copy_dense2.c + - ln -s $< ui_copy_dense2.c + $(C) -c $(I) ui_copy_dense2.c + +ui_copy_sparse.o: ../Utility/cholmod_copy_sparse.c + - ln -s $< ui_copy_sparse.c + $(C) -c $(I) ui_copy_sparse.c + +ui_copy_triplet.o: ../Utility/cholmod_copy_triplet.c + - ln -s $< ui_copy_triplet.c + $(C) -c $(I) ui_copy_triplet.c + +ui_cumsum.o: ../Utility/cholmod_cumsum.c + - ln -s $< ui_cumsum.c + $(C) -c $(I) ui_cumsum.c + +ui_dbound.o: ../Utility/cholmod_dbound.c + - ln -s $< ui_dbound.c + $(C) -c $(I) ui_dbound.c -z_common.o: ../Core/cholmod_common.c - - ln -s $< z_common.c - $(C) -c $(I) z_common.c +ui_defaults.o: ../Utility/cholmod_defaults.c + - ln -s $< ui_defaults.c + $(C) -c $(I) ui_defaults.c -z_version.o: ../Core/cholmod_version.c - - ln -s $< z_version.c - $(C) -c $(I) z_version.c +ui_dense_nnz.o: ../Utility/cholmod_dense_nnz.c + - ln -s $< ui_dense_nnz.c + $(C) -c $(I) ui_dense_nnz.c -z_dense.o: ../Core/cholmod_dense.c - - ln -s $< z_dense.c - $(C) -c $(I) z_dense.c +ui_dense_to_sparse.o: ../Utility/cholmod_dense_to_sparse.c + - ln -s $< ui_dense_to_sparse.c + $(C) -c $(I) ui_dense_to_sparse.c -z_factor.o: ../Core/cholmod_factor.c - - ln -s $< z_factor.c - $(C) -c $(I) z_factor.c +ui_divcomplex.o: ../Utility/cholmod_divcomplex.c + - ln -s $< ui_divcomplex.c + $(C) -c $(I) ui_divcomplex.c -z_change_factor.o: ../Core/cholmod_change_factor.c - - ln -s $< z_change_factor.c - $(C) -c $(I) z_change_factor.c +ui_ensure_dense.o: ../Utility/cholmod_ensure_dense.c + - ln -s $< ui_ensure_dense.c + $(C) -c $(I) ui_ensure_dense.c -z_memory.o: ../Core/cholmod_memory.c - - ln -s $< z_memory.c - $(C) -c $(I) z_memory.c +ui_error.o: ../Utility/cholmod_error.c + - ln -s $< ui_error.c + $(C) -c $(I) ui_error.c -z_sparse.o: ../Core/cholmod_sparse.c - - ln -s $< z_sparse.c - $(C) -c $(I) z_sparse.c +ui_eye.o: ../Utility/cholmod_eye.c + - ln -s $< ui_eye.c + $(C) -c $(I) ui_eye.c -z_complex.o: ../Core/cholmod_complex.c - - ln -s $< z_complex.c - $(C) -c $(I) z_complex.c +ui_finish.o: ../Utility/cholmod_finish.c + - ln -s $< ui_finish.c + $(C) -c $(I) ui_finish.c -z_transpose.o: ../Core/cholmod_transpose.c - - ln -s $< z_transpose.c - $(C) -c $(I) z_transpose.c +ui_free.o: ../Utility/cholmod_free.c + - ln -s $< ui_free.c + $(C) -c $(I) ui_free.c -z_band.o: ../Core/cholmod_band.c - - ln -s $< z_band.c - $(C) -c $(I) z_band.c +ui_free_dense.o: ../Utility/cholmod_free_dense.c + - ln -s $< ui_free_dense.c + $(C) -c $(I) ui_free_dense.c -z_copy.o: ../Core/cholmod_copy.c - - ln -s $< z_copy.c - $(C) -c $(I) z_copy.c +ui_free_sparse.o: ../Utility/cholmod_free_sparse.c + - ln -s $< ui_free_sparse.c + $(C) -c $(I) ui_free_sparse.c -z_triplet.o: ../Core/cholmod_triplet.c - - ln -s $< z_triplet.c - $(C) -c $(I) z_triplet.c +ui_free_triplet.o: ../Utility/cholmod_free_triplet.c + - ln -s $< ui_free_triplet.c + $(C) -c $(I) ui_free_triplet.c -z_error.o: ../Core/cholmod_error.c - - ln -s $< z_error.c - $(C) -c $(I) z_error.c +ui_free_work.o: ../Utility/cholmod_free_work.c + - ln -s $< ui_free_work.c + $(C) -c $(I) ui_free_work.c -z_aat.o: ../Core/cholmod_aat.c - - ln -s $< z_aat.c - $(C) -c $(I) z_aat.c +ui_hypot.o: ../Utility/cholmod_hypot.c + - ln -s $< ui_hypot.c + $(C) -c $(I) ui_hypot.c -z_add.o: ../Core/cholmod_add.c - - ln -s $< z_add.c - $(C) -c $(I) z_add.c +ui_malloc.o: ../Utility/cholmod_malloc.c + - ln -s $< ui_malloc.c + $(C) -c $(I) ui_malloc.c + +ui_maxrank.o: ../Utility/cholmod_maxrank.c + - ln -s $< ui_maxrank.c + $(C) -c $(I) ui_maxrank.c + +ui_mult_size_t.o: ../Utility/cholmod_mult_size_t.c + - ln -s $< ui_mult_size_t.c + $(C) -c $(I) ui_mult_size_t.c + +ui_nnz.o: ../Utility/cholmod_nnz.c + - ln -s $< ui_nnz.c + $(C) -c $(I) ui_nnz.c + +ui_ones.o: ../Utility/cholmod_ones.c + - ln -s $< ui_ones.c + $(C) -c $(I) ui_ones.c + +ui_realloc.o: ../Utility/cholmod_realloc.c + - ln -s $< ui_realloc.c + $(C) -c $(I) ui_realloc.c + +ui_realloc_multiple.o: ../Utility/cholmod_realloc_multiple.c + - ln -s $< ui_realloc_multiple.c + $(C) -c $(I) ui_realloc_multiple.c + +ui_reallocate_sparse.o: ../Utility/cholmod_reallocate_sparse.c + - ln -s $< ui_reallocate_sparse.c + $(C) -c $(I) ui_reallocate_sparse.c + +ui_reallocate_triplet.o: ../Utility/cholmod_reallocate_triplet.c + - ln -s $< ui_reallocate_triplet.c + $(C) -c $(I) ui_reallocate_triplet.c + +ui_sbound.o: ../Utility/cholmod_sbound.c + - ln -s $< ui_sbound.c + $(C) -c $(I) ui_sbound.c + +ui_score_comp.o: ../Utility/cholmod_score_comp.c + - ln -s $< ui_score_comp.c + $(C) -c $(I) ui_score_comp.c + +ui_set_empty.o: ../Utility/cholmod_set_empty.c + - ln -s $< ui_set_empty.c + $(C) -c $(I) ui_set_empty.c + +ui_sparse_to_dense.o: ../Utility/cholmod_sparse_to_dense.c + - ln -s $< ui_sparse_to_dense.c + $(C) -c $(I) ui_sparse_to_dense.c + +ui_sparse_to_triplet.o: ../Utility/cholmod_sparse_to_triplet.c + - ln -s $< ui_sparse_to_triplet.c + $(C) -c $(I) ui_sparse_to_triplet.c + +ui_speye.o: ../Utility/cholmod_speye.c + - ln -s $< ui_speye.c + $(C) -c $(I) ui_speye.c + +ui_spzeros.o: ../Utility/cholmod_spzeros.c + - ln -s $< ui_spzeros.c + $(C) -c $(I) ui_spzeros.c + +ui_start.o: ../Utility/cholmod_start.c + - ln -s $< ui_start.c + $(C) -c $(I) ui_start.c + +ui_triplet_to_sparse.o: ../Utility/cholmod_triplet_to_sparse.c + - ln -s $< ui_triplet_to_sparse.c + $(C) -c $(I) ui_triplet_to_sparse.c + +ui_version.o: ../Utility/cholmod_version.c + - ln -s $< ui_version.c + $(C) -c $(I) ui_version.c + +ui_xtype.o: ../Utility/cholmod_xtype.c + - ln -s $< ui_xtype.c + $(C) -c $(I) ui_xtype.c + +ui_zeros.o: ../Utility/cholmod_zeros.c + - ln -s $< ui_zeros.c + $(C) -c $(I) ui_zeros.c + +#------------------------------------------------------------------------------- +# Utility, just one compilation +#------------------------------------------------------------------------------- + +u_mult_uint64_t.o: ../Utility/cholmod_mult_uint64_t.c + - ln -s $< u_mult_uint64_t.c + $(C) -c $(I) u_mult_uint64_t.c + +u_memdebug.o: ../Utility/cholmod_memdebug.c + - ln -s $< u_memdebug.c + $(C) -c $(I) u_memdebug.c + +#------------------------------------------------------------------------------- +# Utility, int64 +#------------------------------------------------------------------------------- + +ul_change_factor.o: ../Utility/cholmod_l_change_factor.c + - ln -s $< ul_change_factor.c + $(C) -c $(I) ul_change_factor.c + +ul_transpose_unsym.o: ../Utility/cholmod_l_transpose_unsym.c + - ln -s $< ul_transpose_unsym.c + $(C) -c $(I) ul_transpose_unsym.c + +ul_transpose_sym.o: ../Utility/cholmod_l_transpose_sym.c + - ln -s $< ul_transpose_sym.c + $(C) -c $(I) ul_transpose_sym.c + +ul_transpose.o: ../Utility/cholmod_l_transpose.c + - ln -s $< ul_transpose.c + $(C) -c $(I) ul_transpose.c + +ul_ptranspose.o: ../Utility/cholmod_l_ptranspose.c + - ln -s $< ul_ptranspose.c + $(C) -c $(I) ul_ptranspose.c + +ul_sort.o: ../Utility/cholmod_l_sort.c + - ln -s $< ul_sort.c + $(C) -c $(I) ul_sort.c + +ul_aat.o: ../Utility/cholmod_l_aat.c + - ln -s $< ul_aat.c + $(C) -c $(I) ul_aat.c + +ul_factor_to_sparse.o: ../Utility/cholmod_l_factor_to_sparse.c + - ln -s $< ul_factor_to_sparse.c + $(C) -c $(I) ul_factor_to_sparse.c + +ul_reallocate_column.o: ../Utility/cholmod_l_reallocate_column.c + - ln -s $< ul_reallocate_column.c + $(C) -c $(I) ul_reallocate_column.c + +ul_copy_factor.o: ../Utility/cholmod_l_copy_factor.c + - ln -s $< ul_copy_factor.c + $(C) -c $(I) ul_copy_factor.c + +ul_pack_factor.o: ../Utility/cholmod_l_pack_factor.c + - ln -s $< ul_pack_factor.c + $(C) -c $(I) ul_pack_factor.c + +ul_reallocate_factor.o: ../Utility/cholmod_l_reallocate_factor.c + - ln -s $< ul_reallocate_factor.c + $(C) -c $(I) ul_reallocate_factor.c + +ul_free_factor.o: ../Utility/cholmod_l_free_factor.c + - ln -s $< ul_free_factor.c + $(C) -c $(I) ul_free_factor.c + +ul_alloc_factor.o: ../Utility/cholmod_l_alloc_factor.c + - ln -s $< ul_alloc_factor.c + $(C) -c $(I) ul_alloc_factor.c + +ul_allocate_factor.o: ../Utility/cholmod_l_allocate_factor.c + - ln -s $< ul_allocate_factor.c + $(C) -c $(I) ul_allocate_factor.c + +ul_copy.o: ../Utility/cholmod_l_copy.c + - ln -s $< ul_copy.c + $(C) -c $(I) ul_copy.c + +ul_add.o: ../Utility/cholmod_l_add.c + - ln -s $< ul_add.c + $(C) -c $(I) ul_add.c + +ul_add_size_t.o: ../Utility/cholmod_l_add_size_t.c + - ln -s $< ul_add_size_t.c + $(C) -c $(I) ul_add_size_t.c + +ul_alloc_work.o: ../Utility/cholmod_l_alloc_work.c + - ln -s $< ul_alloc_work.c + $(C) -c $(I) ul_alloc_work.c + +ul_allocate_dense.o: ../Utility/cholmod_l_allocate_dense.c + - ln -s $< ul_allocate_dense.c + $(C) -c $(I) ul_allocate_dense.c + +ul_allocate_sparse.o: ../Utility/cholmod_l_allocate_sparse.c + - ln -s $< ul_allocate_sparse.c + $(C) -c $(I) ul_allocate_sparse.c + +ul_allocate_triplet.o: ../Utility/cholmod_l_allocate_triplet.c + - ln -s $< ul_allocate_triplet.c + $(C) -c $(I) ul_allocate_triplet.c + +ul_allocate_work.o: ../Utility/cholmod_l_allocate_work.c + - ln -s $< ul_allocate_work.c + $(C) -c $(I) ul_allocate_work.c + +ul_band.o: ../Utility/cholmod_l_band.c + - ln -s $< ul_band.c + $(C) -c $(I) ul_band.c + +ul_band_nnz.o: ../Utility/cholmod_l_band_nnz.c + - ln -s $< ul_band_nnz.c + $(C) -c $(I) ul_band_nnz.c + +ul_calloc.o: ../Utility/cholmod_l_calloc.c + - ln -s $< ul_calloc.c + $(C) -c $(I) ul_calloc.c + +ul_clear_flag.o: ../Utility/cholmod_l_clear_flag.c + - ln -s $< ul_clear_flag.c + $(C) -c $(I) ul_clear_flag.c + +ul_copy_dense.o: ../Utility/cholmod_l_copy_dense.c + - ln -s $< ul_copy_dense.c + $(C) -c $(I) ul_copy_dense.c + +ul_copy_dense2.o: ../Utility/cholmod_l_copy_dense2.c + - ln -s $< ul_copy_dense2.c + $(C) -c $(I) ul_copy_dense2.c + +ul_copy_sparse.o: ../Utility/cholmod_l_copy_sparse.c + - ln -s $< ul_copy_sparse.c + $(C) -c $(I) ul_copy_sparse.c + +ul_copy_triplet.o: ../Utility/cholmod_l_copy_triplet.c + - ln -s $< ul_copy_triplet.c + $(C) -c $(I) ul_copy_triplet.c + +ul_cumsum.o: ../Utility/cholmod_l_cumsum.c + - ln -s $< ul_cumsum.c + $(C) -c $(I) ul_cumsum.c + +ul_dbound.o: ../Utility/cholmod_l_dbound.c + - ln -s $< ul_dbound.c + $(C) -c $(I) ul_dbound.c + +ul_defaults.o: ../Utility/cholmod_l_defaults.c + - ln -s $< ul_defaults.c + $(C) -c $(I) ul_defaults.c + +ul_dense_nnz.o: ../Utility/cholmod_l_dense_nnz.c + - ln -s $< ul_dense_nnz.c + $(C) -c $(I) ul_dense_nnz.c + +ul_dense_to_sparse.o: ../Utility/cholmod_l_dense_to_sparse.c + - ln -s $< ul_dense_to_sparse.c + $(C) -c $(I) ul_dense_to_sparse.c + +ul_divcomplex.o: ../Utility/cholmod_l_divcomplex.c + - ln -s $< ul_divcomplex.c + $(C) -c $(I) ul_divcomplex.c + +ul_ensure_dense.o: ../Utility/cholmod_l_ensure_dense.c + - ln -s $< ul_ensure_dense.c + $(C) -c $(I) ul_ensure_dense.c + +ul_error.o: ../Utility/cholmod_l_error.c + - ln -s $< ul_error.c + $(C) -c $(I) ul_error.c + +ul_eye.o: ../Utility/cholmod_l_eye.c + - ln -s $< ul_eye.c + $(C) -c $(I) ul_eye.c + +ul_finish.o: ../Utility/cholmod_l_finish.c + - ln -s $< ul_finish.c + $(C) -c $(I) ul_finish.c + +ul_free.o: ../Utility/cholmod_l_free.c + - ln -s $< ul_free.c + $(C) -c $(I) ul_free.c + +ul_free_dense.o: ../Utility/cholmod_l_free_dense.c + - ln -s $< ul_free_dense.c + $(C) -c $(I) ul_free_dense.c + +ul_free_sparse.o: ../Utility/cholmod_l_free_sparse.c + - ln -s $< ul_free_sparse.c + $(C) -c $(I) ul_free_sparse.c + +ul_free_triplet.o: ../Utility/cholmod_l_free_triplet.c + - ln -s $< ul_free_triplet.c + $(C) -c $(I) ul_free_triplet.c + +ul_free_work.o: ../Utility/cholmod_l_free_work.c + - ln -s $< ul_free_work.c + $(C) -c $(I) ul_free_work.c + +ul_hypot.o: ../Utility/cholmod_l_hypot.c + - ln -s $< ul_hypot.c + $(C) -c $(I) ul_hypot.c + +ul_malloc.o: ../Utility/cholmod_l_malloc.c + - ln -s $< ul_malloc.c + $(C) -c $(I) ul_malloc.c + +ul_maxrank.o: ../Utility/cholmod_l_maxrank.c + - ln -s $< ul_maxrank.c + $(C) -c $(I) ul_maxrank.c + +ul_mult_size_t.o: ../Utility/cholmod_l_mult_size_t.c + - ln -s $< ul_mult_size_t.c + $(C) -c $(I) ul_mult_size_t.c + +ul_nnz.o: ../Utility/cholmod_l_nnz.c + - ln -s $< ul_nnz.c + $(C) -c $(I) ul_nnz.c + +ul_ones.o: ../Utility/cholmod_l_ones.c + - ln -s $< ul_ones.c + $(C) -c $(I) ul_ones.c + +ul_realloc.o: ../Utility/cholmod_l_realloc.c + - ln -s $< ul_realloc.c + $(C) -c $(I) ul_realloc.c + +ul_realloc_multiple.o: ../Utility/cholmod_l_realloc_multiple.c + - ln -s $< ul_realloc_multiple.c + $(C) -c $(I) ul_realloc_multiple.c + +ul_reallocate_sparse.o: ../Utility/cholmod_l_reallocate_sparse.c + - ln -s $< ul_reallocate_sparse.c + $(C) -c $(I) ul_reallocate_sparse.c + +ul_reallocate_triplet.o: ../Utility/cholmod_l_reallocate_triplet.c + - ln -s $< ul_reallocate_triplet.c + $(C) -c $(I) ul_reallocate_triplet.c + +ul_sbound.o: ../Utility/cholmod_l_sbound.c + - ln -s $< ul_sbound.c + $(C) -c $(I) ul_sbound.c + +ul_score_comp.o: ../Utility/cholmod_l_score_comp.c + - ln -s $< ul_score_comp.c + $(C) -c $(I) ul_score_comp.c + +ul_set_empty.o: ../Utility/cholmod_l_set_empty.c + - ln -s $< ul_set_empty.c + $(C) -c $(I) ul_set_empty.c + +ul_sparse_to_dense.o: ../Utility/cholmod_l_sparse_to_dense.c + - ln -s $< ul_sparse_to_dense.c + $(C) -c $(I) ul_sparse_to_dense.c + +ul_sparse_to_triplet.o: ../Utility/cholmod_l_sparse_to_triplet.c + - ln -s $< ul_sparse_to_triplet.c + $(C) -c $(I) ul_sparse_to_triplet.c + +ul_speye.o: ../Utility/cholmod_l_speye.c + - ln -s $< ul_speye.c + $(C) -c $(I) ul_speye.c + +ul_spzeros.o: ../Utility/cholmod_l_spzeros.c + - ln -s $< ul_spzeros.c + $(C) -c $(I) ul_spzeros.c + +ul_start.o: ../Utility/cholmod_l_start.c + - ln -s $< ul_start.c + $(C) -c $(I) ul_start.c + +ul_triplet_to_sparse.o: ../Utility/cholmod_l_triplet_to_sparse.c + - ln -s $< ul_triplet_to_sparse.c + $(C) -c $(I) ul_triplet_to_sparse.c + +ul_version.o: ../Utility/cholmod_l_version.c + - ln -s $< ul_version.c + $(C) -c $(I) ul_version.c + +ul_xtype.o: ../Utility/cholmod_l_xtype.c + - ln -s $< ul_xtype.c + $(C) -c $(I) ul_xtype.c + +ul_zeros.o: ../Utility/cholmod_l_zeros.c + - ln -s $< ul_zeros.c + $(C) -c $(I) ul_zeros.c #------------------------------------------------------------------------------- @@ -1017,9 +1639,9 @@ z_nesdis.o: ../Partition/cholmod_nesdis.c $(C) -c $(I) z_nesdis.c # do not use test coverage for this file: -z_metis_wrapper.o: ../Partition/cholmod_metis_wrapper.c - - ln -s $< z_metis_wrapper.c - $(CN) -c $(I) z_metis_wrapper.c +n_metis_wrapper.o: ../Partition/cholmod_metis_wrapper.c + - ln -s $< n_metis_wrapper.c + $(CN) -c $(I) n_metis_wrapper.c #------------------------------------------------------------------------------- @@ -1092,7 +1714,6 @@ z_super_solve.o: ../Supernodal/cholmod_super_solve.c $(C) -c $(I) z_super_solve.c #------------------------------------------------------------------------------- -#------------------------------------------------------------------------------- l_check.o: ../Check/cholmod_l_check.c - ln -s $< l_check.c @@ -1108,68 +1729,6 @@ l_write.o: ../Check/cholmod_l_write.c #------------------------------------------------------------------------------- -l_common.o: ../Core/cholmod_l_common.c - - ln -s $< l_common.c - $(C) -c $(I) l_common.c - -l_version.o: ../Core/cholmod_l_version.c - - ln -s $< l_version.c - $(C) -c $(I) l_version.c - -l_dense.o: ../Core/cholmod_l_dense.c - - ln -s $< l_dense.c - $(C) -c $(I) l_dense.c - -l_factor.o: ../Core/cholmod_l_factor.c - - ln -s $< l_factor.c - $(C) -c $(I) l_factor.c - -l_change_factor.o: ../Core/cholmod_l_change_factor.c - - ln -s $< l_change_factor.c - $(C) -c $(I) l_change_factor.c - -l_memory.o: ../Core/cholmod_l_memory.c - - ln -s $< l_memory.c - $(C) -c $(I) l_memory.c - -l_sparse.o: ../Core/cholmod_l_sparse.c - - ln -s $< l_sparse.c - $(C) -c $(I) l_sparse.c - -l_complex.o: ../Core/cholmod_l_complex.c - - ln -s $< l_complex.c - $(C) -c $(I) l_complex.c - -l_transpose.o: ../Core/cholmod_l_transpose.c - - ln -s $< l_transpose.c - $(C) -c $(I) l_transpose.c - -l_band.o: ../Core/cholmod_l_band.c - - ln -s $< l_band.c - $(C) -c $(I) l_band.c - -l_copy.o: ../Core/cholmod_l_copy.c - - ln -s $< l_copy.c - $(C) -c $(I) l_copy.c - -l_triplet.o: ../Core/cholmod_l_triplet.c - - ln -s $< l_triplet.c - $(C) -c $(I) l_triplet.c - -l_error.o: ../Core/cholmod_l_error.c - - ln -s $< l_error.c - $(C) -c $(I) l_error.c - -l_aat.o: ../Core/cholmod_l_aat.c - - ln -s $< l_aat.c - $(C) -c $(I) l_aat.c - -l_add.o: ../Core/cholmod_l_add.c - - ln -s $< l_add.c - $(C) -c $(I) l_add.c - -#------------------------------------------------------------------------------- - l_amd.o: ../Cholesky/cholmod_l_amd.c - ln -s $< l_amd.c $(C) -c $(I) l_amd.c diff --git a/CHOLMOD/Tcov/amdtest.c b/CHOLMOD/Tcov/amdtest.c index e9b85b94f..430119310 100644 --- a/CHOLMOD/Tcov/amdtest.c +++ b/CHOLMOD/Tcov/amdtest.c @@ -10,10 +10,12 @@ /* Test for amd v2.0 */ +#undef ASSERT #include "amd.h" #include "amd_internal.h" #undef FLIP #undef UNFLIP +#undef ASSERT #include "cm.h" diff --git a/CHOLMOD/Tcov/amdtest_l.c b/CHOLMOD/Tcov/amdtest_l.c index 2edf77e0f..b77e76158 100644 --- a/CHOLMOD/Tcov/amdtest_l.c +++ b/CHOLMOD/Tcov/amdtest_l.c @@ -8,6 +8,7 @@ //------------------------------------------------------------------------------ +#define CHOLMOD_INT64 #define DLONG #include "amdtest.c" diff --git a/CHOLMOD/Tcov/camdtest.c b/CHOLMOD/Tcov/camdtest.c index f5950d09c..6cde21e4a 100644 --- a/CHOLMOD/Tcov/camdtest.c +++ b/CHOLMOD/Tcov/camdtest.c @@ -10,10 +10,12 @@ /* Test for camd v2.0 */ +#undef ASSERT #include "cm.h" #undef FLIP #undef UNFLIP +#undef ASSERT #ifndef NCAMD #include "camd.h" #include "camd_internal.h" diff --git a/CHOLMOD/Tcov/camdtest_l.c b/CHOLMOD/Tcov/camdtest_l.c index 35a62a1e5..f8566e040 100644 --- a/CHOLMOD/Tcov/camdtest_l.c +++ b/CHOLMOD/Tcov/camdtest_l.c @@ -8,6 +8,7 @@ //------------------------------------------------------------------------------ +#define CHOLMOD_INT64 #define DLONG #include "camdtest.c" diff --git a/CHOLMOD/Tcov/cl.c b/CHOLMOD/Tcov/cl.c index 5a6f15ff7..4d0a25386 100644 --- a/CHOLMOD/Tcov/cl.c +++ b/CHOLMOD/Tcov/cl.c @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cm.c" #include "test_ops.c" #include "null.c" diff --git a/CHOLMOD/Tcov/clread.c b/CHOLMOD/Tcov/clread.c index faed3b267..811d5c8f5 100644 --- a/CHOLMOD/Tcov/clread.c +++ b/CHOLMOD/Tcov/clread.c @@ -8,5 +8,5 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 #include "cmread.c" diff --git a/CHOLMOD/Tcov/cm.c b/CHOLMOD/Tcov/cm.c index e7c8d5b52..823cdd0d9 100644 --- a/CHOLMOD/Tcov/cm.c +++ b/CHOLMOD/Tcov/cm.c @@ -127,7 +127,7 @@ void progress (Int force, char s) void my_handler (int status, const char *file, int line, const char *msg) { - printf ("Error handler: file %s line %d status %d: %s\n", + printf ("Error handler: file %s line %d status %d: %s\n", file, line, status, msg) ; if (status < CHOLMOD_OK || status > CHOLMOD_DSMALL) { @@ -1261,7 +1261,7 @@ double do_matrix (cholmod_sparse *A) /* test various matrix operations */ /* -------------------------------------------------------------- */ - err = test_ops (A) ; /* RAND */ + err = test_ops (A) ; /* RAND */ MAXERR (maxerr, err, 1) ; /* -------------------------------------------------------------- */ @@ -1523,6 +1523,7 @@ int main (int argc, char **argv) OK (CHOLMOD(print_sparse) (A, "Test matrix, A", cm)) ; C = unpack (A) ; /* RAND */ OK (CHOLMOD(print_sparse) (C, "Unpacked/unsorted version of A", cm)) ; + cm->print = 1 ; if (T != NULL) @@ -1537,7 +1538,16 @@ int main (int argc, char **argv) /* basic error tests */ /* ------------------------------------------------------------------ */ - null2 (T, do_nantests) ; /* RAND */ +// printf ("null2:: start malloc count "ID" inuse "ID"\n", +// (Int) cm->malloc_count, +// (Int) cm->memory_inuse) ; + + null2 (T, do_nantests) ; /* RAND */ + +// printf ("null2:: done malloc count "ID" inuse "ID"\n", +// (Int) cm->malloc_count, +// (Int) cm->memory_inuse) ; + printf ("Null2 OK : no error\n") ; if (do_nantests) { @@ -1570,9 +1580,11 @@ int main (int argc, char **argv) cholmod_sparse *F ; int save = T->stype ; + printf ("triplet to sparse:\n") ; T->stype = 0 ; F = CHOLMOD(triplet_to_sparse) (T, 0, cm) ; T->stype = save ; + // OKP (F) ; /* ET = CHOLMOD(transpose) (E, 2, cm) ; @@ -1619,7 +1631,7 @@ int main (int argc, char **argv) /* matrix ops */ /* ------------------------------------------------------------------ */ - err = test_ops (A) ; /* RAND */ + err = test_ops (A) ; /* RAND */ MAXERR (maxerr, err, 1) ; printf ("initial testops error %.1g\n", err) ; @@ -1744,9 +1756,11 @@ int main (int argc, char **argv) CHOLMOD(finish) (cm) ; cm->print = 5 ; OK (CHOLMOD(print_common) ("cm", cm)) ; - printf ("malloc count "ID" inuse "ID"\n", - (Int) cm->malloc_count, + + printf ("FINAL::malloc count "ID" inuse "ID"\n", + (Int) cm->malloc_count, (Int) cm->memory_inuse) ; + OK (cm->malloc_count == 0) ; OK (cm->memory_inuse == 0) ; t = SuiteSparse_toc (tic) ; diff --git a/CHOLMOD/Tcov/cm.h b/CHOLMOD/Tcov/cm.h index ce8366929..8a326b8d5 100644 --- a/CHOLMOD/Tcov/cm.h +++ b/CHOLMOD/Tcov/cm.h @@ -146,7 +146,7 @@ void camdtest (cholmod_sparse *A) ; /* AMD, COLAMD, and CCOLAMD */ /* -------------------------------------------------------------------------- */ -#if ( ITYPE == CHOLMOD_LONG ) +#ifdef CHOLMOD_INT64 #define AMD_order amd_l_order #define AMD_defaults amd_l_defaults diff --git a/CHOLMOD/Tcov/cmread.c b/CHOLMOD/Tcov/cmread.c index be793d7f6..5f366c56d 100644 --- a/CHOLMOD/Tcov/cmread.c +++ b/CHOLMOD/Tcov/cmread.c @@ -17,7 +17,7 @@ #include "cholmod.h" -#ifdef DLONG +#ifdef CHOLMOD_INT64 #define CHOLMOD(routine) cholmod_l_ ## routine #define Int int64_t #define UInt uint64_t diff --git a/CHOLMOD/Tcov/covall b/CHOLMOD/Tcov/covall index c50c4a48a..9667506cb 100755 --- a/CHOLMOD/Tcov/covall +++ b/CHOLMOD/Tcov/covall @@ -6,7 +6,7 @@ # SPDX-License-Identifier: GPL-2.0+ # ------------------------------------------------------------------------------ -./gcovs z*.c l_*c +./gcovs z_*.c zz_*.c l_*.c ui_*.c ul_*.c zl_*.c ./covs *.gcov > covs.out echo -n "statments not yet tested: " grep -c "#####" covs.out diff --git a/CHOLMOD/Tcov/huge.c b/CHOLMOD/Tcov/huge.c index 3d8f2db2a..78c6f2ed1 100644 --- a/CHOLMOD/Tcov/huge.c +++ b/CHOLMOD/Tcov/huge.c @@ -35,17 +35,16 @@ void huge ( ) cholmod_dense *X ; size_t n, nbig ; int ok = TRUE, save ; - Int junk ; + Int junk = 0 ; FILE *f ; double beta [2] ; n = SIZE_MAX ; CHOLMOD (free_work) (cm) ; CHOLMOD (allocate_work) (n, 0, 0, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); - n = CHOLMOD(add_size_t) (n, 1, &ok) ; - NOT (ok) ; + n = CHOLMOD(add_size_t) (n, 1, &ok) ; NOT (ok) ; /* create a fake zero sparse matrix, with huge dimensions */ A = CHOLMOD (spzeros) (1, 1, 0, CHOLMOD_REAL, cm) ; @@ -58,7 +57,7 @@ void huge ( ) OKP (L) ; L->n = SIZE_MAX ; CHOLMOD (factorize) (A, L, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); /* free the fake factor */ L->n = 1 ; @@ -78,7 +77,7 @@ void huge ( ) ok = CHOLMOD (resymbol) (C, NULL, 0, 0, L, cm) ; NOT (ok) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); printf ("rowfac:\n") ; beta [0] = 1 ; @@ -87,7 +86,7 @@ void huge ( ) L->xtype = CHOLMOD_COMPLEX ; ok = CHOLMOD (rowfac) (C, NULL, beta, 0, 0, L, cm) ; printf ("rowfac %d\n", cm->status) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); C->xtype = CHOLMOD_REAL ; L->xtype = CHOLMOD_REAL ; printf ("rowfac done:\n") ; @@ -95,18 +94,18 @@ void huge ( ) C->stype = -1 ; ok = CHOLMOD (resymbol_noperm) (C, NULL, 0, 0, L, cm) ; NOT (ok) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); C->ncol = 1 ; CHOLMOD (rowadd) (0, C, L, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); CHOLMOD (rowdel) (0, C, L, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); C->ncol = 4 ; CHOLMOD (updown) (1, C, L, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); C->nrow = 1 ; C->ncol = 1 ; @@ -114,74 +113,82 @@ void huge ( ) CHOLMOD (free_sparse) (&C, cm) ; CHOLMOD (free_factor) (&L, cm) ; - C = CHOLMOD (allocate_sparse) (SIZE_MAX, SIZE_MAX, SIZE_MAX, 0, 0, 0, 0, cm); + C = CHOLMOD (allocate_sparse) (SIZE_MAX, SIZE_MAX, SIZE_MAX, + 0, 0, 0, 0, cm) ; + printf ("cm->status %d\n", cm->status) ; NOP (C) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); CHOLMOD (rowcolcounts) (A, NULL, 0, &junk, &junk, &junk, &junk, &junk, &junk, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); + + C = CHOLMOD (submatrix) (A, &junk, SIZE_MAX/4, &junk, SIZE_MAX/4, + 0, 0, cm) ; - C = CHOLMOD (submatrix) (A, &junk, SIZE_MAX/2, &junk, SIZE_MAX/2, 0, 0, cm) ; NOP (C) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); ok = CHOLMOD (transpose_unsym) (A, 0, &junk, &junk, SIZE_MAX, A, cm) ; NOT (ok) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || + cm->status == CHOLMOD_OUT_OF_MEMORY || + cm->status == CHOLMOD_INVALID); A->stype = 1 ; ok = CHOLMOD (transpose_sym) (A, 0, &junk, A, cm) ; NOT (ok) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || + cm->status == CHOLMOD_OUT_OF_MEMORY || + cm->status == CHOLMOD_INVALID); C = CHOLMOD (ptranspose) (A, 0, &junk, NULL, 0, cm) ; NOP (C) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); A->stype = 0 ; CHOLMOD (amd) (A, NULL, 0, &junk, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); L = CHOLMOD (analyze) (A, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); NOP (L) ; #ifndef NCAMD CHOLMOD (camd) (A, NULL, 0, &junk, NULL, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); #endif printf ("calling colamd\n") ; CHOLMOD (colamd) (A, NULL, 0, 0, &junk, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); #ifndef NCAMD printf ("calling ccolamd\n") ; CHOLMOD (ccolamd) (A, NULL, 0, NULL, &junk, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); #endif CHOLMOD (etree) (A, &junk, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); L = CHOLMOD (allocate_factor) (SIZE_MAX, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); NOP (L) ; #ifndef NPARTITION CHOLMOD (metis) (A, NULL, 0, 0, &junk, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); CHOLMOD (bisect) (A, NULL, 0, 0, &junk, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); CHOLMOD (nested_dissection) (A, NULL, 0, &junk, &junk, &junk, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); #endif CHOLMOD (postorder) (&junk, SIZE_MAX, &junk, &junk, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); /* causes overflow in 32-bit version, but not 64-bit */ f = fopen ("../Tcov/Matrix/mega.tri", "r") ; @@ -196,8 +203,9 @@ void huge ( ) n = SIZE_MAX ; X = CHOLMOD (allocate_dense) (n, 1, n, CHOLMOD_REAL, cm) ; + printf ("status %d\n", cm->status) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); NOP (X) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; /* supernodal symbolic test */ C = CHOLMOD (speye) (1, 1, CHOLMOD_REAL, cm) ; @@ -211,7 +219,7 @@ void huge ( ) C->ncol = SIZE_MAX ; L->n = SIZE_MAX ; CHOLMOD (super_symbolic) (C, C, &junk, L, cm) ; - OK (cm->status == CHOLMOD_TOO_LARGE) ; + OK (cm->status == CHOLMOD_TOO_LARGE || cm->status == CHOLMOD_OUT_OF_MEMORY); cm->supernodal = save ; C->nrow = 1 ; C->ncol = 1 ; diff --git a/CHOLMOD/Tcov/huge_l.c b/CHOLMOD/Tcov/huge_l.c index 21b79f6c6..be413254d 100644 --- a/CHOLMOD/Tcov/huge_l.c +++ b/CHOLMOD/Tcov/huge_l.c @@ -8,6 +8,7 @@ //------------------------------------------------------------------------------ -#define DLONG +#define CHOLMOD_INT64 +#include "cholmod_internal.h" #include "huge.c" diff --git a/CHOLMOD/Tcov/null.c b/CHOLMOD/Tcov/null.c index 4f4a7ab8d..1f13e8fbc 100644 --- a/CHOLMOD/Tcov/null.c +++ b/CHOLMOD/Tcov/null.c @@ -66,7 +66,7 @@ void null_test (cholmod_common *cn) #endif /* ---------------------------------------------------------------------- */ - /* Core */ + /* Utility */ /* ---------------------------------------------------------------------- */ if (cn == NULL) @@ -282,7 +282,7 @@ void null_test2 (void) int ok ; /* ---------------------------------------------------------------------- */ - /* Test Core Common */ + /* Test Common */ /* ---------------------------------------------------------------------- */ ok = CHOLMOD(allocate_work)(SIZE_MAX, 1, 1, cm) ; NOT (ok) ; @@ -308,9 +308,13 @@ void null_test2 (void) /* dense */ /* ---------------------------------------------------------------------- */ - X = CHOLMOD(allocate_dense)(5, 4, 1, CHOLMOD_REAL, cm) ; NOP (X) ; + X = CHOLMOD(allocate_dense)(5, 4, 1, CHOLMOD_REAL, cm) ; + OKP (X) ; + OK (X->d == 5) ; + CHOLMOD(free_dense)(&X, cm) ; + X = CHOLMOD(allocate_dense)(1, Int_max, 1, CHOLMOD_REAL, cm) ; NOP (X) ; - X = CHOLMOD(allocate_dense)(1, 1, 1, -1, cm) ; NOP (X) ; + X = CHOLMOD(allocate_dense)(1, 1, 1, CHOLMOD_PATTERN, cm) ; NOP (X) ; CHOLMOD(free_dense)(&X, cm) ; /* free a NULL dense matrix */ @@ -318,9 +322,13 @@ void null_test2 (void) ok = CHOLMOD(free_dense)(NULL, cm) ; OK (ok) ; /* make an invalid sparse matrix */ - Sbad = CHOLMOD(speye)(2, 3, CHOLMOD_REAL, cm) ; OKP (Sbad) ; + printf ("\nspeye:\n") ; + Sbad = CHOLMOD(speye)(2, 3, CHOLMOD_REAL, cm) ; + OKP (Sbad) ; + Sbad->stype = 1 ; ok = CHOLMOD(check_sparse)(Sbad, cm) ; NOT (ok) ; + printf ("\nSparse to dense:\n") ; X = CHOLMOD(sparse_to_dense)(Sbad, cm) ; NOP (X) ; ok = CHOLMOD(free_sparse)(&Sbad, cm) ; OK (ok) ; @@ -341,7 +349,7 @@ void null_test2 (void) /* free a NULL sparse matrix */ ok = CHOLMOD(free_sparse)(&A, cm) ; OK (ok) ; ok = CHOLMOD(free_sparse)(NULL, cm) ; OK (ok) ; - A = CHOLMOD(copy_sparse)(NULL, cm) ; NOP (A) ; + A = CHOLMOD(copy_sparse)(NULL, cm) ; NOP (A) ; /* ---------------------------------------------------------------------- */ /* error tests done */ diff --git a/CHOLMOD/Tcov/null2.c b/CHOLMOD/Tcov/null2.c index 4b17bbf67..72a0e1bc8 100644 --- a/CHOLMOD/Tcov/null2.c +++ b/CHOLMOD/Tcov/null2.c @@ -26,12 +26,12 @@ void null2 (cholmod_triplet *Tok, int do_nantests) { double nm, gsave0, gsave1, r, anorm, beta [2], maxerr, xnan, rcond, - ax, az, bx, bz, cx, cz, dx, dz, ex, ez ; + ax, az, bx, bz, cx, cz, dx, dz, fx, fz ; cholmod_sparse *A, *C, *AT, *E, *F, *G, *Sok, *R0, *R1, *Aboth, *Axbad, *I1, *Abad, *R, *Acopy, *R3, *Abad2, *I, *I3, *Abad3, *AA, *Rt, *AF, *AFT, *I7, *C2, *R2, *Z ; cholmod_dense *Xok, *Bok, *Two, *X, *W, *XX, *YY, *Xbad2, *B, *Scale, - *Y, *X1, *B1, *B2, *X7, *B7 ; + *Y, *X1, *B1, *B2, *X7, *B7 ; cholmod_factor *L, *L2, *L3, *L4, *L5, *L6, *Lcopy, *Lbad, *L7 ; cholmod_triplet *T, *T2, *Tz, *T3 ; Int *fsetok, *Pok, *Flag, *Head, *Cp, *Ci, *P2, *Parent, *Lperm, @@ -55,6 +55,7 @@ void null2 (cholmod_triplet *Tok, int do_nantests) xnan = 0 ; xtype = Tok->xtype ; + printf ("Tok xtype is %d\n", (int) xtype) ; isreal = (xtype == CHOLMOD_REAL) ; /* ---------------------------------------------------------------------- */ @@ -82,9 +83,9 @@ void null2 (cholmod_triplet *Tok, int do_nantests) dx = cx * bx - cz * bz ; dz = cz * bx + cx * bz ; /* e = d-a, which should be zero */ - ex = dx - ax ; - ez = dz - az ; - r = CHOLMOD(hypot)(ex, ez) ; + fx = dx - ax ; + fz = dz - az ; + r = CHOLMOD(hypot)(fx, fz) ; MAXERR (maxerr, r, 1) ; OK (r < 1e-14) ; } @@ -266,48 +267,62 @@ void null2 (cholmod_triplet *Tok, int do_nantests) C = CHOLMOD(ptranspose)(A, 1, Pbad, NULL, 0, cm) ; NOP (C) ; } - C = CHOLMOD(allocate_sparse)(ncol, nrow, anz, TRUE, TRUE, - -(A->stype), xtype, cm) ; OKP (C) ; - ok = CHOLMOD(transpose_unsym)(A, 1, NULL, NULL, 0, - C, cm) ; OK (ok); - ok = CHOLMOD(free_sparse)(&C, cm) ; OK (ok) ; - - C = CHOLMOD(allocate_sparse)(ncol, nrow, anz, TRUE, FALSE, - -(A->stype), xtype, cm) ; OKP (C) ; - ok = CHOLMOD(transpose_unsym)(A, 1, NULL, NULL, 0, - C, cm) ; OK (ok); - ok = CHOLMOD(free_sparse)(&C, cm) ; OK (ok) ; - - C = CHOLMOD(allocate_sparse)(ncol, nrow, anz, TRUE, FALSE, - -(A->stype), xtype, cm) ; OKP (C) ; - ok = CHOLMOD(transpose_unsym)(A, 1, Pok, NULL, 0, - C, cm) ; OK (ok); - ok = CHOLMOD(free_sparse)(&C, cm) ; OK (ok) ; - - C = CHOLMOD(allocate_sparse)(ncol, nrow, anz, TRUE, FALSE, - -(A->stype), xtype, cm) ; OKP (C) ; - ok = CHOLMOD(transpose_unsym)(A, 1, Pok, fsetok, fsizeok, - C, cm) ; OK (ok); - ok = CHOLMOD(free_sparse)(&C, cm) ; OK (ok) ; - - C = CHOLMOD(allocate_sparse)(ncol, nrow, anz, TRUE, FALSE, - -(A->stype), xtype, cm) ; OKP (C) ; - ok = CHOLMOD(transpose_unsym)(A, 1, NULL, fsetok, fsizeok, - C, cm) ; OK (ok); - ok = CHOLMOD(free_sparse)(&C, cm) ; OK (ok) ; - - C = CHOLMOD(allocate_sparse)(ncol, nrow, anz, TRUE, FALSE, - -(A->stype), CHOLMOD_PATTERN, cm) ; OKP (C) ; - ok = CHOLMOD(transpose_unsym)(A, 1, NULL, fsetok, fsizeok, - C, cm) ; OK (ok); + if (A->stype == 0) + { + C = CHOLMOD(allocate_sparse)(ncol, nrow, anz, TRUE, TRUE, + -(A->stype), xtype, cm) ; OKP (C) ; + ok = CHOLMOD(transpose_unsym)(A, 1, NULL, NULL, 0, + C, cm) ; OK (ok); + ok = CHOLMOD(free_sparse)(&C, cm) ; OK (ok) ; + + C = CHOLMOD(allocate_sparse)(ncol, nrow, anz, TRUE, FALSE, + -(A->stype), xtype, cm) ; OKP (C) ; + ok = CHOLMOD(transpose_unsym)(A, 1, NULL, NULL, 0, + C, cm) ; OK (ok); + ok = CHOLMOD(free_sparse)(&C, cm) ; OK (ok) ; + + C = CHOLMOD(allocate_sparse)(ncol, nrow, anz, TRUE, FALSE, + -(A->stype), xtype, cm) ; OKP (C) ; + ok = CHOLMOD(transpose_unsym)(A, 1, Pok, NULL, 0, + C, cm) ; OK (ok); + ok = CHOLMOD(free_sparse)(&C, cm) ; OK (ok) ; + + C = CHOLMOD(allocate_sparse)(ncol, nrow, anz, TRUE, FALSE, + -(A->stype), xtype, cm) ; OKP (C) ; + ok = CHOLMOD(transpose_unsym)(A, 1, Pok, fsetok, fsizeok, + C, cm) ; OK (ok); + ok = CHOLMOD(free_sparse)(&C, cm) ; OK (ok) ; + + C = CHOLMOD(allocate_sparse)(ncol, nrow, anz, TRUE, FALSE, + -(A->stype), xtype, cm) ; OKP (C) ; + ok = CHOLMOD(transpose_unsym)(A, 1, NULL, fsetok, fsizeok, + C, cm) ; OK (ok); + ok = CHOLMOD(free_sparse)(&C, cm) ; OK (ok) ; + + C = CHOLMOD(allocate_sparse)(ncol, nrow, anz, TRUE, FALSE, + -(A->stype), CHOLMOD_PATTERN, cm) ; OKP (C) ; + ok = CHOLMOD(transpose_unsym)(A, 1, NULL, fsetok, fsizeok, + C, cm) ; OK (ok); + + E = CHOLMOD(allocate_sparse)(nrow, ncol, anz, TRUE, FALSE, + (A->stype), CHOLMOD_PATTERN, cm) ; OKP (C) ; + enz = CHOLMOD(nnz)(E, cm) ; + OK (enz == 0) ; + ok = CHOLMOD(transpose_unsym)(C, 1, NULL, Pok, nrow, + E, cm) ; OK (ok); + ok = CHOLMOD(free_sparse)(&E, cm) ; OK (ok) ; - E = CHOLMOD(allocate_sparse)(nrow, ncol, anz, TRUE, FALSE, - (A->stype), CHOLMOD_PATTERN, cm) ; OKP (C) ; - enz = CHOLMOD(nnz)(E, cm) ; - OK (enz == 0) ; - ok = CHOLMOD(transpose_unsym)(C, 1, NULL, Pok, nrow, - E, cm) ; OK (ok); - ok = CHOLMOD(free_sparse)(&E, cm) ; OK (ok) ; + } + else + { + // A is symmetric so transpose_unsym will fail + C = CHOLMOD(allocate_sparse)(ncol, nrow, anz, TRUE, TRUE, + -(A->stype), xtype, cm) ; OKP (C) ; + ok = CHOLMOD(transpose_unsym)(A, 1, NULL, NULL, 0, + C, cm) ; NOT (ok); + OK (cm->status == CHOLMOD_INVALID) ; + ok = CHOLMOD(free_sparse)(&C, cm) ; OK (ok) ; + } if (A->nrow != A->ncol) { @@ -328,25 +343,40 @@ void null2 (cholmod_triplet *Tok, int do_nantests) ok = CHOLMOD(transpose_unsym)(C, 1, NULL, NULL, 0, Abad3, cm) ;NOT (ok); ok = CHOLMOD(transpose_unsym)(Abad3, 1, NULL, NULL, 0, C, cm) ;NOT (ok); + printf ("xtypes %d %d %d\n", C->xtype, E->xtype, (int) xtype) ; + switch (xtype) { case CHOLMOD_REAL: - CHOLMOD(sparse_xtype)(CHOLMOD_COMPLEX, E, cm) ; + printf ("make E complex:1\n") ; + ok = CHOLMOD(sparse_xtype)(CHOLMOD_COMPLEX, E, cm) ; + OK (ok) ; break ; case CHOLMOD_COMPLEX: - CHOLMOD(sparse_xtype)(CHOLMOD_ZOMPLEX, E, cm) ; + printf ("make E zomplex\n") ; + ok = CHOLMOD(sparse_xtype)(CHOLMOD_ZOMPLEX, E, cm) ; + OK (ok) ; break ; case CHOLMOD_ZOMPLEX: - CHOLMOD(sparse_xtype)(CHOLMOD_COMPLEX, E, cm) ; + printf ("make E complex\n") ; + ok = CHOLMOD(sparse_xtype)(CHOLMOD_COMPLEX, E, cm) ; + OK (ok) ; break ; } + printf ("xtypes %d %d %d now\n", C->xtype, E->xtype, (int) xtype) ; + printf ("dtypes %d %d\n", C->dtype, E->dtype) ; + printf ("mismatch start [:\n") ; ok = CHOLMOD(transpose_sym)(C, 1, NULL, E, cm) ; NOT (ok) ; ok = CHOLMOD(transpose_sym)(E, 1, NULL, C, cm) ; NOT (ok) ; ok = CHOLMOD(transpose_sym)(C, 2, NULL, E, cm) ; NOT (ok) ; ok = CHOLMOD(transpose_sym)(E, 2, NULL, C, cm) ; NOT (ok) ; - ok = CHOLMOD(transpose_unsym)(C, 1, NULL, NULL, 0, E, cm) ; NOT (ok); + + printf ("unsym transpose:\n") ; + ok = CHOLMOD(transpose_unsym)(C, 1, NULL, NULL, 0, E, cm) ; + NOT (ok); + ok = CHOLMOD(transpose_unsym)(E, 1, NULL, NULL, 0, C, cm) ; NOT (ok); ok = CHOLMOD(transpose_unsym)(C, 2, NULL, NULL, 0, E, cm) ; NOT (ok); ok = CHOLMOD(transpose_unsym)(E, 2, NULL, NULL, 0, C, cm) ; NOT (ok); @@ -411,9 +441,9 @@ void null2 (cholmod_triplet *Tok, int do_nantests) C = CHOLMOD(add)(A, NULL, one, one, TRUE, TRUE, cm) ; NOP (C) ; C = CHOLMOD(add)(NULL, AT, one, one, TRUE, TRUE, cm) ; NOP (C) ; - C = CHOLMOD(add)(A, AT, one, one, TRUE, TRUE, cm) ; if (A->nrow == A->ncol && isreal) { + C = CHOLMOD(add)(A, AT, one, one, TRUE, TRUE, cm) ; OKP (C) ; /* C should equal 2*A if A=A' */ if (stype) @@ -486,15 +516,21 @@ void null2 (cholmod_triplet *Tok, int do_nantests) } CHOLMOD(free_sparse)(&C, cm) ; } - else - { - NOP (C) ; - } Axbad = CHOLMOD(copy_sparse)(A, cm) ; /* [ */ Axbad_type = Axbad->xtype ; Axbad->xtype = CHOLMOD_COMPLEX ; - C = CHOLMOD(add)(A, Axbad, one, one, TRUE, TRUE, cm) ; NOP (C) ; + C = CHOLMOD(add)(A, Axbad, one, one, TRUE, TRUE, cm) ; + bool Axbad_is_ok = (Axbad_type == CHOLMOD_COMPLEX) ; + if (Axbad_is_ok) + { + OKP (C) ; + ok = CHOLMOD(free_sparse)(&C, cm) ; OK (ok) ; + } + else + { + NOP (C) ; + } if (nrow > 1 && xtype == CHOLMOD_REAL) { @@ -513,8 +549,8 @@ void null2 (cholmod_triplet *Tok, int do_nantests) cm->print = 4 ; ok = CHOLMOD(reallocate_sparse)(10, NULL, cm) ; NOT (ok) ; - C = CHOLMOD(allocate_sparse)(10, 10, 10, TRUE, TRUE, 0, -1, cm) ; NOP (C) ; - ok = CHOLMOD(reallocate_sparse)(Abad2->nzmax, Abad2, cm) ; NOT (ok) ; + ok = CHOLMOD(reallocate_sparse)(2 * Abad2->nzmax, Abad2, cm) ; NOT (ok) ; + C = CHOLMOD(copy_sparse)(Abad2, cm) ; NOP (C) ; C = CHOLMOD(allocate_sparse)(2, 3, 6, TRUE, TRUE, 1, 0, cm) ; NOP (C) ; @@ -602,6 +638,9 @@ void null2 (cholmod_triplet *Tok, int do_nantests) /* analyze */ /* ---------------------------------------------------------------------- */ + cm->print = 4 ; + ok = CHOLMOD(print_common)("OKcm", cm) ; OK (ok) ; + cm->nmethods = 1 ; cm->method [0].ordering = -1 ; ok = CHOLMOD(print_common)("Bad cm", cm) ; NOT (ok) ; @@ -844,6 +883,8 @@ void null2 (cholmod_triplet *Tok, int do_nantests) Head [0] = -1 ; ok = CHOLMOD(print_common)("ok Head", cm) ; OK (ok) ; + cm->status = CHOLMOD_OK ; + printf ("\nbad Xwork:\n") ; Xwork = cm->Xwork ; cm->Xwork = NULL ; ok = CHOLMOD(print_common)("bad Xwork", cm) ; NOT (ok) ; @@ -872,13 +913,11 @@ void null2 (cholmod_triplet *Tok, int do_nantests) cm->print = 3 ; C->itype = EMPTY ; ok = CHOLMOD(print_sparse)(C, "CIbad", cm) ; NOT (ok) ; - C->itype = CHOLMOD_INTLONG ; - ok = CHOLMOD(print_sparse)(C, "Cibad", cm) ; NOT (ok) ; C->itype = cm->itype ; cm->print = 1 ; cm->print = 4 ; -#if ( ITYPE == CHOLMOD_LONG ) +#if defined ( CHOLMOD_INT64 ) C->itype = CHOLMOD_INT ; #else C->itype = CHOLMOD_LONG ; @@ -888,7 +927,7 @@ void null2 (cholmod_triplet *Tok, int do_nantests) cm->print = 1 ; C->dtype = CHOLMOD_SINGLE ; - ok = CHOLMOD(print_sparse)(C, "Cdbad", cm) ; NOT (ok) ; + ok = CHOLMOD(print_sparse)(C, "C single: OK", cm) ; OK (ok) ; C->dtype = EMPTY ; ok = CHOLMOD(print_sparse)(C, "CDbad", cm) ; NOT (ok) ; C->dtype = CHOLMOD_DOUBLE ; @@ -1058,7 +1097,7 @@ void null2 (cholmod_triplet *Tok, int do_nantests) ok = CHOLMOD(print_dense)(X, "X OK", cm) ; OK (ok) ; X->dtype = CHOLMOD_SINGLE ; - ok = CHOLMOD(print_dense)(X, "X float", cm) ; NOT (ok) ; + ok = CHOLMOD(print_dense)(X, "X float: OK", cm) ; OK (ok) ; X->dtype = -1 ; ok = CHOLMOD(print_dense)(X, "X unknown", cm) ; NOT (ok) ; X->dtype = CHOLMOD_DOUBLE ; @@ -1175,15 +1214,13 @@ void null2 (cholmod_triplet *Tok, int do_nantests) OK (L->xtype == CHOLMOD_PATTERN) ; OK (L->is_super) ; - L->itype = CHOLMOD_INTLONG ; - ok = CHOLMOD(print_factor)(L, "L int/long", cm) ; NOT (ok) ; L->itype = -1 ; ok = CHOLMOD(print_factor)(L, "L int unknown", cm) ; NOT (ok) ; L->itype = cm->itype ; ok = CHOLMOD(print_factor)(L, "L OK", cm) ; OK (ok) ; cm->print = 4 ; -#if ( ITYPE == CHOLMOD_LONG ) +#if defined ( CHOLMOD_INT64 ) L->itype = CHOLMOD_INT ; #else L->itype = CHOLMOD_LONG ; @@ -1245,7 +1282,7 @@ void null2 (cholmod_triplet *Tok, int do_nantests) ok = CHOLMOD(super_symbolic)(A, Abad2, Parent, L, cm) ; NOT (ok) ; ok = CHOLMOD(super_symbolic)(Abad2, A, Parent, L, cm) ; NOT (ok) ; - W = CHOLMOD(zeros)(nrow, 1, L->xtype, cm) ; OKP (W) ; + W = CHOLMOD(zeros)(L->maxesize, 1, L->xtype, cm) ; OKP (W) ; X = CHOLMOD(ones)(nrow, 1, L->xtype, cm) ; OKP (X) ; ok = CHOLMOD(super_lsolve)(L, X, W, cm) ; OK (ok) ; ok = CHOLMOD(super_ltsolve)(L, X, W, cm) ; OK (ok) ; @@ -1318,7 +1355,7 @@ void null2 (cholmod_triplet *Tok, int do_nantests) ok = CHOLMOD(print_factor)(L, "L OK", cm) ; OK (ok) ; L->dtype = CHOLMOD_SINGLE ; - ok = CHOLMOD(print_factor)(L, "L float", cm) ; NOT (ok) ; + ok = CHOLMOD(print_factor)(L, "L float: OK", cm) ; OK (ok) ; L->dtype = -1 ; ok = CHOLMOD(print_factor)(L, "L unknown", cm) ; NOT (ok) ; L->dtype = CHOLMOD_DOUBLE ; @@ -1357,7 +1394,7 @@ void null2 (cholmod_triplet *Tok, int do_nantests) /* check LDL' unpacked */ ok = CHOLMOD(print_factor)(L, "L OK for L2 copy", cm) ; OK (ok) ; L2 = CHOLMOD(copy_factor)(L, cm) ; /* [ */ OKP (L2) ; - ok = CHOLMOD(change_factor)(L->xtype, FALSE, FALSE, FALSE, + ok = CHOLMOD(change_factor)(L->xtype, FALSE, FALSE, FALSE, TRUE, L2, cm) ; /* check LDL' packed */ @@ -1663,7 +1700,7 @@ void null2 (cholmod_triplet *Tok, int do_nantests) if (nrow > 0 && Lpi [1] - Lpi [0] > 3) { - p = Ls [2] ; + p = Ls [2] ; Ls [2] = Ls [1] ; ok = CHOLMOD(print_factor)(L, "L unsorted s", cm) ; NOT (ok) ; Ls [2] = p ; @@ -1695,7 +1732,7 @@ void null2 (cholmod_triplet *Tok, int do_nantests) if (nrow > 0 && Lpi [1] - Lpi [0] > 3) { - p = Ls [2] ; + p = Ls [2] ; Ls [2] = Ls [1] ; ok = CHOLMOD(print_factor)(L3, "Lsym unsorted s", cm) ; NOT (ok) ; Ls [2] = p ; @@ -1708,7 +1745,7 @@ void null2 (cholmod_triplet *Tok, int do_nantests) Int nsrow = Lpi [1] - Lpi [0] ; if (nsrow > nscol + 1) { - p = Ls [nscol] ; + p = Ls [nscol] ; Ls [nscol] = Ls [nscol+1] ; ok = CHOLMOD(print_factor)(L3, "Lsym unsorted s2", cm) ; NOT (ok) ; Ls [nscol] = p ; @@ -1828,9 +1865,6 @@ void null2 (cholmod_triplet *Tok, int do_nantests) ok = CHOLMOD(resymbol)(I1, NULL, 0, TRUE, L, cm) ; NOT (ok) ; ok = CHOLMOD(resymbol_noperm)(I1, NULL, 0, TRUE, L, cm) ; NOT (ok) ; - ok = CHOLMOD(change_factor)(-1, FALSE, FALSE, FALSE, FALSE, L, cm) ; - NOT (ok) ; - ok = CHOLMOD(change_factor)(L->xtype, FALSE, FALSE, FALSE, FALSE, Lbad, cm); NOT (ok) ; @@ -1891,7 +1925,7 @@ void null2 (cholmod_triplet *Tok, int do_nantests) ok = CHOLMOD(print_factor)(L4, "L4 ok, for colrealloc", cm) ; OK (ok) ; OK (nrow == (Int)(L->n)) ; ok = CHOLMOD(reallocate_column)(nrow, 1, L4, cm) ; NOT (ok) ; - ok = CHOLMOD(reallocate_column)(nrow-1, 0, L4, cm) ; NOT (ok) ; +// ok = CHOLMOD(reallocate_column)(nrow-1, 0, L4, cm) ; NOT (ok) ; ok = CHOLMOD(reallocate_column)(nrow-1, 10, L4, cm) ; OK (ok) ; cm->grow0 = 2e10 ; @@ -2322,8 +2356,10 @@ if (do_nantests) C = CHOLMOD(horzcat)(A, AT, TRUE, cm) ; NOP (C) ; C = CHOLMOD(vertcat)(A, AT, TRUE, cm) ; NOP (C) ; } - C = CHOLMOD(horzcat)(A, Axbad, TRUE, cm) ; NOP (C) ; - C = CHOLMOD(vertcat)(A, Axbad, TRUE, cm) ; NOP (C) ; + + C = CHOLMOD(horzcat)(A, Axbad, TRUE, cm) ; NOP (C) ; + C = CHOLMOD(vertcat)(A, Axbad, TRUE, cm) ; NOP (C) ; + C = CHOLMOD(vertcat)(A, NULL, TRUE, cm) ; NOP (C) ; C = CHOLMOD(vertcat)(NULL, AT, TRUE, cm) ; NOP (C) ; C = CHOLMOD(horzcat)(A, NULL, TRUE, cm) ; NOP (C) ; @@ -2363,13 +2399,11 @@ if (do_nantests) T->itype = -1 ; ok = CHOLMOD(print_triplet)(T, "T itype bad", cm) ; NOT (ok) ; - T->itype = CHOLMOD_INTLONG ; - ok = CHOLMOD(print_triplet)(T, "T itype bad", cm) ; NOT (ok) ; T->itype = cm->itype ; ok = CHOLMOD(print_triplet)(T, "T ok", cm) ; OK (ok) ; cm->print = 4 ; -#if ( ITYPE == CHOLMOD_LONG ) +#if defined ( CHOLMOD_INT64 ) T->itype = CHOLMOD_INT ; #else T->itype = CHOLMOD_LONG ; @@ -2388,7 +2422,7 @@ if (do_nantests) T->dtype = -1 ; ok = CHOLMOD(print_triplet)(T, "T dtype bad", cm) ; NOT (ok) ; T->dtype = CHOLMOD_SINGLE ; - ok = CHOLMOD(print_triplet)(T, "T dtype bad", cm) ; NOT (ok) ; + ok = CHOLMOD(print_triplet)(T, "T dtype float: OK", cm) ; OK (ok) ; T->dtype = CHOLMOD_DOUBLE ; ok = CHOLMOD(print_triplet)(T, "T ok", cm) ; OK (ok) ; @@ -2429,6 +2463,7 @@ if (do_nantests) } cm->print = 4 ; +// ok = CHOLMOD(print_triplet)(T, "T ok", cm) ; OK (ok) ; CHOLMOD(triplet_xtype)(CHOLMOD_PATTERN, T, cm) ; ok = CHOLMOD(print_triplet)(T, "T pattern ok", cm) ; OK (ok) ; cm->print = 1 ; @@ -2454,12 +2489,32 @@ if (do_nantests) Ti = T->i ; T->i = NULL ; - C = CHOLMOD(triplet_to_sparse)(T, 0, cm) ; NOP (C) ; + C = CHOLMOD(triplet_to_sparse)(T, 0, cm) ; + if (T->nnz == 0) + { + OKP (C) ; + ASSERT (CHOLMOD(nnz) (C, cm) == 0) ; + ok = CHOLMOD(free_sparse)(&C, cm) ; OK (ok) ; + } + else + { + NOP (C) ; + } T->i = Ti ; Tj = T->j ; T->j = NULL ; - C = CHOLMOD(triplet_to_sparse)(T, 0, cm) ; NOP (C) ; + C = CHOLMOD(triplet_to_sparse)(T, 0, cm) ; + if (T->nnz == 0) + { + OKP (C) ; + ASSERT (CHOLMOD(nnz) (C, cm) == 0) ; + ok = CHOLMOD(free_sparse)(&C, cm) ; OK (ok) ; + } + else + { + NOP (C) ; + } T->j = Tj ; T->stype = 1 ; @@ -2519,10 +2574,10 @@ if (do_nantests) ok = CHOLMOD(reallocate_triplet)(16, T2, cm) ; NOT (ok) ; T = CHOLMOD(copy_triplet)(T2, cm) ; NOP (T) ; C = CHOLMOD(triplet_to_sparse)(T2, 100, cm) ; NOP (C) ; - T2->xtype = CHOLMOD_REAL ; + T2->xtype = CHOLMOD_REAL ; CHOLMOD(free_triplet)(&T2, cm) ; - T = CHOLMOD(allocate_triplet)(4, 4, 16, 0, -1, cm); NOP (T) ; +// T = CHOLMOD(allocate_triplet)(4, 4, 16, 0, -1, cm); NOP (T) ; T = CHOLMOD(sparse_to_triplet)(Abad2, cm) ; NOP (T) ; @@ -2568,13 +2623,32 @@ if (do_nantests) Ti = T->i ; T->i = NULL ; - T2 = CHOLMOD(copy_triplet)(T, cm) ; NOP (T2) ; + T2 = CHOLMOD(copy_triplet)(T, cm) ; + + if (T->nnz == 0) + { + OKP (T2) ; + } + else + { + NOP (T2) ; + } T->i = Ti ; + ok = CHOLMOD(free_triplet)(&T2, cm) ; OK (ok) ; Tj = T->j ; T->j = NULL ; - T2 = CHOLMOD(copy_triplet)(T, cm) ; NOP (T2) ; + T2 = CHOLMOD(copy_triplet)(T, cm) ; + if (T->nnz == 0) + { + OKP (T2) ; + } + else + { + NOP (T2) ; + } T->j = Tj ; + ok = CHOLMOD(free_triplet)(&T2, cm) ; OK (ok) ; ok = CHOLMOD(free_triplet)(&T, cm) ; OK (ok) ; A->stype = 1 ; @@ -2929,11 +3003,11 @@ if (do_nantests) ok = CHOLMOD(free_dense)(&W, cm) ; OK (ok) ; C = CHOLMOD(speye)(4, 4, CHOLMOD_COMPLEX, cm) ; OKP (C) ; - ok = CHOLMOD(sparse_xtype)(-1, C, cm) ; NOT (ok) ; + ok = CHOLMOD(sparse_xtype)(-1, C, cm) ; OK (ok) ; ok = CHOLMOD(sparse_xtype)(CHOLMOD_ZOMPLEX, C, cm) ; OK (ok) ; ok = CHOLMOD(sparse_xtype)(CHOLMOD_ZOMPLEX, NULL, cm) ; NOT (ok) ; T = CHOLMOD(sparse_to_triplet)(C, cm) ; OKP (T) ; - ok = CHOLMOD(triplet_xtype)(-1, T, cm) ; NOT (ok) ; + ok = CHOLMOD(triplet_xtype)(-1, T, cm) ; OK (ok) ; ok = CHOLMOD(triplet_xtype)(CHOLMOD_ZOMPLEX, T, cm) ; OK (ok) ; ok = CHOLMOD(triplet_xtype)(CHOLMOD_ZOMPLEX, NULL, cm) ; NOT (ok) ; @@ -3050,7 +3124,7 @@ if (do_nantests) } C = CHOLMOD(ssmult)(NULL, A, 0, TRUE, TRUE, cm) ; NOP (C) ; C = CHOLMOD(ssmult)(A, NULL, 0, TRUE, TRUE, cm) ; NOP (C) ; - C = CHOLMOD(ssmult)(A, Axbad, 0, TRUE, TRUE, cm) ; NOP (C) ; + C = CHOLMOD(ssmult)(A, Axbad, 0, TRUE, TRUE, cm) ; NOP (C) ; } /* ---------------------------------------------------------------------- */ @@ -3250,7 +3324,7 @@ if (do_nantests) NOT (ok) ; ok = CHOLMOD (allocate_work) (1, 2, 1, cm) ; NOT (ok) ; - ok = CHOLMOD (allocate_work) (1, 1, 2, cm) ; + ok = CHOLMOD (allocate_work) (1, 1, 8, cm) ; NOT (ok) ; cm->no_workspace_reallocate = FALSE ; ok = CHOLMOD (allocate_work) (1, 1, 2, cm) ; @@ -3338,10 +3412,11 @@ if (do_nantests) ok = CHOLMOD(rowfac)(A, NULL, beta, 0, 0, L, cm) ; NOT (ok) ; ok = CHOLMOD(transpose_unsym)(A, 1, Pok, NULL, 0, R, cm) ; NOT (ok) ; ok = CHOLMOD(transpose_sym)(A, 1, Pok, R, cm) ; NOT (ok) ; - if (nrow > 1) - { - ok = CHOLMOD(sort)(A, cm) ; NOT (ok) ; - } +// if (nrow > 1) +// { +// ok = CHOLMOD(sort)(A, cm) ; +// NOT (ok) ; +// } ok = CHOLMOD(row_subtree)(A, AT, 0, Parent, R3, cm) ; NOT (ok) ; ATi = (AT == NULL) ? NULL : AT->i ; diff --git a/CHOLMOD/Tcov/solve.c b/CHOLMOD/Tcov/solve.c index e86fb9e42..92060cd58 100644 --- a/CHOLMOD/Tcov/solve.c +++ b/CHOLMOD/Tcov/solve.c @@ -706,13 +706,26 @@ double solve (cholmod_sparse *A) CHOLMOD(free) (ncol, sizeof (Int), fset, cm) ; G = CHOLMOD(ssmult) (AF, AFt, 0, TRUE, TRUE, cm) ; +// int save = cm->print ; +// cm->print = 5 ; +// CHOLMOD (print_sparse) (A, "HERE A", cm) ; +// CHOLMOD (print_sparse) (AFt, "HERE AFt", cm) ; +// CHOLMOD (print_sparse) (AF, "HERE AF", cm) ; +// CHOLMOD (print_sparse) (G, "HERE G", cm) ; + /* also try aat */ H = CHOLMOD(aat) (AF, NULL, 0, 1, cm) ; + +// CHOLMOD (print_sparse) (H, "HERE H", cm) ; +// printf ("status %d\n", cm->status) ; +// cm->print = save ; + E = CHOLMOD(add) (G, H, one, minusone, TRUE, FALSE, cm) ; + enorm = CHOLMOD(norm_sparse) (E, 0, cm) ; gnorm = CHOLMOD(norm_sparse) (G, 0, cm) ; MAXERR (maxerr, enorm, gnorm) ; - if (cm->print > 1) + if (1) // (cm->print > 1) { printf ("enorm %g gnorm %g hnorm %g\n", enorm, gnorm, CHOLMOD(norm_sparse) (H, 0, cm)) ; @@ -726,6 +739,7 @@ double solve (cholmod_sparse *A) CHOLMOD(free_sparse) (&AF, cm) ; CHOLMOD(free_sparse) (&E, cm) ; CHOLMOD(free_sparse) (&H, cm) ; + } else { diff --git a/CHOLMOD/Valgrind/suppress b/CHOLMOD/Tcov/suppress similarity index 100% rename from CHOLMOD/Valgrind/suppress rename to CHOLMOD/Tcov/suppress diff --git a/CHOLMOD/Tcov/test_ops.c b/CHOLMOD/Tcov/test_ops.c index 4d99ba8f2..50ad63ba9 100644 --- a/CHOLMOD/Tcov/test_ops.c +++ b/CHOLMOD/Tcov/test_ops.c @@ -152,6 +152,7 @@ static void check_equality (cholmod_sparse *E, cholmod_sparse *D, Int xtype) OK (E->ncol == D->ncol) ; OK (E->nrow == D->nrow) ; + OK (E->packed == D->packed) ; ncol = E->ncol ; @@ -240,6 +241,9 @@ double test_ops (cholmod_sparse *A) /* E = pattern of A */ E = CHOLMOD(copy) (A, 0, 0, cm) ; CHOLMOD(print_sparse) (E, "E = pattern of A", cm) ; +// int64_t enz = CHOLMOD (nnz) (E, cm) ; +// int64_t anz = CHOLMOD (nnz) (A, cm) ; +// if (E->stype == A->stype) { OK (enz == anz) ; } r1 = CHOLMOD(norm_sparse) (E, 1, cm) ; rinf = CHOLMOD(norm_sparse) (E, 0, cm) ; OK (r1 <= nrow) ; @@ -286,13 +290,6 @@ double test_ops (cholmod_sparse *A) /* read/write */ /* ---------------------------------------------------------------------- */ -/* - i = cm->print ; - cm->print = 4 ; - CHOLMOD(print_sparse) (A, "A for read/write", cm) ; - cm->print = i ; -*/ - /* delete the contents of the temp1.mtx and temp2.mtx file */ f = fopen ("temp1.mtx", "w") ; fprintf (f, "temp1\n") ; @@ -428,7 +425,7 @@ double test_ops (cholmod_sparse *A) S = CHOLMOD(sparse_to_triplet) (A, cm) ; /* [ */ - if (S != NULL && nmin > 0) + if (S != NULL && nmin > 0 && S->nnz > 0) { /* double the number of entries in S */ @@ -749,7 +746,7 @@ double test_ops (cholmod_sparse *A) /* G = E+F */ G = CHOLMOD(add) (E, F, one, one, TRUE, TRUE, cm) ; - CHOLMOD(print_sparse) (G, "G=E+F", cm) ; + CHOLMOD(print_sparse) (G, "G=E+F (1)", cm) ; /* D = A-G, which should be empty */ D = CHOLMOD(add) (G, A, one, minusone, TRUE, TRUE, cm) ; @@ -807,7 +804,7 @@ double test_ops (cholmod_sparse *A) /* G = E+C */ G = CHOLMOD(add) (E, C, one, one, TRUE, FALSE, cm) ; - CHOLMOD(print_sparse) (G, "G=E+F", cm) ; + CHOLMOD(print_sparse) (G, "G = E+F", cm) ; CHOLMOD(sort) (G, cm) ; CHOLMOD(drop) (0, G, cm) ; @@ -847,7 +844,6 @@ double test_ops (cholmod_sparse *A) /* try CHOLMOD's interface to METIS_ComputeVertexSeparator */ cm->metis_memory = 2.0 ; - /* cm->print = 5 ; */ CHOLMOD(print_sparse) (A, "A for bisect", cm) ; csep = CHOLMOD(bisect) (A, NULL, 0, TRUE, Partition, cm) ; if (csep != EMPTY) @@ -939,7 +935,7 @@ double test_ops (cholmod_sparse *A) nc_new = CHOLMOD(collapse_septree) (1, 1, 0.1, 400, CParent, Cmember, cm) ; OK (nc_new == 1 || nc_new == EMPTY) ; - nc_new = CHOLMOD(collapse_septree) (Int_max, Int_max, + nc_new = CHOLMOD(collapse_septree) (SIZE_MAX, SIZE_MAX, 0.1, 400, CParent, Cmember, cm) ; OK (nc_new == EMPTY) ; @@ -986,8 +982,12 @@ double test_ops (cholmod_sparse *A) { F = CHOLMOD(add) (E, D, one, minusone, TRUE, TRUE, cm) ; r = CHOLMOD(norm_sparse) (F, 0, cm) ; - if (F != NULL) + if (F != NULL && cm->status == CHOLMOD_OK) { + if (r != 0) + { + printf ("r %g at %d:%s\n", r, __LINE__, __FILE__) ; + } OK (r == 0) ; } CHOLMOD(free_sparse) (&F, cm) ; @@ -1020,19 +1020,21 @@ double test_ops (cholmod_sparse *A) F = CHOLMOD(transpose) (E, 1, cm) ; G = CHOLMOD(add) (D, F, one, minusone, TRUE, FALSE, cm) ; r = CHOLMOD(norm_sparse) (G, 0, cm) ; - if (G != NULL) + if (G != NULL && cm->status == CHOLMOD_OK) { OK (r == 0) ; } CHOLMOD(drop) (0, G, cm) ; r = CHOLMOD(norm_sparse) (G, 0, cm) ; - nz = CHOLMOD(nnz) (G, cm) ; - if (G != NULL) + if (G != NULL && cm->status == CHOLMOD_OK) { OK (r == 0) ; + } + nz = CHOLMOD(nnz) (G, cm) ; + if (G != NULL && cm->status == CHOLMOD_OK) + { OK (nz == 0) ; } - CHOLMOD(free_sparse) (&C, cm) ; CHOLMOD(free_sparse) (&D, cm) ; CHOLMOD(free_sparse) (&E, cm) ; @@ -1059,10 +1061,16 @@ double test_ops (cholmod_sparse *A) C = CHOLMOD(copy_sparse) (A, cm) ; CHOLMOD(sort) (C, cm) ; + int cstype = (C == NULL) ? 0 : C->stype ; + E = CHOLMOD(copy) (C, cstype, 1, cm) ; + F = CHOLMOD(copy) (D, cstype, 1, cm) ; + /* C and D should be equal */ - check_equality (C, D, xtype) ; + check_equality (E, F, xtype) ; CHOLMOD(free_sparse) (&C, cm) ; CHOLMOD(free_sparse) (&D, cm) ; + CHOLMOD(free_sparse) (&E, cm) ; + CHOLMOD(free_sparse) (&F, cm) ; /* C = A.' */ C = CHOLMOD(transpose) (A, 1, cm) ; @@ -1076,10 +1084,16 @@ double test_ops (cholmod_sparse *A) C = CHOLMOD(copy_sparse) (A, cm) ; CHOLMOD(sort) (C, cm) ; + cstype = (C == NULL) ? 0 : C->stype ; + E = CHOLMOD(copy) (C, cstype, 1, cm) ; + F = CHOLMOD(copy) (D, cstype, 1, cm) ; + /* C and D should be equal */ - check_equality (C, D, xtype) ; + check_equality (E, F, xtype) ; CHOLMOD(free_sparse) (&C, cm) ; CHOLMOD(free_sparse) (&D, cm) ; + CHOLMOD(free_sparse) (&E, cm) ; + CHOLMOD(free_sparse) (&F, cm) ; } /* ---------------------------------------------------------------------- */ diff --git a/CHOLMOD/Utility/cholmod_aat.c b/CHOLMOD/Utility/cholmod_aat.c new file mode 100644 index 000000000..794093841 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_aat.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_aat: compute AA' or A(:,f)*A(:,f)' +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_aat.c" + diff --git a/CHOLMOD/Utility/cholmod_add.c b/CHOLMOD/Utility/cholmod_add.c new file mode 100644 index 000000000..02dff7359 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_add.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_add: C = alpha*A + beta*B +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_add.c" + diff --git a/CHOLMOD/Utility/cholmod_add_size_t.c b/CHOLMOD/Utility/cholmod_add_size_t.c new file mode 100644 index 000000000..51400bc7b --- /dev/null +++ b/CHOLMOD/Utility/cholmod_add_size_t.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_add_size_t: add two size_t values +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_add_size_t.c" + diff --git a/CHOLMOD/Core/cholmod_l_factor.c b/CHOLMOD/Utility/cholmod_alloc_factor.c similarity index 55% rename from CHOLMOD/Core/cholmod_l_factor.c rename to CHOLMOD/Utility/cholmod_alloc_factor.c index 865555df9..0c9924f83 100644 --- a/CHOLMOD/Core/cholmod_l_factor.c +++ b/CHOLMOD/Utility/cholmod_alloc_factor.c @@ -1,13 +1,13 @@ //------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_factor.c: int64_t version of cholmod_factor +// CHOLMOD/Utility/cholmod_alloc_factor: allocate a simplicial factor //------------------------------------------------------------------------------ -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. // SPDX-License-Identifier: LGPL-2.1+ //------------------------------------------------------------------------------ -#define DLONG -#include "cholmod_factor.c" +#define CHOLMOD_INT32 +#include "t_cholmod_alloc_factor.c" diff --git a/CHOLMOD/Utility/cholmod_alloc_work.c b/CHOLMOD/Utility/cholmod_alloc_work.c new file mode 100644 index 000000000..46b0029a8 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_alloc_work.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_alloc_work: alloc workspace (double/single, int32) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_alloc_work.c" + diff --git a/CHOLMOD/Utility/cholmod_allocate_dense.c b/CHOLMOD/Utility/cholmod_allocate_dense.c new file mode 100644 index 000000000..e0497697e --- /dev/null +++ b/CHOLMOD/Utility/cholmod_allocate_dense.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_allocate_dense: allocate dense matrix (int32) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_allocate_dense.c" + diff --git a/CHOLMOD/Utility/cholmod_allocate_factor.c b/CHOLMOD/Utility/cholmod_allocate_factor.c new file mode 100644 index 000000000..5ac43cae7 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_allocate_factor.c @@ -0,0 +1,25 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_allocate_factor: allocate a simplicial factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// For backward compatibilty; L is returned as double precision. +// Use cholmod_alloc_factor to allocate a single precision factor. + +#define CHOLMOD_INT32 +#include "cholmod_internal.h" + +cholmod_factor *cholmod_allocate_factor // return the new factor L +( + size_t n, // L is factorization of an n-by-n matrix + cholmod_common *Common +) +{ + return (cholmod_alloc_factor (n, CHOLMOD_DOUBLE, Common)) ; +} + diff --git a/CHOLMOD/Utility/cholmod_allocate_sparse.c b/CHOLMOD/Utility/cholmod_allocate_sparse.c new file mode 100644 index 000000000..1cc566b8a --- /dev/null +++ b/CHOLMOD/Utility/cholmod_allocate_sparse.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_allocate_sparse: allocate a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_allocate_sparse.c" + diff --git a/CHOLMOD/Utility/cholmod_allocate_triplet.c b/CHOLMOD/Utility/cholmod_allocate_triplet.c new file mode 100644 index 000000000..0bce378ea --- /dev/null +++ b/CHOLMOD/Utility/cholmod_allocate_triplet.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_allocate_triplet: allocate triplet matrix (int32) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_allocate_triplet.c" + diff --git a/CHOLMOD/Utility/cholmod_allocate_work.c b/CHOLMOD/Utility/cholmod_allocate_work.c new file mode 100644 index 000000000..61e4996a3 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_allocate_work.c @@ -0,0 +1,24 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_allocate_work: alloc workspace (double, int32) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +int cholmod_allocate_work +( + size_t nrow, + size_t iworksize, + size_t xworksize, + cholmod_common *Common +) +{ + return (cholmod_alloc_work (nrow, iworksize, xworksize, CHOLMOD_DOUBLE, + Common)) ; +} + diff --git a/CHOLMOD/Utility/cholmod_band.c b/CHOLMOD/Utility/cholmod_band.c new file mode 100644 index 000000000..20efa58c4 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_band.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_band: extract the band of a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_band.c" + diff --git a/CHOLMOD/Utility/cholmod_band_nnz.c b/CHOLMOD/Utility/cholmod_band_nnz.c new file mode 100644 index 000000000..7efc5c04a --- /dev/null +++ b/CHOLMOD/Utility/cholmod_band_nnz.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_band_nnz: # of entries in a band of sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_band_nnz.c" + diff --git a/CHOLMOD/Utility/cholmod_calloc.c b/CHOLMOD/Utility/cholmod_calloc.c new file mode 100644 index 000000000..90cbe6e9d --- /dev/null +++ b/CHOLMOD/Utility/cholmod_calloc.c @@ -0,0 +1,15 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_calloc: calloc (int32 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_ALLOC_FUNCTION cholmod_calloc +#define SUITESPARSE_ALLOC_FUNCTION SuiteSparse_calloc +#define CHOLMOD_INT32 +#include "t_cholmod_malloc.c" + diff --git a/CHOLMOD/Utility/cholmod_change_factor.c b/CHOLMOD/Utility/cholmod_change_factor.c new file mode 100644 index 000000000..3f9b0492e --- /dev/null +++ b/CHOLMOD/Utility/cholmod_change_factor.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_change_factor: change format of a factor object +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_change_factor.c" + diff --git a/CHOLMOD/Utility/cholmod_clear_flag.c b/CHOLMOD/Utility/cholmod_clear_flag.c new file mode 100644 index 000000000..753064822 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_clear_flag.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_clear_flag: clear Common->Flag +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_clear_flag.c" + diff --git a/CHOLMOD/Utility/cholmod_copy.c b/CHOLMOD/Utility/cholmod_copy.c new file mode 100644 index 000000000..d2c92f608 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_copy.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_copy: copy a sparse matrix (with change of stype) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_copy.c" + diff --git a/CHOLMOD/Utility/cholmod_copy_dense.c b/CHOLMOD/Utility/cholmod_copy_dense.c new file mode 100644 index 000000000..20795d122 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_copy_dense.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_copy_dense: copy a dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_copy_dense.c" + diff --git a/CHOLMOD/Utility/cholmod_copy_dense2.c b/CHOLMOD/Utility/cholmod_copy_dense2.c new file mode 100644 index 000000000..65efdea67 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_copy_dense2.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_copy_dense2: copy a dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_copy_dense2.c" + diff --git a/CHOLMOD/Utility/cholmod_copy_factor.c b/CHOLMOD/Utility/cholmod_copy_factor.c new file mode 100644 index 000000000..bafdd7e3a --- /dev/null +++ b/CHOLMOD/Utility/cholmod_copy_factor.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_copy_factor: copy a factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_copy_factor.c" + diff --git a/CHOLMOD/Utility/cholmod_copy_sparse.c b/CHOLMOD/Utility/cholmod_copy_sparse.c new file mode 100644 index 000000000..24cb68fdd --- /dev/null +++ b/CHOLMOD/Utility/cholmod_copy_sparse.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_copy_sparse: copy a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_copy_sparse.c" + diff --git a/CHOLMOD/Utility/cholmod_copy_triplet.c b/CHOLMOD/Utility/cholmod_copy_triplet.c new file mode 100644 index 000000000..d97d6a3a8 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_copy_triplet.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_copy_triplet: copy a triplet matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_copy_triplet.c" + diff --git a/CHOLMOD/Utility/cholmod_cumsum.c b/CHOLMOD/Utility/cholmod_cumsum.c new file mode 100644 index 000000000..cd4b22983 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_cumsum.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_cumsum: cumulative sum (int32) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_cumsum.c" + diff --git a/CHOLMOD/Utility/cholmod_dbound.c b/CHOLMOD/Utility/cholmod_dbound.c new file mode 100644 index 000000000..ab2050abd --- /dev/null +++ b/CHOLMOD/Utility/cholmod_dbound.c @@ -0,0 +1,18 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_dbound: bound diagonal of LDL (double, int32) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_BOUND_FUNCTION cholmod_dbound +#define COMMON_BOUND (Common->dbound) +#define COMMON_BOUNDS_HIT (Common->ndbounds_hit) +#define Real double + +#define CHOLMOD_INT32 +#include "t_cholmod_bound.c" + diff --git a/CHOLMOD/Utility/cholmod_defaults.c b/CHOLMOD/Utility/cholmod_defaults.c new file mode 100644 index 000000000..ed8560936 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_defaults.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_defaults: set CHOLMOD defaults (int32 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_defaults.c" + diff --git a/CHOLMOD/Utility/cholmod_dense_nnz.c b/CHOLMOD/Utility/cholmod_dense_nnz.c new file mode 100644 index 000000000..bf504b483 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_dense_nnz.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_dense_nnz: # of nonzeros in a dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_dense_nnz.c" + diff --git a/CHOLMOD/Utility/cholmod_dense_to_sparse.c b/CHOLMOD/Utility/cholmod_dense_to_sparse.c new file mode 100644 index 000000000..02a726d43 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_dense_to_sparse.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_dense_to_sparse: convert a dense matrix to sparse +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_dense_to_sparse.c" + diff --git a/CHOLMOD/Utility/cholmod_divcomplex.c b/CHOLMOD/Utility/cholmod_divcomplex.c new file mode 100644 index 000000000..cc3edb6e9 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_divcomplex.c @@ -0,0 +1,24 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_divcomplex: complex divide +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +// Compute c = a/b + +int cholmod_divcomplex +( + double ar, double ai, // a (real, imaginary) + double br, double bi, // b (real, imaginary) + double *cr, double *ci // c (real, imaginary) +) +{ + return (SuiteSparse_config_divcomplex (ar, ai, br, bi, cr, ci)) ; +} + diff --git a/CHOLMOD/Utility/cholmod_ensure_dense.c b/CHOLMOD/Utility/cholmod_ensure_dense.c new file mode 100644 index 000000000..d0f3de262 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_ensure_dense.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_ensure_dense: ensure dense matrix has a given size +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_ensure_dense.c" + diff --git a/CHOLMOD/Utility/cholmod_error.c b/CHOLMOD/Utility/cholmod_error.c new file mode 100644 index 000000000..1d6a2f3b4 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_error.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_error: CHOLMOD error handling +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_error.c" + diff --git a/CHOLMOD/Utility/cholmod_eye.c b/CHOLMOD/Utility/cholmod_eye.c new file mode 100644 index 000000000..3d80185fb --- /dev/null +++ b/CHOLMOD/Utility/cholmod_eye.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_eye: dense identity matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_eye.c" + diff --git a/CHOLMOD/Utility/cholmod_factor_to_sparse.c b/CHOLMOD/Utility/cholmod_factor_to_sparse.c new file mode 100644 index 000000000..f22616fa0 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_factor_to_sparse.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_factor_to_sparse: convert factor to sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_factor_to_sparse.c" + diff --git a/CHOLMOD/Utility/cholmod_finish.c b/CHOLMOD/Utility/cholmod_finish.c new file mode 100644 index 000000000..6f2277589 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_finish.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_finish: finish CHOLMOD (int32 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_finish.c" + diff --git a/CHOLMOD/Utility/cholmod_free.c b/CHOLMOD/Utility/cholmod_free.c new file mode 100644 index 000000000..3bb235a52 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_free.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_free: free (int32 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_free.c" + diff --git a/CHOLMOD/Utility/cholmod_free_dense.c b/CHOLMOD/Utility/cholmod_free_dense.c new file mode 100644 index 000000000..89d0e59f9 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_free_dense.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_free_dense: free dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_free_dense.c" + diff --git a/CHOLMOD/Utility/cholmod_free_factor.c b/CHOLMOD/Utility/cholmod_free_factor.c new file mode 100644 index 000000000..a3f2caf04 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_free_factor.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_free_factor: free a sparse factorization +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_free_factor.c" + diff --git a/CHOLMOD/Utility/cholmod_free_sparse.c b/CHOLMOD/Utility/cholmod_free_sparse.c new file mode 100644 index 000000000..2a5f9399f --- /dev/null +++ b/CHOLMOD/Utility/cholmod_free_sparse.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_free_sparse: free sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_free_sparse.c" + diff --git a/CHOLMOD/Utility/cholmod_free_triplet.c b/CHOLMOD/Utility/cholmod_free_triplet.c new file mode 100644 index 000000000..1734cf2f1 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_free_triplet.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_free_triplet: free triplet matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_free_triplet.c" + diff --git a/CHOLMOD/Utility/cholmod_free_work.c b/CHOLMOD/Utility/cholmod_free_work.c new file mode 100644 index 000000000..6695a4a72 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_free_work.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_free_work: free workspace in Common (int32) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_free_work.c" + diff --git a/CHOLMOD/Core/cholmod_l_change_factor.c b/CHOLMOD/Utility/cholmod_hypot.c similarity index 52% rename from CHOLMOD/Core/cholmod_l_change_factor.c rename to CHOLMOD/Utility/cholmod_hypot.c index 875089034..57ea322ad 100644 --- a/CHOLMOD/Core/cholmod_l_change_factor.c +++ b/CHOLMOD/Utility/cholmod_hypot.c @@ -1,14 +1,17 @@ //------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_change_factor.c: -// int64_t version of cholmod_change_factor +// CHOLMOD/Utility/cholmod_hypot: complex hypot //------------------------------------------------------------------------------ -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. // SPDX-License-Identifier: LGPL-2.1+ //------------------------------------------------------------------------------ -#define DLONG -#include "cholmod_change_factor.c" +#include "cholmod_internal.h" + +double cholmod_hypot (double x, double y) +{ + return (SuiteSparse_config_hypot (x, y)) ; +} diff --git a/CHOLMOD/Core/cholmod_l_aat.c b/CHOLMOD/Utility/cholmod_l_aat.c similarity index 55% rename from CHOLMOD/Core/cholmod_l_aat.c rename to CHOLMOD/Utility/cholmod_l_aat.c index d45149739..153645fc6 100644 --- a/CHOLMOD/Core/cholmod_l_aat.c +++ b/CHOLMOD/Utility/cholmod_l_aat.c @@ -1,13 +1,13 @@ //------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_aat.c: int64_t version of cholmod_aat +// CHOLMOD/Utility/cholmod_l_aat: compute AA' or A(:,f)*A(:,f)' //------------------------------------------------------------------------------ -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. // SPDX-License-Identifier: LGPL-2.1+ //------------------------------------------------------------------------------ -#define DLONG -#include "cholmod_aat.c" +#define CHOLMOD_INT64 +#include "t_cholmod_aat.c" diff --git a/CHOLMOD/Core/cholmod_l_add.c b/CHOLMOD/Utility/cholmod_l_add.c similarity index 55% rename from CHOLMOD/Core/cholmod_l_add.c rename to CHOLMOD/Utility/cholmod_l_add.c index 070a12ae9..7b2465ca9 100644 --- a/CHOLMOD/Core/cholmod_l_add.c +++ b/CHOLMOD/Utility/cholmod_l_add.c @@ -1,13 +1,13 @@ //------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_add.c: int64_t version of cholmod_add +// CHOLMOD/Utility/cholmod_l_add: C = alpha*A + beta*B //------------------------------------------------------------------------------ -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. // SPDX-License-Identifier: LGPL-2.1+ //------------------------------------------------------------------------------ -#define DLONG -#include "cholmod_add.c" +#define CHOLMOD_INT64 +#include "t_cholmod_add.c" diff --git a/CHOLMOD/Utility/cholmod_l_add_size_t.c b/CHOLMOD/Utility/cholmod_l_add_size_t.c new file mode 100644 index 000000000..60a461fe4 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_add_size_t.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_add_size_t: add two size_t values +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_add_size_t.c" + diff --git a/CHOLMOD/Utility/cholmod_l_alloc_factor.c b/CHOLMOD/Utility/cholmod_l_alloc_factor.c new file mode 100644 index 000000000..6dac2c02e --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_alloc_factor.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_alloc_factor: allocate a simplicial factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_alloc_factor.c" + diff --git a/CHOLMOD/Utility/cholmod_l_alloc_work.c b/CHOLMOD/Utility/cholmod_l_alloc_work.c new file mode 100644 index 000000000..484329734 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_alloc_work.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_alloc_work: alloc workspace (double/single, int64) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_alloc_work.c" + diff --git a/CHOLMOD/Utility/cholmod_l_allocate_dense.c b/CHOLMOD/Utility/cholmod_l_allocate_dense.c new file mode 100644 index 000000000..581e0c078 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_allocate_dense.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_allocate_dense: allocate dense matrix (int64) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_allocate_dense.c" + diff --git a/CHOLMOD/Utility/cholmod_l_allocate_factor.c b/CHOLMOD/Utility/cholmod_l_allocate_factor.c new file mode 100644 index 000000000..cf81b411f --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_allocate_factor.c @@ -0,0 +1,25 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_allocate_factor: allocate a simplicial factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// For backward compatibilty; L is returned as double precision. +// Use cholmod_l_alloc_factor to allocate a single precision factor. + +#define CHOLMOD_INT64 +#include "cholmod_internal.h" + +cholmod_factor *cholmod_l_allocate_factor // return the new factor L +( + size_t n, // L is factorization of an n-by-n matrix + cholmod_common *Common +) +{ + return (cholmod_l_alloc_factor (n, CHOLMOD_DOUBLE, Common)) ; +} + diff --git a/CHOLMOD/Utility/cholmod_l_allocate_sparse.c b/CHOLMOD/Utility/cholmod_l_allocate_sparse.c new file mode 100644 index 000000000..bef6996d1 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_allocate_sparse.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_allocate_sparse: allocate a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_allocate_sparse.c" + diff --git a/CHOLMOD/Utility/cholmod_l_allocate_triplet.c b/CHOLMOD/Utility/cholmod_l_allocate_triplet.c new file mode 100644 index 000000000..7e578e8a0 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_allocate_triplet.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_allocate_triplet: allocate triplet matrix (int64) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_allocate_triplet.c" + diff --git a/CHOLMOD/Utility/cholmod_l_allocate_work.c b/CHOLMOD/Utility/cholmod_l_allocate_work.c new file mode 100644 index 000000000..ee167e354 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_allocate_work.c @@ -0,0 +1,24 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_allocate_work: alloc workspace (double, int64) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +int cholmod_l_allocate_work +( + size_t nrow, + size_t iworksize, + size_t xworksize, + cholmod_common *Common +) +{ + return (cholmod_l_alloc_work (nrow, iworksize, xworksize, CHOLMOD_DOUBLE, + Common)) ; +} + diff --git a/CHOLMOD/Core/cholmod_l_band.c b/CHOLMOD/Utility/cholmod_l_band.c similarity index 55% rename from CHOLMOD/Core/cholmod_l_band.c rename to CHOLMOD/Utility/cholmod_l_band.c index 49d4d8fa0..3a560b618 100644 --- a/CHOLMOD/Core/cholmod_l_band.c +++ b/CHOLMOD/Utility/cholmod_l_band.c @@ -1,13 +1,13 @@ //------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_band.c: int64_t version of cholmod_band +// CHOLMOD/Utility/cholmod_l_band: extract the band of a sparse matrix //------------------------------------------------------------------------------ -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. // SPDX-License-Identifier: LGPL-2.1+ //------------------------------------------------------------------------------ -#define DLONG -#include "cholmod_band.c" +#define CHOLMOD_INT64 +#include "t_cholmod_band.c" diff --git a/CHOLMOD/Utility/cholmod_l_band_nnz.c b/CHOLMOD/Utility/cholmod_l_band_nnz.c new file mode 100644 index 000000000..343a03e5a --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_band_nnz.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_band_nnz: # of entries in a band of sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_band_nnz.c" + diff --git a/CHOLMOD/Utility/cholmod_l_calloc.c b/CHOLMOD/Utility/cholmod_l_calloc.c new file mode 100644 index 000000000..004e17ece --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_calloc.c @@ -0,0 +1,15 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_calloc: calloc (int64 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_ALLOC_FUNCTION cholmod_l_calloc +#define SUITESPARSE_ALLOC_FUNCTION SuiteSparse_calloc +#define CHOLMOD_INT64 +#include "t_cholmod_malloc.c" + diff --git a/CHOLMOD/Utility/cholmod_l_change_factor.c b/CHOLMOD/Utility/cholmod_l_change_factor.c new file mode 100644 index 000000000..f80779e70 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_change_factor.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_change_factor: change format of a factor object +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_change_factor.c" + diff --git a/CHOLMOD/Utility/cholmod_l_clear_flag.c b/CHOLMOD/Utility/cholmod_l_clear_flag.c new file mode 100644 index 000000000..cd604a29a --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_clear_flag.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_clear_flag: clear Common->Flag +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_clear_flag.c" + diff --git a/CHOLMOD/Core/cholmod_l_copy.c b/CHOLMOD/Utility/cholmod_l_copy.c similarity index 55% rename from CHOLMOD/Core/cholmod_l_copy.c rename to CHOLMOD/Utility/cholmod_l_copy.c index f47ceb8cd..aa9f687b9 100644 --- a/CHOLMOD/Core/cholmod_l_copy.c +++ b/CHOLMOD/Utility/cholmod_l_copy.c @@ -1,13 +1,13 @@ //------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_copy.c: int64_t version of cholmod_copy +// CHOLMOD/Utility/cholmod_l_copy: copy a sparse matrix (with change of stype) //------------------------------------------------------------------------------ -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. // SPDX-License-Identifier: LGPL-2.1+ //------------------------------------------------------------------------------ -#define DLONG -#include "cholmod_copy.c" +#define CHOLMOD_INT64 +#include "t_cholmod_copy.c" diff --git a/CHOLMOD/Utility/cholmod_l_copy_dense.c b/CHOLMOD/Utility/cholmod_l_copy_dense.c new file mode 100644 index 000000000..dfe71cb9e --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_copy_dense.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_copy_dense: copy a dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_copy_dense.c" + diff --git a/CHOLMOD/Utility/cholmod_l_copy_dense2.c b/CHOLMOD/Utility/cholmod_l_copy_dense2.c new file mode 100644 index 000000000..561ae16a9 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_copy_dense2.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_copy_dense2: copy a dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_copy_dense2.c" + diff --git a/CHOLMOD/Utility/cholmod_l_copy_factor.c b/CHOLMOD/Utility/cholmod_l_copy_factor.c new file mode 100644 index 000000000..ed0d0d660 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_copy_factor.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_copy_factor: copy a factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_copy_factor.c" + diff --git a/CHOLMOD/Utility/cholmod_l_copy_sparse.c b/CHOLMOD/Utility/cholmod_l_copy_sparse.c new file mode 100644 index 000000000..f5eaf83cc --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_copy_sparse.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_copy_sparse: copy a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_copy_sparse.c" + diff --git a/CHOLMOD/Utility/cholmod_l_copy_triplet.c b/CHOLMOD/Utility/cholmod_l_copy_triplet.c new file mode 100644 index 000000000..e580ec151 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_copy_triplet.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_copy_triplet: copy a triplet matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_copy_triplet.c" + diff --git a/CHOLMOD/Utility/cholmod_l_cumsum.c b/CHOLMOD/Utility/cholmod_l_cumsum.c new file mode 100644 index 000000000..f3e2f73f4 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_cumsum.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_cumsum: cumulative sum (int64) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_cumsum.c" + diff --git a/CHOLMOD/Utility/cholmod_l_dbound.c b/CHOLMOD/Utility/cholmod_l_dbound.c new file mode 100644 index 000000000..9ee679884 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_dbound.c @@ -0,0 +1,18 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_dbound: bound diagonal of LDL (double, int64) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_BOUND_FUNCTION cholmod_l_dbound +#define COMMON_BOUND (Common->dbound) +#define COMMON_BOUNDS_HIT (Common->ndbounds_hit) +#define Real double + +#define CHOLMOD_INT64 +#include "t_cholmod_bound.c" + diff --git a/CHOLMOD/Utility/cholmod_l_defaults.c b/CHOLMOD/Utility/cholmod_l_defaults.c new file mode 100644 index 000000000..d5990258f --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_defaults.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_defaults: set CHOLMOD defaults (int64 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_defaults.c" + diff --git a/CHOLMOD/Utility/cholmod_l_dense_nnz.c b/CHOLMOD/Utility/cholmod_l_dense_nnz.c new file mode 100644 index 000000000..4611f6091 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_dense_nnz.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_dense_nnz: # of nonzeros in a dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_dense_nnz.c" + diff --git a/CHOLMOD/Utility/cholmod_l_dense_to_sparse.c b/CHOLMOD/Utility/cholmod_l_dense_to_sparse.c new file mode 100644 index 000000000..d1cd95326 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_dense_to_sparse.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_dense_to_sparse: convert a dense matrix to sparse +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_dense_to_sparse.c" + diff --git a/CHOLMOD/Utility/cholmod_l_divcomplex.c b/CHOLMOD/Utility/cholmod_l_divcomplex.c new file mode 100644 index 000000000..1a8901a0b --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_divcomplex.c @@ -0,0 +1,22 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_divcomplex: complex divide +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +int cholmod_l_divcomplex +( + double ar, double ai, // a (real, imaginary) + double br, double bi, // b (real, imaginary) + double *cr, double *ci // c (real, imaginary) +) +{ + return (SuiteSparse_config_divcomplex (ar, ai, br, bi, cr, ci)) ; +} + diff --git a/CHOLMOD/Utility/cholmod_l_ensure_dense.c b/CHOLMOD/Utility/cholmod_l_ensure_dense.c new file mode 100644 index 000000000..e53d82645 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_ensure_dense.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_ensure_dense: ensure dense matrix has a given size +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_ensure_dense.c" + diff --git a/CHOLMOD/Utility/cholmod_l_error.c b/CHOLMOD/Utility/cholmod_l_error.c new file mode 100644 index 000000000..aff983ce6 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_error.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_error: CHOLMOD error handling +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_error.c" + diff --git a/CHOLMOD/Utility/cholmod_l_eye.c b/CHOLMOD/Utility/cholmod_l_eye.c new file mode 100644 index 000000000..49014647f --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_eye.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_eye: dense identity matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_eye.c" + diff --git a/CHOLMOD/Utility/cholmod_l_factor_to_sparse.c b/CHOLMOD/Utility/cholmod_l_factor_to_sparse.c new file mode 100644 index 000000000..74a63289c --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_factor_to_sparse.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_factor_to_sparse: convert factor to sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_factor_to_sparse.c" + diff --git a/CHOLMOD/Utility/cholmod_l_finish.c b/CHOLMOD/Utility/cholmod_l_finish.c new file mode 100644 index 000000000..a0066f150 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_finish.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_finish: finish CHOLMOD (int64 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_finish.c" + diff --git a/CHOLMOD/Utility/cholmod_l_free.c b/CHOLMOD/Utility/cholmod_l_free.c new file mode 100644 index 000000000..cc4ff9ef7 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_free.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_free: free (int64 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_free.c" + diff --git a/CHOLMOD/Utility/cholmod_l_free_dense.c b/CHOLMOD/Utility/cholmod_l_free_dense.c new file mode 100644 index 000000000..f692f29a3 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_free_dense.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_free_dense: free dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_free_dense.c" + diff --git a/CHOLMOD/Utility/cholmod_l_free_factor.c b/CHOLMOD/Utility/cholmod_l_free_factor.c new file mode 100644 index 000000000..182bccdb1 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_free_factor.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_free_factor: free a sparse factorization +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_free_factor.c" + diff --git a/CHOLMOD/Utility/cholmod_l_free_sparse.c b/CHOLMOD/Utility/cholmod_l_free_sparse.c new file mode 100644 index 000000000..d8717fa9e --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_free_sparse.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_free_sparse: free sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_free_sparse.c" + diff --git a/CHOLMOD/Utility/cholmod_l_free_triplet.c b/CHOLMOD/Utility/cholmod_l_free_triplet.c new file mode 100644 index 000000000..c65d4bd5d --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_free_triplet.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_free_triplet: free triplet matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_free_triplet.c" + diff --git a/CHOLMOD/Utility/cholmod_l_free_work.c b/CHOLMOD/Utility/cholmod_l_free_work.c new file mode 100644 index 000000000..8b1cbb90e --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_free_work.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_free_work: free workspace in Common (int64) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_free_work.c" + diff --git a/CHOLMOD/Utility/cholmod_l_hypot.c b/CHOLMOD/Utility/cholmod_l_hypot.c new file mode 100644 index 000000000..f6a647067 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_hypot.c @@ -0,0 +1,17 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_hypot: complex hypot +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +double cholmod_l_hypot (double x, double y) +{ + return (SuiteSparse_config_hypot (x, y)) ; +} + diff --git a/CHOLMOD/Utility/cholmod_l_malloc.c b/CHOLMOD/Utility/cholmod_l_malloc.c new file mode 100644 index 000000000..d344e627a --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_malloc.c @@ -0,0 +1,15 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_malloc: malloc (int64 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_ALLOC_FUNCTION cholmod_l_malloc +#define SUITESPARSE_ALLOC_FUNCTION SuiteSparse_malloc +#define CHOLMOD_INT64 +#include "t_cholmod_malloc.c" + diff --git a/CHOLMOD/Utility/cholmod_l_maxrank.c b/CHOLMOD/Utility/cholmod_l_maxrank.c new file mode 100644 index 000000000..fc6991e34 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_maxrank.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_maxrank: find valid value of Common->maxrank +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_maxrank.c" + diff --git a/CHOLMOD/Utility/cholmod_l_mult_size_t.c b/CHOLMOD/Utility/cholmod_l_mult_size_t.c new file mode 100644 index 000000000..53d5310b2 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_mult_size_t.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_mult_size_t: multiply two size_t values +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_mult_size_t.c" + diff --git a/CHOLMOD/Utility/cholmod_l_nnz.c b/CHOLMOD/Utility/cholmod_l_nnz.c new file mode 100644 index 000000000..2b21822f9 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_nnz.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_nnz: # of entries in a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_nnz.c" + diff --git a/CHOLMOD/Utility/cholmod_l_ones.c b/CHOLMOD/Utility/cholmod_l_ones.c new file mode 100644 index 000000000..71ff5bddc --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_ones.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_ones: dense matrix of all ones +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_ones.c" + diff --git a/CHOLMOD/Utility/cholmod_l_pack_factor.c b/CHOLMOD/Utility/cholmod_l_pack_factor.c new file mode 100644 index 000000000..72fa3e1f2 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_pack_factor.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_pack_factor: pack a simplicial factorization +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_pack_factor.c" + diff --git a/CHOLMOD/Utility/cholmod_l_ptranspose.c b/CHOLMOD/Utility/cholmod_l_ptranspose.c new file mode 100644 index 000000000..f7cf6880b --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_ptranspose.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_ptranspose: permuted transpose +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_ptranspose.c" + diff --git a/CHOLMOD/Utility/cholmod_l_realloc.c b/CHOLMOD/Utility/cholmod_l_realloc.c new file mode 100644 index 000000000..4c0320a76 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_realloc.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_realloc: realloc (int64 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_realloc.c" + diff --git a/CHOLMOD/Utility/cholmod_l_realloc_multiple.c b/CHOLMOD/Utility/cholmod_l_realloc_multiple.c new file mode 100644 index 000000000..8cea78c9a --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_realloc_multiple.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_realloc_multiple: multiple realloc (int64 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_realloc_multiple.c" + diff --git a/CHOLMOD/Utility/cholmod_l_reallocate_column.c b/CHOLMOD/Utility/cholmod_l_reallocate_column.c new file mode 100644 index 000000000..34d75b7fe --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_reallocate_column.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_reallocate_column: reallocate a column of a factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_reallocate_column.c" + diff --git a/CHOLMOD/Utility/cholmod_l_reallocate_factor.c b/CHOLMOD/Utility/cholmod_l_reallocate_factor.c new file mode 100644 index 000000000..a8986990b --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_reallocate_factor.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_reallocate_factor: reallocate a factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_reallocate_factor.c" + diff --git a/CHOLMOD/Utility/cholmod_l_reallocate_sparse.c b/CHOLMOD/Utility/cholmod_l_reallocate_sparse.c new file mode 100644 index 000000000..3d69bd0df --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_reallocate_sparse.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_reallocate_sparse: reallocate sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_reallocate_sparse.c" + diff --git a/CHOLMOD/Utility/cholmod_l_reallocate_triplet.c b/CHOLMOD/Utility/cholmod_l_reallocate_triplet.c new file mode 100644 index 000000000..964bdba25 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_reallocate_triplet.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_reallocate_triplet: reallocate triplet matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_reallocate_triplet.c" + diff --git a/CHOLMOD/Utility/cholmod_l_sbound.c b/CHOLMOD/Utility/cholmod_l_sbound.c new file mode 100644 index 000000000..7cc46b496 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_sbound.c @@ -0,0 +1,18 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_sbound: bound diagonal of LDL (single, int64) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_BOUND_FUNCTION cholmod_l_sbound +#define COMMON_BOUND (Common->sbound) +#define COMMON_BOUNDS_HIT (Common->nsbounds_hit) +#define Real float + +#define CHOLMOD_INT64 +#include "t_cholmod_bound.c" + diff --git a/CHOLMOD/Utility/cholmod_l_score_comp.c b/CHOLMOD/Utility/cholmod_l_score_comp.c new file mode 100644 index 000000000..b654c9e1d --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_score_comp.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_score_comp: for sorting supernodes +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_score_comp.c" + diff --git a/CHOLMOD/Utility/cholmod_l_set_empty.c b/CHOLMOD/Utility/cholmod_l_set_empty.c new file mode 100644 index 000000000..0d20de058 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_set_empty.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_set_empty: set an int64 array to EMPTY +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_set_empty.c" + diff --git a/CHOLMOD/Utility/cholmod_l_sort.c b/CHOLMOD/Utility/cholmod_l_sort.c new file mode 100644 index 000000000..b64f07439 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_sort.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_sort: sort a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_sort.c" + diff --git a/CHOLMOD/Utility/cholmod_l_sparse_to_dense.c b/CHOLMOD/Utility/cholmod_l_sparse_to_dense.c new file mode 100644 index 000000000..6889cdf50 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_sparse_to_dense.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_sparse_to_dense: convert a sparse matrix to dense +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_sparse_to_dense.c" + diff --git a/CHOLMOD/Utility/cholmod_l_sparse_to_triplet.c b/CHOLMOD/Utility/cholmod_l_sparse_to_triplet.c new file mode 100644 index 000000000..f3b819b52 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_sparse_to_triplet.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_sparse_to_triplet: convert sparse to triplet +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_sparse_to_triplet.c" + diff --git a/CHOLMOD/Utility/cholmod_l_speye.c b/CHOLMOD/Utility/cholmod_l_speye.c new file mode 100644 index 000000000..5f8e95109 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_speye.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_speye: sparse identity matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_speye.c" + diff --git a/CHOLMOD/Utility/cholmod_l_spzeros.c b/CHOLMOD/Utility/cholmod_l_spzeros.c new file mode 100644 index 000000000..857d2e64c --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_spzeros.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_spzeros: all-zero sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_spzeros.c" + diff --git a/CHOLMOD/Utility/cholmod_l_start.c b/CHOLMOD/Utility/cholmod_l_start.c new file mode 100644 index 000000000..a0ed14a57 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_start.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_start: start CHOLMOD (int64 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_start.c" + diff --git a/CHOLMOD/Utility/cholmod_l_transpose.c b/CHOLMOD/Utility/cholmod_l_transpose.c new file mode 100644 index 000000000..1d409ad17 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_transpose.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_transpose: transpose a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_transpose.c" + diff --git a/CHOLMOD/Utility/cholmod_l_transpose_sym.c b/CHOLMOD/Utility/cholmod_l_transpose_sym.c new file mode 100644 index 000000000..b844026a7 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_transpose_sym.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_transpose_sym: symmetric permuted transpose +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_transpose_sym.c" + diff --git a/CHOLMOD/Utility/cholmod_l_transpose_unsym.c b/CHOLMOD/Utility/cholmod_l_transpose_unsym.c new file mode 100644 index 000000000..264ecabb6 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_transpose_unsym.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_transpose_unsym: unsymmetric permuted transpose +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_transpose_unsym.c" + diff --git a/CHOLMOD/Utility/cholmod_l_triplet_to_sparse.c b/CHOLMOD/Utility/cholmod_l_triplet_to_sparse.c new file mode 100644 index 000000000..31e7126e6 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_triplet_to_sparse.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_triplet_to_sparse: convert triplet to sparse +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_triplet_to_sparse.c" + diff --git a/CHOLMOD/Utility/cholmod_l_version.c b/CHOLMOD/Utility/cholmod_l_version.c new file mode 100644 index 000000000..5c31ea984 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_version.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_version: CHOLMOD version +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_version.c" + diff --git a/CHOLMOD/Utility/cholmod_l_xtype.c b/CHOLMOD/Utility/cholmod_l_xtype.c new file mode 100644 index 000000000..1f8703271 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_xtype.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_xtype.c: change xtype and/or dtype +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_change_xdtype.c" + diff --git a/CHOLMOD/Utility/cholmod_l_zeros.c b/CHOLMOD/Utility/cholmod_l_zeros.c new file mode 100644 index 000000000..8868d5165 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_l_zeros.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_l_zeros: allocate an all-zero dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT64 +#include "t_cholmod_zeros.c" + diff --git a/CHOLMOD/Utility/cholmod_malloc.c b/CHOLMOD/Utility/cholmod_malloc.c new file mode 100644 index 000000000..8946b189d --- /dev/null +++ b/CHOLMOD/Utility/cholmod_malloc.c @@ -0,0 +1,15 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_malloc: malloc (int32 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_ALLOC_FUNCTION cholmod_malloc +#define SUITESPARSE_ALLOC_FUNCTION SuiteSparse_malloc +#define CHOLMOD_INT32 +#include "t_cholmod_malloc.c" + diff --git a/CHOLMOD/Utility/cholmod_maxrank.c b/CHOLMOD/Utility/cholmod_maxrank.c new file mode 100644 index 000000000..713cfcd40 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_maxrank.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_maxrank: find valid value of Common->maxrank +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_maxrank.c" + diff --git a/CHOLMOD/Utility/cholmod_memdebug.c b/CHOLMOD/Utility/cholmod_memdebug.c new file mode 100644 index 000000000..eda9d8634 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_memdebug.c @@ -0,0 +1,182 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_memdebug: memory debugging +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis +// All Rights Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +#ifndef NDEBUG + + #define CM_MEMTABLE_SIZE 10000 + static void *memtable_p [CM_MEMTABLE_SIZE] ; + static size_t memtable_s [CM_MEMTABLE_SIZE] ; + static int nmemtable = 0 ; + +//------------------------------------------------------------------------------ +// CM_memtable_dump: dump the memtable +//------------------------------------------------------------------------------ + +void CM_memtable_dump (void) +{ + printf ("\nmemtable dump: %d\n", nmemtable) ; + for (int k = 0 ; k < nmemtable ; k++) + { + printf (" %4d: %12p : %ld\n", k, memtable_p [k], memtable_s [k]) ; + } +} + +//------------------------------------------------------------------------------ +// CM_memtable_n: return # of items in the memtable +//------------------------------------------------------------------------------ + +int CM_memtable_n (void) +{ + return (nmemtable) ; +} + +//------------------------------------------------------------------------------ +// CM_memtable_clear: clear the memtable +//------------------------------------------------------------------------------ + +void CM_memtable_clear (void) +{ + nmemtable = 0 ; +} + +//------------------------------------------------------------------------------ +// CM_memtable_add: add a pointer to the memtable of malloc'd blocks +//------------------------------------------------------------------------------ + +void CM_memtable_add (void *p, size_t size) +{ + if (p == NULL) return ; + + bool fail = false ; + #ifdef CM_MEMDUMP + printf ("memtable add %p size %ld\n", p, size) ; + #endif + + int n = nmemtable ; + fail = (n > CM_MEMTABLE_SIZE) ; + if (!fail) + { + for (int i = 0 ; i < n ; i++) + { + if (p == memtable_p [i]) + { + printf ("\nadd duplicate %p size %ld\n", p, size) ; + CM_memtable_dump ( ) ; + fail = true ; + break ; + } + } + } + if (!fail && p != NULL) + { + memtable_p [n] = p ; + memtable_s [n] = size ; + nmemtable++ ; + } + + ASSERT (!fail) ; + #ifdef CM_MEMDUMP + CM_memtable_dump ( ) ; + #endif +} + +//------------------------------------------------------------------------------ +// CM_memtable_size: get the size of a malloc'd block +//------------------------------------------------------------------------------ + +size_t CM_memtable_size (void *p) +{ + size_t size = 0 ; + + if (p == NULL) return (0) ; + bool found = false ; + + int n = nmemtable ; + for (int i = 0 ; i < n ; i++) + { + if (p == memtable_p [i]) + { + size = memtable_s [i] ; + found = true ; + break ; + } + } + + if (!found) + { + printf ("\nFAIL: %p not found\n", p) ; + CM_memtable_dump ( ) ; + ASSERT (0) ; + } + return (size) ; +} + +//------------------------------------------------------------------------------ +// CM_memtable_find: test if a malloc'd block is in the table +//------------------------------------------------------------------------------ + +bool CM_memtable_find (void *p) +{ + bool found = false ; + if (p == NULL) return (false) ; + int n = nmemtable ; + for (int i = 0 ; i < n ; i++) + { + if (p == memtable_p [i]) + { + found = true ; + break ; + } + } + return (found) ; +} + +//------------------------------------------------------------------------------ +// CM_memtable_remove: remove a pointer from the table of malloc'd blocks +//------------------------------------------------------------------------------ + +void CM_memtable_remove (void *p) +{ + if (p == NULL) return ; + + bool found = false ; + #ifdef CM_MEMDUMP + printf ("memtable remove %p ", p) ; + #endif + + int n = nmemtable ; + for (int i = 0 ; i < n ; i++) + { + if (p == memtable_p [i]) + { + // found p in the table; remove it + memtable_p [i] = memtable_p [n-1] ; + memtable_s [i] = memtable_s [n-1] ; + nmemtable -- ; + found = true ; + break ; + } + } + + if (!found) + { + printf ("remove %p NOT FOUND\n", p) ; + CM_memtable_dump ( ) ; + } + ASSERT (found) ; + #ifdef CM_MEMDUMP + CM_memtable_dump ( ) ; + #endif +} + +#endif + diff --git a/CHOLMOD/Utility/cholmod_mult_size_t.c b/CHOLMOD/Utility/cholmod_mult_size_t.c new file mode 100644 index 000000000..09a3a0163 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_mult_size_t.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_mult_size_t: multiply two size_t values +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_mult_size_t.c" + diff --git a/CHOLMOD/Utility/cholmod_mult_uint64_t.c b/CHOLMOD/Utility/cholmod_mult_uint64_t.c new file mode 100644 index 000000000..42a3a4653 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_mult_uint64_t.c @@ -0,0 +1,90 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_mult_uint64_t: multiply two uint64_t values +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. This file is licensed the same as GraphBLAS (Apache-2.0). +// SPDX-License-Identifier: Apache-2.0 + +//------------------------------------------------------------------------------ + +// c = a*b but check for overflow + +// If c=a*b is large, c = UINT64_MAX is set, and the function returns false. +// "large" means that c=a*b might overflow; see details below. + +// Otherwise c = a*b < INT64_MAX is guaranteed to be returned, and the function +// returns true. + +// Derived from GraphBLAS/Source/GB_uint64_multiply. + +#include "cholmod_internal.h" + +bool cholmod_mult_uint64_t // c = a*b, return true if ok +( + uint64_t *restrict c, + const uint64_t a, + const uint64_t b +) +{ + + if (a <= 1 || b <= 1) + { + (*c) = a*b ; + return (true) ; + } + + uint64_t a1 = a >> 30 ; // a1 = a / 2^30 + uint64_t b1 = b >> 30 ; // b1 = b / 2^30 + if (a1 > 0 && b1 > 0) + { + // c = a*b will likely overflow, since both a and b are >= 2^30 and + // thus c >= 2^60. This is slightly pessimistic. + (*c) = UINT64_MAX ; + return (false) ; + } + + // a = a1 * 2^30 + a0 + uint64_t a0 = a & 0x3FFFFFFFL ; + + // b = b1 * 2^30 + b0 + uint64_t b0 = b & 0x3FFFFFFFL ; + + // a*b = (a1*b1) * 2^60 + (a1*b0 + a0*b1) * 2^30 + a0*b0 + + // since either a1 or b1 are zero, a1*b1 is zero + + // a0, b0 are < 2^30 + // a1, b1 are < 2^34 + + // a1*b0 < 2^64 + // a0*b1 < 2^64 + // a0*b0 < 2^60 + // thus + + // a*b = (a1*b0 + a0*b1) * 2^30 + a0*b0 + // < (2^64 + 2^64 ) * 2^30 + 2^60 + + // so it is safe to compute t0 and t1 without risk of overflow: + + uint64_t t0 = a1*b0 ; + uint64_t t1 = a0*b1 ; + + // a*b = (t0 + t1) * 2^30 + a0*b0 + + if (t0 >= 0x40000000L || t1 >= 0x40000000L) + { + // t >= 2^31, so t * 2^30 might overflow. This is also slightly + // pessimistic, but good enough for the usage of this function. + (*c) = UINT64_MAX ; + return (false) ; + } + + // t = t0 + t1 < 2^30 + 2^30 < 2^31, so + + // c = a*b = t * 2^30 + a0*b0 < 2^61 + 2^60 < 2^62, no overflow possible + uint64_t t = t0 + t1 ; + (*c) = (t << 30) + a0*b0 ; + return (true) ; +} + diff --git a/CHOLMOD/Utility/cholmod_nnz.c b/CHOLMOD/Utility/cholmod_nnz.c new file mode 100644 index 000000000..2464e541c --- /dev/null +++ b/CHOLMOD/Utility/cholmod_nnz.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_nnz: # of entries in a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_nnz.c" + diff --git a/CHOLMOD/Utility/cholmod_ones.c b/CHOLMOD/Utility/cholmod_ones.c new file mode 100644 index 000000000..c237afcdf --- /dev/null +++ b/CHOLMOD/Utility/cholmod_ones.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_ones: dense matrix of all ones +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_ones.c" + diff --git a/CHOLMOD/Utility/cholmod_pack_factor.c b/CHOLMOD/Utility/cholmod_pack_factor.c new file mode 100644 index 000000000..d1943828e --- /dev/null +++ b/CHOLMOD/Utility/cholmod_pack_factor.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_pack_factor: pack a simplicial factorization +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_pack_factor.c" + diff --git a/CHOLMOD/Utility/cholmod_ptranspose.c b/CHOLMOD/Utility/cholmod_ptranspose.c new file mode 100644 index 000000000..a06e1244d --- /dev/null +++ b/CHOLMOD/Utility/cholmod_ptranspose.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_ptranspose: permuted transpose +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_ptranspose.c" + diff --git a/CHOLMOD/Utility/cholmod_realloc.c b/CHOLMOD/Utility/cholmod_realloc.c new file mode 100644 index 000000000..3346b660d --- /dev/null +++ b/CHOLMOD/Utility/cholmod_realloc.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_realloc: realloc (int32 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_realloc.c" + diff --git a/CHOLMOD/Utility/cholmod_realloc_multiple.c b/CHOLMOD/Utility/cholmod_realloc_multiple.c new file mode 100644 index 000000000..0124dcac5 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_realloc_multiple.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_realloc_multiple: multiple realloc (int32 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_realloc_multiple.c" + diff --git a/CHOLMOD/Utility/cholmod_reallocate_column.c b/CHOLMOD/Utility/cholmod_reallocate_column.c new file mode 100644 index 000000000..09d880bb8 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_reallocate_column.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_reallocate_column: reallocate a column of a factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_reallocate_column.c" + diff --git a/CHOLMOD/Utility/cholmod_reallocate_factor.c b/CHOLMOD/Utility/cholmod_reallocate_factor.c new file mode 100644 index 000000000..4ca9c01bd --- /dev/null +++ b/CHOLMOD/Utility/cholmod_reallocate_factor.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_reallocate_factor: reallocate a factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_reallocate_factor.c" + diff --git a/CHOLMOD/Utility/cholmod_reallocate_sparse.c b/CHOLMOD/Utility/cholmod_reallocate_sparse.c new file mode 100644 index 000000000..943b24792 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_reallocate_sparse.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_reallocate_sparse: reallocate sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_reallocate_sparse.c" + diff --git a/CHOLMOD/Utility/cholmod_reallocate_triplet.c b/CHOLMOD/Utility/cholmod_reallocate_triplet.c new file mode 100644 index 000000000..90c27b4ee --- /dev/null +++ b/CHOLMOD/Utility/cholmod_reallocate_triplet.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_reallocate_triplet: reallocate triplet matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_reallocate_triplet.c" + diff --git a/CHOLMOD/Utility/cholmod_sbound.c b/CHOLMOD/Utility/cholmod_sbound.c new file mode 100644 index 000000000..e0764502a --- /dev/null +++ b/CHOLMOD/Utility/cholmod_sbound.c @@ -0,0 +1,18 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_sbound: bound diagonal of LDL (single, int32) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_BOUND_FUNCTION cholmod_sbound +#define COMMON_BOUND (Common->sbound) +#define COMMON_BOUNDS_HIT (Common->nsbounds_hit) +#define Real float + +#define CHOLMOD_INT32 +#include "t_cholmod_bound.c" + diff --git a/CHOLMOD/Utility/cholmod_score_comp.c b/CHOLMOD/Utility/cholmod_score_comp.c new file mode 100644 index 000000000..1863d8201 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_score_comp.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_score_comp: for sorting supernodes +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_score_comp.c" + diff --git a/CHOLMOD/Utility/cholmod_set_empty.c b/CHOLMOD/Utility/cholmod_set_empty.c new file mode 100644 index 000000000..68d476f01 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_set_empty.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_set_empty: set an int32 array to EMPTY +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_set_empty.c" + diff --git a/CHOLMOD/Utility/cholmod_sort.c b/CHOLMOD/Utility/cholmod_sort.c new file mode 100644 index 000000000..7259eab6f --- /dev/null +++ b/CHOLMOD/Utility/cholmod_sort.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_sort: sort a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_sort.c" + diff --git a/CHOLMOD/Utility/cholmod_sparse_to_dense.c b/CHOLMOD/Utility/cholmod_sparse_to_dense.c new file mode 100644 index 000000000..8d92f7f2a --- /dev/null +++ b/CHOLMOD/Utility/cholmod_sparse_to_dense.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_sparse_to_dense: convert a sparse matrix to dense +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_sparse_to_dense.c" + diff --git a/CHOLMOD/Core/cholmod_l_triplet.c b/CHOLMOD/Utility/cholmod_sparse_to_triplet.c similarity index 56% rename from CHOLMOD/Core/cholmod_l_triplet.c rename to CHOLMOD/Utility/cholmod_sparse_to_triplet.c index 3d46b1a6c..73b103ba4 100644 --- a/CHOLMOD/Core/cholmod_l_triplet.c +++ b/CHOLMOD/Utility/cholmod_sparse_to_triplet.c @@ -1,13 +1,13 @@ //------------------------------------------------------------------------------ -// CHOLMOD/Core/cholmod_l_triplet.c: int64_t version of cholmod_triplet +// CHOLMOD/Utility/cholmod_sparse_to_triplet: convert sparse to triplet //------------------------------------------------------------------------------ -// CHOLMOD/Core Module. Copyright (C) 2005-2022, University of Florida. -// All Rights Reserved. Author: Timothy A. Davis +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. // SPDX-License-Identifier: LGPL-2.1+ //------------------------------------------------------------------------------ -#define DLONG -#include "cholmod_triplet.c" +#define CHOLMOD_INT32 +#include "t_cholmod_sparse_to_triplet.c" diff --git a/CHOLMOD/Utility/cholmod_speye.c b/CHOLMOD/Utility/cholmod_speye.c new file mode 100644 index 000000000..877aa7be1 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_speye.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_speye: sparse identity matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_speye.c" + diff --git a/CHOLMOD/Utility/cholmod_spzeros.c b/CHOLMOD/Utility/cholmod_spzeros.c new file mode 100644 index 000000000..94ae9840e --- /dev/null +++ b/CHOLMOD/Utility/cholmod_spzeros.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_spzeros: all-zero sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_spzeros.c" + diff --git a/CHOLMOD/Utility/cholmod_start.c b/CHOLMOD/Utility/cholmod_start.c new file mode 100644 index 000000000..35ac72ec3 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_start.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_start: start CHOLMOD (int32 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_start.c" + diff --git a/CHOLMOD/Utility/cholmod_transpose.c b/CHOLMOD/Utility/cholmod_transpose.c new file mode 100644 index 000000000..6949bd5f5 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_transpose.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_transpose: transpose a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_transpose.c" + diff --git a/CHOLMOD/Utility/cholmod_transpose_sym.c b/CHOLMOD/Utility/cholmod_transpose_sym.c new file mode 100644 index 000000000..b82c177dd --- /dev/null +++ b/CHOLMOD/Utility/cholmod_transpose_sym.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_transpose_sym: symmetric permuted transpose +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_transpose_sym.c" + diff --git a/CHOLMOD/Utility/cholmod_transpose_unsym.c b/CHOLMOD/Utility/cholmod_transpose_unsym.c new file mode 100644 index 000000000..69c1af7bf --- /dev/null +++ b/CHOLMOD/Utility/cholmod_transpose_unsym.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_transpose_unsym: unsymmetric permuted transpose +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_transpose_unsym.c" + diff --git a/CHOLMOD/Utility/cholmod_triplet_to_sparse.c b/CHOLMOD/Utility/cholmod_triplet_to_sparse.c new file mode 100644 index 000000000..343ff3ed6 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_triplet_to_sparse.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_triplet_to_sparse: convert triplet to sparse +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_triplet_to_sparse.c" + diff --git a/CHOLMOD/Utility/cholmod_version.c b/CHOLMOD/Utility/cholmod_version.c new file mode 100644 index 000000000..bcedb35f1 --- /dev/null +++ b/CHOLMOD/Utility/cholmod_version.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_version: CHOLMOD version +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_version.c" + diff --git a/CHOLMOD/Utility/cholmod_xtype.c b/CHOLMOD/Utility/cholmod_xtype.c new file mode 100644 index 000000000..f6b38821b --- /dev/null +++ b/CHOLMOD/Utility/cholmod_xtype.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_xtype.c: change xtype and/or dtype +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_change_xdtype.c" + diff --git a/CHOLMOD/Utility/cholmod_zeros.c b/CHOLMOD/Utility/cholmod_zeros.c new file mode 100644 index 000000000..a15ab703c --- /dev/null +++ b/CHOLMOD/Utility/cholmod_zeros.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/cholmod_zeros: allocate an all-zero dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#define CHOLMOD_INT32 +#include "t_cholmod_zeros.c" + diff --git a/CHOLMOD/Core/lesser.txt b/CHOLMOD/Utility/lesser.txt similarity index 100% rename from CHOLMOD/Core/lesser.txt rename to CHOLMOD/Utility/lesser.txt diff --git a/CHOLMOD/Utility/t_cholmod_aat.c b/CHOLMOD/Utility/t_cholmod_aat.c new file mode 100644 index 000000000..4147879c8 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_aat.c @@ -0,0 +1,260 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_aat: compute A*A' or A(:,f)*A(:,f)' +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// C = A*A' or C = A(:,f)*A(:,f)', where for complex/zomplex matrices, A' can +// be computed as a matrix (complex conjugate) transpose, or an array (complex +// non-conjugate) transpose. On output the C->stype is zero. The input matrix +// A must have A->stype = 0. + +// workspace: +// Iwork of size max (nrow,ncol) +// Xwork of size n if real and mode > 0, or 2*n if complex and mode > 0 + +// The mode parameter: +// 2 numerical, with conjugate transpose +// 1 numerical, with non-conjugate transpose +// 0 pattern, keeping the diagonal +// -1 pattern, remove the diagonal +// -2 pattern, and add 50% + n extra space to C +// as elbow room for AMD and CAMD, when converting +// a symmetric matrix A to an unsymmetric matrix C + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_sparse) (&C, Common) ; \ + CHOLMOD(free_sparse) (&F, Common) ; \ + return (NULL) ; \ + } + +//------------------------------------------------------------------------------ +// t_cholmod_aat_worker template +//------------------------------------------------------------------------------ + +#define PATTERN +#include "t_cholmod_aat_worker.c" + +#define DOUBLE +#define REAL +#include "t_cholmod_aat_worker.c" +#define COMPLEX +#include "t_cholmod_aat_worker.c" +#define ZOMPLEX +#include "t_cholmod_aat_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_aat_worker.c" +#define COMPLEX +#include "t_cholmod_aat_worker.c" +#define ZOMPLEX +#include "t_cholmod_aat_worker.c" + +//------------------------------------------------------------------------------ +// cholmod_aat: C=A*A' or A(:,f)*A(:,f)' +//------------------------------------------------------------------------------ + +cholmod_sparse *CHOLMOD(aat) +( + cholmod_sparse *A, // input matrix + Int *fset, // a list of column indices in range 0:A->ncol-1 + size_t fsize, // # of entries in fset + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // 0: pattern (with diag), -1: pattern (remove diag), + // -2: pattern (remove diag; add ~50% extra space in C) + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + RETURN_IF_SPARSE_MATRIX_INVALID (A, NULL) ; + Common->status = CHOLMOD_OK ; + cholmod_sparse *C = NULL, *F = NULL ; + ASSERT (CHOLMOD(dump_sparse) (A, "aat:A", Common) >= 0) ; + + if (A->stype != 0) + { + ERROR (CHOLMOD_INVALID, "input matrix must be unsymmetric") ; + return (NULL) ; + } + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + bool ignore_diag = (mode < 0) ; + bool values = (mode > 0) && (A->xtype != CHOLMOD_PATTERN) ; + int axtype = (values) ? A->xtype : CHOLMOD_PATTERN ; + bool conj = (mode >= 2) ; + + Int nrow = A->nrow ; + Int ncol = A->ncol ; + Int n = A->nrow ; + + Int *Ap = (Int *) A->p ; + Int *Anz = (Int *) A->nz ; + Int *Ai = (Int *) A->i ; + bool packed = A->packed ; + + //-------------------------------------------------------------------------- + // get the sizes of the entries of C and A + //-------------------------------------------------------------------------- + + size_t ei = sizeof (Int) ; + size_t e = (A->dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + size_t ew = ((axtype == CHOLMOD_PATTERN) ? 0 : + ((axtype == CHOLMOD_COMPLEX) ? 2 : 1)) ; + size_t ex = e * ew ; + size_t ez = e * ((axtype == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + + //-------------------------------------------------------------------------- + // allocate workspace + //-------------------------------------------------------------------------- + + CHOLMOD(alloc_work) (0, MAX (ncol, nrow), ew, A->dtype, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // construct the transpose F = A' or F = A(:,f)', or complex conjugate + //-------------------------------------------------------------------------- + + // no row permutation (Perm is NULL) + // uses Common->Iwork if fset is not NULL + F = CHOLMOD(ptranspose) (A, mode, /* Perm: */ NULL, fset, fsize, Common) ; + RETURN_IF_ERROR ; + + Int *Fp = (Int *) F->p ; + Int *Fi = (Int *) F->i ; + + Int *W = Common->Iwork ; // size n, not yet initialized + CHOLMOD(set_empty) (W, n) ; // W [0..n-1] = EMPTY + + //-------------------------------------------------------------------------- + // cnz = nnz (C) + //-------------------------------------------------------------------------- + + int64_t cnz = 0 ; + for (Int j = 0 ; j < n ; j++) + { + + //---------------------------------------------------------------------- + // If W [i] != jmark then row i has not yet been seen in C(:,j) + //---------------------------------------------------------------------- + + Int jmark = -j-2 ; + + //---------------------------------------------------------------------- + // compute # of entries in C(:,j) = A*F(:,j) + //---------------------------------------------------------------------- + + for (Int pf = Fp [j] ; pf < Fp [j+1] ; pf++) + { + + //------------------------------------------------------------------ + // get the F(t,j) entry + //------------------------------------------------------------------ + + Int t = Fi [pf] ; + + //------------------------------------------------------------------ + // add any entries A(i,t) not already in C(:,j) pattern + //------------------------------------------------------------------ + + Int p = Ap [t] ; + Int pend = (packed) ? (Ap [t+1]) : (p + Anz [t]) ; + for ( ; p < pend ; p++) + { + // get A(i,t); it is seen for first time if W [i] != jmark + Int i = Ai [p] ; + if (ignore_diag && i == j) continue ; + if (W [i] != jmark) + { + W [i] = jmark ; + cnz++ ; + } + } + } + + //---------------------------------------------------------------------- + // check for integer overflow + //---------------------------------------------------------------------- + + if (cnz < 0 || cnz >= Int_max / sizeof (Int)) + { + Common->status = CHOLMOD_TOO_LARGE ; + break ; + } + } + + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // allocate C + //-------------------------------------------------------------------------- + + size_t cnzmax = cnz + ((mode == -2) ? (cnz/2 + n) : 0) ; + C = CHOLMOD(allocate_sparse) (n, n, cnzmax, + /* C is not sorted: */ FALSE, /* C is packed: */ TRUE, + /* C stype: */ 0, axtype + A->dtype, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // compute the pattern and values of C + //-------------------------------------------------------------------------- + + switch ((C->xtype + C->dtype) % 8) + { + + default: + p_cholmod_aat_worker (C, A, F, ignore_diag, Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_aat_worker (C, A, F, ignore_diag, Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_aat_worker (C, A, F, ignore_diag, Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_aat_worker (C, A, F, ignore_diag, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_aat_worker (C, A, F, ignore_diag, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_aat_worker (C, A, F, ignore_diag, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_aat_worker (C, A, F, ignore_diag, Common) ; + break ; + } + + //-------------------------------------------------------------------------- + // free workspace and return result + //-------------------------------------------------------------------------- + + DEBUG (size_t nnzdiag = CHOLMOD(dump_sparse) (C, "aat:C", Common)) ; + ASSERT (IMPLIES (ignore_diag, nnzdiag == 0)) ; + CHOLMOD(free_sparse) (&F, Common) ; + return (C) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_aat_worker.c b/CHOLMOD/Utility/t_cholmod_aat_worker.c new file mode 100644 index 000000000..07dda10d0 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_aat_worker.c @@ -0,0 +1,142 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_aat_worker: C = A*A' or A(:,f)*A*(:,f)' +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_aat_worker) +( + cholmod_sparse *C, // output matrix + cholmod_sparse *A, // input matrix, not modified + cholmod_sparse *F, // input matrix, not modified, F = A' or A(:,f)' + bool ignore_diag, // if true, ignore diagonal + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (A->stype == 0) ; + ASSERT (C->stype == 0) ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int n = A->nrow ; + Int *Ap = (Int *) A->p ; + Int *Anz = (Int *) A->nz ; + Int *Ai = (Int *) A->i ; + Real *Ax = (Real *) A->x ; + Real *Az = (Real *) A->z ; + bool packed = A->packed ; + + Int *Fp = (Int *) F->p ; + Int *Fi = (Int *) F->i ; + Real *Fx = (Real *) F->x ; + Real *Fz = (Real *) F->z ; + ASSERT (F->packed) ; + + Int *Cp = (Int *) C->p ; + Int *Ci = (Int *) C->i ; + Real *Cx = (Real *) C->x ; + Real *Cz = (Real *) C->z ; + ASSERT (C->packed) ; + + //-------------------------------------------------------------------------- + // get workspace + //-------------------------------------------------------------------------- + + // W is all negative, because jmark in t_cholmod_aat is always negative. + + Int *W = Common->Iwork ; // size n, all < 0 + #ifndef NDEBUG + for (Int i = 0 ; i < n ; i++) + { + ASSERT (W [i] < 0) ; + } + #endif + + //-------------------------------------------------------------------------- + // C = A*A' or A(:,f)*A(:,f)' + //-------------------------------------------------------------------------- + + Int pc = 0 ; + + for (Int j = 0 ; j < n ; j++) + { + + //---------------------------------------------------------------------- + // log the start of C(:,j) + //---------------------------------------------------------------------- + + Int pc_start = pc ; + Cp [j] = pc ; + + //---------------------------------------------------------------------- + // compute C(:,j) = A*F(:,j) + //---------------------------------------------------------------------- + + for (Int pf = Fp [j] ; pf < Fp [j+1] ; pf++) + { + + //------------------------------------------------------------------ + // get the F(t,j) entry + //------------------------------------------------------------------ + + Int t = Fi [pf] ; + Real fx [2] = {0,0} ; + Real fz [1] = {0} ; + ASSIGN (fx, fz, 0, Fx, Fz, pf) ; + + //------------------------------------------------------------------ + // C(:,j) += A(:,t)*F(t,j) + //------------------------------------------------------------------ + + Int p = Ap [t] ; + Int pend = (packed) ? (Ap [t+1]) : (p + Anz [t]) ; + for ( ; p < pend ; p++) + { + // get the A(i,t) entry + Int i = Ai [p] ; + if (ignore_diag && i == j) continue ; + Int pi = W [i] ; + if (pi < pc_start) + { + // C(i,j) is a new entry; log its position + Ci [pc] = i ; + W [i] = pc ; + // C(i,j) = A(i,t) * F(t,j) + MULT (Cx, Cz, pc, Ax, Az, p, fx, fz, 0) ; + pc++ ; + } + else + { + // C(i,j) exists in C(:,j) at position pi + // C(i,j) += A(i,t) * F(t,j) + MULTADD (Cx, Cz, pi, Ax, Az, p, fx, fz, 0) ; + } + } + } + } + + //-------------------------------------------------------------------------- + // log the end of the last column of C + //-------------------------------------------------------------------------- + + Cp [n] = pc ; +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_add.c b/CHOLMOD/Utility/t_cholmod_add.c new file mode 100644 index 000000000..e618998e7 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_add.c @@ -0,0 +1,261 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_add: C = alpha*A + beta*B +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// The C matrix is returned as packed and sorted. A and B must have the same +// xtype, unless one of them is pattern, in which case only the patterns of A +// and B are used, and C has xtype of pattern. A, B, and C must all have the +// same dtype. If A->stype and B->stype differ, then C is computed as +// unsymmetric (stype of 0). + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_sparse) (&C, Common) ; \ + CHOLMOD(free_sparse) (&A2, Common) ; \ + CHOLMOD(free_sparse) (&B2, Common) ; \ + return (NULL) ; \ + } + +//------------------------------------------------------------------------------ +// t_cholmod_add_worker template +//------------------------------------------------------------------------------ + +#define PATTERN +#include "t_cholmod_add_worker.c" + +#define DOUBLE +#define REAL +#include "t_cholmod_add_worker.c" +#define COMPLEX +#include "t_cholmod_add_worker.c" +#define ZOMPLEX +#include "t_cholmod_add_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_add_worker.c" +#define COMPLEX +#include "t_cholmod_add_worker.c" +#define ZOMPLEX +#include "t_cholmod_add_worker.c" + +//------------------------------------------------------------------------------ +// cholmod_add: C = alpha*A + beta*B +//------------------------------------------------------------------------------ + +cholmod_sparse *CHOLMOD(add) // return C = alpha*A + beta*B +( + cholmod_sparse *A, // input matrix + cholmod_sparse *B, // input matrix + double alpha [2], // scale factor for A (two entires used if complex) + double beta [2], // scale factor for B (two entries used if complex) + int values, // if TRUE compute the numerical values of C + int sorted, // ignored; C is now always returned as sorted + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs and determine the xtype and dtype of C + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + RETURN_IF_SPARSE_MATRIX_INVALID (A, NULL) ; + RETURN_IF_SPARSE_MATRIX_INVALID (B, NULL) ; + ASSERT (CHOLMOD(dump_sparse) (A, "add:A", Common) >= 0) ; + ASSERT (CHOLMOD(dump_sparse) (B, "add:B", Common) >= 0) ; + Common->status = CHOLMOD_OK ; + cholmod_sparse *A2 = NULL, *B2 = NULL, *C = NULL ; + + if (A->nrow != B->nrow || A->ncol != B->ncol) + { + ERROR (CHOLMOD_INVALID, "A and B dimensions do not match") ; + return (NULL) ; + } + + int axtype = A->xtype ; + int bxtype = B->xtype ; + if (!values || axtype == CHOLMOD_PATTERN || bxtype == CHOLMOD_PATTERN) + { + // treat A and B as if they are pattern-only matrices; C is pattern + values = FALSE ; + axtype = CHOLMOD_PATTERN ; + bxtype = CHOLMOD_PATTERN ; + } + + if (axtype != bxtype) + { + ERROR (CHOLMOD_INVALID, "A and B xtypes do not match") ; + return (NULL) ; + } + + if (values && A->dtype != B->dtype) + { + ERROR (CHOLMOD_INVALID, "A and B dtypes do not match") ; + return (NULL) ; + } + + int xtype = axtype ; + int dtype = A->dtype ; + + //-------------------------------------------------------------------------- + // get the sizes of the entries of C, A, and B + //-------------------------------------------------------------------------- + + size_t ei = sizeof (Int) ; + size_t e = (dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + size_t ex = e * ((xtype == CHOLMOD_PATTERN) ? 0 : + ((xtype == CHOLMOD_COMPLEX) ? 2 : 1)) ; + size_t ez = e * ((xtype == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + + //-------------------------------------------------------------------------- + // convert/sort A and/or B, if needed + //-------------------------------------------------------------------------- + + int mode = values ? 1 : 0 ; + + if (A->stype == B->stype) + { + + //---------------------------------------------------------------------- + // A and B have the same stype, but make sure they are both sorted + //---------------------------------------------------------------------- + + // A2 = sorted copy of A, if A is not sorted, with same stype as A + if (!A->sorted) + { + A2 = CHOLMOD(copy) (A, A->stype, mode, Common) ; + RETURN_IF_ERROR ; + CHOLMOD(sort) (A2, Common) ; + RETURN_IF_ERROR ; + A = A2 ; + } + + // B2 = sorted copy of B, if B is not sorted, with same stype as B + if (!B->sorted) + { + B2 = CHOLMOD(copy) (B, B->stype, mode, Common) ; + RETURN_IF_ERROR ; + CHOLMOD(sort) (B2, Common) ; + RETURN_IF_ERROR ; + B = B2 ; + } + + } + else + { + + //---------------------------------------------------------------------- + // the stype of A and B differ, so make both unsymmetric and sorted + //---------------------------------------------------------------------- + + if (!(A->stype == 0 && A->sorted)) + { + // A2 = sorted unsymmetric copy of A with stype of zero + A2 = CHOLMOD(copy) (A, 0, mode, Common) ; + RETURN_IF_ERROR ; + if (!A2->sorted) + { + CHOLMOD(sort) (A2, Common) ; + RETURN_IF_ERROR ; + } + A = A2 ; + } + + if (!(B->stype == 0 && B->sorted)) + { + // B2 = sorted unsymmetric copy of A with stype of zero + B2 = CHOLMOD(copy) (B, 0, mode, Common) ; + RETURN_IF_ERROR ; + if (!B2->sorted) + { + CHOLMOD(sort) (B2, Common) ; + RETURN_IF_ERROR ; + } + B = B2 ; + } + } + + // C, A, and B now all have the same stype, and are sorted + ASSERT (A->stype == B->stype) ; + ASSERT (A->sorted) ; + ASSERT (B->sorted) ; + + //-------------------------------------------------------------------------- + // allocate C + //-------------------------------------------------------------------------- + + size_t nzmax = CHOLMOD(nnz) (A, Common) + CHOLMOD(nnz) (B, Common) ; + C = CHOLMOD(allocate_sparse) (A->nrow, A->ncol, nzmax, + /* C is sorted: */ TRUE, /* C is packed: */ TRUE, + A->stype, xtype + dtype, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // C = alpha*A + beta*B + //-------------------------------------------------------------------------- + + switch ((xtype + dtype) % 8) + { + default: + p_cholmod_add_worker (C, A, B, alpha, beta, Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_add_worker (C, A, B, alpha, beta, Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_add_worker (C, A, B, alpha, beta, Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_add_worker (C, A, B, alpha, beta, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_add_worker (C, A, B, alpha, beta, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_add_worker (C, A, B, alpha, beta, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_add_worker (C, A, B, alpha, beta, Common) ; + break ; + } + + //-------------------------------------------------------------------------- + // free temporary copies of A and B, if created + //-------------------------------------------------------------------------- + + CHOLMOD(free_sparse) (&A2, Common) ; + CHOLMOD(free_sparse) (&B2, Common) ; + + //-------------------------------------------------------------------------- + // compact the space of C + //-------------------------------------------------------------------------- + + size_t cnz = CHOLMOD(nnz) (C, Common) ; + CHOLMOD(reallocate_sparse) (cnz, C, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (CHOLMOD(dump_sparse) (C, "add:C", Common) >= 0) ; + return (C) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_add_size_t.c b/CHOLMOD/Utility/t_cholmod_add_size_t.c new file mode 100644 index 000000000..a728b1500 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_add_size_t.c @@ -0,0 +1,38 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_add_size_t: add two size_t values +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +size_t CHOLMOD(add_size_t) (size_t a, size_t b, int *ok) +{ + + //-------------------------------------------------------------------------- + // add a and b + //-------------------------------------------------------------------------- + + size_t s = a + b ; + + //-------------------------------------------------------------------------- + // check for size_t overflow + //-------------------------------------------------------------------------- + + if (s < a || s < b) + { + (*ok) = FALSE ; + s = 0 ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (s) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_add_worker.c b/CHOLMOD/Utility/t_cholmod_add_worker.c new file mode 100644 index 000000000..f73557aa6 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_add_worker.c @@ -0,0 +1,158 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_add_worker: C = alpha*A + beta*B +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +//------------------------------------------------------------------------------ +// cholmod_add: C = alpha*A + beta*B +//------------------------------------------------------------------------------ + +static void TEMPLATE (cholmod_add_worker) +( + cholmod_sparse *C, + cholmod_sparse *A, + cholmod_sparse *B, + double alpha [2], + double beta [2], + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + ASSERT (A->sorted) ; + ASSERT (B->sorted) ; + ASSERT (C->sorted) ; + ASSERT (A->stype == B->stype) ; + ASSERT (A->stype == C->stype) ; + ASSERT (C->packed) ; + + bool upper = (A->stype > 0) ; + bool lower = (A->stype < 0) ; + + Int *Ap = (Int *) A->p ; + Int *Anz = (Int *) A->nz ; + Int *Ai = (Int *) A->i ; + bool apacked = A->packed ; + size_t ncol = A->ncol ; + + Int *Bp = (Int *) B->p ; + Int *Bnz = (Int *) B->nz ; + Int *Bi = (Int *) B->i ; + bool bpacked = B->packed ; + + Int *Cp = (Int *) C->p ; + Int *Ci = (Int *) C->i ; + + #ifndef PATTERN + Real *Ax = (Real *) A->x ; + Real *Bx = (Real *) B->x ; + Real *Cx = (Real *) C->x ; + Real alphax [2], betax [2] ; + alphax [0] = (Real) alpha [0] ; + betax [0] = (Real) beta [0] ; + #endif + + #ifdef COMPLEX + alphax [1] = (Real) alpha [1] ; + betax [1] = (Real) beta [1] ; + #endif + + #ifdef ZOMPLEX + Real *Az = (Real *) A->z ; + Real *Bz = (Real *) B->z ; + Real *Cz = (Real *) C->z ; + Real alphaz [1], betaz [1] ; + alphaz [0] = (Real) alpha [1] ; + betaz [0] = (Real) beta [1] ; + #endif + + //-------------------------------------------------------------------------- + // C = alpha*A + beta*B + //-------------------------------------------------------------------------- + + Int cnz = 0 ; + + for (Int j = 0 ; j < ncol ; j++) + { + + //---------------------------------------------------------------------- + // log the start of the jth column of C + //---------------------------------------------------------------------- + + Cp [j] = cnz ; + + //---------------------------------------------------------------------- + // get A(:,j) and B(:,j) + //---------------------------------------------------------------------- + + Int pa = Ap [j] ; + Int paend = (apacked) ? (Ap [j+1]) : (pa + Anz [j]) ; + + Int pb = Bp [j] ; + Int pbend = (bpacked) ? (Bp [j+1]) : (pb + Bnz [j]) ; + + //---------------------------------------------------------------------- + // C(:,j) = alpha*A(:,j) + beta*B(:,j) + //---------------------------------------------------------------------- + + while (pa < paend || pb < pbend) + { + // get A(i,j) + Int iA = (pa < paend) ? Ai [pa] : Int_max ; + + // get B(i,j) + Int iB = (pb < pbend) ? Bi [pb] : Int_max ; + + // skip if C(i,j) is in the ignored part of the matrix + Int i = MIN (iA, iB) ; + if ((upper && i > j) || (lower && i < j)) continue ; + + // compute C(i,j) + ASSERT (cnz < C->nzmax) ; + Ci [cnz] = i ; + if (iA < iB) + { + // B(:,j) is not present, so C(i,j) = alpha*A(i,j) + MULT (Cx, Cz, cnz, alphax, alphaz, 0, Ax, Az, pa) ; + pa++ ; + } + else if (iA > iB) + { + // A(:,j) is not present, so C(i,j) = beta*B(i,j) + MULT (Cx, Cz, cnz, betax, betaz, 0, Bx, Bz, pb) ; + pb++ ; + } + else + { + // C(i,j) = alpha*A(i,j) + beta*B(i,j) + MULT (Cx, Cz, cnz, alphax, alphaz, 0, Ax, Az, pa) ; + MULTADD (Cx, Cz, cnz, betax, betaz, 0, Bx, Bz, pb) ; + pa++ ; + pb++ ; + } + cnz++ ; + } + } + + //-------------------------------------------------------------------------- + // log the end of the last column of C + //-------------------------------------------------------------------------- + + Cp [ncol] = cnz ; +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_alloc_factor.c b/CHOLMOD/Utility/t_cholmod_alloc_factor.c new file mode 100644 index 000000000..58a68e52d --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_alloc_factor.c @@ -0,0 +1,97 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_alloc_factor: allocate a simplicial factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Allocates a simplicial symbolic factor, with only L->Perm and L->ColCount +// created and set to empty values (L->Perm is the identity permutation, and +// ColCount is all 1's). L is pattern. Unlike cholmod_allocate_factor, the +// factor can be either single or double precision. L->xtype is +// CHOLMOD_PATTERN. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_factor) (&L, Common) ; \ + return (NULL) ; \ + } + +cholmod_factor *CHOLMOD(alloc_factor) // return the new factor L +( + size_t n, // L is factorization of an n-by-n matrix + int dtype, // CHOLMOD_SINGLE or CHOLMOD_DOUBLE + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + Common->status = CHOLMOD_OK ; + + if ((int64_t) n >= Int_max) + { + ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; + return (NULL) ; + } + + //-------------------------------------------------------------------------- + // get the dtype + //-------------------------------------------------------------------------- + + dtype = dtype & 4 ; // double or single + + //-------------------------------------------------------------------------- + // allocate the header for L + //-------------------------------------------------------------------------- + + cholmod_factor *L = CHOLMOD(calloc) (1, sizeof (cholmod_factor), Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // fill the header + //-------------------------------------------------------------------------- + + L->n = n ; // # of rows and columns + L->itype = ITYPE ; // integer type + L->dtype = dtype ; // double or single + L->is_monotonic = TRUE ; // columns of L appear in order 0..n-1 + L->minor = n ; // L has not been factorized + + //-------------------------------------------------------------------------- + // allocate Perm and ColCount + //-------------------------------------------------------------------------- + + L->Perm = CHOLMOD(malloc) (n, sizeof (Int), Common) ; + L->ColCount = CHOLMOD(malloc) (n, sizeof (Int), Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // initialize Perm and and ColCount + //-------------------------------------------------------------------------- + + Int *Perm = (Int *) L->Perm ; + Int *ColCount = (Int *) L->ColCount ; + + for (Int j = 0 ; j < n ; j++) + { + Perm [j] = j ; + ColCount [j] = 1 ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (L) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_alloc_work.c b/CHOLMOD/Utility/t_cholmod_alloc_work.c new file mode 100644 index 000000000..d45e3549d --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_alloc_work.c @@ -0,0 +1,116 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_alloc_work: double/single int32/64 workspace +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Allocates and initializes CHOLMOD workspace in Common, or increases the size +// of the workspace if already allocated. If the required workspace is already +// allocated, no action is taken. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_work) (Common) ; \ + return (FALSE) ; \ + } + +#define RETURN_IF_ALLOC_NOT_ALLOWED \ + if (Common->no_workspace_reallocate) \ + { \ + Common->status = CHOLMOD_INVALID ; \ + return (FALSE) ; \ + } + +int CHOLMOD(alloc_work) +( + size_t nrow, // # of rows in the matrix A + size_t iworksize, // size of Iwork (# of integers, int32 or int64) + size_t xworksize, // size of Xwork (in # of entries, double or single) + int dtype, // CHOLMOD_DOUBLE or CHOLMOD_SINGLE + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // allocate Flag (of size nrow Ints) and Head (of size nrow+1 Ints) + //-------------------------------------------------------------------------- + + // ensure at least 1 entry allocated, and check for size_t overflow + nrow = MAX (1, nrow) ; + size_t nrow1 = nrow + 1 ; + if (nrow1 < nrow) Common->status = CHOLMOD_TOO_LARGE ; + RETURN_IF_ERROR ; + + if (nrow > Common->nrow) + { + RETURN_IF_ALLOC_NOT_ALLOWED ; + Common->Flag = CHOLMOD(free) (Common->nrow, sizeof (Int), + Common->Flag, Common) ; + Common->Head = CHOLMOD(free) (Common->nrow+1, sizeof (Int), + Common->Head, Common) ; + Common->nrow = nrow ; + Common->Flag = CHOLMOD(malloc) (nrow, sizeof (Int), Common) ; + Common->Head = CHOLMOD(malloc) (nrow1, sizeof (Int), Common) ; + RETURN_IF_ERROR ; + // clear the Flag and Head workspace + Common->mark = 0 ; + CHOLMOD(set_empty) (Common->Flag, nrow) ; + CHOLMOD(set_empty) (Common->Head, nrow+1) ; + } + + //-------------------------------------------------------------------------- + // allocate Iwork (of size iworksize Ints) + //-------------------------------------------------------------------------- + + iworksize = MAX (1, iworksize) ; + if (iworksize > Common->iworksize) + { + RETURN_IF_ALLOC_NOT_ALLOWED ; + CHOLMOD(free) (Common->iworksize, sizeof (Int), Common->Iwork, Common) ; + Common->iworksize = iworksize ; + Common->Iwork = CHOLMOD(malloc) (iworksize, sizeof (Int), Common) ; + RETURN_IF_ERROR ; + } + + //-------------------------------------------------------------------------- + // allocate Xwork (xworksize) and set it to 0 + //-------------------------------------------------------------------------- + + // make sure xworksize is >= 2 + xworksize = MAX (2, xworksize) ; + + size_t e = (dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + + if (xworksize > Common->xworkbytes / e) + { + RETURN_IF_ALLOC_NOT_ALLOWED ; + CHOLMOD(free) (Common->xworkbytes, sizeof (uint8_t), Common->Xwork, + Common) ; + Common->Xwork = CHOLMOD(malloc) (xworksize, e, Common) ; + RETURN_IF_ERROR ; + // clear the Xwork workspace + Common->xworkbytes = xworksize * e ; + memset (Common->Xwork, 0, Common->xworkbytes) ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_allocate_dense.c b/CHOLMOD/Utility/t_cholmod_allocate_dense.c new file mode 100644 index 000000000..b0da190f2 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_allocate_dense.c @@ -0,0 +1,97 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_allocate_dense: allocate dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Allocate a dense matrix. The space is not initialized. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_dense) (&X, Common) ; \ + return (NULL) ; \ + } + +cholmod_dense *CHOLMOD(allocate_dense) +( + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t d, // leading dimension + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX) + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // get the xtype and dtype + //-------------------------------------------------------------------------- + + int xtype = xdtype & 3 ; // real, complex, or zomplex (not pattern) + int dtype = xdtype & 4 ; // double or single + + if (xtype == CHOLMOD_PATTERN) + { + ERROR (CHOLMOD_INVALID, "xtype invalid") ; + return (NULL) ; + } + + d = MAX (d, nrow) ; // leading dimension d must be >= nrow + + int ok = TRUE ; + size_t nzmax = CHOLMOD(mult_size_t) (d, ncol, &ok) ; + if (!ok || nzmax >= Int_max) + { + ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; + return (NULL) ; + } + + //-------------------------------------------------------------------------- + // allocate the header + //-------------------------------------------------------------------------- + + cholmod_dense *X = CHOLMOD(calloc) (1, sizeof (cholmod_dense), Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // fill the header + //-------------------------------------------------------------------------- + + X->nrow = nrow ; // # rows + X->ncol = ncol ; // # columns + X->xtype = xtype ; // real, complex, or zomplex + X->dtype = dtype ; // double or single + X->d = d ; // leading dimension + + //-------------------------------------------------------------------------- + // reallocate the dense matrix to change X->nzmax from 0 to nzmax + //-------------------------------------------------------------------------- + + CHOLMOD(realloc_multiple) (nzmax, /* nint: */ 0, xtype + dtype, + /* I not used: */ NULL, /* J not used: */ NULL, &(X->x), &(X->z), + &(X->nzmax), Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + +// ASSERT (CHOLMOD(dump_dense) (X, "allocate_dense:X", Common) >= 0) ; + return (X) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_allocate_sparse.c b/CHOLMOD/Utility/t_cholmod_allocate_sparse.c new file mode 100644 index 000000000..ca38c9f72 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_allocate_sparse.c @@ -0,0 +1,105 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_allocate_sparse: allocate a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Allocate a sparse matrix. The contents A->i, A->x, and A->z (if zomplex) +// exist but are not initialized. A->p and A->nz (if unpacked) are set to +// zero, giving a valid sparse matrix with no entries. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_sparse) (&A, Common) ; \ + return (NULL) ; \ + } + +cholmod_sparse *CHOLMOD(allocate_sparse) +( + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t nzmax, // max # of entries the matrix can hold + int sorted, // true if columns are sorted + int packed, // true if A is be packed (A->nz NULL), false if unpacked + int stype, // the stype of the matrix (unsym, tril, or triu) + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + Common->status = CHOLMOD_OK ; + + if (stype != 0 && nrow != ncol) + { + ERROR (CHOLMOD_INVALID, "rectangular matrix with stype != 0 invalid") ; + return (NULL) ; + } + + //-------------------------------------------------------------------------- + // get the xtype and dtype + //-------------------------------------------------------------------------- + + int xtype = xdtype & 3 ; // pattern, real, complex, or zomplex + int dtype = xdtype & 4 ; // double or single + + //-------------------------------------------------------------------------- + // allocate the header for A + //-------------------------------------------------------------------------- + + cholmod_sparse *A = CHOLMOD(calloc) (1, sizeof (cholmod_sparse), Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // fill the header + //-------------------------------------------------------------------------- + + A->nrow = nrow ; // # rows + A->ncol = ncol ; // # columns + A->stype = stype ; // symmetry type + A->itype = ITYPE ; // integer type + A->xtype = xtype ; // pattern, real, complex, or zomplex + A->dtype = dtype ; // double or single + + A->packed = packed ; // packed or unpacked + A->sorted = sorted ; // columns sorted or unsorted + + //-------------------------------------------------------------------------- + // allocate and clear A->p and A->nz + //-------------------------------------------------------------------------- + + A->p = CHOLMOD(calloc) (ncol+1, sizeof (Int), Common) ; + if (!packed) + { + A->nz = CHOLMOD(calloc) (ncol, sizeof (Int), Common) ; + } + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // reallocate the sparse matrix to change A->nzmax from 0 to nzmax + //-------------------------------------------------------------------------- + + CHOLMOD(reallocate_sparse) (nzmax, A, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (CHOLMOD(dump_sparse) (A, "allocate_sparse:A", Common) >= 0) ; + return (A) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_allocate_triplet.c b/CHOLMOD/Utility/t_cholmod_allocate_triplet.c new file mode 100644 index 000000000..55572ff7c --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_allocate_triplet.c @@ -0,0 +1,88 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_allocate_triplet: allocate triplet matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Allocate an empty triplet matrix, with space to hold a given max # of +// entries. The contents of T->i, T->j, T->x, and T->z are not initialized. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_triplet) (&T, Common) ; \ + return (NULL) ; \ + } + +cholmod_triplet *CHOLMOD(allocate_triplet) // return triplet matrix T +( + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t nzmax, // max # of entries the matrix can hold + int stype, // the stype of the matrix (unsym, tril, or triu) + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + Common->status = CHOLMOD_OK ; + + if (stype != 0 && nrow != ncol) + { + ERROR (CHOLMOD_INVALID, "rectangular matrix with stype != 0 invalid") ; + return (NULL) ; + } + + //-------------------------------------------------------------------------- + // get the xtype and dtype + //-------------------------------------------------------------------------- + + int xtype = xdtype & 3 ; // pattern, real, complex, or zomplex + int dtype = xdtype & 4 ; // double or single + + //-------------------------------------------------------------------------- + // allocate the header for T + //-------------------------------------------------------------------------- + + cholmod_triplet *T = CHOLMOD(calloc) (1, sizeof (cholmod_triplet), Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // fill the header + //-------------------------------------------------------------------------- + + T->nrow = nrow ; // # rows + T->ncol = ncol ; // # columns + T->stype = stype ; // symmetry type + T->itype = ITYPE ; // integer type + T->xtype = xtype ; // pattern, real, complex, or zomplex + T->dtype = dtype ; // double or single + + //-------------------------------------------------------------------------- + // reallocate the triplet matrix to change T->nzmax from 0 to nzmax + //-------------------------------------------------------------------------- + + CHOLMOD(reallocate_triplet) (nzmax, T, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (CHOLMOD(dump_triplet) (T, "allocate_triplet:T", Common) >= 0) ; + return (T) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_band.c b/CHOLMOD/Utility/t_cholmod_band.c new file mode 100644 index 000000000..1fd981c26 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_band.c @@ -0,0 +1,226 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_band: extract the band of a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Construct a sparse matrix C that contains entries in bands k1:k2 of an input +// sparse matrix A. A can have any xtype, stype, or dtype. C is sorted if and +// only if A is sorted. + +// A can be constructed in place, but only if it is in packed form. +// The diagonal can be ignored, if the ignore_diag flag is true. +// C can optionally be constructed as a pattern matrix. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_sparse) (&C2, Common) ; \ + return (NULL) ; \ + } + +//------------------------------------------------------------------------------ +// t_cholmod_band_worker template +//------------------------------------------------------------------------------ + +#define PATTERN +#include "t_cholmod_band_worker.c" + +#define DOUBLE +#define REAL +#include "t_cholmod_band_worker.c" +#define COMPLEX +#include "t_cholmod_band_worker.c" +#define ZOMPLEX +#include "t_cholmod_band_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_band_worker.c" +#define COMPLEX +#include "t_cholmod_band_worker.c" +#define ZOMPLEX +#include "t_cholmod_band_worker.c" + +//------------------------------------------------------------------------------ +// band_helper +//------------------------------------------------------------------------------ + +static cholmod_sparse *band_helper +( + cholmod_sparse *A, + int64_t k1, // count entries in k1:k2 diagonals + int64_t k2, + bool values, // if true and A numerical, C is numerical + bool inplace, // if true, convert A in place (A cannot be packed) + bool ignore_diag, // if true, ignore diagonal + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + RETURN_IF_SPARSE_MATRIX_INVALID (A, NULL) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int nrow = A->nrow ; + Int ncol = A->ncol ; + + if (A->stype > 0 && k1 < 0) + { + // A is symmetric with the strictly lower triangular part ignored + k1 = 0 ; + } + else if (A->stype < 0 && k2 > 0) + { + // A is symmetric with the strictly upper triangular part ignored + k2 = 0 ; + } + + // ensure k1 and k2 are in range -nrow:ncol + k1 = RANGE (k1, -nrow, ncol) ; + k2 = RANGE (k2, -nrow, ncol) ; + + values = values && (A->xtype != CHOLMOD_PATTERN) ; + + //-------------------------------------------------------------------------- + // allocate new matrix C, or operate on A in place + //-------------------------------------------------------------------------- + + cholmod_sparse *C, *C2 = NULL ; + if (inplace) + { + // convert A in place + if (!values) + { + // change A to pattern + CHOLMOD(sparse_xtype) (CHOLMOD_PATTERN + A->dtype, A, Common) ; + } + C = A ; + } + else + { + // count # of entries in C and allocate it + int64_t cnz = CHOLMOD(band_nnz) (A, k1, k2, ignore_diag, Common) ; + int cxtype = values ? A->xtype : CHOLMOD_PATTERN ; + C2 = CHOLMOD(allocate_sparse) (nrow, ncol, cnz, A->sorted, + /* C is packed: */ TRUE, A->stype, cxtype + A->dtype, Common) ; + C = C2 ; + } + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // C = band (A) + //-------------------------------------------------------------------------- + + switch ((C->xtype + C->dtype) % 8) + { + default: + p_cholmod_band_worker (C, A, k1, k2, ignore_diag) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_band_worker (C, A, k1, k2, ignore_diag) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_band_worker (C, A, k1, k2, ignore_diag) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_band_worker (C, A, k1, k2, ignore_diag) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_band_worker (C, A, k1, k2, ignore_diag) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_band_worker (C, A, k1, k2, ignore_diag) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_band_worker (C, A, k1, k2, ignore_diag) ; + break ; + } + + //-------------------------------------------------------------------------- + // shrink A if computed in-place + //-------------------------------------------------------------------------- + + if (inplace) + { + int64_t anz = CHOLMOD(nnz) (A, Common) ; + CHOLMOD(reallocate_sparse) (anz, A, Common) ; + RETURN_IF_ERROR ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + DEBUG (int64_t nzdiag = CHOLMOD(dump_sparse) (C, "band:C", Common)) ; + ASSERT (nzdiag >= 0) ; + ASSERT (IMPLIES (ignore_diag, nzdiag == 0)) ; + return (C) ; +} + +//------------------------------------------------------------------------------ +// cholmod_band +//------------------------------------------------------------------------------ + +cholmod_sparse *CHOLMOD(band) // return a new matrix C +( + cholmod_sparse *A, // input matrix + int64_t k1, // count entries in k1:k2 diagonals + int64_t k2, + int mode, // >0: numerical, 0: pattern, <0: pattern (no diag) + cholmod_common *Common +) +{ + bool values = (mode > 0) ; + bool inplace = FALSE ; + bool ignore_diag = (mode < 0) ; + return (band_helper (A, k1, k2, values, inplace, ignore_diag, Common)) ; +} + +//------------------------------------------------------------------------------ +// cholmod_band_inplace +//------------------------------------------------------------------------------ + +int CHOLMOD(band_inplace) +( + int64_t k1, // count entries in k1:k2 diagonals + int64_t k2, + int mode, // >0: numerical, 0: pattern, <0: pattern (no diag) + cholmod_sparse *A, // input/output matrix + cholmod_common *Common +) +{ + bool values = (mode > 0) ; + bool inplace = TRUE ; + bool ignore_diag = (mode < 0) ; + if (A != NULL && !(A->packed)) + { + /* cannot operate on an unpacked matrix in place */ + ERROR (CHOLMOD_INVALID, "cannot operate on unpacked matrix in-place") ; + return (FALSE) ; + } + return (band_helper (A, k1, k2, values, inplace, ignore_diag, Common) + != NULL) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_band_nnz.c b/CHOLMOD/Utility/t_cholmod_band_nnz.c new file mode 100644 index 000000000..0f3d0d3e3 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_band_nnz.c @@ -0,0 +1,93 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_band_nnz: # of entries in a band of sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Counts the # of entries with diagonals k1 to k2 of a sparse matrix. +// For example, to count entries in the tridagonal part, use k1=-1 and k2=1. +// To include the diagonal (k = 0), use ignore_diag = false; to exclude it, use +// ignore_diag = true. + +#include "cholmod_internal.h" + +int64_t CHOLMOD(band_nnz) // return # of entries in a band (-1 if error) +( + cholmod_sparse *A, // matrix to examine + int64_t k1, // count entries in k1:k2 diagonals + int64_t k2, + bool ignore_diag, // if true, exclude any diagonal entries + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (EMPTY) ; + RETURN_IF_SPARSE_MATRIX_INVALID (A, EMPTY) ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int *Ap = (Int *) A->p ; + Int *Ai = (Int *) A->i ; + Int *Anz = (Int *) A->nz ; + bool packed = (bool) A->packed ; + Int nrow = A->nrow ; + Int ncol = A->ncol ; + + if (A->stype > 0 && k1 < 0) + { + // A is symmetric with the strictly lower triangular part ignored + k1 = 0 ; + } + else if (A->stype < 0 && k2 > 0) + { + // A is symmetric with the strictly upper triangular part ignored + k2 = 0 ; + } + + // ensure k1 and k2 are in range -nrow:ncol + k1 = RANGE (k1, -nrow, ncol) ; + k2 = RANGE (k2, -nrow, ncol) ; + + // check for quick return + if (k1 > k2) return (0) ; + + // columns outside of j1:j2 have no entries in diagonals k1:k2 + Int j1 = MAX (k1, 0) ; + Int j2 = MIN (k2+nrow, ncol) ; + + //-------------------------------------------------------------------------- + // count entries within the k1:k2 band + //-------------------------------------------------------------------------- + + int64_t bnz = 0 ; + for (Int j = j1 ; j < j2 ; j++) + { + Int p = Ap [j] ; + Int pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; + for ( ; p < pend ; p++) + { + // A(i,j) is in the kth diagonal, where k = j-i + Int k = j - Ai [p] ; + // check if k is in range k1:k2; if k is zero and diagonal is + // ignored, then skip this entry + bnz += ((k >= k1) && (k <= k2) && !(k == 0 && ignore_diag)) ; + } + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (bnz) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_band_worker.c b/CHOLMOD/Utility/t_cholmod_band_worker.c new file mode 100644 index 000000000..2729ed5f7 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_band_worker.c @@ -0,0 +1,103 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_band_worker: extract the band of a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_band_worker) +( + cholmod_sparse *C, + cholmod_sparse *A, + int64_t k1, // keep entries in k1:k2 diagonals + int64_t k2, + bool ignore_diag // if true, exclude any diagonal entries +) +{ + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int nrow = A->nrow ; + Int ncol = A->ncol ; + + Int *Ap = (Int *) A->p ; + Int *Anz = (Int *) A->nz ; + Int *Ai = (Int *) A->i ; + Real *Ax = (Real *) A->x ; + Real *Az = (Real *) A->x ; + bool packed = A->packed ; + + Int *Cp = (Int *) C->p ; + Int *Ci = (Int *) C->i ; + Real *Cx = (Real *) C->x ; + Real *Cz = (Real *) C->z ; + + // columns outside of j1:j2 have no entries in diagonals k1:k2 + Int j1 = MAX (k1, 0) ; + Int j2 = MIN (k2+nrow, ncol) ; + + //-------------------------------------------------------------------------- + // columns 0 to j1-1 are empty + //-------------------------------------------------------------------------- + + memset (Cp, 0, j1 * sizeof (Int)) ; + + //-------------------------------------------------------------------------- + // handle columns j1:j2-1 + //-------------------------------------------------------------------------- + + Int cnz = 0 ; + for (Int j = j1 ; j < j2 ; j++) + { + + //---------------------------------------------------------------------- + // get A(:,j) and log the start of C(:,j) + //---------------------------------------------------------------------- + + // NOTE: C and A can be aliased + Int p = Ap [j] ; + Int pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; + Cp [j] = cnz ; + + //---------------------------------------------------------------------- + // extract entries in the band of A(:,j) + //---------------------------------------------------------------------- + + for ( ; p < pend ; p++) + { + // A(i,j) is in the kth diagonal, where k = j-i + Int i = Ai [p] ; + Int k = j - i ; + // check if k is in range k1:k2; if k is zero and diagonal is + // ignored, then skip this entry + if ((k >= k1) && (k <= k2) && !(k == 0 && ignore_diag)) + { + // C(i,j) = A(i,j) + ASSIGN (Cx, Cz, cnz, Ax, Az, p) ; + Ci [cnz++] = i ; + } + } + } + + //-------------------------------------------------------------------------- + // columns j2 to ncol-1 are empty + //-------------------------------------------------------------------------- + + for (Int j = j2 ; j <= ncol ; j++) + { + Cp [j] = cnz ; + } +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_bound.c b/CHOLMOD/Utility/t_cholmod_bound.c new file mode 100644 index 000000000..7045068e4 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_bound.c @@ -0,0 +1,79 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_bound: bound diagonal of LDL +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +// Template for creating the following functions: +// cholmod_dbound double, int32, using Common->dbound and ndbounds_hit +// cholmod_l_dbound double, int64, using Common->dbound and ndbounds_hit +// cholmod_sbound single, int32, using Common->sbound and nsbounds_hit +// cholmod_l_sbound single, int64, using Common->sbound and nsbounds_hit + +// This method ensures that the absolute value of D(j,j) is greater than dbound +// (for double) or sbound (for single), for LDL' factorization and +// update/downdate. It is not used for supernodal factorization. + +Real CHOLMOD_BOUND_FUNCTION // returns modified diagonal entry D(j,j) +( + Real djj, // input diagonal entry D(j,j) + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (0) ; + if (isnan (djj)) return (djj) ; // no change if D(j,j) is NaN + + //-------------------------------------------------------------------------- + // check the bound + //-------------------------------------------------------------------------- + + bool hit ; + Real bound ; + if (djj >= 0) + { + // D(j,j) is positive: check if djj in range [0,Common->bound] + bound = COMMON_BOUND ; + hit = (djj < bound) ; + } + else + { + // D(j,j) is negative: check if djj in range [-Common->bound,0] + bound = -COMMON_BOUND ; + hit = (djj > bound) ; + } + + //-------------------------------------------------------------------------- + // record the hit + //-------------------------------------------------------------------------- + + if (hit) + { + // bound the diagonal entry + djj = bound ; + // record the # of times the bound was hit + COMMON_BOUNDS_HIT++ ; + // set an error flag, if not already set + if (Common->status == CHOLMOD_OK) + { + ERROR (CHOLMOD_DSMALL, "diagonal entry is below threshold") ; + } + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (djj) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_change_factor.c b/CHOLMOD/Utility/t_cholmod_change_factor.c new file mode 100644 index 000000000..2d88b417b --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_change_factor.c @@ -0,0 +1,1288 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_change_factor: change format of a factor object +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// The cholmod_factor object holds a sparse Cholesky factorization in one of +// many formats. It can be numeric or symbolic, L*L' or L*D*L', simplicial +// or supernodal, packed or unpacked, and its columns can appear in order +// (monotonic) or not (non-monotonic). Not all combinations are possible. + +// The L->xtype field describes the type of the entries: + +// CHOLMOD_PATTERN: L->x and L->z are NULL, no values are stored. +// CHOLMOD_REAL: L->x is float or double, and L->z is NULL. The numeric +// value of the (p)th entry is L->x [p]. +// CHOLMOD_COMPLEX: L->x is float or double, the matrix is complex, +// where the value of (p)th entry is L->x [2*p] (the real part), +// and L->x [2*p+1] (the imaginary part). L->z is NULL. +// CHOLMOD_ZOMPLEX: L->x and L->z are float or double. The matrix is +// "zomplex", which means the matrix is mathematically complex, but +// the real and imaginary parts are held in two separate arrays. +// The value of the (p)th entry is L->x [p] (the real part), and +// L->z [p] (the imaginary part). Supernodal factors are never +// zomplex. + +// This method can change the L->xtype of a factor object L, but only to +// convert it to CHOLMOD_PATTERN (thus freeing all numeric values), or by +// changing a factor of xtype CHOLMOD_PATTERN to any of the three other types +// (thus allocating empty space, or placing a placeholder value of an +// identitity matrix. + +// The L->dtype field, just like the CHOLMOD sparse matrix, triplet matrix, and +// dense matrix formats, defines the underlying floating point type: single +// (float) or double, as CHOLMOD_SINGLE or CHOLMOD_DOUBLE. Matrices of +// different dtypes cannot be mixed. To convert the xtype and dtype of an +// object, use the cholmod_*_xtype methods (named "_xtype" for backward +// compatibility with CHOLMOD v4 and earlier). That method will preserve the +// values of the factor L. + +// CHOLMOD has the following basic kinds of factor formats: +// +// (1) simplicial symbolic: this consists of just two arrays of size n. +// L->Perm contains the fill-reducing ordering, and L->ColCount is an +// array containing the # of entries in each column of L. All of the other +// factor objects contain this information as well. The simplicial +// symbolic format does not hold the pattern of the matrix L itself. +// +// (2) simplicial numeric: this can hold either an LL' or LDL' factorization. +// +// LDL': The numeric L matrix itself is unit-diagonal, and the diagonal +// entries of L are not stored. The jth column appears in positions +// L->p [j] to L->p [j] + L->nz [j], in the arrays L->i, L->x, and (if +// zomplex), L->z. Thus, L->nz [j] is the # of entries in the jth column, +// which includes the entry D(j,j) as the first entry held in that column. +// The columns of L need not appear in order 0, 1, ... n-1 in L->(i,x,z). +// Instead, a doubly-link list is used (with L->prev and L->next). +// The value D(j,j) can be negative (that is, the matrix being factorized +// can be symmetric indefinite but with all principal minor matrices being +// full rank). +// +// LL': this is the same format as LL', except the first entry in each +// column is L(j,j). The diagonal matrix D is not preset. +// +// (3) supernodal symbolic: this represents the nonzero pattern of the +// supernodes for a supernodal factorization, with L->nsuper supernodes. +// The kth supernode contains columns L->super [k] to L->super [k+1]-1. +// Its row indices are held in L->s [L->pi [k] ... L->pi [k+1]-1]. +// L->x is not allocated, and is NULL. +// +// (4) supernodal numeric: This is always an LL' factorization (not LDL'). +// L->x holds then numeric values of each supernode. The values of +// the kth supernode (for the real case) are held in +// L->x [L->px [k] ... L->px [k+1]-1]. The factor can be complex but +// not zomplex (L->z is never used for a supernodal numeric factor). +// +// Within each column, or which each supernode, the row indices in L->i +// (simplicial) or L->s (supernodal) are kept sorted, from low to high. +// +// This function, cholmod_change_factor and cholmod_l_change_factor, converts +// a factor object between these representations, with some limitations: +// +// (a) a simplicial numeric factor cannot be converted to supernodal. +// +// (b) only a symbolic factor (simplicial or supernodal) can be converted +// into a supernodal numeric factor. +// +// (c) L->dtype is not changed (single or double precision). +// +// (d) L->xtype can be changed but the numeric contents of L are discarded. +// +// Some of these conversions are only meant for internal use by CHOLMOD itself, +// and they allocate space whose contents are not defined: simplicial +// symbolic to supernodal symbolic, and converting any factor to supernodal +// numeric. CHOLMOD performs these conversions just before it does its +// numeric factorization. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR(result) \ +{ \ + if (Common->status < CHOLMOD_OK) \ + { \ + return result ; \ + } \ +} + +//------------------------------------------------------------------------------ +// grow_column: increase the space for a single column of L +//------------------------------------------------------------------------------ + +static Int grow_column (Int len, double grow1, double grow2, Int maxlen) +{ + double xlen = (double) len ; + xlen = grow1 * xlen + grow2 ; + xlen = MIN (xlen, maxlen) ; + len = (Int) xlen ; + len = MAX (1, len) ; + len = MIN (len, maxlen) ; + return (len) ; +} + +//------------------------------------------------------------------------------ +// grow_L: grow the space at the end of L +//------------------------------------------------------------------------------ + +static Int grow_L (Int lnz, double grow0, Int n) +{ + double xlnz = (double) lnz ; + xlnz *= grow0 ; + xlnz = MIN (xlnz, (double) SIZE_MAX) ; + double d = (double) n ; + d = (d*d + d) / 2 ; + xlnz = MIN (xlnz, d) ; + lnz = (Int) xlnz ; + return (lnz) ; +} + +//------------------------------------------------------------------------------ +// t_cholmod_change_factor_*_worker +//------------------------------------------------------------------------------ + +#define DOUBLE + + #define REAL + #include "t_cholmod_change_factor_1_worker.c" + #include "t_cholmod_change_factor_2_worker.c" + #include "t_cholmod_change_factor_3_worker.c" + #undef REAL + + #define COMPLEX + #include "t_cholmod_change_factor_1_worker.c" + #include "t_cholmod_change_factor_2_worker.c" + #include "t_cholmod_change_factor_3_worker.c" + #undef COMPLEX + + #define ZOMPLEX + #include "t_cholmod_change_factor_1_worker.c" + #include "t_cholmod_change_factor_2_worker.c" + #undef ZOMPLEX + +#undef DOUBLE +#define SINGLE + + #define REAL + #include "t_cholmod_change_factor_1_worker.c" + #include "t_cholmod_change_factor_2_worker.c" + #include "t_cholmod_change_factor_3_worker.c" + #undef REAL + + #define COMPLEX + #include "t_cholmod_change_factor_1_worker.c" + #include "t_cholmod_change_factor_2_worker.c" + #include "t_cholmod_change_factor_3_worker.c" + #undef COMPLEX + + #define ZOMPLEX + #include "t_cholmod_change_factor_1_worker.c" + #include "t_cholmod_change_factor_2_worker.c" + #undef ZOMPLEX + +//------------------------------------------------------------------------------ +// natural list: create a doubly-link list of columns, in ordering 0 to n-1 +//------------------------------------------------------------------------------ + +// The head of the link list is always n+1, and the tail is always n, where +// n = L->n. The actual columns of L are in range 0 to L->n. + +static void natural_list (cholmod_factor *L) +{ + // get inputs + Int *Lnext = (Int *) L->next ; + Int *Lprev = (Int *) L->prev ; + ASSERT (Lprev != NULL && Lnext != NULL) ; + Int n = L->n ; + + // create the head node + Int head = n+1 ; + Lnext [head] = 0 ; + Lprev [head] = EMPTY ; + + // create the tail node + Int tail = n ; + Lnext [tail] = EMPTY ; + Lprev [tail] = n-1 ; + + // link columns 0 to n-1 in increasing order: 0, 1, 2, ... n-1 + for (Int j = 0 ; j < n ; j++) + { + Lnext [j] = j+1 ; + Lprev [j] = j-1 ; + } + + // the prev node of the first coumn 0 is n+1 + Lprev [0] = head ; + + // the columns appear in order 0, 1, 2, ... n-1 in the link list + L->is_monotonic = TRUE ; +} + + +//------------------------------------------------------------------------------ +// L_is_packed: return true if no column of L has any extra space after it +//------------------------------------------------------------------------------ + +// This method is used for debugging only. + +#ifndef NDEBUG +static int L_is_packed (cholmod_factor *L, cholmod_common *Common) +{ + Int *Lnz = (Int *) L->nz ; + Int *Lp = (Int *) L->p ; + Int n = L->n ; + + if (Lnz == NULL || Lp == NULL || L->xtype == CHOLMOD_PATTERN || L->is_super) + { + // nothing to check: L is intrinsically packed + return (TRUE) ; + } + + if (!L->is_monotonic) + { + // L is not packed, by definition + return (FALSE) ; + } + + for (Int j = 0 ; j < n ; j++) + { + PRINT3 (("j: "ID" Lnz "ID" Lp[j+1] "ID" Lp[j] "ID"\n", j, Lnz [j], + Lp [j+1], Lp [j])) ; + Int total_space_for_column_j = Lp [j+1] - Lp [j] ; + Int entries_in_column_j = Lnz [j] ; + if (entries_in_column_j != total_space_for_column_j) + { + // L(:,j) has extra slack space at the end of the column + PRINT2 (("L is not packed\n")) ; + return (FALSE) ; + } + } + + // L is packed + return (TRUE) ; +} +#endif + +//------------------------------------------------------------------------------ +// alloc_simplicial_num: allocate size-n arrays for simplicial numeric +//------------------------------------------------------------------------------ + +// Does not allocate L->i, L->x, or L->z, which are larger. +// See also cholmod_alloc_factor, which allocates L->Perm and L->ColCount. + +static int alloc_simplicial_num +( + cholmod_factor *L, + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (L->xtype == CHOLMOD_PATTERN || L->is_super) ; + ASSERT (L->p == NULL) ; + ASSERT (L->nz == NULL) ; + ASSERT (L->prev == NULL) ; + ASSERT (L->next == NULL) ; + + size_t n = L->n ; + + //-------------------------------------------------------------------------- + // allocate the four arrays + //-------------------------------------------------------------------------- + + Int *Lp = CHOLMOD(malloc) (n+1, sizeof (Int), Common) ; + Int *Lnz = CHOLMOD(malloc) (n, sizeof (Int), Common) ; + Int *Lprev = CHOLMOD(malloc) (n+2, sizeof (Int), Common) ; + Int *Lnext = CHOLMOD(malloc) (n+2, sizeof (Int), Common) ; + + //-------------------------------------------------------------------------- + // check if out of memory + //-------------------------------------------------------------------------- + + if (Common->status < CHOLMOD_OK) + { + // out of memory + CHOLMOD(free) (n+1, sizeof (Int), Lp, Common) ; + CHOLMOD(free) (n, sizeof (Int), Lnz, Common) ; + CHOLMOD(free) (n+2, sizeof (Int), Lprev, Common) ; + CHOLMOD(free) (n+2, sizeof (Int), Lnext, Common) ; + return (FALSE) ; + } + + //-------------------------------------------------------------------------- + // place the arrays in L + //-------------------------------------------------------------------------- + + L->p = Lp ; + L->nz = Lnz ; + L->prev = Lprev ; + L->next = Lnext ; + + //-------------------------------------------------------------------------- + // initialize the link list of the columns of L + //-------------------------------------------------------------------------- + + natural_list (L) ; + return (TRUE) ; +} + +//------------------------------------------------------------------------------ +// simplicial_sym_to_super_sym: converts simplicial symbolic to super +//------------------------------------------------------------------------------ + +// converts a simplicial symbolic factor to supernodal symbolic. The space +// is allocated but not initialized. + +static int simplicial_sym_to_super_sym +( + cholmod_factor *L, + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) ; + + //-------------------------------------------------------------------------- + // allocate L->super, L->pi, L->px, and L->s + //-------------------------------------------------------------------------- + + Int *Lsuper = CHOLMOD(malloc) (L->nsuper+1, sizeof (Int), Common) ; + Int *Lpi = CHOLMOD(malloc) (L->nsuper+1, sizeof (Int), Common) ; + Int *Lpx = CHOLMOD(malloc) (L->nsuper+1, sizeof (Int), Common) ; + Int *Ls = CHOLMOD(malloc) (L->ssize, sizeof (Int), Common) ; + + //-------------------------------------------------------------------------- + // check if out of memory + //-------------------------------------------------------------------------- + + if (Common->status < CHOLMOD_OK) + { + // out of memory + CHOLMOD(free) (L->nsuper+1, sizeof (Int), Lsuper, Common) ; + CHOLMOD(free) (L->nsuper+1, sizeof (Int), Lpi, Common) ; + CHOLMOD(free) (L->nsuper+1, sizeof (Int), Lpx, Common) ; + CHOLMOD(free) (L->ssize, sizeof (Int), Ls, Common) ; + return (FALSE) ; + } + + //-------------------------------------------------------------------------- + // place the arrays in L + //-------------------------------------------------------------------------- + + L->super = Lsuper ; + L->pi = Lpi ; + L->px = Lpx ; + L->s = Ls ; + + //-------------------------------------------------------------------------- + // revise the header of L (L->dtype is not changed) + //-------------------------------------------------------------------------- + + L->xtype = CHOLMOD_PATTERN ; // L is symbolic (no L->x, L->i, L->z) + L->is_super = TRUE ; // L is now supernodal + Ls [0] = EMPTY ; // contents of supernodal pattern undefined + L->is_ll = TRUE ; // L is a supernodal LL' factorization + L->maxcsize = 0 ; // size of largest update matrix + L->maxesize = 0 ; // max rows in any supernode excl tri. part) + L->minor = L->n ; // see cholmod.h for a description + return (TRUE) ; +} + +//------------------------------------------------------------------------------ +// super_num_to_super_sym: convert numeric supernodal to symbolic +//------------------------------------------------------------------------------ + +// This method converts a supernodal numeric factor L to supernodal symbolic, +// by freeing the numeric values of all the supernodes. The supernodal +// pattern (L->s) is kept. + +static void super_num_to_super_sym +( + cholmod_factor *L, + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (L->xtype != CHOLMOD_PATTERN) ; + ASSERT (L->xtype != CHOLMOD_ZOMPLEX) ; + ASSERT (L->is_super) ; + ASSERT (L->is_ll) ; + DEBUG (CHOLMOD(dump_factor) (L, "supernum to supersym:L input", Common)) ; + + //-------------------------------------------------------------------------- + // free L->x only + //-------------------------------------------------------------------------- + + size_t e = (L->dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + size_t ex = e * ((L->xtype == CHOLMOD_PATTERN) ? 0 : + ((L->xtype == CHOLMOD_COMPLEX) ? 2 : 1)) ; + + L->x = CHOLMOD(free) (L->xsize, ex, L->x, Common) ; + + //-------------------------------------------------------------------------- + // change the header contents to reflect the supernodal symbolic status + //-------------------------------------------------------------------------- + + L->xtype = CHOLMOD_PATTERN ; // L is symbolic + L->minor = L->n ; // see cholmod.h + L->is_ll = TRUE ; // supernodal factor is always LL', not LDL' + DEBUG (CHOLMOD(dump_factor) (L, "supernum to supersym:L output", Common)) ; +} + +//------------------------------------------------------------------------------ +// simplicial_sym_to_simplicial_num: convert simplicial numeric to symbolic +//------------------------------------------------------------------------------ + +// This methods allocates space and converts a simplicial symbolic L to +// simplicial numeric. L is set to the identity matrix, except in one case +// where the contents of L are not initialized (packed < 0 case). + +static void simplicial_sym_to_simplicial_num +( + cholmod_factor *L, // factor to modify + int to_ll, // if true, convert to LL. if false: to LDL' + int packed, // if > 0: L is packed, if 0: L is unpacked, + // if < 0: L is packed but contents are not initialized + int to_xtype, // the L->xtype (real, complex, or zomplex) + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) ; + + //-------------------------------------------------------------------------- + // allocate space for the simplicial numeric factor (except L->(i,x,z)) + //-------------------------------------------------------------------------- + + if (!alloc_simplicial_num (L, Common)) + { + // out of memory; error status is already in Common->status + return ; + } + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int n = L->n ; + Int *Lp = L->p ; + Int *Lnz = L->nz ; + Int *ColCount = L->ColCount ; + + //-------------------------------------------------------------------------- + // initialize L->p and L->nz + //-------------------------------------------------------------------------- + + bool ok = true ; + Int lnz = 0 ; + + if (packed < 0) + { + + //---------------------------------------------------------------------- + // do not initialize the space + //---------------------------------------------------------------------- + + lnz = L->nzmax ; + L->nzmax = 0 ; + + } + else if (packed > 0) + { + + //---------------------------------------------------------------------- + // initialize the packed LL' or LDL' case (L is identity) + //---------------------------------------------------------------------- + + for (Int j = 0 ; j < n ; j++) + { + // ensure ColCount [j] is in the range 1 to n-j + Int len = ColCount [j] ; + len = MAX (1, len) ; + len = MIN (len, n-j) ; + lnz += len ; + ok = (lnz >= 0) ; + if (!ok) break ; + } + // each column L(:,j) holds a single diagonal entry + for (Int j = 0 ; j <= n ; j++) + { + Lp [j] = j ; + } + for (Int j = 0 ; j < n ; j++) + { + Lnz [j] = 1 ; + } + + } + else + { + + //---------------------------------------------------------------------- + // initialize the unpacked LL' or LDL' case (L is identity) + //---------------------------------------------------------------------- + + // slack space will be added to L below + double grow0 = Common->grow0 ; + double grow1 = Common->grow1 ; + double grow2 = (double) Common->grow2 ; + grow0 = isnan (grow0) ? 1 : grow0 ; + grow1 = isnan (grow1) ? 1 : grow1 ; + Int grow = (grow0 >= 1.0) && (grow1 >= 1.0) && (grow2 > 0) ; + + for (Int j = 0 ; j < n ; j++) + { + + //------------------------------------------------------------------ + // log the start of L(:,j), containing a single entry + //------------------------------------------------------------------ + + Lp [j] = lnz ; + Lnz [j] = 1 ; + + //------------------------------------------------------------------ + // ensure ColCount [j] is in the range 1 to n-j + //------------------------------------------------------------------ + + Int len = ColCount [j] ; + len = MAX (1, len) ; + len = MIN (len, n-j) ; + + //------------------------------------------------------------------ + // add some slack space to L(:,j) + //------------------------------------------------------------------ + + if (grow) + { + len = grow_column (len, grow1, grow2, n-j) ; + } + lnz += len ; + ok = (lnz >= 0) ; + if (!ok) break ; + } + + //---------------------------------------------------------------------- + // add slack space at the end of L + //---------------------------------------------------------------------- + + if (ok) + { + Lp [n] = lnz ; + if (grow) + { + lnz = grow_L (lnz, grow0, n) ; + } + } + } + + //-------------------------------------------------------------------------- + // allocate L->i, L->x, and L->z with the new xtype and existing dtype + //-------------------------------------------------------------------------- + + ASSERT (L->nzmax == 0) ; + lnz = MAX (1, lnz) ; + int nint = 1 ; + if (!ok || !CHOLMOD(realloc_multiple) (lnz, nint, to_xtype + L->dtype, + &(L->i), NULL, &(L->x), &(L->z), &(L->nzmax), Common)) + { + // out of memory: convert L back to simplicial symbolic + CHOLMOD(to_simplicial_sym) (L, to_ll, Common) ; + return ; + } + + L->xtype = to_xtype ; + L->minor = n ; + + //-------------------------------------------------------------------------- + // set L to the identity matrix, if requested + //-------------------------------------------------------------------------- + + if (packed >= 0) + { + + switch ((L->xtype + L->dtype) % 8) + { + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_change_factor_1_worker (L) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_change_factor_1_worker (L) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_change_factor_1_worker (L) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_change_factor_1_worker (L) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_change_factor_1_worker (L) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_change_factor_1_worker (L) ; + break ; + } + } + + L->is_ll = to_ll ; +} + +//------------------------------------------------------------------------------ +// change_simplicial_num: change LL' to LDL' or LDL' to LL' +//------------------------------------------------------------------------------ + +// L must be simplicial numeric. +// +// to_ll: if true, L is converted to LL'; if false, to LDL' +// to_packed: if true, L is converted to packed and monotonic +// (to_monotonic is treated as true) +// +// to_monotonoic: if true but to_packed is false, L is converted to monotonic +// but the columns are not packed. Slack space is left in +// the columns of L. +// +// If both to_packed and to_monotonic are false: the columns of L are +// converted in place, and neither packed nor made monotonic. +// +// To convert LDL' to LL', columns with D(j,j) <= 0 are left as-is, but L is +// not numerically valid. The column L(:,j) is unchanged. If converted back +// to LDL', the column is also left as-is, so that the LDL' can be recovered. +// L->minor is set to the first j where D(j,j) <= 0. + +static void change_simplicial_num +( + cholmod_factor *L, // factor to modify + int to_ll, // if true: convert to LL'; else LDL' + int to_packed, // if true: pack the columns of L + int to_monotonic, // if true: make columns of L monotonic + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (Common != NULL) ; + DEBUG (CHOLMOD(dump_factor) (L, "change simplnum:L input", Common)) ; + ASSERT (L->xtype != CHOLMOD_PATTERN) ; + ASSERT (!L->is_super) ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + bool out_of_place = ((to_packed || to_monotonic) && !(L->is_monotonic)) ; + bool make_ll = (to_ll && !(L->is_ll)) ; + bool make_ldl = (!to_ll && L->is_ll) ; + + Int n = L->n ; + Int *Lp = (Int *) L->p ; + Int *Li = (Int *) L->i ; + Int *Lnz = (Int *) L->nz ; + + bool grow = false ; + double grow0 = Common->grow0 ; + double grow1 = Common->grow1 ; + double grow2 = (double) Common->grow2 ; + grow0 = isnan (grow0) ? 1 : grow0 ; + grow1 = isnan (grow1) ? 1 : grow1 ; + + void *Li2 = NULL ; + void *Lx2 = NULL ; + void *Lz2 = NULL ; + + size_t ei = sizeof (Int) ; + size_t e = (L->dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + size_t ex = e * ((L->xtype == CHOLMOD_COMPLEX) ? 2 : 1) ; + size_t ez = e * ((L->xtype == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + + //-------------------------------------------------------------------------- + // resize if changing to monotonic and/or packed and not already monotonic + //-------------------------------------------------------------------------- + + Int lnz = 0 ; + + if (out_of_place) + { + + //---------------------------------------------------------------------- + // out-of-place: construct L in new space (Li2, Lx2, and Lz2) + //---------------------------------------------------------------------- + + // The columns of L are out of order (not monotonic), but L is being + // changed to being either monotonic, or packed, or both. Thus, L + // needs to be resized, in newly allocated space (Li2, Lx2, and Lz2). + + //---------------------------------------------------------------------- + // determine if L should grow + //---------------------------------------------------------------------- + + if (!to_packed) + { + grow = (grow0 >= 1.0) && (grow1 >= 1.0) && (grow2 > 0) ; + } + + //---------------------------------------------------------------------- + // compute the new space for each column of L + //---------------------------------------------------------------------- + + for (Int j = 0 ; j < n ; j++) + { + Int len = Lnz [j] ; + ASSERT (len >= 1 && len <= n-j) ; + if (grow) + { + len = grow_column (len, grow1, grow2, n-j) ; + } + ASSERT (len >= Lnz [j] && len <= n-j) ; + lnz += len ; + if (lnz <= 0) + { + ERROR (CHOLMOD_TOO_LARGE, "problem too large") ; + return ; + } + } + + //---------------------------------------------------------------------- + // add additional space at the end of L, if requested + //---------------------------------------------------------------------- + + if (grow) + { + lnz = grow_L (lnz, grow0, n) ; + } + + //---------------------------------------------------------------------- + // allocate Li2, Lx2, and Lz2 (as newly allocated space) + //---------------------------------------------------------------------- + + lnz = MAX (1, lnz) ; + int nint = 1 ; + size_t nzmax0 = 0 ; + CHOLMOD(realloc_multiple) (lnz, nint, L->xtype + L->dtype, &Li2, + NULL, &Lx2, &Lz2, &nzmax0, Common) ; + RETURN_IF_ERROR () ; + } + + //-------------------------------------------------------------------------- + // convert the simplicial L + //-------------------------------------------------------------------------- + + switch ((L->xtype + L->dtype) % 8) + { + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_change_factor_2_worker (L, to_packed, Li2, Lx2, Lz2, + lnz, grow, grow1, grow2, make_ll, out_of_place, make_ldl, + Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_change_factor_2_worker (L, to_packed, Li2, Lx2, Lz2, + lnz, grow, grow1, grow2, make_ll, out_of_place, make_ldl, + Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_change_factor_2_worker (L, to_packed, Li2, Lx2, Lz2, + lnz, grow, grow1, grow2, make_ll, out_of_place, make_ldl, + Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_change_factor_2_worker (L, to_packed, Li2, Lx2, Lz2, + lnz, grow, grow1, grow2, make_ll, out_of_place, make_ldl, + Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_change_factor_2_worker (L, to_packed, Li2, Lx2, Lz2, + lnz, grow, grow1, grow2, make_ll, out_of_place, make_ldl, + Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_change_factor_2_worker (L, to_packed, Li2, Lx2, Lz2, + lnz, grow, grow1, grow2, make_ll, out_of_place, make_ldl, + Common) ; + break ; + } + + //-------------------------------------------------------------------------- + // finalize the result L + //-------------------------------------------------------------------------- + + L->is_ll = to_ll ; + + if (out_of_place) + { + + //---------------------------------------------------------------------- + // free the old space and move the new space into L + //---------------------------------------------------------------------- + + CHOLMOD(free) (L->nzmax, ei, L->i, Common) ; + CHOLMOD(free) (L->nzmax, ex, L->x, Common) ; + CHOLMOD(free) (L->nzmax, ez, L->z, Common) ; + + L->i = Li2 ; + L->x = Lx2 ; + L->z = Lz2 ; + L->nzmax = lnz ; + + //---------------------------------------------------------------------- + // revise the link list (columns 0 to n-1 now in natural order) + //---------------------------------------------------------------------- + + natural_list (L) ; + } + + DEBUG (CHOLMOD(dump_factor) (L, "change simplnum:L output", Common)) ; +} + +//------------------------------------------------------------------------------ +// super_num_to_simplicial_num: convert supernodal numeric to simplicial numeric +//------------------------------------------------------------------------------ + +static void super_num_to_simplicial_num +( + cholmod_factor *L, + int to_packed, + int to_ll, + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (L != NULL) ; + ASSERT (Common != NULL) ; + DEBUG (CHOLMOD(dump_factor) (L, "supernum to simplnum:L input", Common)) ; + ASSERT (L->xtype != CHOLMOD_PATTERN) ; + ASSERT (L->xtype != CHOLMOD_ZOMPLEX) ; + ASSERT (L->is_ll) ; + ASSERT (L->is_super) ; + ASSERT (L->x != NULL) ; + ASSERT (L->i == NULL) ; + ASSERT (L->z == NULL) ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int n = L->n ; + Int nsuper = L->nsuper ; + Int *Lpi = (Int *) L->pi ; + Int *Lpx = (Int *) L->px ; + Int *Ls = (Int *) L->s ; + Int *Super = (Int *) L->super ; + + size_t ei = sizeof (Int) ; + size_t e = (L->dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + size_t ex = e * ((L->xtype == CHOLMOD_COMPLEX) ? 2 : 1) ; + + //-------------------------------------------------------------------------- + // determine the size of L after conversion to simplicial numeric + //-------------------------------------------------------------------------- + + Int lnz = 0 ; + + if (to_packed) + { + + //---------------------------------------------------------------------- + // count the # of nonzeros in all supernodes of L + //---------------------------------------------------------------------- + + // Each supernode is lower trapezoidal, with a top part that is lower + // triangular (with diagonal present) and a bottom part that is + // rectangular. In this example below, nscol = 5, so the supernode + // represents 5 columns of L, and nsrow = 8, which means that the + // first column of the supernode has 8 entries, including the + // diagonal. + // + // x . . . . + // x x . . . + // x x x . . + // x x x x . + // x x x x x + // x x x x x + // x x x x x + // x x x x x + // + // The '.' entries above are in the data structure but not used, and + // are not copied into the simplicial factor L. The 'x' entries are + // used, but some might be exactly equal to zero. Some of these zeros + // come from relaxed supernodal algamation, and some come from exact + // numeric cancellation. These entries appear in the final + // simplicial factor L. + + for (Int s = 0 ; s < nsuper ; s++) + { + + //------------------------------------------------------------------ + // get the supernode + //------------------------------------------------------------------ + + Int k1 = Super [s] ; // L(:,k1) is 1st col in supernode s + Int k2 = Super [s+1] ; // L(:,k2) is 1st col in supernode s+1 + Int psi = Lpi [s] ; // start of pattern in Ls of supernode s + Int psend = Lpi [s+1] ; // start of pattern in Ls of s+1 + Int nsrow = psend - psi ; // # entries in 1st col of supernode s + Int nscol = k2 - k1 ; // # of columns in supernode + ASSERT (nsrow >= nscol) ; + Int erows = nsrow - nscol ; // # of rows below triangular part + + //------------------------------------------------------------------ + // count the entries in the supernode, including any exact zeros + //------------------------------------------------------------------ + + // lower triangular part + lnz += nscol * (nscol+1) / 2 ; + + // rectangular part + lnz += nscol * erows ; + } + + } + else + { + + //---------------------------------------------------------------------- + // the supernodal L will not be packed + //---------------------------------------------------------------------- + + // L->x holds all numeric values of the supernodes, and these entries + // will remain in place. L->x will not be decreased in size, so Li + // will have the same size as L->x. + + lnz = L->xsize ; + } + + ASSERT (lnz >= 0 && lnz <= (Int) (L->xsize)) ; + + //-------------------------------------------------------------------------- + // allocate Li for the pattern L->i of the simplicial factor of L + //-------------------------------------------------------------------------- + + Int *Li = CHOLMOD(malloc) (lnz, ei, Common) ; + RETURN_IF_ERROR () ; + + //-------------------------------------------------------------------------- + // allocate the size-n arrays for L: L->p, L->nz, L->prev, and L->nex + //-------------------------------------------------------------------------- + + if (!alloc_simplicial_num (L, Common)) + { + // out of memory + CHOLMOD(free) (lnz, ei, Li, Common) ; + return ; + } + + //-------------------------------------------------------------------------- + // convert the supernodal numeric L into a simplicial numeric L + //-------------------------------------------------------------------------- + + L->i = Li ; + L->nzmax = lnz ; + + switch ((L->xtype + L->dtype) % 8) + { + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_change_factor_3_worker (L, to_packed, to_ll, Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_change_factor_3_worker (L, to_packed, to_ll, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_change_factor_3_worker (L, to_packed, to_ll, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_change_factor_3_worker (L, to_packed, to_ll, Common) ; + break ; + } + + //-------------------------------------------------------------------------- + // reduce the size of L->x to match L->i (this cannot fail) + //-------------------------------------------------------------------------- + + L->x = CHOLMOD(realloc) (lnz, ex, L->x, &(L->xsize), Common) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // free the supernodal parts of L and return result + //-------------------------------------------------------------------------- + + L->is_super = FALSE ; // L is now simplicial + L->is_ll = to_ll ; // L is LL' or LDL', according to to_ll + L->pi = CHOLMOD(free) (nsuper+1, ei, L->pi, Common) ; + L->px = CHOLMOD(free) (nsuper+1, ei, L->px, Common) ; + L->super = CHOLMOD(free) (nsuper+1, ei, L->super, Common) ; + L->s = CHOLMOD(free) (L->ssize, ei, L->s, Common) ; + L->ssize = 0 ; // L->s is not present + L->xsize = 0 ; // L->x is not present + L->nsuper = 0 ; // no supernodes + L->maxesize = 0 ; // no rows in any supernodes + L->maxcsize = 0 ; // largest update matrix is size zero + + DEBUG (CHOLMOD(dump_factor) (L, "supernum to simplnum:L output", Common)) ; +} + +//------------------------------------------------------------------------------ +// super_sym_to_super_num: convert supernodal symbolic to numeric +//------------------------------------------------------------------------------ + +static int super_sym_to_super_num +( + int to_xtype, + cholmod_factor *L, + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (L != NULL) ; + ASSERT (Common != NULL) ; + ASSERT (L->xtype == CHOLMOD_PATTERN) ; + ASSERT (L->is_super) ; + ASSERT (L->x == NULL) ; + ASSERT (to_xtype == CHOLMOD_REAL || to_xtype == CHOLMOD_COMPLEX) ; + + //-------------------------------------------------------------------------- + // get the sizes of the entries + //-------------------------------------------------------------------------- + + size_t ei = sizeof (Int) ; + size_t e = (L->dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + size_t ex = e * ((to_xtype == CHOLMOD_COMPLEX) ? 2 : 1) ; + size_t xs = L->xsize ; + + //-------------------------------------------------------------------------- + // allocate the space + //-------------------------------------------------------------------------- + + double *Lx = CHOLMOD(malloc) (xs, ex, Common) ; + RETURN_IF_ERROR ((FALSE)) ; + + //-------------------------------------------------------------------------- + // finalize L and return result + //-------------------------------------------------------------------------- + + // clear the first few entries so valgrind is satisfied + memset (Lx, 0, MIN (2 * sizeof (double), xs*ex)) ; + L->x = Lx ; // new space for numeric values + L->xtype = to_xtype ; // real or complex + L->minor = L->n ; + return (TRUE) ; +} + +//============================================================================== +// cholmod_change_factor +//============================================================================== + +// Convert a factor L. Some conversions simply allocate uninitialized space +// that is meant to be filled later. + +int CHOLMOD(change_factor) +( + int to_xtype, // CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX + int to_ll, // if true: convert to LL'; else to LDL' + int to_super, // if true: convert to supernodal; else to simplicial + int to_packed, // if true: pack simplicial columns' else: do not pack + int to_monotonic, // if true, put simplicial columns in order + cholmod_factor *L, // factor to change + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_NULL (L, FALSE) ; + RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ; + Common->status = CHOLMOD_OK ; + + to_xtype = to_xtype & 3 ; + to_ll = to_ll ? 1 : 0 ; + if (to_super && (to_xtype == CHOLMOD_ZOMPLEX)) + { + ERROR (CHOLMOD_INVALID, "supernodal zomplex L not supported") ; + return (FALSE) ; + } + + PRINT1 (("-----convert from (%d,%d,%d,%d,%d) to (%d,%d,%d,%d,%d)\n", + L->xtype, L->is_ll, L->is_super, L_is_packed (L, Common), L->is_monotonic, + to_xtype, to_ll, to_super, to_packed, to_monotonic)) ; + + //-------------------------------------------------------------------------- + // convert the factor L + //-------------------------------------------------------------------------- + + if (to_xtype == CHOLMOD_PATTERN) + { + + //---------------------------------------------------------------------- + // convert to symbolic + //---------------------------------------------------------------------- + + if (!to_super) + { + + //------------------------------------------------------------------ + // convert to simplicial symbolic factor (this cannot fail) + //------------------------------------------------------------------ + + CHOLMOD(to_simplicial_sym) (L, to_ll, Common) ; + + } + else + { + + //------------------------------------------------------------------ + // convert to supernodal symbolic factor + //------------------------------------------------------------------ + + if (L->xtype != CHOLMOD_PATTERN && L->is_super) + { + // convert supernodal numeric to supernodal symbolic, + // keeping the pattern but freeing the numeric values. + super_num_to_super_sym (L, Common) ; + } + else if (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) + { + // convert simplicial symbolic to supernodal symbolic, + // only meant for use internally to CHOLMOD. + simplicial_sym_to_super_sym (L, Common) ; + } + else + { + // can't convert simplicial numeric to supernodal symbolic + ERROR (CHOLMOD_INVALID, "failed to change L") ; + return (FALSE) ; + } + } + + } + else + { + + //---------------------------------------------------------------------- + // convert to numeric + //---------------------------------------------------------------------- + + if (to_super) + { + + //------------------------------------------------------------------ + // convert to supernodal numeric factor + //------------------------------------------------------------------ + + if (L->xtype == CHOLMOD_PATTERN) + { + if (L->is_super) + { + // convert supernodal symbolic to supernodal numeric, + // only meant for use internally to CHOLMOD. + super_sym_to_super_num (to_xtype, L, Common) ; + } + else + { + // convert simplicial symbolic to supernodal numeric, + // only meant for use internally to CHOLMOD. + if (!simplicial_sym_to_super_sym (L, Common)) + { + // failure, convert back to simplicial symbolic + CHOLMOD(to_simplicial_sym) (L, to_ll, Common) ; + return (FALSE) ; + } + // convert supernodal symbolic to supernodal numeric + super_sym_to_super_num (to_xtype, L, Common) ; + } + } + else + { + // nothing to do if already supernodal numeric + if (!(L->is_super)) + { + ERROR (CHOLMOD_INVALID, "failed to change L") ; + return (FALSE) ; + } + } + + } + else + { + + //------------------------------------------------------------------ + // convert any factor to simplicial numeric + //------------------------------------------------------------------ + + if (L->xtype == CHOLMOD_PATTERN && !(L->is_super)) + { + // convert simplicial symbolic to simplicial numeric (L=D=I) + simplicial_sym_to_simplicial_num (L, to_ll, to_packed, + to_xtype, Common) ; + } + else if (L->xtype != CHOLMOD_PATTERN && L->is_super) + { + // convert a supernodal LL' to simplicial numeric + super_num_to_simplicial_num (L, to_packed, to_ll, Common) ; + } + else if (L->xtype == CHOLMOD_PATTERN && L->is_super) + { + // convert a supernodal symbolic to simplicial numeric (L=D=I) + CHOLMOD(to_simplicial_sym) (L, to_ll, Common) ; + simplicial_sym_to_simplicial_num (L, to_ll, to_packed, + to_xtype, Common) ; + } + else + { + // change a simplicial numeric factor: change LL' to LDL', LDL' + // to LL', or leave as-is. pack the columns of L, or leave + // as-is. Ensure the columns are monotonic, or leave as-is. + change_simplicial_num (L, to_ll, to_packed, to_monotonic, + Common) ; + } + } + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (Common->status >= CHOLMOD_OK) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_change_factor_1_worker.c b/CHOLMOD/Utility/t_cholmod_change_factor_1_worker.c new file mode 100644 index 000000000..eb64b05f2 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_change_factor_1_worker.c @@ -0,0 +1,57 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_change_factor_1_worker: change factor to identity +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +//------------------------------------------------------------------------------ +// t_cholmod_change_factor_1_worker: set L to the identity matrix +//------------------------------------------------------------------------------ + +// L is simplicial numeric. + +static void TEMPLATE (cholmod_change_factor_1_worker) +( + cholmod_factor *L +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (L->xtype != CHOLMOD_PATTERN) ; + ASSERT (!L->is_super) ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int *Lp = (Int *) L->p ; + Int *Li = (Int *) L->i ; + Real *Lx = (Real *) L->x ; + Real *Lz = (Real *) L->z ; + Int n = L->n ; + + //-------------------------------------------------------------------------- + // set L to the identity matrix + //-------------------------------------------------------------------------- + + Real onex [2] = {1,0} ; + Real onez [1] = {0} ; + + for (Int j = 0 ; j < n ; j++) + { + Int p = Lp [j] ; + ASSERT (p < Lp [j+1]) ; + Li [p] = j ; + ASSIGN (Lx, Lz, p, onex, onez, 0) ; + } +} + diff --git a/CHOLMOD/Utility/t_cholmod_change_factor_2_template.c b/CHOLMOD/Utility/t_cholmod_change_factor_2_template.c new file mode 100644 index 000000000..1e5988eb7 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_change_factor_2_template.c @@ -0,0 +1,273 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_change_factor_2_template +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Converts a simplicial numeric factor: to/from LL' and LDL', either +// out-of-place or in-place. + +#ifdef OUT_OF_PLACE + // the new L is created in new space: Li2, Lx2, Lz2 + #define Li_NEW Li2 + #define Lx_NEW Lx2 + #define Lz_NEW Lx2 +#else + // L is modified in its existing space: Li, Lx, and Lz + #define Li_NEW Li + #define Lx_NEW Lx + #define Lz_NEW Lz +#endif + +#ifdef IN_PLACE + // Li is not modified. Entries in Lx and Lz are changed but not moved + // to a different place in Lx and Lz + #define p_NEW p +#else + #define p_NEW pnew +#endif + +//------------------------------------------------------------------------------ + +{ + Int pnew = 0 ; + + if (make_ll) + { + + //---------------------------------------------------------------------- + // convert an LDL' factorization to LL' + //---------------------------------------------------------------------- + + for (Int j = 0 ; j < n ; j++) + { + + //------------------------------------------------------------------ + // get column L(:,j) + //------------------------------------------------------------------ + + Int p = Lp [j] ; + Int len = Lnz [j] ; + + // get the diagonal entry, djj = D(j,j) + Real djj [1] ; + ASSIGN_REAL (djj, 0, Lx, p) ; + + if (djj [0] <= 0) + { + + //-------------------------------------------------------------- + // the matrix is not positive definite + //-------------------------------------------------------------- + + // The matrix is not postive-definite and cannot be converted + // to LL'. The column L(:,j) is moved to its new space but not + // numerically modified so it can be converted back to a valid + // LDL' factorization. + + if (L->minor == (size_t) n) + { + ERROR (CHOLMOD_NOT_POSDEF, "L not positive definite") ; + L->minor = j ; + } + + #ifndef IN_PLACE + for (Int k = 0 ; k < len ; k++) + { + Li_NEW [p_NEW+k] = Li [p+k] ; + ASSIGN (Lx_NEW, Lz_NEW, p_NEW+k, Lx, Lz, p+k) ; + } + #endif + + } + else + { + + //-------------------------------------------------------------- + // convert L(:,j) from an LDL' factorization to LL' + //-------------------------------------------------------------- + + // L(j,j) = sqrt (D(j,j)) + Real ljj [1] ; + ljj [0] = sqrt (djj [0]) ; + #ifndef IN_PLACE + Li_NEW [p_NEW] = j ; + #endif + ASSIGN_REAL (Lx_NEW, p_NEW, ljj, 0) ; + CLEAR_IMAG (Lx_NEW, Lz_NEW, p_NEW) ; + + // L(j+1:n,j) = L(j+1:n,j) * L(j,j) + for (Int k = 1 ; k < len ; k++) + { + #ifndef IN_PLACE + Li_NEW [p_NEW+k] = Li [p+k] ; + #endif + MULT_REAL (Lx_NEW, Lz_NEW, p_NEW+k, Lx, Lz, p+k, ljj, 0) ; + } + } + + //------------------------------------------------------------------ + // grow column L(:,j) if requested, and advance to column j+1 + //------------------------------------------------------------------ + + #ifndef IN_PLACE + Lp [j] = p_NEW ; + #ifdef OUT_OF_PLACE + if (grow) len = grow_column (len, grow1, grow2, n-j) ; + #endif + p_NEW += len ; + #endif + } + + // log the end of the last column + #ifndef IN_PLACE + Lp [n] = p_NEW ; + #endif + + } + else if (make_ldl) + { + + //---------------------------------------------------------------------- + // convert an LL' factorization to LDL' + //---------------------------------------------------------------------- + + for (Int j = 0 ; j < n ; j++) + { + + //------------------------------------------------------------------ + // get column L(:,j) + //------------------------------------------------------------------ + + Int len = Lnz [j] ; + Int p = Lp [j] ; + + // get the diagonal entry, ljj = L(j,j) + Real ljj [1] ; + ASSIGN_REAL (ljj, 0, Lx, p) ; + + if (ljj [0] <= 0) + { + + //-------------------------------------------------------------- + // the matrix is not positive definite + //-------------------------------------------------------------- + + // do not modify L(:,j), just copy it to its new place + + #ifndef IN_PLACE + for (Int k = 0 ; k < len ; k++) + { + Li_NEW [p_NEW+k] = Li [p+k] ; + ASSIGN (Lx_NEW, Lz_NEW, p_NEW+k, Lx, Lz, p+k) ; + } + #endif + + } + else + { + + //-------------------------------------------------------------- + // convert L(:,j) from an LL' factorization to LDL' + //-------------------------------------------------------------- + + // D(j,j) = L(j,j)^2 + #ifndef IN_PLACE + Li_NEW [p_NEW] = j ; + #endif + Real djj [1] ; + djj [0] = ljj [0] * ljj [0] ; + ASSIGN_REAL (Lx_NEW, p_NEW, djj, 0) ; + CLEAR_IMAG (Lx_NEW, Lz_NEW, p_NEW) ; + + // L(j+1:n) = L(j+1:n) / L(j,j) + for (Int k = 1 ; k < len ; k++) + { + #ifndef IN_PLACE + Li_NEW [p_NEW+k] = Li [p+k] ; + #endif + DIV_REAL (Lx_NEW, Lz_NEW, p_NEW+k, Lx, Lz, p+k, ljj, 0) ; + } + } + + //------------------------------------------------------------------ + // grow column L(:,j) if requested, and advance to column j+1 + //------------------------------------------------------------------ + + #ifndef IN_PLACE + Lp [j] = p_NEW ; + #ifdef OUT_OF_PLACE + if (grow) len = grow_column (len, grow1, grow2, n-j) ; + #endif + p_NEW += len ; + #endif + } + + // log the end of the last column + #ifndef IN_PLACE + Lp [n] = p_NEW ; + #endif + + } + else + { + + //---------------------------------------------------------------------- + // factorization remains as is, but space may be revised + //---------------------------------------------------------------------- + + #ifndef IN_PLACE + for (Int j = 0 ; j < n ; j++) + { + + //------------------------------------------------------------------ + // get column L(:,j) + //------------------------------------------------------------------ + + Int len = Lnz [j] ; + Int p = Lp [j] ; + + //------------------------------------------------------------------ + // move L(:,j) to its new position + //------------------------------------------------------------------ + + #ifdef TO_PACKED + if (p_NEW < p) + #endif + { + for (Int k = 0 ; k < len ; k++) + { + Li_NEW [p_NEW+k] = Li [p+k] ; + ASSIGN (Lx_NEW, Lz_NEW, p_NEW+k, Lx, Lz, p+k) ; + } + Lp [j] = p_NEW ; + } + + //------------------------------------------------------------------ + // grow column L(:,j) if requested, and advance to column j+1 + //------------------------------------------------------------------ + + #ifdef OUT_OF_PLACE + if (grow) len = grow_column (len, grow1, grow2, n-j) ; + #endif + p_NEW += len ; + } + + // log the end of the last column + Lp [n] = p_NEW ; + #endif + } +} + +#undef OUT_OF_PLACE +#undef TO_PACKED +#undef IN_PLACE +#undef Li_NEW +#undef Lx_NEW +#undef Lz_NEW +#undef p_NEW + diff --git a/CHOLMOD/Utility/t_cholmod_change_factor_2_worker.c b/CHOLMOD/Utility/t_cholmod_change_factor_2_worker.c new file mode 100644 index 000000000..0844e2e08 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_change_factor_2_worker.c @@ -0,0 +1,118 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_change_factor_2_worker: change format of a factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +//------------------------------------------------------------------------------ +// t_cholmod_change_factor_2_worker: changes a simplicial numeric factor +//------------------------------------------------------------------------------ + +// The contents of the old L->(i,x,z) is copied/converted into Li2, Lx2, and +// Lz2. + +static void TEMPLATE (cholmod_change_factor_2_worker) +( + cholmod_factor *L, // factor to modify + int to_packed, // if true: convert L to packed + Int *Li2, // new space for L->i (if out_of_place is true) + Real *Lx2, // new space for L->x (if out_of_place is true) + Real *Lz2, // new space for L->z (if out_of_place is true) + Int lnz, // max # of entries that Li2, Lx2, Lz2 can hold + bool grow, // if true: add slack space to the new columns of L + double grow1, // growth factor for each column + double grow2, // growth factor for each column + bool make_ll, // if true: convert LDL' to LL' + bool out_of_place, // if true: convert L out-of-place using Li2, Lx2, Lz2 + bool make_ldl, // if true: convert LL' to LDL' + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (!L->is_super) ; + ASSERT (L->xtype != CHOLMOD_PATTERN) ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int n = L->n ; + Int *Lp = (Int *) L->p ; + Int *Li = (Int *) L->i ; + Real *Lx = (Real *) L->x ; + Real *Lz = (Real *) L->z ; + Int *Lnz = (Int *) L->nz ; + + //-------------------------------------------------------------------------- + // initialize L->minor; will be set below to the min j where D(j,j) <= 0 + //-------------------------------------------------------------------------- + + if (make_ll) + { + L->minor = n ; + } + + //-------------------------------------------------------------------------- + // convert the simplicial numeric L + //-------------------------------------------------------------------------- + + if (out_of_place) + { + + //---------------------------------------------------------------------- + // L must be converted out of place + //---------------------------------------------------------------------- + + // L is converted out-of-place, into the newly allocate space Li2, Lx2, + // and Lz2. This occurs if L is to be packed and/or made monotonic, + // but L is not already monotonic. + + ASSERT (Li2 != NULL) ; + ASSERT (Lx2 != NULL) ; + ASSERT (IMPLIES (L->xtype == CHOLMOD_ZOMPLEX, Lz2 != NULL)) ; + + #define OUT_OF_PLACE + #include "t_cholmod_change_factor_2_template.c" + + } + else if (to_packed) + { + + //---------------------------------------------------------------------- + // pack L, removing all slack space, in existing Li, Lx, and Lz space + //---------------------------------------------------------------------- + + ASSERT (Li2 == NULL) ; + ASSERT (Lx2 == NULL) ; + ASSERT (Lz2 == NULL) ; + + #define TO_PACKED + #include "t_cholmod_change_factor_2_template.c" + + } + else + { + + //---------------------------------------------------------------------- + // in-place conversion of L: no entries are moved + //---------------------------------------------------------------------- + + ASSERT (Li2 == NULL) ; + ASSERT (Lx2 == NULL) ; + ASSERT (Lz2 == NULL) ; + + #define IN_PLACE + #include "t_cholmod_change_factor_2_template.c" + } +} + diff --git a/CHOLMOD/Utility/t_cholmod_change_factor_3_template.c b/CHOLMOD/Utility/t_cholmod_change_factor_3_template.c new file mode 100644 index 000000000..e3bb492e9 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_change_factor_3_template.c @@ -0,0 +1,117 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_change_factor_3_template +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +{ + Int p = 0 ; // current position in simplicial L + + for (Int s = 0 ; s < nsuper ; s++) + { + + //------------------------------------------------------------------ + // get the Supernode (0:nsrow-1, 0:nscol-1) + //------------------------------------------------------------------ + + Int k1 = Super [s] ; // 1st column of supernode s + Int k2 = Super [s+1] ; // k2-1 is last column of supernode s + Int psi = Lpi [s] ; // Ls [psi:psend-1]: pattern of s + Int psend = Lpi [s+1] ; + Int psx = Lpx [s] ; // Lx [psx:..]: values of supernode s + Int nsrow = psend - psi ; // # of rows in 1st column of s + Int nscol = k2 - k1 ; // # of cols in the supernode + + //------------------------------------------------------------------ + // convert the Supernode to the simplicial L (k1,k2-1) + //------------------------------------------------------------------ + + for (Int jj = 0 ; jj < nscol ; jj++) + { + + //-------------------------------------------------------------- + // convert L(:,j) from Supernode (:,jj) + //-------------------------------------------------------------- + + Int j = jj + k1 ; // L(:,j) is Supernode column jj + Lnz [j] = nsrow - jj ; // # entries in L(:,j) + + //-------------------------------------------------------------- + // log the start of L(:,j) in the simplicial form of L + //-------------------------------------------------------------- + + Int ii = jj ; + Int q = psx + jj + jj*nsrow ; + Lp [j] = TO_PACKED ? p:q ; + + //-------------------------------------------------------------- + // handle the diagonal for LDL' + //-------------------------------------------------------------- + + Real ljj [1] ; + if (!TO_LL) + { + // create the row index for L(j,j) + Li [TO_PACKED ? p:q] = j ; + + // compute D(j,j) + ASSIGN_REAL (ljj, 0, Lx, q) ; + if (ljj [0] <= 0) + { + // not positive definite: values of L(:,j) not changed + ASSIGN_REAL (Lx, TO_PACKED ? p:q, ljj, 0) ; + CLEAR_IMAG (Lx, , TO_PACKED ? p:q) ; + ljj [0] = 1 ; + } + else + { + // D(j,j) = L (j,j)^2 + Real djj [1] ; + djj [0] = ljj [0] * ljj [0] ; + ASSIGN_REAL (Lx, TO_PACKED ? p:q, djj, 0) ; + CLEAR_IMAG (Lx, , TO_PACKED ? p:q) ; + } + + // advance to the first off-diagonal entry of L(:,j) + ii++ ; + p++ ; + } + + //-------------------------------------------------------------- + // convert the remainder of L(:,j) + //-------------------------------------------------------------- + + for ( ; ii < nsrow ; ii++, p++) + { + // create the row index for L(i,j) + q = psx + ii + jj*nsrow ; + Li [TO_PACKED ? p:q] = Ls [psi + ii] ; + // revise the numeric value of L(i,j) + if (TO_LL) + { + // for LL': L(i,j) is unchanged; move to new position + if (TO_PACKED) + { + ASSIGN (Lx, , p, Lx, , q) ; + } + } + else + { + // for LDL': L(i,j) = L(i,j) / L(j,j) + DIV_REAL (Lx, , TO_PACKED ? p:q, Lx, , q, ljj, 0) ; + } + } + } + } + + // log the end of the last column in L + Lp [n] = TO_PACKED ? p : Lpx [nsuper] ; +} + +#undef TO_PACKED +#undef TO_LL + diff --git a/CHOLMOD/Utility/t_cholmod_change_factor_3_worker.c b/CHOLMOD/Utility/t_cholmod_change_factor_3_worker.c new file mode 100644 index 000000000..3cd76f3e7 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_change_factor_3_worker.c @@ -0,0 +1,144 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_change_factor_3_worker: change format of a factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Converts a supernodal numeric L into a simplicial numeric L. The factor is +// modified in place in Lx. + +// If to_packed is false, entries in Lx stay in the same position they had in +// the supernode, and Li is created to hold the pattern of all those entries. +// Gaps will naturally appear because of the unused space in each supernode. +// +// Consider the following example: +// +// Each supernode is lower trapezoidal, with a top part that is lower +// triangular (with diagonal present) and a bottom part that is rectangular. +// In this example below, nscol = 5, so the supernode represents 5 columns of +// L, and nsrow = 8, which means that the first column of the supernode has 8 +// entries, including the diagonal. +// +// x 1 2 3 4 +// x x 2 3 4 +// x x x 3 4 +// x x x x 4 +// x x x x x +// x x x x x +// x x x x x +// x x x x x +// +// If the entries in the supernode are not moved, the first column will have a +// single entry of slack space at the end of the space (the "1" above). The +// 2nd column has 2 entries of slack space ("2"). The 3rd column has 3 entries +// of slack space ("3"), and so on. The last column (5th) has no slack space +// since it is followed by the next supenode. + +// If to_packed is true, the space is compressed and the unused entries above +// the diagonal of each supernode are removed. That is, in this example, the +// supernode takes up 40 entries in Lx in supernodal form. In the simplicial +// form, there is no slack space, and the total space becomes 8 + 7 + 6 + 5 + 4 +// = 30. The first column starts at position Lpx [s] in Lx for supernode s, +// and is moved to the 'left', starting at position Lp [j] if the first column +// is j = L->super [s]. Since space is being compacted, Lp [j] <= Lpx [s] +// holds, and thus Lx can be compacted in place when to_packed is true. +// +// x +// x x +// x x x +// x x x x +// x x x x x +// x x x x x +// x x x x x +// x x x x x + +// The factor is either real or complex (not pattern nor complex). Thus, +// L->x is always non-NULL, and L->z is NULL and not used. Instead of Lz, +// a blank appears in the macros that access the values of L below. + +#include "cholmod_template.h" + +//------------------------------------------------------------------------------ +// t_cholmod_change_factor_3_worker: convert supernodal numeric L to simplicial +//------------------------------------------------------------------------------ + +static void TEMPLATE (cholmod_change_factor_3_worker) +( + cholmod_factor *L, // factor to modify + int to_packed, // if true: convert L to packed + int to_ll, // if true, convert to LL. if false: to LDL' + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (L->is_super) ; + ASSERT (L->xtype == CHOLMOD_REAL || L->xtype == CHOLMOD_COMPLEX) ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int n = L->n ; // L is n-by-n + Int nsuper = L->nsuper ; // # of supernodes + Int *Lpi = (Int *) L->pi ; // index into L->s for supernode pattern + Int *Lpx = (Int *) L->px ; // index into L->x for supernode values + Int *Ls = (Int *) L->s ; // pattern of supernodes + Int *Super = (Int *) L->super ; // 1st column in each supernode + + // Lx holds supernode values on input; simplicial values on output: + Real *Lx = (Real *) L->x ; // numerical values (real or complex) + + // the simplicial space is allocated but not initialized on input: + Int *Lp = (Int *) L->p ; // simplicial col pointers + Int *Li = (Int *) L->i ; // simplicial row indices + Int *Lnz = (Int *) L->nz ; // simplicial column counts + Int lnz = L->nzmax ; // size of Li, Lp, and Lx + + //---------------------------------------------------------------------- + // convert supernodal LL' to simplicial LL' or LDL' (packed/unpacked) + //---------------------------------------------------------------------- + + if (to_packed) + { + if (to_ll) + { + // convert to simplicial packed LL' + #define TO_PACKED true + #define TO_LL true + #include "t_cholmod_change_factor_3_template.c" + } + else + { + // convert to simplicial packed LDL' + #define TO_PACKED true + #define TO_LL false + #include "t_cholmod_change_factor_3_template.c" + } + } + else + { + if (to_ll) + { + // convert to simplicial unpacked LL' + #define TO_PACKED false + #define TO_LL true + #include "t_cholmod_change_factor_3_template.c" + } + else + { + // convert to simplicial unpacked LDL' + #define TO_PACKED false + #define TO_LL false + #include "t_cholmod_change_factor_3_template.c" + } + } +} + diff --git a/CHOLMOD/Utility/t_cholmod_change_xdtype.c b/CHOLMOD/Utility/t_cholmod_change_xdtype.c new file mode 100644 index 000000000..8aaf8d23d --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_change_xdtype.c @@ -0,0 +1,221 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_xtype: change xtype and/or dtype of an object +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +//------------------------------------------------------------------------------ +// t_change_xdtype_template +//------------------------------------------------------------------------------ + +#define CHANGE_XDTYPE2 change_xdtype_d2d +#define Real_IN double +#define Real_OUT double +#include "t_cholmod_change_xdtype_template.c" + +#define CHANGE_XDTYPE2 change_xdtype_d2s +#define Real_IN double +#define Real_OUT float +#include "t_cholmod_change_xdtype_template.c" + +#define CHANGE_XDTYPE2 change_xdtype_s2d +#define Real_IN float +#define Real_OUT double +#include "t_cholmod_change_xdtype_template.c" + +#define CHANGE_XDTYPE2 change_xdtype_s2s +#define Real_IN float +#define Real_OUT float +#include "t_cholmod_change_xdtype_template.c" + +//------------------------------------------------------------------------------ +// change_xdtype: change the xtype and/or dtype of an array +//------------------------------------------------------------------------------ + +static int change_xdtype +( + Int nz, // # of entries + int *input_xtype, // xtype of input: pattern, real, complex, zomplex + int output_xtype, // xtype of output: pattern, real, complex, zomplex + int *input_dtype, // dtype of input: double or single + int output_dtype, // dtype of output: double or single + void **X, // X array for real, complex, zomplex cases + void **Z, // Z array for zomplex case + cholmod_common *Common +) +{ + if (*input_dtype == CHOLMOD_DOUBLE) + { + if (output_dtype == CHOLMOD_DOUBLE) + { + // double to double + return (change_xdtype_d2d (nz, input_xtype, output_xtype, + input_dtype, output_dtype, X, Z, Common)) ; + } + else + { + // double to single + return (change_xdtype_d2s (nz, input_xtype, output_xtype, + input_dtype, output_dtype, X, Z, Common)) ; + } + } + else + { + if (output_dtype == CHOLMOD_DOUBLE) + { + // single to double + return (change_xdtype_s2d (nz, input_xtype, output_xtype, + input_dtype, output_dtype, X, Z, Common)) ; + } + else + { + // single to single + return (change_xdtype_s2s (nz, input_xtype, output_xtype, + input_dtype, output_dtype, X, Z, Common)) ; + } + } +} + +//------------------------------------------------------------------------------ +// cholmod_sparse_xtype: change xtype and/or dtype of a sparse matrix +//------------------------------------------------------------------------------ + +int CHOLMOD(sparse_xtype) +( + int to_xdtype, // requested xtype and dtype + cholmod_sparse *A, // sparse matrix to change + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_SPARSE_MATRIX_INVALID (A, FALSE) ; + + //-------------------------------------------------------------------------- + // change the xtype and/or dtype + //-------------------------------------------------------------------------- + + int output_xtype = to_xdtype & 3 ; // pattern, real, complex, or zomplex + int output_dtype = to_xdtype & 4 ; // double or single + + return (change_xdtype (A->nzmax, &(A->xtype), output_xtype, + &(A->dtype), output_dtype, &(A->x), &(A->z), Common)) ; +} + +//------------------------------------------------------------------------------ +// cholmod_triplet_xtype: change xtype and/or dtype of a triplet matrix +//------------------------------------------------------------------------------ + +int CHOLMOD(triplet_xtype) +( + int to_xdtype, // requested xtype and dtype + cholmod_triplet *T, // triplet matrix to change + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_TRIPLET_MATRIX_INVALID (T, FALSE) ; + + //-------------------------------------------------------------------------- + // change the xtype and/or dtype + //-------------------------------------------------------------------------- + + int output_xtype = to_xdtype & 3 ; // pattern, real, complex, or zomplex + int output_dtype = to_xdtype & 4 ; // double or single + + return (change_xdtype (T->nzmax, &(T->xtype), output_xtype, + &(T->dtype), output_dtype, &(T->x), &(T->z), Common)) ; +} + +//------------------------------------------------------------------------------ +// cholmod_dense_xtype: change xtype and/or dtype of a dense matrix +//------------------------------------------------------------------------------ + +int CHOLMOD(dense_xtype) +( + int to_xdtype, // requested xtype and dtype + cholmod_dense *X, // dense matrix to change + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_DENSE_MATRIX_INVALID (X, FALSE) ; + + //-------------------------------------------------------------------------- + // change the xtype and/or dtype + //-------------------------------------------------------------------------- + + int output_xtype = to_xdtype & 3 ; // real, complex, or zomplex + int output_dtype = to_xdtype & 4 ; // double or single + + if (output_xtype <= CHOLMOD_PATTERN) + { + // output_xtype not supported + ERROR (CHOLMOD_INVALID, "invalid xtype") ; + return (FALSE) ; + } + + return (change_xdtype (X->nzmax, &(X->xtype), output_xtype, + &(X->dtype), output_dtype, &(X->x), &(X->z), Common)) ; +} + +//------------------------------------------------------------------------------ +// cholmod_factor_xtype: change xtype and/or dtype of a factor +//------------------------------------------------------------------------------ + +int CHOLMOD(factor_xtype) +( + int to_xdtype, // requested xtype and dtype + cholmod_factor *L, // factor to change + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_FACTOR_INVALID (L, FALSE) ; + + //-------------------------------------------------------------------------- + // change the xtype and/or dtype + //-------------------------------------------------------------------------- + + int output_xtype = to_xdtype & 3 ; // real, complex, or zomplex + int output_dtype = to_xdtype & 4 ; // double or single + + if (output_xtype <= CHOLMOD_PATTERN || + L->is_super && output_xtype == CHOLMOD_ZOMPLEX) + { + // output_xtype not supported + ERROR (CHOLMOD_INVALID, "invalid xtype") ; + return (FALSE) ; + } + + Int nzmax = L->is_super ? L->xsize : L->nzmax ; + + return (change_xdtype (nzmax, &(L->xtype), output_xtype, + &(L->dtype), output_dtype, &(L->x), &(L->z), Common)) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_change_xdtype_template.c b/CHOLMOD/Utility/t_cholmod_change_xdtype_template.c new file mode 100644 index 000000000..a3707fb51 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_change_xdtype_template.c @@ -0,0 +1,255 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_change_xdtype_template: change xtype and/or dtype +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Changes the xtype and/or dtype of X and Z. +// X and Z are arrays of size 0, nz, 2*nz, and are modified (in/out). + +#include "cholmod_internal.h" + +#define TRY(statement) \ + { \ + statement ; \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free) (nz, exout, X_output, Common) ; \ + CHOLMOD(free) (nz, ezout, Z_output, Common) ; \ + return (FALSE) ; \ + } \ + } + +//------------------------------------------------------------------------------ + +static int CHANGE_XDTYPE2 +( + Int nz, // # of entries in X and/or Z + + int *input_xtype, // changed to output_xtype on output + // CHOLMOD_PATTERN: X and Z are NULL on input + // CHOLMOD_REAL: X is size nz, and Z is NULL on input + // CHOLMOD_COMPLEX: X is size 2*nz, and Z is NULL on input + // CHOLMOD_ZOMPLEX: X and Z are size nz on input + + int output_xtype, + // CHOLMOD_PATTERN: X and Z are NULL on output + // CHOLMOD_REAL: X is size nz, and Z is NULL on output + // CHOLMOD_COMPLEX: X is size 2*nz, and Z is NULL on output + // CHOLMOD_ZOMPLEX: X and Z are size nz on output + + int *input_dtype, // changed to output_dtype on output + int output_dtype, + + // input/output: + void **X, // &X on input, reallocated on output + void **Z, // &Z on input, reallocated on output + + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + Common->status = CHOLMOD_OK ; + if (*input_xtype == output_xtype && sizeof (Real_IN) == sizeof (Real_OUT)) + { + // nothing to do + return (TRUE) ; + } + + //-------------------------------------------------------------------------- + // get the entry sizes of the input and output + //-------------------------------------------------------------------------- + + size_t ein = sizeof (Real_IN) ; + size_t exin = ein * (((*input_xtype) == CHOLMOD_PATTERN) ? 0 : + (((*input_xtype) == CHOLMOD_COMPLEX) ? 2 : 1)) ; + size_t ezin = ein * (((*input_xtype) == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + + size_t eout = sizeof (Real_OUT) ; + size_t exout = eout * (((output_xtype) == CHOLMOD_PATTERN) ? 0 : + (((output_xtype) == CHOLMOD_COMPLEX) ? 2 : 1)) ; + size_t ezout = eout * (((output_xtype) == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + + //-------------------------------------------------------------------------- + // convert the array + //-------------------------------------------------------------------------- + + Real_IN *X_input = (Real_IN *) *X ; + Real_IN *Z_input = (Real_IN *) *Z ; + Real_OUT *X_output = NULL ; + Real_OUT *Z_output = NULL ; + + switch (output_xtype) + { + + //---------------------------------------------------------------------- + case CHOLMOD_PATTERN: // convert any xtype to pattern + //---------------------------------------------------------------------- + + break ; + + //---------------------------------------------------------------------- + case CHOLMOD_REAL: // convert any xtype to real + //---------------------------------------------------------------------- + + TRY (X_output = CHOLMOD(malloc) (nz, exout, Common)) ; + + switch (*input_xtype) + { + + case CHOLMOD_PATTERN: // pattern to real + + for (Int k = 0 ; k < nz ; k++) + { + X_output [k] = 1 ; + } + break ; + + case CHOLMOD_REAL: // real to real + + for (Int k = 0 ; k < nz ; k++) + { + X_output [k] = (Real_OUT) X_input [k] ; + } + break ; + + case CHOLMOD_COMPLEX: // complex to real + + for (Int k = 0 ; k < nz ; k++) + { + X_output [k] = (Real_OUT) X_input [2*k] ; + } + break ; + + case CHOLMOD_ZOMPLEX: // zomplex to real + + for (Int k = 0 ; k < nz ; k++) + { + X_output [k] = (Real_OUT) X_input [k] ; + } + break ; + + } + break ; + + //---------------------------------------------------------------------- + case CHOLMOD_COMPLEX: // convert any xtype to complex + //---------------------------------------------------------------------- + + TRY (X_output = CHOLMOD(malloc) (nz, exout, Common)) ; + + switch (*input_xtype) + { + + case CHOLMOD_PATTERN: // pattern to complex + + for (Int k = 0 ; k < nz ; k++) + { + X_output [2*k ] = 1 ; + X_output [2*k+1] = 0 ; + } + break ; + + case CHOLMOD_REAL: // real to complex + + for (Int k = 0 ; k < nz ; k++) + { + X_output [2*k ] = (Real_OUT) X_input [k] ; + X_output [2*k+1] = 0 ; + } + break ; + + case CHOLMOD_COMPLEX: // complex to complex + + for (Int k = 0 ; k < 2*nz ; k++) + { + X_output [k] = (Real_OUT) X_input [k] ; + } + break ; + + case CHOLMOD_ZOMPLEX: // zomplex to complex + + for (Int k = 0 ; k < nz ; k++) + { + X_output [2*k ] = (Real_OUT) X_input [k] ; + X_output [2*k+1] = (Real_OUT) Z_input [k] ; + } + break ; + } + break ; + + //---------------------------------------------------------------------- + case CHOLMOD_ZOMPLEX: // convert any xtype to zomplex + //---------------------------------------------------------------------- + + TRY (X_output = CHOLMOD(malloc) (nz, exout, Common)) ; + TRY (Z_output = CHOLMOD(malloc) (nz, ezout, Common)) ; + + switch (*input_xtype) + { + case CHOLMOD_PATTERN: // pattern to zomplex + + for (Int k = 0 ; k < nz ; k++) + { + X_output [k] = 1 ; + Z_output [k] = 0 ; + } + break ; + + case CHOLMOD_REAL: // real to zomplex + + for (Int k = 0 ; k < nz ; k++) + { + X_output [k] = (Real_OUT) X_input [k] ; + Z_output [k] = 0 ; + } + break ; + + case CHOLMOD_COMPLEX: // complex to zomplex + + for (Int k = 0 ; k < nz ; k++) + { + X_output [k] = (Real_OUT) X_input [2*k ] ; + Z_output [k] = (Real_OUT) X_input [2*k+1] ; + } + break ; + + case CHOLMOD_ZOMPLEX: // zomplex to zomplex + + for (Int k = 0 ; k < nz ; k++) + { + X_output [k] = (Real_OUT) X_input [k] ; + Z_output [k] = (Real_OUT) Z_input [k] ; + } + break ; + + } + break ; + + } + + //-------------------------------------------------------------------------- + // free the input arrays and return result + //-------------------------------------------------------------------------- + + CHOLMOD(free) (nz, exin, X_input, Common) ; + CHOLMOD(free) (nz, ezin, Z_input, Common) ; + (*X) = X_output ; + (*Z) = Z_output ; + (*input_xtype) = output_xtype ; + (*input_dtype) = output_dtype ; + return (TRUE) ; +} + +#undef CHANGE_XDTYPE2 +#undef Real_IN +#undef Real_OUT + diff --git a/CHOLMOD/Utility/t_cholmod_clear_flag.c b/CHOLMOD/Utility/t_cholmod_clear_flag.c new file mode 100644 index 000000000..c0f7320f7 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_clear_flag.c @@ -0,0 +1,58 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_clear_flag: clear Common->Flag +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +// cholmod_clear_flag increments Common->mark to ensure +// Common->Flag [0..Common->nrow-1] < mark holds. If incrementing +// Common->mark results in integer overflow, Flag is set to EMPTY and +// Common->mark is set to zero. + +int64_t CHOLMOD(clear_flag) // returns the new Common->mark +( + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (EMPTY) ; + + //-------------------------------------------------------------------------- + // increment the mark + //-------------------------------------------------------------------------- + + Common->mark++ ; + + //-------------------------------------------------------------------------- + // check for int32 or int64 overflow + //-------------------------------------------------------------------------- + + bool overflow = (Common->mark <= 0) ; + #if defined ( CHOLMOD_INT32 ) + overflow = overflow || (Common->mark > INT32_MAX) ; + #endif + + if (overflow) + { + Common->mark = 0 ; + CHOLMOD(set_empty) (Common->Flag, Common->nrow) ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (check_flag (Common)) ; + return (Common->mark) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_copy.c b/CHOLMOD/Utility/t_cholmod_copy.c new file mode 100644 index 000000000..d8b378449 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_copy.c @@ -0,0 +1,332 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_copy: copy a sparse matrix (with change of stype) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Create a copy (C) of a sparse matrix A, with change of stype. +// A has any xtype, dtype, and stype, and can be packed or unpacked. +// C has the same xtype and dtype, but any stype (unless A is rectangular, +// in which case C->stype must be zero). C is packed. + +// A->stype == 0: A is unsymmetric +// A->stype < 0: A is symmetric with lower triangular part stored. Any entries +// above the diagonal are ignored. +// A->stype > 0: A is symmetric with upper triangular part stored. Any entries +// below the diagonal are ignored. + +// C can be returned as numerical or pattern-only; and in the latter case, +// the diagonal entries can be ignored. + +// In MATLAB: Using cholmod_copy: +// --------- ---------------------------- +// C = A ; A unsymmetric, C unsymmetric +// C = tril (A) ; A unsymmetric, C sym lower +// C = triu (A) ; A unsymmetric, C sym upper +// U = triu (A) ; L = tril (U',-1) ; C = L+U ; A sym upper, C unsymmetric +// C = triu (A)' ; A sym upper, C sym lower +// C = triu (A) ; A sym upper, C sym upper +// L = tril (A) ; U = triu (L',1) ; C = L+U ; A sym lower, C unsymmetric +// C = tril (A) ; A sym lower, C sym lower +// C = tril (A)' ; A sym lower, C sym upper + +// If A is complex or zomplex, then U' or L' above can be computed as an +// array (non-conjugate) transpose, or a matrix (conjugate) transpose. + +// The mode parameter: +// 2 numerical, with conjugate transpose +// 1 numerical, with non-conjugate transpose +// 0 pattern, keeping the diagonal +// -1 pattern, remove the diagonal +// -2 pattern, and add 50% + n extra space to C +// as elbow room for AMD and CAMD, when converting +// a symmetric matrix A to an unsymmetric matrix C + +// workspace: Iwork (max (nrow,ncol)) + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_sparse) (&C, Common) ; \ + return (NULL) ; \ + } + +//------------------------------------------------------------------------------ +// t_cholmod_copy_worker template +//------------------------------------------------------------------------------ + +#define PATTERN +#include "t_cholmod_copy_worker.c" + +#define DOUBLE +#define REAL +#include "t_cholmod_copy_worker.c" + +#define COMPLEX +#include "t_cholmod_copy_worker.c" +#define COMPLEX +#define NCONJUGATE +#include "t_cholmod_copy_worker.c" + +#define ZOMPLEX +#include "t_cholmod_copy_worker.c" +#define ZOMPLEX +#define NCONJUGATE +#include "t_cholmod_copy_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_copy_worker.c" + +#define COMPLEX +#include "t_cholmod_copy_worker.c" +#define COMPLEX +#define NCONJUGATE +#include "t_cholmod_copy_worker.c" + +#define ZOMPLEX +#include "t_cholmod_copy_worker.c" +#define ZOMPLEX +#define NCONJUGATE +#include "t_cholmod_copy_worker.c" + +//------------------------------------------------------------------------------ + +cholmod_sparse *CHOLMOD(copy) +( + cholmod_sparse *A, // input matrix, not modified + int stype, // stype of C + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // 0: pattern (with diag), -1: pattern (remove diag), + // -2: pattern (remove diag; add ~50% extra space in C) + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + RETURN_IF_SPARSE_MATRIX_INVALID (A, NULL) ; + Common->status = CHOLMOD_OK ; + cholmod_sparse *C = NULL ; + + Int nrow = A->nrow ; + Int ncol = A->ncol ; + int astype = SIGN (A->stype) ; + stype = SIGN (stype) ; + if ((stype || astype) && nrow != ncol) + { + ERROR (CHOLMOD_INVALID, "matrix invalid") ; + return (NULL) ; + } + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + bool ignore_diag = (mode < 0) ; + bool up = (astype > 0) ; + bool lo = (astype < 0) ; + bool values = (mode > 0) && (A->xtype != CHOLMOD_PATTERN) ; + bool conj = (mode >= 2) ; + + //-------------------------------------------------------------------------- + // copy the matrix + //-------------------------------------------------------------------------- + + if (astype == stype) + { + + //---------------------------------------------------------------------- + // no change of stype, but possible remove of diagonal + //---------------------------------------------------------------------- + + C = CHOLMOD(band) (A, -nrow, ncol, mode, Common) ; + RETURN_IF_ERROR ; + + } + else if (astype == 0) + { + + //---------------------------------------------------------------------- + // A is unsymmetric; C is symmetric upper or lower + //---------------------------------------------------------------------- + + size_t nlo = (stype > 0) ? 0 : (-nrow) ; + size_t nup = (stype > 0) ? ncol : 0 ; + C = CHOLMOD(band) (A, nlo, nup, mode, Common) ; + RETURN_IF_ERROR ; + C->stype = stype ; + + } + else if (astype == -stype) + { + + //---------------------------------------------------------------------- + // both A and C are symmetric, but opposite, so a transpose is needed + //---------------------------------------------------------------------- + + C = CHOLMOD(transpose) (A, mode, Common) ; + RETURN_IF_ERROR ; + if (ignore_diag) + { + // remove diagonal, if requested + CHOLMOD(band_inplace) (-nrow, ncol, -1, C, Common) ; + RETURN_IF_ERROR ; + } + + } + else + { + + //---------------------------------------------------------------------- + // A is symmetric and C is unsymmetric + //---------------------------------------------------------------------- + + Int *Ap = (Int *) A->p ; + Int *Anz = (Int *) A->nz ; + Int *Ai = (Int *) A->i ; + bool packed = A->packed ; + + //---------------------------------------------------------------------- + // allocate workspace + //---------------------------------------------------------------------- + + ASSERT (nrow == ncol) ; + CHOLMOD(allocate_work) (0, ncol, 0, Common) ; + RETURN_IF_ERROR ; + Int *Wj = (Int *) Common->Iwork ; + + //---------------------------------------------------------------------- + // count entries in each column of C + //---------------------------------------------------------------------- + + memset (Wj, 0, ncol * sizeof (Int)) ; + size_t cnz = 0 ; + + for (Int j = 0 ; j < ncol ; j++) + { + Int p = Ap [j] ; + Int pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; + for ( ; p < pend ; p++) + { + Int i = Ai [p] ; + if (i == j) + { + // diagonal entry A(i,i) + if (ignore_diag) continue ; + Wj [j]++ ; + cnz++ ; + } + else if ((up && i < j) || (lo && i > j)) + { + // A(i,j) is placed in both upper and lower part of C + Wj [j]++ ; + Wj [i]++ ; + cnz += 2 ; + } + } + } + + //---------------------------------------------------------------------- + // allocate C + //---------------------------------------------------------------------- + + size_t cnzmax = cnz + ((mode == -2) ? (cnz/2 + ncol) : 0) ; + C = CHOLMOD(allocate_sparse) (nrow, ncol, cnzmax, + /* C is sorted if A is sorted: */ A->sorted, + /* C is packed: */ TRUE, /* C stype: */ 0, + (values ? A->xtype : CHOLMOD_PATTERN) + A->dtype, Common) ; + RETURN_IF_ERROR ; + + //---------------------------------------------------------------------- + // Cp = cumsum of column counts (Wj), and then copy Cp back to Wj + //---------------------------------------------------------------------- + + Int *Cp = C->p ; + CHOLMOD(cumsum) (Cp, Wj, ncol) ; + memcpy (Wj, Cp, ncol * sizeof (Int)) ; + + //---------------------------------------------------------------------- + // construct C via the template function + //---------------------------------------------------------------------- + + switch ((C->xtype + C->dtype) % 8) + { + + default: + p_cholmod_copy_worker (C, A, ignore_diag, Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_copy_worker (C, A, ignore_diag, Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + if (conj) + { + c_s_cholmod_copy_worker (C, A, ignore_diag, Common) ; + } + else + { + ct_s_cholmod_copy_worker (C, A, ignore_diag, Common) ; + } + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + if (conj) + { + z_s_cholmod_copy_worker (C, A, ignore_diag, Common) ; + } + else + { + zt_s_cholmod_copy_worker (C, A, ignore_diag, Common) ; + } + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_copy_worker (C, A, ignore_diag, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + if (conj) + { + c_cholmod_copy_worker (C, A, ignore_diag, Common) ; + } + else + { + ct_cholmod_copy_worker (C, A, ignore_diag, Common) ; + } + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + if (conj) + { + z_cholmod_copy_worker (C, A, ignore_diag, Common) ; + } + else + { + zt_cholmod_copy_worker (C, A, ignore_diag, Common) ; + } + break ; + } + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + DEBUG (size_t nnzdiag = CHOLMOD(dump_sparse) (C, "copy:C", Common)) ; + ASSERT (IMPLIES (ignore_diag, nnzdiag == 0)) ; + return (C) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_copy_dense.c b/CHOLMOD/Utility/t_cholmod_copy_dense.c new file mode 100644 index 000000000..137a1b2c1 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_copy_dense.c @@ -0,0 +1,58 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_dense: copy a dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Copies a dense matrix X into a new dense matrix Y, with the same leading +// dimensions. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_dense) (&Y, Common) ; \ + return (NULL) ; \ + } + +cholmod_dense *CHOLMOD(copy_dense) // returns new dense matrix +( + cholmod_dense *X, // input dense matrix + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_DENSE_MATRIX_INVALID (X, FALSE) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // allocate the output matrix Y with same properties as X + //-------------------------------------------------------------------------- + + cholmod_dense *Y = CHOLMOD(allocate_dense) (X->nrow, X->ncol, X->d, + X->xtype + X->dtype, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // copy X = Y + //-------------------------------------------------------------------------- + + CHOLMOD(copy_dense2) (X, Y, Common) ; + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (Y) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_copy_dense2.c b/CHOLMOD/Utility/t_cholmod_copy_dense2.c new file mode 100644 index 000000000..c19b4f531 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_copy_dense2.c @@ -0,0 +1,131 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_dense2: copy a dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Copies a dense matrix X into another dense matrix Y, which must already +// be allocated on input. The dimensions, xtype, and dtype of X and Y must +// match, but X->d and Y->d can differ. + +#include "cholmod_internal.h" + +//------------------------------------------------------------------------------ +// t_cholmod_copy_dense2_worker template +//------------------------------------------------------------------------------ + +#define DOUBLE +#define REAL +#include "t_cholmod_copy_dense2_worker.c" +#define COMPLEX +#include "t_cholmod_copy_dense2_worker.c" +#define ZOMPLEX +#include "t_cholmod_copy_dense2_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_copy_dense2_worker.c" +#define COMPLEX +#include "t_cholmod_copy_dense2_worker.c" +#define ZOMPLEX +#include "t_cholmod_copy_dense2_worker.c" + +//------------------------------------------------------------------------------ + +int CHOLMOD(copy_dense2) +( + cholmod_dense *X, // input dense matrix + cholmod_dense *Y, // output dense matrix (already allocated on input) + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_DENSE_MATRIX_INVALID (X, FALSE) ; + RETURN_IF_DENSE_MATRIX_INVALID (Y, FALSE) ; + Common->status = CHOLMOD_OK ; + + if (X->nrow != Y->nrow || + X->ncol != Y->ncol || + X->xtype != Y->xtype || + X->dtype != Y->dtype) + { + ERROR (CHOLMOD_INVALID, "X and Y: wrong dimensions or type") ; + return (FALSE) ; + } + + //-------------------------------------------------------------------------- + // get the sizes of the entries + //-------------------------------------------------------------------------- + + size_t e = (X->dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + size_t ex = e * ((X->xtype == CHOLMOD_COMPLEX) ? 2 : 1) ; + size_t ez = e * ((X->xtype == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + + //-------------------------------------------------------------------------- + // copy X = Y + //-------------------------------------------------------------------------- + + if (X->d == Y->d) + { + + //---------------------------------------------------------------------- + // no change of leading dimension: copy all of X and Y as-is + //---------------------------------------------------------------------- + + size_t nz = X->d * X->ncol ; + if (X->x != NULL) memcpy (Y->x, X->x, nz * ex) ; + if (X->z != NULL) memcpy (Y->z, X->z, nz * ez) ; + + } + else + { + + //---------------------------------------------------------------------- + // copy Y into X, with possible change of leading dimension + //---------------------------------------------------------------------- + + switch ((X->xtype + X->dtype) % 8) + { + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_copy_dense2_worker (X, Y) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_copy_dense2_worker (X, Y) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_copy_dense2_worker (X, Y) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_copy_dense2_worker (X, Y) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_copy_dense2_worker (X, Y) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_copy_dense2_worker (X, Y) ; + break ; + } + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_copy_dense2_worker.c b/CHOLMOD/Utility/t_cholmod_copy_dense2_worker.c new file mode 100644 index 000000000..d4a0ace8a --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_copy_dense2_worker.c @@ -0,0 +1,84 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_dense2_worker: copy a dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Copies a dense matrix X into Y, with change of leading dimension. If the +// leading dimensions are the same, the copy is done in the caller, +// t_cholmod_copy_dense2. + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_copy_dense2_worker) +( + cholmod_dense *X, + cholmod_dense *Y +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (X->d != Y->d) ; + ASSERT (X->nrow == Y->nrow) ; + ASSERT (X->ncol == Y->ncol) ; + ASSERT (X->dtype == Y->dtype) ; + ASSERT (X->xtype == Y->xtype) ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Real *Xx = (Real *) X->x ; + Real *Xz = (Real *) X->z ; + Real *Yx = (Real *) Y->x ; + Real *Yz = (Real *) Y->z ; + size_t nrow = X->nrow ; + size_t ncol = X->ncol ; + size_t xd = X->d ; + size_t yd = Y->d ; + + //-------------------------------------------------------------------------- + // get the sizes of the entries + //-------------------------------------------------------------------------- + + size_t e = (X->dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + size_t fx = ((X->xtype == CHOLMOD_COMPLEX) ? 2 : 1) ; + size_t fz = ((X->xtype == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + size_t e_fx_nrow = e * fx * nrow ; + size_t e_fz_nrow = e * fz * nrow ; + + //-------------------------------------------------------------------------- + // copy X = Y + //-------------------------------------------------------------------------- + + for (size_t j = 0 ; j < ncol ; j++) + { + + //---------------------------------------------------------------------- + // Y (:,j) = X (:,j) + //---------------------------------------------------------------------- + + memcpy (Yx, Xx, e_fx_nrow) ; + Xx += xd * fx ; + Yx += yd * fx ; + + #if defined ( ZOMPLEX ) + memcpy (Yz, Xz, e_fz_nrow) ; + Xz += xd * fz ; + Yz += yd * fz ; + #endif + } +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_copy_factor.c b/CHOLMOD/Utility/t_cholmod_copy_factor.c new file mode 100644 index 000000000..9f4102fd0 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_copy_factor.c @@ -0,0 +1,193 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_copy_factor: copy a factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Creates an exact copy of a sparse factorization object. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_factor) (&H, Common) ; \ + return (NULL) ; \ + } + +//------------------------------------------------------------------------------ +// t_cholmod_copy_factor_worker template +//------------------------------------------------------------------------------ + +#define DOUBLE +#define REAL +#include "t_cholmod_copy_factor_worker.c" +#define COMPLEX +#include "t_cholmod_copy_factor_worker.c" +#define ZOMPLEX +#include "t_cholmod_copy_factor_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_copy_factor_worker.c" +#define COMPLEX +#include "t_cholmod_copy_factor_worker.c" +#define ZOMPLEX +#include "t_cholmod_copy_factor_worker.c" + +//------------------------------------------------------------------------------ + +cholmod_factor *CHOLMOD(copy_factor) // return a copy of the factor +( + cholmod_factor *L, // factor to copy (not modified) + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + RETURN_IF_FACTOR_INVALID (L, FALSE) ; + Common->status = CHOLMOD_OK ; + + DEBUG (CHOLMOD(dump_factor) (L, "copy_factor:L", Common)) ; + + //-------------------------------------------------------------------------- + // get inputs and sizes of entries + //-------------------------------------------------------------------------- + + size_t n = L->n ; + size_t ei = sizeof (Int) ; + size_t e = (L->dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + size_t ex = e * ((L->xtype == CHOLMOD_PATTERN) ? 0 : + ((L->xtype == CHOLMOD_COMPLEX) ? 2 : 1)) ; + size_t ez = e * ((L->xtype == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + + //-------------------------------------------------------------------------- + // allocate the new factor H, H->Perm, and H->ColCount + //-------------------------------------------------------------------------- + + cholmod_factor *H = CHOLMOD(allocate_factor) (n, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // copy the symbolic contents (same for simplicial or supernodal) + //-------------------------------------------------------------------------- + + memcpy (H->Perm, L->Perm, n * ei) ; + memcpy (H->ColCount, L->ColCount, n * ei) ; + H->ordering = L->ordering ; + H->is_ll = L->is_ll ; + + //-------------------------------------------------------------------------- + // copy the rest of the factor + //-------------------------------------------------------------------------- + + if (L->is_super) + { + + //---------------------------------------------------------------------- + // L is a numerical supernodal factor; change H to supernodal + //---------------------------------------------------------------------- + + H->xsize = L->xsize ; + H->ssize = L->ssize ; + H->nsuper = L->nsuper ; + + CHOLMOD(change_factor) (L->xtype + L->dtype, /* to LL': */ TRUE, + /* to supernodal: */ TRUE, /* to packed: */ TRUE, + /* to monotonic: */ TRUE, H, Common) ; + RETURN_IF_ERROR ; + + //---------------------------------------------------------------------- + // copy the supernodal contents + //---------------------------------------------------------------------- + + H->maxcsize = L->maxcsize ; + H->maxesize = L->maxesize ; + + memcpy (H->super, L->super, (L->nsuper + 1) * ei) ; + memcpy (H->pi, L->pi, (L->nsuper + 1) * ei) ; + memcpy (H->px, L->px, (L->nsuper + 1) * ei) ; + memset (H->s, 0, ei) ; + memcpy (H->s, L->s, (L->ssize) * ei) ; + + if (L->xtype == CHOLMOD_REAL || L->xtype == CHOLMOD_COMPLEX) + { + memcpy (H->x, L->x, (L->xsize) * ex) ; + } + + } + else if (L->xtype != CHOLMOD_PATTERN) + { + + //---------------------------------------------------------------------- + // L is a numerical simplicial factor; change H to the same + //---------------------------------------------------------------------- + + H->nzmax = L->nzmax ; + CHOLMOD(change_factor) (L->xtype + L->dtype, L->is_ll, + /* to supernodal: */ FALSE, /* to packed: */ -1, + /* to monotonic: */ TRUE, H, Common) ; + RETURN_IF_ERROR ; + + //---------------------------------------------------------------------- + // copy the simplicial contents + //---------------------------------------------------------------------- + + H->xtype = L->xtype ; + H->dtype = L->dtype ; + + memcpy (H->p, L->p, (n+1) * ei) ; + memcpy (H->prev, L->prev, (n+2) * ei) ; + memcpy (H->next, L->next, (n+2) * ei) ; + memcpy (H->nz, L->nz, n * ei) ; + + switch ((L->xtype + L->dtype) % 8) + { + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_copy_factor_worker (L, H) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_copy_factor_worker (L, H) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_copy_factor_worker (L, H) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_copy_factor_worker (L, H) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_copy_factor_worker (L, H) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_copy_factor_worker (L, H) ; + break ; + } + } + + //-------------------------------------------------------------------------- + // finalize the copy and return result + //-------------------------------------------------------------------------- + + H->minor = L->minor ; + H->is_monotonic = L->is_monotonic ; + + DEBUG (CHOLMOD(dump_factor) (H, "copy_factor:H", Common)) ; + ASSERT (H->xtype == L->xtype && H->is_super == L->is_super) ; + return (H) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_copy_factor_worker.c b/CHOLMOD/Utility/t_cholmod_copy_factor_worker.c new file mode 100644 index 000000000..80c2c96c2 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_copy_factor_worker.c @@ -0,0 +1,58 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_copy_factor_worker: copy a factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Columns are copied individually, to avoid copying uninitialized space + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_copy_factor_worker) +( + cholmod_factor *L, // input factor to copy (not modified) + cholmod_factor *H // output factor +) +{ + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + size_t n = L->n ; + + Int *Lp = (Int *) L->p ; + Int *Li = (Int *) L->i ; + Int *Lnz = (Int *) L->nz ; + Real *Lx = (Real *) L->x ; + Real *Lz = (Real *) L->z ; + + Int *Hi = (Int *) H->i ; + Real *Hx = (Real *) H->x ; + Real *Hz = (Real *) H->z ; + + //-------------------------------------------------------------------------- + // copy each column + //-------------------------------------------------------------------------- + + for (Int j = 0 ; j < n ; j++) + { + Int p = Lp [j] ; + Int pend = p + Lnz [j] ; + for ( ; p < pend ; p++) + { + Hi [p] = Li [p] ; + ASSIGN (Hx, Hz, p, Lx, Lz, p) ; + } + } +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_copy_sparse.c b/CHOLMOD/Utility/t_cholmod_copy_sparse.c new file mode 100644 index 000000000..042bd2bbd --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_copy_sparse.c @@ -0,0 +1,144 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_copy_sparse: copy a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Creates an exact copy of a sparse matrix. For making a copy with a change +// of stype and/or copying the pattern of a numerical matrix, see cholmod_copy. +// For changing the xtype and/or dtype, see cholmod_sparse_xtype. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_sparse) (&C, Common) ; \ + return (NULL) ; \ + } + +//------------------------------------------------------------------------------ +// t_cholmod_copy_sparse_worker template +//------------------------------------------------------------------------------ + +#define PATTERN +#include "t_cholmod_copy_sparse_worker.c" + +#define DOUBLE +#define REAL +#include "t_cholmod_copy_sparse_worker.c" +#define COMPLEX +#include "t_cholmod_copy_sparse_worker.c" +#define ZOMPLEX +#include "t_cholmod_copy_sparse_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_copy_sparse_worker.c" +#define COMPLEX +#include "t_cholmod_copy_sparse_worker.c" +#define ZOMPLEX +#include "t_cholmod_copy_sparse_worker.c" + +cholmod_sparse *CHOLMOD(copy_sparse) // return new sparse matrix +( + cholmod_sparse *A, // sparse matrix to copy + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + RETURN_IF_SPARSE_MATRIX_INVALID (A, NULL) ; + Common->status = CHOLMOD_OK ; + ASSERT (CHOLMOD(dump_sparse) (A, "copy_sparse:A", Common) >= 0) ; + + //-------------------------------------------------------------------------- + // allocate the copy C with the same characteristcs as A + //-------------------------------------------------------------------------- + + cholmod_sparse *C = CHOLMOD(allocate_sparse) (A->nrow, A->ncol, + A->nzmax, A->sorted, A->packed, A->stype, A->xtype + A->dtype, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // get the sizes of the entries + //-------------------------------------------------------------------------- + + size_t ei = sizeof (Int) ; + size_t e = (A->dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + size_t ex = e * ((A->xtype == CHOLMOD_PATTERN) ? 0 : + ((A->xtype == CHOLMOD_COMPLEX) ? 2 : 1)) ; + size_t ez = e * ((A->xtype == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + + //-------------------------------------------------------------------------- + // copy the contents from A to C + //-------------------------------------------------------------------------- + + size_t ncol = A->ncol ; + + // copy A->p (both packed and unpacked cases) + memcpy (C->p, A->p, (ncol+1) * ei) ; + + if (A->packed) + { + // use memcpy when A is packed + int64_t anz = CHOLMOD(nnz) (A, Common) ; + if (A->i != NULL) memcpy (C->i, A->i, anz * ei) ; + if (A->x != NULL) memcpy (C->x, A->x, anz * ex) ; + if (A->z != NULL) memcpy (C->z, A->z, anz * ez) ; + } + else + { + // copy A->nz (for any xtype and dtype) + if (A->nz != NULL) memcpy (C->nz, A->nz, ncol * ei) ; + + // use a template worker when A is unpacked to copy A->i, A->x, and A->z + switch ((A->xtype + A->dtype) % 8) + { + default: + p_cholmod_copy_sparse_worker (C, A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_copy_sparse_worker (C, A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_copy_sparse_worker (C, A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_copy_sparse_worker (C, A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_copy_sparse_worker (C, A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_copy_sparse_worker (C, A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_copy_sparse_worker (C, A) ; + break ; + } + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (CHOLMOD(dump_sparse) (C, "copy_sparse:C", Common) >= 0) ; + return (C) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_copy_sparse_worker.c b/CHOLMOD/Utility/t_cholmod_copy_sparse_worker.c new file mode 100644 index 000000000..b101952c0 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_copy_sparse_worker.c @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_copy_sparse_worker: copy a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_copy_sparse_worker) +( + cholmod_sparse *C, // output sparse matrix + cholmod_sparse *A // sparse matrix to copy +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + // This worker is only used for the unpacked case + ASSERT (!(A->packed)) ; + + //-------------------------------------------------------------------------- + // get the A and C matrices + //-------------------------------------------------------------------------- + + Int *Ap = (Int *) A->p ; + Int *Anz = (Int *) A->nz ; + Int *Ai = (Int *) A->i ; + Real *Ax = (Real *) A->x ; + Real *Az = (Real *) A->z ; + size_t ncol = A->ncol ; + + Int *Ci = (Int *) C->i ; + Real *Cx = (Real *) C->x ; + Real *Cz = (Real *) C->z ; + + //-------------------------------------------------------------------------- + // copy the contents from A to C + //-------------------------------------------------------------------------- + + for (Int j = 0 ; j < ncol ; j++) + { + Int p = Ap [j] ; + Int pend = p + Anz [j] ; + for ( ; p < pend ; p++) + { + // C(i,j) = A (i,j) + Ci [p] = Ai [p] ; + ASSIGN (Cx, Cz, p, Ax, Az, p) ; + } + } +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_copy_triplet.c b/CHOLMOD/Utility/t_cholmod_copy_triplet.c new file mode 100644 index 000000000..9acab33a8 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_copy_triplet.c @@ -0,0 +1,70 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_copy_triplet: copy a triplet matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_triplet) (&C, Common) ; \ + return (NULL) ; \ + } + +cholmod_triplet *CHOLMOD(copy_triplet) // return new triplet matrix +( + cholmod_triplet *T, // triplet matrix to copy + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + RETURN_IF_TRIPLET_MATRIX_INVALID (T, NULL) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // allocate the copy + //-------------------------------------------------------------------------- + + cholmod_triplet *C = CHOLMOD(allocate_triplet) (T->nrow, T->ncol, + T->nzmax, T->stype, T->xtype + T->dtype, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // get the sizes of the entries + //-------------------------------------------------------------------------- + + size_t ei = sizeof (Int) ; + size_t e = (T->dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + size_t ex = e * ((T->xtype == CHOLMOD_PATTERN) ? 0 : + ((T->xtype == CHOLMOD_COMPLEX) ? 2 : 1)) ; + size_t ez = e * ((T->xtype == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + + //-------------------------------------------------------------------------- + // copy the contents from T to C + //-------------------------------------------------------------------------- + + C->nnz = T->nnz ; + if (T->i != NULL) memcpy (C->i, T->i, T->nnz * ei) ; + if (T->j != NULL) memcpy (C->j, T->j, T->nnz * ei) ; + if (T->x != NULL) memcpy (C->x, T->x, T->nnz * ex) ; + if (T->z != NULL) memcpy (C->z, T->z, T->nnz * ez) ; + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (CHOLMOD(dump_triplet) (C, "copy_triplet:C", Common)) ; + return (C) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_copy_worker.c b/CHOLMOD/Utility/t_cholmod_copy_worker.c new file mode 100644 index 000000000..f125caf2a --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_copy_worker.c @@ -0,0 +1,148 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_copy_worker: copy sparse matrix (change of stype) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// A is symmetric upper or lower, and C is unsymmetric. Both are square. + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_copy_worker) +( + cholmod_sparse *C, // output matrix + cholmod_sparse *A, // input matrix, not modified + bool ignore_diag, // if true, ignore diagonal + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + Int n = A->ncol ; + ASSERT (A->stype != 0) ; + ASSERT (C->stype == 0) ; + ASSERT (n == A->ncol) ; + ASSERT (n == C->nrow) ; + ASSERT (n == C->ncol) ; + ASSERT (C->packed) ; + ASSERT (C->sorted == A->sorted) ; + ASSERT (C->dtype == A->dtype) ; + ASSERT (C->xtype == A->xtype || C->xtype == CHOLMOD_PATTERN) ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int *Wj = (Int *) Common->Iwork ; // size n integer workspace + + Int *Ap = (Int *) A->p ; + Int *Anz = (Int *) A->nz ; + Int *Ai = (Int *) A->i ; + Real *Ax = (Real *) A->x ; + Real *Az = (Real *) A->z ; + bool packed = A->packed ; + + Int *Cp = (Int *) C->p ; + Int *Ci = (Int *) C->i ; + Real *Cx = (Real *) C->x ; + Real *Cz = (Real *) C->z ; + bool keep_diag = !ignore_diag ; + + //-------------------------------------------------------------------------- + // create an unsymmetric matrix C from a symmetric matrix A + //-------------------------------------------------------------------------- + + // place A(i,j) in C(:,k) + #define ASSIGN_CIJ(i,j) \ + { \ + Int q = Wj [j]++ ; \ + ASSIGN (Cx, Cz, q, Ax, Az, p) ; \ + Ci [q] = i ; \ + } + + // place conj(A(i,j)) or A(i,j) in C(:,k) + #define ASSIGN_CIJ_CONJ_OR_NCONJ(i,j) \ + { \ + Int q = Wj [i]++ ; \ + ASSIGN_CONJ_OR_NCONJ (Cx, Cz, q, Ax, Az, p) ; \ + Ci [q] = j ; \ + } + + if (A->stype > 0) + { + + //---------------------------------------------------------------------- + // A is symmetric upper + //---------------------------------------------------------------------- + + for (Int j = 0 ; j < n ; j++) + { + Int p = Ap [j] ; + Int pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; + for ( ; p < pend ; p++) + { + // get A(i,j) + Int i = Ai [p] ; + // skip entries in strictly lower part + if (i > j) continue ; + if (i == j) + { + // place diagonal entry A(i,i) in C(:,i) + if (keep_diag) ASSIGN_CIJ (i,i) ; + } + else + { + // place A(i,j) in C(:,j) and conj(A(i,j)) in C(:,i) + ASSIGN_CIJ (i,j) ; + ASSIGN_CIJ_CONJ_OR_NCONJ (i,j) ; + } + } + } + + } + else // A->stype < 0 + { + + //---------------------------------------------------------------------- + // A is symmetric lower + //---------------------------------------------------------------------- + + for (Int j = 0 ; j < n ; j++) + { + Int p = Ap [j] ; + Int pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; + for ( ; p < pend ; p++) + { + // get A(i,j) + Int i = Ai [p] ; + // skip entries in strictly upper part + if (i < j) continue ; + if (i == j) + { + // place diagonal entry A(i,i) in C(:,i) + if (keep_diag) ASSIGN_CIJ (i,i) ; + } + else + { + // place A(i,j) in C(:,j) and conj(A(i,j)) in C(:,i) + ASSIGN_CIJ (i,j) ; + ASSIGN_CIJ_CONJ_OR_NCONJ (i,j) ; + } + } + } + } +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX +#undef NCONJUGATE + diff --git a/CHOLMOD/Utility/t_cholmod_cumsum.c b/CHOLMOD/Utility/t_cholmod_cumsum.c new file mode 100644 index 000000000..61ce582fe --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_cumsum.c @@ -0,0 +1,46 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_cumsum: cumulative sum +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Cp [0:n] = cumulative sum of Cnz [0:n-1]. Returns the total sum, or -1 +// if integer overflow has occurred. + +// Cp [0] = 0 +// Cp [1] = Cnz [0] +// Cp [2] = Cnz [0] + Cnz [1] ; +// Cp [3] = Cnz [0] + Cnz [1] + Cnz [2] ; +// ... +// Cp [k] = sum (Cnz [0 ... k-1]) +// ... +// Cp [n] = sum (Cnz [0 ... n-1]) + +#include "cholmod_internal.h" + +int64_t CHOLMOD(cumsum) +( + Int *Cp, // size n+1, output array, the cumsum of Cnz + Int *Cnz, // size n, input array + size_t n // size of Cp and Cnz +) +{ + Int p = 0 ; + for (Int k = 0 ; k < n ; k++) + { + Cp [k] = p ; + p += Cnz [k] ; + if (p < 0) + { + // integer overflow has occured + return (EMPTY) ; + } + } + Cp [n] = p ; + return ((int64_t) p) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_defaults.c b/CHOLMOD/Utility/t_cholmod_defaults.c new file mode 100644 index 000000000..a6525a568 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_defaults.c @@ -0,0 +1,132 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_defaults: set CHOLMOD defaults +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +// Sets all CHOLMOD parameters to their default values. + +int CHOLMOD(defaults) (cholmod_common *Common) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + + //-------------------------------------------------------------------------- + // set defaults + //-------------------------------------------------------------------------- + + Common->dbound = 0.0 ; // bound D for LDL' (double case) + Common->sbound = 0.0 ; // bound D for LDL' (single case) + Common->grow0 = 1.2 ; // how to grow L for simplicial method + Common->grow1 = 1.2 ; + Common->grow2 = 5 ; + Common->maxrank = 8 ; // max rank for update/downdate + + Common->final_asis = TRUE ; // leave L as-is + Common->final_super = TRUE ; // leave L supernodal + Common->final_ll = FALSE ; // leave factorization as LDL' + Common->final_pack = TRUE ; // pack columns when done + Common->final_monotonic = TRUE ; // sort columns when done + Common->final_resymbol = FALSE ; // do not resymbol when done + + Common->supernodal = CHOLMOD_AUTO ; // select supernodal automatically + Common->supernodal_switch = 40 ; // how to select super vs simpicial + + Common->prefer_zomplex = FALSE ; // use complex, not zomplex + Common->prefer_upper = TRUE ; // sym case: use upper not lower + Common->prefer_binary = FALSE ; // use 1's when converting from pattern + Common->quick_return_if_not_posdef = FALSE ; // return early if not posdef + + Common->metis_memory = 0.0 ; // metis memory control + Common->metis_nswitch = 3000 ; + Common->metis_dswitch = 0.66 ; + + Common->nrelax [0] = 4 ; // supernodal relaxation parameters + Common->nrelax [1] = 16 ; + Common->nrelax [2] = 48 ; + Common->zrelax [0] = 0.8 ; + Common->zrelax [1] = 0.1 ; + Common->zrelax [2] = 0.05 ; + + Common->print = 3 ; // print control + Common->precise = FALSE ; // print 5 digits + + //-------------------------------------------------------------------------- + // ordering methods + //-------------------------------------------------------------------------- + + Common->nmethods = 0 ; // use default strategy + Common->default_nesdis = FALSE ; // use METIS not NESDIS + Common->current = 0 ; // method being evaluated + Common->selected = EMPTY ; // final method chosen + Common->postorder = TRUE ; // use weighted postordering + + // defaults for all methods (revised below) + for (int i = 0 ; i <= CHOLMOD_MAXMETHODS ; i++) + { + Common->method [i].ordering = CHOLMOD_AMD ; // use AMD + Common->method [i].fl = EMPTY ; // no flop counts yet + Common->method [i].lnz = EMPTY ; // no lnz counts yet + Common->method [i].prune_dense = 10.0 ; // dense row/col parameter + Common->method [i].prune_dense2 = -1 ; // dense row/col parameter + Common->method [i].aggressive = TRUE ; // aggressive absorption + Common->method [i].order_for_lu = FALSE ; // order for chol, not lu + Common->method [i].nd_small = 200 ; // nesdis: small graph + Common->method [i].nd_compress = TRUE ; // nesdis: compression + Common->method [i].nd_camd = 1 ; // nesdis: use CAMD + Common->method [i].nd_components = FALSE ; // nesdis: use components + Common->method [i].nd_oksep = 1.0 ; // nesdis: for good sep + } + + // define the 9 methods: + // (0) given (skipped if no user permutation) + // (1) amd + // (2) metis + // (3) nesdis with defaults + // (4) natural + // (5) nesdis: stop at subgraphs of 20000 nodes + // (6) nesdis: stop at subgraphs of 4 nodes, do not use CAMD + // (7) nesdis: no pruning on of dense rows/cols + // (8) colamd + + Common->method [0].ordering = CHOLMOD_GIVEN ; + Common->method [2].ordering = CHOLMOD_METIS ; + Common->method [3].ordering = CHOLMOD_NESDIS ; + Common->method [4].ordering = CHOLMOD_NATURAL ; + Common->method [5].ordering = CHOLMOD_NESDIS ; + Common->method [5].nd_small = 20000 ; + Common->method [6].ordering = CHOLMOD_NESDIS ; + Common->method [6].nd_small = 4 ; + Common->method [6].nd_camd = 0 ; + Common->method [7].ordering = CHOLMOD_NESDIS ; + Common->method [7].prune_dense = -1. ; + Common->method [8].ordering = CHOLMOD_COLAMD ; + + //-------------------------------------------------------------------------- + // GPU + //-------------------------------------------------------------------------- + + #if defined ( CHOLMOD_INT64 ) + // only use the GPU for the int64 version + Common->useGPU = EMPTY ; + #else + Common->useGPU = 0 ; + #endif + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_dense_nnz.c b/CHOLMOD/Utility/t_cholmod_dense_nnz.c new file mode 100644 index 000000000..cc48defd7 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_dense_nnz.c @@ -0,0 +1,95 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_dense_nnz: # of nonzeros in a dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Returns the # of nonzero entries in a dense matrix. + +#include "cholmod_internal.h" + +//------------------------------------------------------------------------------ +// t_cholmod_dense_nnz_worker template +//------------------------------------------------------------------------------ + +#define DOUBLE +#define REAL +#include "t_cholmod_dense_nnz_worker.c" +#define COMPLEX +#include "t_cholmod_dense_nnz_worker.c" +#define ZOMPLEX +#include "t_cholmod_dense_nnz_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_dense_nnz_worker.c" +#define COMPLEX +#include "t_cholmod_dense_nnz_worker.c" +#define ZOMPLEX +#include "t_cholmod_dense_nnz_worker.c" + +//------------------------------------------------------------------------------ +// cholmod_dense_nnz +//------------------------------------------------------------------------------ + +int64_t CHOLMOD(dense_nnz) // return # of entries in the dense matrix +( + cholmod_dense *X, // input matrix + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (EMPTY) ; + RETURN_IF_DENSE_MATRIX_INVALID (X, EMPTY) ; + Common->status = CHOLMOD_OK ; + ASSERT (CHOLMOD(dump_dense) (X, "dense_nnz:X", Common) >= 0) ; + + //-------------------------------------------------------------------------- + // count the # of nonzero entries in X + //-------------------------------------------------------------------------- + + int xnz = 0 ; + switch ((X->xtype + X->dtype) % 8) + { + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + xnz = r_s_cholmod_dense_nnz_worker (X) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + xnz = c_s_cholmod_dense_nnz_worker (X) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + xnz = z_s_cholmod_dense_nnz_worker (X) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + xnz = r_cholmod_dense_nnz_worker (X) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + xnz = c_cholmod_dense_nnz_worker (X) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + xnz = z_cholmod_dense_nnz_worker (X) ; + break ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (xnz) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_dense_nnz_worker.c b/CHOLMOD/Utility/t_cholmod_dense_nnz_worker.c new file mode 100644 index 000000000..433834253 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_dense_nnz_worker.c @@ -0,0 +1,54 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_dense_nnz: # of nonzeros in a dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +static int64_t TEMPLATE (cholmod_dense_nnz_worker) +( + cholmod_dense *X // input dense matrix +) +{ + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Real *Xx = (Real *) X->x ; + Real *Xz = (Real *) X->z ; + + Int nrow = (Int) X->nrow ; + Int ncol = (Int) X->ncol ; + Int d = (Int) X->d ; + + //-------------------------------------------------------------------------- + // count # of nonzeros in X + //-------------------------------------------------------------------------- + + int64_t xnz = 0 ; + for (Int j = 0, jx = 0 ; j < ncol ; j++, jx += d) + { + for (Int p = jx ; p < jx + nrow ; p++) + { + xnz += ENTRY_IS_NONZERO (Xx, Xz, p) ; + } + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (xnz) ; +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_dense_to_sparse.c b/CHOLMOD/Utility/t_cholmod_dense_to_sparse.c new file mode 100644 index 000000000..03267f384 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_dense_to_sparse.c @@ -0,0 +1,116 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_dense_to_sparse: convert a dense matrix to sparse +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Converts a dense matrix X (as input) to a new sparse matrix C (as output). +// The xtype and dtype are preserved, except if values is false in which case +// C is returned as a pattern sparse matrix. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_sparse) (&C, Common) ; \ + return (NULL) ; \ + } + +//------------------------------------------------------------------------------ +// t_cholmod_dense_to_sparse_worker template +//------------------------------------------------------------------------------ + +#define DOUBLE +#define REAL +#include "t_cholmod_dense_to_sparse_worker.c" +#define COMPLEX +#include "t_cholmod_dense_to_sparse_worker.c" +#define ZOMPLEX +#include "t_cholmod_dense_to_sparse_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_dense_to_sparse_worker.c" +#define COMPLEX +#include "t_cholmod_dense_to_sparse_worker.c" +#define ZOMPLEX +#include "t_cholmod_dense_to_sparse_worker.c" + +//------------------------------------------------------------------------------ +// cholmod_dense_to_sparse +//------------------------------------------------------------------------------ + +cholmod_sparse *CHOLMOD(dense_to_sparse) // return a sparse matrix C +( + cholmod_dense *X, // input matrix + int values, // if true, copy the values; if false, C is pattern + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + RETURN_IF_DENSE_MATRIX_INVALID (X, NULL) ; + Common->status = CHOLMOD_OK ; + ASSERT (CHOLMOD(dump_dense) (X, "dense_to_sparse:X", Common) >= 0) ; + + //-------------------------------------------------------------------------- + // allocate the sparse matrix result C + //-------------------------------------------------------------------------- + + int cnz = CHOLMOD(dense_nnz) (X, Common) ; + int cxtype = values ? X->xtype : CHOLMOD_PATTERN ; + cholmod_sparse *C = CHOLMOD(allocate_sparse) (X->nrow, X->ncol, cnz, + /* C is sorted: */ TRUE, /* C is packed: */ TRUE, /* C->stype: */ 0, + cxtype + X->dtype, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // copy the nonzeros (or just their pattern) from X into C + //-------------------------------------------------------------------------- + + switch ((X->xtype + X->dtype) % 8) + { + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_dense_to_sparse_worker (C, X) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_dense_to_sparse_worker (C, X) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_dense_to_sparse_worker (C, X) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_dense_to_sparse_worker (C, X) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_dense_to_sparse_worker (C, X) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_dense_to_sparse_worker (C, X) ; + break ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (CHOLMOD(dump_sparse) (C, "sparse_to_dense:C", Common) >= 0) ; + return (C) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_dense_to_sparse_worker.c b/CHOLMOD/Utility/t_cholmod_dense_to_sparse_worker.c new file mode 100644 index 000000000..788818f0d --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_dense_to_sparse_worker.c @@ -0,0 +1,112 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_dense_to_sparse_worker: dense to sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_dense_to_sparse_worker) +( + cholmod_sparse *C, // output sparse matrix, already allocated + cholmod_dense *X // input dense matrix +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (X->nrow == C->nrow) ; + ASSERT (X->ncol == C->ncol) ; + ASSERT (X->d >= X->nrow) ; + ASSERT (X->dtype == C->dtype) ; + ASSERT (C->packed) ; + ASSERT (C->sorted) ; + ASSERT (C->stype == 0) ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Real *Xx = (Real *) X->x ; + Real *Xz = (Real *) X->z ; + Int nrow = X->nrow ; + Int ncol = X->ncol ; + Int d = X->d ; + + Int *Cp = (Int *) C->p ; + Int *Ci = (Int *) C->i ; + Real *Cx = (Real *) C->x ; + Real *Cz = (Real *) C->z ; + bool pattern = (C->xtype == CHOLMOD_PATTERN) ; + + //-------------------------------------------------------------------------- + // copy the dense matrix into the sparse matrix C + //-------------------------------------------------------------------------- + + Int p = 0 ; + + if (pattern) + { + + //---------------------------------------------------------------------- + // copy just the pattern of the nonzeros of X into C + //---------------------------------------------------------------------- + + for (Int j = 0, jx = 0 ; j < ncol ; j++, jx += d) + { + // log the start of C(:,j) + Cp [j] = p ; + // find the pattern of nonzeros in X(:,j) + for (Int i = 0, q = jx ; i < nrow ; i++, q++) + { + if (ENTRY_IS_NONZERO (Xx, Xz, q)) + { + Ci [p++] = i ; + } + } + } + + } + else + { + + //---------------------------------------------------------------------- + // copy the pattern and values of nonzeros in X into C + //---------------------------------------------------------------------- + + ASSERT (C->xtype == X->xtype) ; + + for (Int j = 0, jx = 0 ; j < ncol ; j++, jx += d) + { + // log the start of C(:,j) + Cp [j] = p ; + // find the pattern and values of nonzeros in X(:,j) + for (Int i = 0, q = jx ; i < nrow ; i++, q++) + { + if (ENTRY_IS_NONZERO (Xx, Xz, q)) + { + ASSIGN (Cx, Cz, p, Xx, Xz, q) ; + Ci [p++] = i ; + } + } + } + } + + //-------------------------------------------------------------------------- + // log the end of the last column of C + //-------------------------------------------------------------------------- + + Cp [ncol] = p ; +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_ensure_dense.c b/CHOLMOD/Utility/t_cholmod_ensure_dense.c new file mode 100644 index 000000000..e375e8f29 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_ensure_dense.c @@ -0,0 +1,100 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_ensure_dense: ensure dense matrix has a given size +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Ensure a dense matrix has a given size, xtype, and dtype. If not, it is +// freed and reallocated. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_dense) (X, Common) ; \ + return (NULL) ; \ + } + +cholmod_dense *CHOLMOD(ensure_dense) +( + cholmod_dense **X, // matrix to resize as needed (*X may be NULL) + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t d, // leading dimension + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX) + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + RETURN_IF_NULL (X, NULL) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // get the xtype and dtype + //-------------------------------------------------------------------------- + + int xtype = xdtype & 3 ; // real, complex, or zomplex (not pattern) + int dtype = xdtype & 4 ; // double or single + + if (xtype == CHOLMOD_PATTERN) + { + ERROR (CHOLMOD_INVALID, "xtype invalid") ; + return (NULL) ; + } + + //-------------------------------------------------------------------------- + // get the dimensions + //-------------------------------------------------------------------------- + + d = MAX (d, nrow) ; // leading dimension d must be >= nrow + int ok = TRUE ; + size_t nzmax_required = CHOLMOD(mult_size_t) (d, ncol, &ok) ; + if (!ok) + { + ERROR (CHOLMOD_INVALID, "problem too large") ; + return (NULL) ; + } + + //-------------------------------------------------------------------------- + // reshape or reallocate the matrix + //-------------------------------------------------------------------------- + + if ((*X) != NULL && nzmax_required <= (*X)->nzmax && xtype == (*X)->xtype + && dtype == (*X)->dtype) + { + // The required total size (nzmax_required) is ok, but the dimensions + // might not be. This allows an n-by-m matrix to be reconfigured in + // O(1) time into an m-by-n matrix. X->nzmax is not changed, so a + // matrix can be reduced in size in O(1) time, and then enlarged again + // back to the original size, also in O(1) time. + (*X)->nrow = nrow ; + (*X)->ncol = ncol ; + (*X)->d = d ; + RETURN_IF_DENSE_MATRIX_INVALID (*X, NULL) ; + } + else + { + // free the matrix and reallocate it with the right properties + CHOLMOD(free_dense) (X, Common) ; + (*X) = CHOLMOD(allocate_dense) (nrow, ncol, d, xdtype, Common) ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (*X) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_error.c b/CHOLMOD/Utility/t_cholmod_error.c new file mode 100644 index 000000000..4d27b980c --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_error.c @@ -0,0 +1,99 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_error: CHOLMOD error handling +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +//------------------------------------------------------------------------------ +// MESSAGE macro: print a message using the given printf function pointer +//------------------------------------------------------------------------------ + +#define MESSAGE(kind) \ +{ \ + printf_function ("CHOLMOD " kind ":") ; \ + if (message != NULL) printf_function (" %s.", message) ; \ + if (file != NULL) printf_function (" file: %s", file) ; \ + if (line > 0 ) printf_function (" line: %d", line) ; \ + printf_function ("\n") ; \ + fflush (stdout) ; \ + fflush (stderr) ; \ +} + +//------------------------------------------------------------------------------ +// cholmod_error +//------------------------------------------------------------------------------ + +int CHOLMOD(error) +( + int status, // Common->status + const char *file, // source file where error occurred + int line, // line number where error occurred + const char *message, // error message to print + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + + //-------------------------------------------------------------------------- + // set the error status + //-------------------------------------------------------------------------- + + Common->status = status ; + + //-------------------------------------------------------------------------- + // handle the error, unless we're inside a CHOLMOD try/catch block + //-------------------------------------------------------------------------- + + if (!(Common->try_catch)) + { + + //---------------------------------------------------------------------- + // print the error message, if permitted + //---------------------------------------------------------------------- + + #ifndef NPRINT + int (*printf_function) (const char *, ...) ; + printf_function = SuiteSparse_config_printf_func_get ( ) ; + if (printf_function != NULL) + { + if (status > 0 && Common->print > 1) + { + // print a warning message + MESSAGE ("warning") ; + } + else if (Common->print > 0) + { + // print an error message + MESSAGE ("error") ; + } + } + #endif + + //---------------------------------------------------------------------- + // call the user error handler, if present + //---------------------------------------------------------------------- + + if (Common->error_handler != NULL) + { + Common->error_handler (status, file, line, message) ; + } + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_eye.c b/CHOLMOD/Utility/t_cholmod_eye.c new file mode 100644 index 000000000..9886a4866 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_eye.c @@ -0,0 +1,111 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_eye: dense identity matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Create a dense identity matrix, possibly rectangular, of any xtype or +// dtype. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_dense) (&X, Common) ; \ + return (NULL) ; \ + } + +//------------------------------------------------------------------------------ +// t_cholmod_eye_worker template +//------------------------------------------------------------------------------ + +#define DOUBLE +#define REAL +#include "t_cholmod_eye_worker.c" +#define COMPLEX +#include "t_cholmod_eye_worker.c" +#define ZOMPLEX +#include "t_cholmod_eye_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_eye_worker.c" +#define COMPLEX +#include "t_cholmod_eye_worker.c" +#define ZOMPLEX +#include "t_cholmod_eye_worker.c" + +//------------------------------------------------------------------------------ +// cholmod_eye: create a dense identity matrix +//------------------------------------------------------------------------------ + +cholmod_dense *CHOLMOD(eye) // return a dense identity matrix +( + size_t nrow, // # of rows + size_t ncol, // # of columns + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (_REAL, _COMPLEX, or _ZOMPLEX) + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // allocate the matrix and set it to all zero + //-------------------------------------------------------------------------- + + cholmod_dense *X = CHOLMOD(zeros) (nrow, ncol, xdtype, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // fill the matrix with all 1's on the diagonal + //-------------------------------------------------------------------------- + + switch (xdtype % 8) + { + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_eye_worker (X) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_eye_worker (X) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_eye_worker (X) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_eye_worker (X) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_eye_worker (X) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_eye_worker (X) ; + break ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (CHOLMOD(dump_dense) (X, "eye:X", Common) >= 0) ; + return (X) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_eye_worker.c b/CHOLMOD/Utility/t_cholmod_eye_worker.c new file mode 100644 index 000000000..4c66dcc4f --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_eye_worker.c @@ -0,0 +1,44 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_eye_worker: dense identity matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_eye_worker) +( + cholmod_dense *X +) +{ + + //-------------------------------------------------------------------------- + // fill the matrix with all 1's on the diagonal + //-------------------------------------------------------------------------- + + Real *Xx = (Real *) X->x ; + Real *Xz = (Real *) X->z ; + + Int nrow = (Int) X->nrow ; + Int ncol = (Int) X->ncol ; + Int n = MIN (nrow, ncol) ; + + Real onex [2] = {1,0} ; + Real onez [1] = {0} ; + + for (Int k = 0 ; k < n ; k++) + { + // X(k,k) = 1 + ASSIGN (Xx, Xz, k + k*nrow, onex, onez, 0) ; + } +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_factor_to_sparse.c b/CHOLMOD/Utility/t_cholmod_factor_to_sparse.c new file mode 100644 index 000000000..df786af4d --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_factor_to_sparse.c @@ -0,0 +1,98 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_factor_to_sparse: convert factor to sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Creates a sparse matrix A from a factor L. The contents of L are +// transferred into A, and L is returned as a simplicial symbolic factor. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_sparse) (&A, Common) ; \ + return (NULL) ; \ + } + +cholmod_sparse *CHOLMOD(factor_to_sparse) +( + cholmod_factor *L, // input: factor to convert; output: L is converted + // to a simplicial symbolic factor + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + RETURN_IF_FACTOR_INVALID (L, NULL) ; + Common->status = CHOLMOD_OK ; + + DEBUG (CHOLMOD(dump_factor) (L, "factor_to_sparse:L input", Common)) ; + + if (L->xtype == CHOLMOD_PATTERN) + { + ERROR (CHOLMOD_INVALID, "L must be numerical on input") ; + return (NULL) ; + } + + cholmod_sparse *A = NULL ; + + //-------------------------------------------------------------------------- + // convert L in place + //-------------------------------------------------------------------------- + + CHOLMOD(change_factor) (L->xtype, L->is_ll, + /* L becomes simplicial: */ FALSE, + /* L becomes packed: */ TRUE, + /* L becomes monotonic: */ TRUE, L, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // allocate the sparse matrix A + //-------------------------------------------------------------------------- + + A = CHOLMOD(calloc) (1, sizeof (cholmod_sparse), Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // move the contents of L into A, and make L pattern + //-------------------------------------------------------------------------- + + A->nrow = L->n ; + A->ncol = L->n ; + A->p = L->p ; L->p = NULL ; + A->i = L->i ; L->i = NULL ; + A->x = L->x ; L->x = NULL ; + A->z = L->z ; L->z = NULL ; + + A->stype = 0 ; + A->itype = L->itype ; + A->xtype = L->xtype ; L->xtype = CHOLMOD_PATTERN ; + A->dtype = L->dtype ; + + A->sorted = TRUE ; + A->packed = TRUE ; + A->nzmax = L->nzmax ; + + CHOLMOD(change_factor) (CHOLMOD_PATTERN, FALSE, FALSE, TRUE, TRUE, L, + Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (CHOLMOD(dump_sparse) (A, "factor to sparse:A", Common) >= 0) ; + DEBUG (CHOLMOD(dump_factor) (L, "factor_to_sparse:L input", Common)) ; + return (A) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_finish.c b/CHOLMOD/Utility/t_cholmod_finish.c new file mode 100644 index 000000000..596f56683 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_finish.c @@ -0,0 +1,22 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_finish: finish CHOLMOD (int32/int64 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +// cholmod_start or cholmod_l_start must be called once prior to calling any +// other CHOLMOD method. It contains workspace that must be freed by +// cholmod_finish or cholmod_l_finish (which is just another name for +// cholmod_free_work or cholmod_l_free_work, respetively), + +int CHOLMOD(finish) (cholmod_common *Common) +{ + return (CHOLMOD(free_work) (Common)) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_free.c b/CHOLMOD/Utility/t_cholmod_free.c new file mode 100644 index 000000000..df473ee85 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_free.c @@ -0,0 +1,57 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_free: free (int64/int32) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +void *CHOLMOD(free) // returns NULL to simplify its usage +( + size_t n, // number of items + size_t size, // size of each item + void *p, // memory to free + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + if (p == NULL) return (NULL) ; // nothing to do (not an error) + + #ifndef NDEBUG + size_t size2 = CM_memtable_size (p) ; + ASSERT (n * size == size2) ; + #endif + + //-------------------------------------------------------------------------- + // free memory + //-------------------------------------------------------------------------- + + SuiteSparse_free (p) ; + + //-------------------------------------------------------------------------- + // log memory usage and return result + //-------------------------------------------------------------------------- + + Common->memory_inuse -= (n * size) ; + Common->malloc_count-- ; + + PRINTM (("cholmod_free %p %g cnt: %g inuse %g\n", + p, (double) n*size, (double) Common->malloc_count, + (double) Common->memory_inuse)) ; + + #ifndef NDEBUG + CM_memtable_remove (p) ; + #endif + + return (NULL) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_free_dense.c b/CHOLMOD/Utility/t_cholmod_free_dense.c new file mode 100644 index 000000000..f682f47b4 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_free_dense.c @@ -0,0 +1,55 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_free_dense: free dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +int CHOLMOD(free_dense) +( + cholmod_dense **X, // handle of dense matrix to free + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + if (X == NULL || (*X) == NULL) + { + // X is already freed; nothing to do + return (TRUE) ; + } + + //-------------------------------------------------------------------------- + // get the sizes of the entries + //-------------------------------------------------------------------------- + + size_t e = ((*X)->dtype == CHOLMOD_SINGLE) ? + sizeof (float) : sizeof (double) ; + size_t ex = e * (((*X)->xtype == CHOLMOD_COMPLEX) ? 2 : 1) ; + size_t ez = e * (((*X)->xtype == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + size_t nzmax = (*X)->nzmax ; + + //-------------------------------------------------------------------------- + // free the two arrays + //-------------------------------------------------------------------------- + + CHOLMOD(free) (nzmax, ex, (*X)->x, Common) ; + CHOLMOD(free) (nzmax, ez, (*X)->z, Common) ; + + //-------------------------------------------------------------------------- + // free the header and return result + //-------------------------------------------------------------------------- + + (*X) = CHOLMOD(free) (1, sizeof (cholmod_dense), (*X), Common) ; + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_free_factor.c b/CHOLMOD/Utility/t_cholmod_free_factor.c new file mode 100644 index 000000000..f085b4d8b --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_free_factor.c @@ -0,0 +1,132 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_free_factor: free a sparse factorization +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +//------------------------------------------------------------------------------ +// cholmod_to_simplicial_sym +//------------------------------------------------------------------------------ + +// L is converted into a valid simplicial symbolic object, containing just +// L->Perm and L->ColCount. This method is used by cholmod_change_factor. L +// itself is not freed. This method is for internal use, not for the end-user +// (who should use cholmod_change_factor to access this functionality). + +void CHOLMOD(to_simplicial_sym) +( + cholmod_factor *L, // sparse factorization to modify + int to_ll, // change L to hold a LL' or LDL' factorization + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (Common != NULL) ; + ASSERT (L != NULL) ; + + //-------------------------------------------------------------------------- + // get the sizes of the entries + //-------------------------------------------------------------------------- + + size_t ei = sizeof (Int) ; + size_t e = (L->dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + size_t ex = e * ((L->xtype == CHOLMOD_PATTERN) ? 0 : + ((L->xtype == CHOLMOD_COMPLEX) ? 2 : 1)) ; + size_t ez = e * ((L->xtype == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + + size_t nzmax = L->nzmax ; + size_t n = L->n ; + size_t s = L->nsuper + 1 ; + size_t xs = (L->is_super) ? L->xsize : nzmax ; + size_t ss = (L->ssize) ; + + //-------------------------------------------------------------------------- + // free the components of L + //-------------------------------------------------------------------------- + + // symbolic part of L (except for L->Perm and L->ColCount) + L->IPerm = CHOLMOD(free) (n, ei, L->IPerm, Common) ; + + // simplicial form of L + L->p = CHOLMOD(free) (n+1, ei, L->p, Common) ; + L->i = CHOLMOD(free) (nzmax, ei, L->i, Common) ; + L->nz = CHOLMOD(free) (n, ei, L->nz, Common) ; + L->next = CHOLMOD(free) (n+2, ei, L->next, Common) ; + L->prev = CHOLMOD(free) (n+2, ei, L->prev, Common) ; + + // supernodal form of L + L->pi = CHOLMOD(free) (s, ei, L->pi, Common) ; + L->px = CHOLMOD(free) (s, ei, L->px, Common) ; + L->super = CHOLMOD(free) (s, ei, L->super, Common) ; + L->s = CHOLMOD(free) (ss, ei, L->s, Common) ; + + // numerical part of L + L->x = CHOLMOD(free) (xs, ex, L->x, Common) ; + L->z = CHOLMOD(free) (xs, ez, L->z, Common) ; + + //-------------------------------------------------------------------------- + // change the header contents to reflect the simplicial symbolic status + //-------------------------------------------------------------------------- + + L->nzmax = 0 ; // no entries + L->is_super = FALSE ; // L is simplicial + L->xtype = CHOLMOD_PATTERN ; // L is symbolic + L->minor = n ; // see cholmod.h + L->is_ll = to_ll ? 1: 0 ; // L represents an LL' or LDL' factorization + L->ssize = 0 ; // L->s is not present + L->xsize = 0 ; // L->x is not present + L->nsuper = 0 ; // no supernodes + L->maxesize = 0 ; // no rows in any supernodes + L->maxcsize = 0 ; // largest update matrix is size zero +} + +//------------------------------------------------------------------------------ +// cholmod_free_factor +//------------------------------------------------------------------------------ + +int CHOLMOD(free_factor) +( + cholmod_factor **L, // handle of sparse factorization to free + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + if (L == NULL || (*L) == NULL) + { + // L is already freed; nothing to do + return (TRUE) ; + } + + //-------------------------------------------------------------------------- + // convert L to a simplicial symbolic LL' factorization + //-------------------------------------------------------------------------- + + CHOLMOD(to_simplicial_sym) (*L, 1, Common) ; + + //-------------------------------------------------------------------------- + // free the rest of L and return result + //-------------------------------------------------------------------------- + + size_t n = (*L)->n ; + size_t ei = sizeof (Int) ; + CHOLMOD(free) (n, ei, (*L)->Perm, Common) ; + CHOLMOD(free) (n, ei, (*L)->ColCount, Common) ; + (*L) = CHOLMOD(free) (1, sizeof (cholmod_factor), (*L), Common) ; + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_free_sparse.c b/CHOLMOD/Utility/t_cholmod_free_sparse.c new file mode 100644 index 000000000..2fa15b624 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_free_sparse.c @@ -0,0 +1,62 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_free_sparse: free sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +int CHOLMOD(free_sparse) +( + cholmod_sparse **A, // handle of sparse matrix to free + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + if (A == NULL || (*A) == NULL) + { + // A is already freed; nothing to do + return (TRUE) ; + } + + //-------------------------------------------------------------------------- + // get the sizes of the entries + //-------------------------------------------------------------------------- + + size_t ei = sizeof (Int) ; + size_t e = ((*A)->dtype == CHOLMOD_SINGLE) ? + sizeof (float) : sizeof (double) ; + size_t ex = e * (((*A)->xtype == CHOLMOD_PATTERN) ? 0 : + (((*A)->xtype == CHOLMOD_COMPLEX) ? 2 : 1)) ; + size_t ez = e * (((*A)->xtype == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + + size_t nzmax = (*A)->nzmax ; + size_t ncol = (*A)->ncol ; + + //-------------------------------------------------------------------------- + // free the five arrays + //-------------------------------------------------------------------------- + + CHOLMOD(free) (ncol+1, ei, (*A)->p, Common) ; + CHOLMOD(free) (ncol, ei, (*A)->nz, Common) ; + CHOLMOD(free) (nzmax, ei, (*A)->i, Common) ; + CHOLMOD(free) (nzmax, ex, (*A)->x, Common) ; + CHOLMOD(free) (nzmax, ez, (*A)->z, Common) ; + + //-------------------------------------------------------------------------- + // free the header and return result + //-------------------------------------------------------------------------- + + (*A) = CHOLMOD(free) (1, sizeof (cholmod_sparse), (*A), Common) ; + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_free_triplet.c b/CHOLMOD/Utility/t_cholmod_free_triplet.c new file mode 100644 index 000000000..3783bbd16 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_free_triplet.c @@ -0,0 +1,59 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_free_triplet: free triplet matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +int CHOLMOD(free_triplet) +( + cholmod_triplet **T, // handle of triplet matrix to free + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + if (T == NULL || (*T) == NULL) + { + // T is already freed; nothing to do + return (TRUE) ; + } + + //-------------------------------------------------------------------------- + // get the sizes of the entries + //-------------------------------------------------------------------------- + + size_t ei = sizeof (Int) ; + size_t e = ((*T)->dtype == CHOLMOD_SINGLE) ? + sizeof (float) : sizeof (double) ; + size_t ex = e * (((*T)->xtype == CHOLMOD_PATTERN) ? 0 : + (((*T)->xtype == CHOLMOD_COMPLEX) ? 2 : 1)) ; + size_t ez = e * (((*T)->xtype == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + size_t nz = (*T)->nzmax ; + + //-------------------------------------------------------------------------- + // free the four arrays + //-------------------------------------------------------------------------- + + CHOLMOD(free) (nz, ei, (*T)->i, Common) ; + CHOLMOD(free) (nz, ei, (*T)->j, Common) ; + CHOLMOD(free) (nz, ex, (*T)->x, Common) ; + CHOLMOD(free) (nz, ez, (*T)->z, Common) ; + + //-------------------------------------------------------------------------- + // free the header and return result + //-------------------------------------------------------------------------- + + (*T) = CHOLMOD(free) (1, sizeof (cholmod_triplet), (*T), Common) ; + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_free_work.c b/CHOLMOD/Utility/t_cholmod_free_work.c new file mode 100644 index 000000000..cda854bc2 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_free_work.c @@ -0,0 +1,61 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_free_work: free workspace in Common (int32/64) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +int CHOLMOD(free_work) (cholmod_common *Common) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + + //-------------------------------------------------------------------------- + // free Flag and Head, of size nrow and nrow+1 Ints + //-------------------------------------------------------------------------- + + size_t nrow = Common->nrow ; + Common->Flag = CHOLMOD(free) (nrow, sizeof (Int), Common->Flag, Common) ; + Common->Head = CHOLMOD(free) (nrow+1, sizeof (Int), Common->Head, Common) ; + Common->nrow = 0 ; + + //-------------------------------------------------------------------------- + // free Iwork, of size iworksize Ints + //-------------------------------------------------------------------------- + + Common->Iwork = CHOLMOD(free) (Common->iworksize, + sizeof (Int), Common->Iwork, Common) ; + Common->iworksize = 0 ; + + //-------------------------------------------------------------------------- + // free Xwork, of size xworksize bytes + //-------------------------------------------------------------------------- + + Common->Xwork = CHOLMOD(free) (Common->xworkbytes, sizeof (uint8_t), + Common->Xwork, Common) ; + Common->xworkbytes = 0 ; + + //-------------------------------------------------------------------------- + // free GPU workspace + //-------------------------------------------------------------------------- + + #ifdef SUITESPARSE_CUDA + CHOLMOD(gpu_deallocate) (Common) ; + #endif + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_malloc.c b/CHOLMOD/Utility/t_cholmod_malloc.c new file mode 100644 index 000000000..8c1b7b33f --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_malloc.c @@ -0,0 +1,62 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_malloc: malloc/calloc (int64/int32) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +// This template creates 4 functions: +// cholmod_malloc int32, malloc, using SuiteSparse_malloc +// cholmod_l_malloc int64, malloc, using SuiteSparse_malloc +// cholmod_calloc int32, calloc, using SuiteSparse_calloc +// cholmod_l_calloc int64, calloc, using SuiteSparse_calloc + +void *CHOLMOD_ALLOC_FUNCTION // return pointer to newly allocated memory +( + size_t n, // number of items + size_t size, // size of each item + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + + //-------------------------------------------------------------------------- + // allocate memory + //-------------------------------------------------------------------------- + + void *p = SUITESPARSE_ALLOC_FUNCTION (n, size) ; // malloc or calloc + + //-------------------------------------------------------------------------- + // log memory usage and return result + //-------------------------------------------------------------------------- + + if (p != NULL) + { + // success: log the change in memory usage + Common->memory_inuse += (n * size) ; + Common->memory_usage = MAX (Common->memory_usage, Common->memory_inuse); + Common->malloc_count++ ; + PRINTM (("cholmod_malloc %p %g cnt: %g inuse %g\n", + p, (double) n*size, (double) Common->malloc_count, + (double) Common->memory_inuse)) ; + #ifndef NDEBUG + CM_memtable_add (p, n*size) ; + #endif + } + else + { + ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory") ; + } + return (p) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_maxrank.c b/CHOLMOD/Utility/t_cholmod_maxrank.c new file mode 100644 index 000000000..508232ffe --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_maxrank.c @@ -0,0 +1,44 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_maxrank: find valid value of Common->maxrank +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +// Returns 0 on error, or 2, 4, or 8 otherwise. + +size_t CHOLMOD(maxrank) // return validated Common->maxrank +( + size_t n, // # of rows of L and A + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (0) ; + + //-------------------------------------------------------------------------- + // determine a valid value of maxrank + //-------------------------------------------------------------------------- + + size_t maxrank = Common->maxrank ; + if (n == 0) return (2) ; + + // guard against size_t overflow (very unlikely) + size_t max_maxrank = SIZE_MAX / (n * sizeof (float)) ; + maxrank = MIN (maxrank, max_maxrank) ; + + // maxrank of 2 or less: use 2 + // maxrank of 3 or 4: use 4 + // else use 8 + return ((maxrank <= 2) ? 2 : ((maxrank <= 4) ? 4 : 8)) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_mult_size_t.c b/CHOLMOD/Utility/t_cholmod_mult_size_t.c new file mode 100644 index 000000000..7bf6c70fd --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_mult_size_t.c @@ -0,0 +1,21 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_mult_size_t: multiply two size_t values +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +// multiply two size_t values and safely check for integer overflow + +size_t CHOLMOD(mult_size_t) (size_t a, size_t b, int *ok) +{ + uint64_t x ; + (*ok) = cholmod_mult_uint64_t (&x, (uint64_t) a, (uint64_t) b) ; + return (((*ok) && x <= SIZE_MAX) ? ((size_t) x) : 0) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_nnz.c b/CHOLMOD/Utility/t_cholmod_nnz.c new file mode 100644 index 000000000..d24931dca --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_nnz.c @@ -0,0 +1,54 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_nnz: # of entries in a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// returns the # of entries held in a sparse matrix data structure. If A is +// symmetric and held in either upper/lower form, then only those entries +// in the upper/lower part are counted. + +#include "cholmod_internal.h" + +int64_t CHOLMOD(nnz) // return # of entries in the sparse matrix +( + cholmod_sparse *A, // sparse matrix to query + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (EMPTY) ; + RETURN_IF_SPARSE_MATRIX_INVALID (A, EMPTY) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // get the # of entries + //-------------------------------------------------------------------------- + + if (!(A->packed)) + { + // A is held in unpacked form, so nnz(A) is sum (Anz [0..ncol-1]) + int64_t anz = 0 ; + int64_t ncol = A->ncol ; + Int *Anz = (Int *) A->nz ; + for (int64_t j = 0 ; j < ncol ; j++) + { + anz += (int64_t) Anz [j] ; + } + return (anz) ; + } + else + { + // A is held in packed form, so nnz(A) is just Ap [ncol] + return ((int64_t) ((Int *) A->p) [A->ncol]) ; + } +} + diff --git a/CHOLMOD/Utility/t_cholmod_ones.c b/CHOLMOD/Utility/t_cholmod_ones.c new file mode 100644 index 000000000..d81f4b12b --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_ones.c @@ -0,0 +1,111 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_ones: dense matrix of all ones +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Create a dense matrix with all entries equal to one, of any xtype or dtype. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_dense) (&X, Common) ; \ + return (NULL) ; \ + } + +//------------------------------------------------------------------------------ +// t_cholmod_ones_worker template +//------------------------------------------------------------------------------ + +#define DOUBLE +#define REAL +#include "t_cholmod_ones_worker.c" +#define COMPLEX +#include "t_cholmod_ones_worker.c" +#define ZOMPLEX +#include "t_cholmod_ones_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_ones_worker.c" +#define COMPLEX +#include "t_cholmod_ones_worker.c" +#define ZOMPLEX +#include "t_cholmod_ones_worker.c" + +//------------------------------------------------------------------------------ +// cholmod_ones: create a dense matrix all equal to 1 +//------------------------------------------------------------------------------ + +cholmod_dense *CHOLMOD(ones) +( + size_t nrow, // # of rows + size_t ncol, // # of columns + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (_REAL, _COMPLEX, or _ZOMPLEX) + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // allocate the matrix + //-------------------------------------------------------------------------- + + cholmod_dense *X = CHOLMOD(allocate_dense) (nrow, ncol, nrow, xdtype, + Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // fill the matrix with all 1's + //-------------------------------------------------------------------------- + + switch (xdtype % 8) + { + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_ones_worker (X) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_ones_worker (X) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_ones_worker (X) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_ones_worker (X) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_ones_worker (X) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_ones_worker (X) ; + break ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (CHOLMOD(dump_dense) (X, "ones:X", Common) >= 0) ; + return (X) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_ones_worker.c b/CHOLMOD/Utility/t_cholmod_ones_worker.c new file mode 100644 index 000000000..50a8ebfcd --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_ones_worker.c @@ -0,0 +1,41 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_ones_worker: dense matrix of all ones +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_ones_worker) +( + cholmod_dense *X +) +{ + + //-------------------------------------------------------------------------- + // fill the matrix with all 1's + //-------------------------------------------------------------------------- + + Real *Xx = (Real *) X->x ; + Real *Xz = (Real *) X->z ; + size_t nzmax = X->nzmax ; + + Real onex [2] = {1,0} ; + Real onez [1] = {0} ; + + for (Int k = 0 ; k < nzmax ; k++) + { + // X(k) = 1 + ASSIGN (Xx, Xz, k, onex, onez, 0) ; + } +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_pack_factor.c b/CHOLMOD/Utility/t_cholmod_pack_factor.c new file mode 100644 index 000000000..244d57c11 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_pack_factor.c @@ -0,0 +1,118 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_pack_factor: pack a simplicial factorization +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// The columns of simplicial factor L can have gaps between them, with empty +// space. This method removes the empty space, leaving all the empty space at +// the tail end of L->i and L->x. Each column of L is reduced in is size so +// that it has at most Common->grow2 empty space at the end of each column. + +// L must be simplicial and numerical (not symbolic). If L is supernodal, or +// symbolic, this method does nothing. + +// This method can be followed by a call to cholmod_reallocate_factor, to +// reduce the size of L->i and L->x. Or, the space can be left to accomodate +// future growth from updates/downdates. + +// The columns of L are not made to appear in monotonic order. For that, +// use cholmod_change_factor which can both pack the columns and make them +// monotonic. + +#include "cholmod_internal.h" + +//------------------------------------------------------------------------------ +// t_cholmod_pack_factor_worker template +//------------------------------------------------------------------------------ + +#define DOUBLE +#define REAL +#include "t_cholmod_pack_factor_worker.c" +#define COMPLEX +#include "t_cholmod_pack_factor_worker.c" +#define ZOMPLEX +#include "t_cholmod_pack_factor_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_pack_factor_worker.c" +#define COMPLEX +#include "t_cholmod_pack_factor_worker.c" +#define ZOMPLEX +#include "t_cholmod_pack_factor_worker.c" + +//------------------------------------------------------------------------------ +// cholmod_pack_factor +//------------------------------------------------------------------------------ + +int CHOLMOD(pack_factor) +( + cholmod_factor *L, // factor to pack + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_FACTOR_INVALID (L, FALSE) ; + Common->status = CHOLMOD_OK ; + + DEBUG (CHOLMOD(dump_factor) (L, "pack:L input", Common)) ; + + if (L->xtype == CHOLMOD_PATTERN || L->is_super) + { + // nothing to do + return (TRUE) ; + } + + //-------------------------------------------------------------------------- + // pack + //-------------------------------------------------------------------------- + + switch ((L->xtype + L->dtype) % 8) + { + default: + break ; + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_pack_factor_worker (L, Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_pack_factor_worker (L, Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_pack_factor_worker (L, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_pack_factor_worker (L, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_pack_factor_worker (L, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_pack_factor_worker (L, Common) ; + break ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + DEBUG (CHOLMOD(dump_factor) (L, "done pack", Common)) ; + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_pack_factor_worker.c b/CHOLMOD/Utility/t_cholmod_pack_factor_worker.c new file mode 100644 index 000000000..f4d5420bc --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_pack_factor_worker.c @@ -0,0 +1,97 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_pack_factor_worker: pack a simplicial factorization +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +//------------------------------------------------------------------------------ +// cholmod_pack_factor_worker +//------------------------------------------------------------------------------ + +static void TEMPLATE (cholmod_pack_factor_worker) +( + cholmod_factor *L, // factor to pack + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int n = L->n ; + Int *Lp = (Int *) L->p ; + Int *Li = (Int *) L->i ; + Real *Lx = (Real *) L->x ; + Real *Lz = (Real *) L->z ; + Int *Lnz = (Int *) L->nz ; + Int *Lnext = (Int *) L->next ; + + Int slack = Common->grow2 ; + + //-------------------------------------------------------------------------- + // pack, traversing the link list of columns of L + //-------------------------------------------------------------------------- + + Int j = Lnext [n+1] ; // first column in the list is Lnext [n+1] + Int pnew = 0 ; // next column can move to pnew + + while (j != n) // j=n is the fictious placeholder at end of list + { + + //---------------------------------------------------------------------- + // get column j, entries currently in Li and Lx [pold...pold+lnzj-1] + //---------------------------------------------------------------------- + + Int pold = Lp [j] ; // start of column j in L->i and L->j + Int lnzj = Lnz [j] ; // # of entries in column j + ASSERT (lnzj > 0) ; + + //---------------------------------------------------------------------- + // pack column j, if possible + //---------------------------------------------------------------------- + + if (pnew < pold) + { + // Li,Lx [pnew...pnew+lnz-1] = Li,Lx [pold...pold+lnz-1] + for (Int k = 0 ; k < lnzj ; k++) + { + // move L(i,j) from position pold+k to position pnew+k + Li [pnew + k] = Li [pold + k] ; + ASSIGN (Lx, Lz, pnew + k, Lx, Lz, pold + k) ; + } + // log the new position of the first entry of L(:,j) + Lp [j] = pnew ; + } + + //---------------------------------------------------------------------- + // add some empty space at the end of column j + //---------------------------------------------------------------------- + + Int desired_space = lnzj + slack ; // add slack space to column j + Int max_space = n - j ; // no need for more than this space + Int total_space = MIN (desired_space, max_space) ; + + //---------------------------------------------------------------------- + // next column will move to position pnew, if possible + //---------------------------------------------------------------------- + + Int jnext = Lnext [j] ; // jnext = next column in the list + Int pnext = Lp [jnext] ; // next column jnext starts here + Int pthis = Lp [j] + total_space ; // one past the end of column j + pnew = MIN (pthis, pnext) ; // next column can move to pnew + j = jnext ; // move to the next column + } +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_ptranspose.c b/CHOLMOD/Utility/t_cholmod_ptranspose.c new file mode 100644 index 000000000..d81663cc0 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_ptranspose.c @@ -0,0 +1,113 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_ptranspose: permuted transpose +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// C = A' or A(p,p)' if A is symmetric. C = A', A(:,f)' or A(p,f)' if A is +// unsymmetric. +// +// workspace: at most nrow+ncol + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_sparse) (&C, Common) ; \ + return (NULL) ; \ + } + +cholmod_sparse *CHOLMOD(ptranspose) +( + cholmod_sparse *A, // input matrix + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // <= 0: pattern (with diag) + Int *Perm, // permutation for C=A(p,f)' or C=A(p,p)', or NULL + Int *fset, // a list of column indices in range 0:A->ncol-1 + size_t fsize, // # of entries in fset + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + RETURN_IF_SPARSE_MATRIX_INVALID (A, NULL) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // count # of entries in C + //-------------------------------------------------------------------------- + + Int cnz = 0 ; + if ((A->stype == 0) && (fset != NULL)) + { + // C = A(p,f)' or A(:,f)' where A is unsymmetric and fset is present + Int ncol = A->ncol ; + if (A->packed) + { + Int *Ap = (Int *) A->p ; + for (Int k = 0 ; k < fsize ; k++) + { + Int j = fset [k] ; + if (j < 0 || j >= ncol) continue ; + cnz += (Ap [j+1] - Ap [j]) ; + } + } + else + { + Int *Anz = (Int *) A->nz ; + for (Int k = 0 ; k < fsize ; k++) + { + Int j = fset [k] ; + if (j < 0 || j >= ncol) continue ; + cnz += Anz [j] ; + } + } + } + else + { + // C = A(p,p)' A is symmetric, or C=A' where A is any matrix + cnz = CHOLMOD(nnz) (A, Common) ; + } + + //-------------------------------------------------------------------------- + // allocate C + //-------------------------------------------------------------------------- + + cholmod_sparse *C = CHOLMOD(allocate_sparse) (A->ncol, A->nrow, cnz, + /* C is sorted: */ TRUE, /* C is packed */ TRUE, + /* C has the opposite stype as A: */ -(A->stype), + ((mode > 0) ? A->xtype : CHOLMOD_PATTERN) + A->dtype, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // construct C + //-------------------------------------------------------------------------- + + if (A->stype != 0) + { + // C = A (p,p)' or A' when A is symmetric (upper or lower) + CHOLMOD(transpose_sym) (A, mode, Perm, C, Common) ; + } + else + { + // C = A (p,f)' or A(:,f)' when A is unsymmetric + CHOLMOD(transpose_unsym) (A, mode, Perm, fset, fsize, C, Common) ; + } + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (C) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_realloc.c b/CHOLMOD/Utility/t_cholmod_realloc.c new file mode 100644 index 000000000..e2cbe5592 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_realloc.c @@ -0,0 +1,80 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_realloc: realloc (int64/int32) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +void *CHOLMOD(realloc) // return newly reallocated block of memory +( + size_t nnew, // # of items in newly reallocate memory + size_t size, // size of each item + void *p, // pointer to memory to reallocate (may be NULL) + size_t *n, // # of items in p on input; nnew on output if success + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + + //-------------------------------------------------------------------------- + // realloc the block + //-------------------------------------------------------------------------- + + int ok ; + bool newly_allocated = (p == NULL) ; + void *pold = p ; + size_t nold = (*n) ; + + p = SuiteSparse_realloc (nnew, *n, size, p, &ok) ; + + //-------------------------------------------------------------------------- + // log memory usage and return result + //-------------------------------------------------------------------------- + + if (ok) + { + // success: log the change in memory usage and update n to new # items + + if (!newly_allocated) + { + PRINTM (("cholmod_free %p %g cnt: %g inuse %g\n", + pold, (double) nold*size, (double) Common->malloc_count-1, + (double) (Common->memory_inuse - nold*size))) ; + #ifndef NDEBUG + size_t size2 = CM_memtable_size (pold) ; + ASSERT (nold * size == size2) ; + CM_memtable_remove (pold) ; + #endif + } + Common->memory_inuse += ((nnew-nold) * size) ; + Common->memory_usage = MAX (Common->memory_usage, Common->memory_inuse); + if (newly_allocated) + { + Common->malloc_count++ ; + } + PRINTM (("cholmod_malloc %p %g cnt: %g inuse %g\n", + p, (double) nnew*size, (double) Common->malloc_count, + (double) Common->memory_inuse)) ; + #ifndef NDEBUG + CM_memtable_add (p, nnew * size) ; + #endif + (*n) = nnew ; + } + else + { + // p is unchanged + ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory") ; + } + return (p) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_realloc_multiple.c b/CHOLMOD/Utility/t_cholmod_realloc_multiple.c new file mode 100644 index 000000000..49f84710d --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_realloc_multiple.c @@ -0,0 +1,130 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_realloc_multiple: multiple realloc (int64/int32) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +int CHOLMOD(realloc_multiple) // returns true if successful, false otherwise +( + size_t nnew, // # of items in newly reallocate memory + int nint, // 0: do not allocate I or J, 1: just I, 2: both I and J + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) + // input/output: + void **I, // integer block of memory (int32_t or int64_t) + void **J, // integer block of memory (int32_t or int64_t) + void **X, // real or complex, double or single, block + void **Z, // zomplex only: double or single block + size_t *n, // current size of I, J, X, and/or Z blocks on input, + // changed to nnew on output, if successful + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + + //-------------------------------------------------------------------------- + // get the xtype and dtype + //-------------------------------------------------------------------------- + + int xtype = xdtype & 3 ; // pattern, real, complex, or zomplex + int dtype = xdtype & 4 ; // double or single + + if (nint < 1 && xtype == CHOLMOD_PATTERN) + { + return (TRUE) ; // nothing to reallocate + } + + //-------------------------------------------------------------------------- + // get the problem size + //-------------------------------------------------------------------------- + + size_t ni = (*n) ; // size of I, if present + size_t nj = (*n) ; // size of J, if present + size_t nx = (*n) ; // size of X, if present + size_t nz = (*n) ; // size of Z, if present + + size_t ei = sizeof (Int) ; + size_t e = (dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + size_t ex = e * ((xtype == CHOLMOD_PATTERN) ? 0 : + ((xtype == CHOLMOD_COMPLEX) ? 2 : 1)) ; + size_t ez = e * ((xtype == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + + if ((nint > 0 && I == NULL) || + (nint > 1 && J == NULL) || + (ex > 0 && X == NULL) || + (ez > 0 && Z == NULL)) + { + if (Common->status != CHOLMOD_OUT_OF_MEMORY) + { + ERROR (CHOLMOD_INVALID, "argument missing") ; + } + return (FALSE) ; + } + + //-------------------------------------------------------------------------- + // reallocate all of the blocks + //-------------------------------------------------------------------------- + + if (nint > 0) (*I) = CHOLMOD(realloc) (nnew, ei, *I, &ni, Common) ; + if (nint > 1) (*J) = CHOLMOD(realloc) (nnew, ei, *J, &nj, Common) ; + if (ex > 0) (*X) = CHOLMOD(realloc) (nnew, ex, *X, &nx, Common) ; + if (ez > 0) (*Z) = CHOLMOD(realloc) (nnew, ez, *Z, &nz, Common) ; + + //-------------------------------------------------------------------------- + // handle any errors + //-------------------------------------------------------------------------- + + if (Common->status < CHOLMOD_OK) + { + if ((*n) == 0) + { + // free all blocks if they were just freshly allocated + if (nint > 0) (*I) = CHOLMOD(free) (ni, ei, *I, Common) ; + if (nint > 1) (*J) = CHOLMOD(free) (nj, ei, *J, Common) ; + if (ex > 0) (*X) = CHOLMOD(free) (nx, ex, *X, Common) ; + if (ez > 0) (*Z) = CHOLMOD(free) (nz, ez, *Z, Common) ; + } + else + { + // resize all blocks to their original size + if (nint > 0) (*I) = CHOLMOD(realloc) ((*n), ei, *I, &ni, Common) ; + if (nint > 1) (*J) = CHOLMOD(realloc) ((*n), ei, *J, &nj, Common) ; + if (ex > 0) (*X) = CHOLMOD(realloc) ((*n), ex, *X, &nx, Common) ; + if (ez > 0) (*Z) = CHOLMOD(realloc) ((*n), ez, *Z, &nz, Common) ; + } + return (FALSE) ; + } + + //-------------------------------------------------------------------------- + // clear the first entry of X and Z + //-------------------------------------------------------------------------- + + if ((*n) == 0) + { + // X and Z have been freshly allocated. Set their first entry to zero, + // so that valgrind doesn't complain about accessing uninitialized + // space in cholmod_*_xtype. + if (*X != NULL && ex > 0) memset (*X, 0, ex) ; + if (*Z != NULL && ez > 0) memset (*Z, 0, ez) ; + } + + //-------------------------------------------------------------------------- + // log the new size and return result + //-------------------------------------------------------------------------- + + (*n) = nnew ; + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_reallocate_column.c b/CHOLMOD/Utility/t_cholmod_reallocate_column.c new file mode 100644 index 000000000..fcbba8cee --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_reallocate_column.c @@ -0,0 +1,207 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_reallocate_column: reallocate a column of a factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Expand the space for a single column L(:,j) of a simplicial factor. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status != CHOLMOD_OK) \ + { \ + /* out of memory; change L to simplicial symbolic */ \ + CHOLMOD(change_factor) (CHOLMOD_PATTERN + L->dtype, L->is_ll, \ + /* make L simplicial: */ FALSE, \ + /* make L packed */ TRUE, \ + /* make L monotonic: */ TRUE, L, Common) ; \ + ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory") ; \ + return (FALSE) ; \ + } + +//------------------------------------------------------------------------------ +// t_cholmod_reallocate_column_worker template +//------------------------------------------------------------------------------ + +#define DOUBLE +#define REAL +#include "t_cholmod_reallocate_column_worker.c" +#define COMPLEX +#include "t_cholmod_reallocate_column_worker.c" +#define ZOMPLEX +#include "t_cholmod_reallocate_column_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_reallocate_column_worker.c" +#define COMPLEX +#include "t_cholmod_reallocate_column_worker.c" +#define ZOMPLEX +#include "t_cholmod_reallocate_column_worker.c" + +//------------------------------------------------------------------------------ +// cholmod_reallocate_column +//------------------------------------------------------------------------------ + +int CHOLMOD(reallocate_column) +( + size_t j, // reallocate L(:,j) + size_t need, // space in L(:,j) for this # of entries + cholmod_factor *L, // L factor modified, L(:,j) resized + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_FACTOR_INVALID (L, FALSE) ; + Common->status = CHOLMOD_OK ; + + DEBUG (CHOLMOD(dump_factor) (L, "realloc col:L input", Common)) ; + + Int n = L->n ; + if (L->xtype == CHOLMOD_PATTERN || L->is_super || j >= n) + { + ERROR (CHOLMOD_INVALID, "L not simplicial or j out of range") ; + return (FALSE) ; + } + + //-------------------------------------------------------------------------- + // ensure need is in range 1:(n-j) and add slack space + //-------------------------------------------------------------------------- + + need = MAX (need, 1) ; + double slack = MAX (Common->grow1, 1.0) * ((double) need) + Common->grow2 ; + slack = MIN (slack, (double) (n-j)) ; + size_t nslack = (size_t) floor (slack) ; + need = MAX (need, slack) ; + need = MAX (need, 1) ; + need = MIN (need, n-j) ; + + //-------------------------------------------------------------------------- + // quick return if L(:,j) already big enough + //-------------------------------------------------------------------------- + + Int *Lp = (Int *) L->p ; + Int *Lnext = (Int *) L->next ; + Int *Lprev = (Int *) L->prev ; + + size_t already_have = ((size_t) Lp [Lnext [j]] - (size_t) Lp [j]) ; + if (already_have >= need) + { + return (TRUE) ; + } + + //-------------------------------------------------------------------------- + // check if enough space at the end of L->i, L->x, and L->z + //-------------------------------------------------------------------------- + + Int tail = n ; + Int new_nzmax_required = need + Lp [tail] ; + if (new_nzmax_required > L->nzmax) + { + + //---------------------------------------------------------------------- + // out of space in L, so grow the entire factor to lnznew space + //---------------------------------------------------------------------- + + double grow0 = Common->grow0 ; + grow0 = (isnan (grow0) || grow0 < 1.2) ? 1.2 : grow0 ; + double xnz = grow0 * (((double) L->nzmax) + ((double) need) + 1) ; + size_t lnznew = (xnz > (double) SIZE_MAX) ? SIZE_MAX : (size_t) xnz ; + + CHOLMOD(reallocate_factor) (lnznew, L, Common) ; + RETURN_IF_ERROR ; + + //---------------------------------------------------------------------- + // count # of times any factor has been reallocated + //---------------------------------------------------------------------- + + Common->nrealloc_factor++ ; + + //---------------------------------------------------------------------- + // repack all columns so each column has some slack spce + //---------------------------------------------------------------------- + + CHOLMOD(pack_factor) (L, Common) ; + RETURN_IF_ERROR ; + } + + //-------------------------------------------------------------------------- + // move j to the end of the list + //-------------------------------------------------------------------------- + + L->is_monotonic = FALSE ; // L is no longer monotonic + Lnext [Lprev [j]] = Lnext [j] ; // remove j from is current place + Lprev [Lnext [j]] = Lprev [j] ; + Lnext [Lprev [tail]] = j ; // place it at the end of the list + Lprev [j] = Lprev [tail] ; + Lnext [j] = tail ; + Lprev [tail] = j ; + + //-------------------------------------------------------------------------- + // add space to L(:,j), now at the end of L + //-------------------------------------------------------------------------- + + Int psrc = Lp [j] ; + Int pdest = Lp [tail] ; + Lp [j] = pdest ; + Lp [tail] += need ; + + //-------------------------------------------------------------------------- + // move L(:,j) to its new space at the end of L + //-------------------------------------------------------------------------- + + switch ((L->xtype + L->dtype) % 8) + { + default: + break ; + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_reallocate_column_worker (L, j, pdest, psrc) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_reallocate_column_worker (L, j, pdest, psrc) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_reallocate_column_worker (L, j, pdest, psrc) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_reallocate_column_worker (L, j, pdest, psrc) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_reallocate_column_worker (L, j, pdest, psrc) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_reallocate_column_worker (L, j, pdest, psrc) ; + break ; + } + + //-------------------------------------------------------------------------- + // count # of times any L(:,j) has been reallocated + //-------------------------------------------------------------------------- + + Common->nrealloc_col++ ; + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + DEBUG (CHOLMOD(dump_factor) (L, "realloc col:L output", Common)) ; + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_reallocate_column_worker.c b/CHOLMOD/Utility/t_cholmod_reallocate_column_worker.c new file mode 100644 index 000000000..b6c5298ab --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_reallocate_column_worker.c @@ -0,0 +1,48 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_reallocate_column_worker +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_reallocate_column_worker) +( + cholmod_factor *L, // L factor modified, L(:,j) resized + Int j, // column L(:,j) to move + Int pdest, // place to move it to + Int psrc // place to move it from +) +{ + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int *Lnz = (Int *) L->nz ; + Int *Li = (Int *) L->i ; + Real *Lx = (Real *) L->x ; + Real *Lz = (Real *) L->z ; + Int len = Lnz [j] ; + + //-------------------------------------------------------------------------- + // move L(:,j) to its new position + //-------------------------------------------------------------------------- + + for (Int k = 0 ; k < len ; k++, pdest++, psrc++) + { + // move L(i,j) from position psrc to position pdest + Li [pdest] = Li [psrc] ; + ASSIGN (Lx, Lz, pdest, Lx, Lz, psrc) ; + } +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_reallocate_factor.c b/CHOLMOD/Utility/t_cholmod_reallocate_factor.c new file mode 100644 index 000000000..aa1ffd458 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_reallocate_factor.c @@ -0,0 +1,55 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_reallocate_factor: reallocate a factor +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Change the max # of nonzeros that can be held in a factor L. +// The factor must be simplicial. + +#include "cholmod_internal.h" + +int CHOLMOD(reallocate_factor) +( + size_t nznew, // new max # of nonzeros the factor matrix can hold + cholmod_factor *L, // factor to reallocate + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_NULL (L, FALSE) ; + RETURN_IF_XTYPE_IS_INVALID (L->xtype, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, + FALSE) ; + if (L->is_super) + { + ERROR (CHOLMOD_INVALID, "L invalid") ; + return (FALSE) ; + } + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // reallocate the sparse matrix + //-------------------------------------------------------------------------- + + nznew = MAX (1, nznew) ; // ensure L can hold at least 1 entry + int nint = 1 ; // reallocate just L->i + + CHOLMOD(realloc_multiple) (nznew, nint, L->xtype + L->dtype, + &(L->i), NULL, &(L->x), &(L->z), &(L->nzmax), Common) ; + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (Common->status == CHOLMOD_OK) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_reallocate_sparse.c b/CHOLMOD/Utility/t_cholmod_reallocate_sparse.c new file mode 100644 index 000000000..df7481451 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_reallocate_sparse.c @@ -0,0 +1,48 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_reallocate_sparse: reallocate sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Change the max # of nonzeros that can be held in a sparse matrix A. + +#include "cholmod_internal.h" + +int CHOLMOD(reallocate_sparse) +( + size_t nznew, // new max # of nonzeros the sparse matrix can hold + cholmod_sparse *A, // sparse matrix to reallocate + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_NULL (A, FALSE) ; + RETURN_IF_XTYPE_IS_INVALID (A->xtype, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, + FALSE) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // reallocate the sparse matrix + //-------------------------------------------------------------------------- + + nznew = MAX (1, nznew) ; // ensure A can hold at least 1 entry + int nint = 1 ; // reallocate just A->i + CHOLMOD(realloc_multiple) (nznew, nint, A->xtype + A->dtype, + &(A->i), NULL, &(A->x), &(A->z), &(A->nzmax), Common) ; + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (Common->status == CHOLMOD_OK) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_reallocate_triplet.c b/CHOLMOD/Utility/t_cholmod_reallocate_triplet.c new file mode 100644 index 000000000..5ffff9edf --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_reallocate_triplet.c @@ -0,0 +1,48 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_reallocate_triplet: reallocate triplet matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Change the max # of nonzeros that can be held in a triplet matrix T. + +#include "cholmod_internal.h" + +int CHOLMOD(reallocate_triplet) +( + size_t nznew, // new max # of nonzeros the triplet matrix can hold + cholmod_triplet *T, // triplet matrix to reallocate + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_NULL (T, FALSE) ; + RETURN_IF_XTYPE_IS_INVALID (T->xtype, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, + FALSE) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // reallocate the triplet matrix + //-------------------------------------------------------------------------- + + nznew = MAX (1, nznew) ; // ensure T can hold at least 1 entry + int nint = 2 ; // reallocate both T->i and T->j + CHOLMOD(realloc_multiple) (nznew, nint, T->xtype + T->dtype, + &(T->i), &(T->j), &(T->x), &(T->z), &(T->nzmax), Common) ; + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + return (Common->status == CHOLMOD_OK) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_score_comp.c b/CHOLMOD/Utility/t_cholmod_score_comp.c new file mode 100644 index 000000000..8f2aaa875 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_score_comp.c @@ -0,0 +1,21 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_score_comp: for sorting supernodes +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +int CHOLMOD(score_comp) +( + struct cholmod_descendant_score_t *i, + struct cholmod_descendant_score_t *j +) +{ + return ((i->score < j->score) ? 1 : -1) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_set_empty.c b/CHOLMOD/Utility/t_cholmod_set_empty.c new file mode 100644 index 000000000..f757f8fc7 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_set_empty.c @@ -0,0 +1,24 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_set_empty: set an Int array to EMPTY +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +void CHOLMOD(set_empty) +( + Int *S, // Int array of size n + size_t n +) +{ + for (size_t k = 0 ; k < n ; k++) + { + S [k] = EMPTY ; + } +} + diff --git a/CHOLMOD/Utility/t_cholmod_sort.c b/CHOLMOD/Utility/t_cholmod_sort.c new file mode 100644 index 000000000..9fe34a914 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_sort.c @@ -0,0 +1,132 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_sort: sort a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Sorts the entries in each column of a sparse matrix. + +#include "cholmod_internal.h" + +//------------------------------------------------------------------------------ +// random number generator for cm_qsort +//------------------------------------------------------------------------------ + +// return a random uint64_t, in range 0 to 2^60 +#define CM_RAND_MAX 32767 + +// return a random number between 0 and CM_RAND_MAX +static inline uint64_t cm_rand15 (uint64_t *seed) +{ + (*seed) = (*seed) * 1103515245 + 12345 ; + return (((*seed) / 65536) % (CM_RAND_MAX + 1)) ; +} + +// return a random uint64_t, in range 0 to 2^60 +static inline uint64_t cm_rand (uint64_t *seed) +{ + uint64_t i = cm_rand15 (seed) ; + i = CM_RAND_MAX * i + cm_rand15 (seed) ; + i = CM_RAND_MAX * i + cm_rand15 (seed) ; + i = CM_RAND_MAX * i + cm_rand15 (seed) ; + return (i) ; +} + +// swap two entries A [a] and A [b] +#define SWAP(type,A,a,b) \ +{ \ + type t = A [a] ; \ + A [a] = A [b] ; \ + A [b] = t ; \ +} + +//------------------------------------------------------------------------------ +// t_cholmod_sort_worker template +//------------------------------------------------------------------------------ + +#define PATTERN +#include "t_cholmod_sort_worker.c" + +#define DOUBLE +#define REAL +#include "t_cholmod_sort_worker.c" +#define COMPLEX +#include "t_cholmod_sort_worker.c" +#define ZOMPLEX +#include "t_cholmod_sort_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_sort_worker.c" +#define COMPLEX +#include "t_cholmod_sort_worker.c" +#define ZOMPLEX +#include "t_cholmod_sort_worker.c" + +//------------------------------------------------------------------------------ +// cholmod_sort +//------------------------------------------------------------------------------ + +int CHOLMOD(sort) +( + cholmod_sparse *A, // input/output matrix to sort + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_SPARSE_MATRIX_INVALID (A, FALSE) ; + ASSERT (CHOLMOD(dump_sparse) (A, "sort:A input", Common) >= 0) ; + + //-------------------------------------------------------------------------- + // sort each column of A + //-------------------------------------------------------------------------- + + switch ((A->xtype + A->dtype) % 8) + { + default: + p_cholmod_sort_worker (A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_sort_worker (A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_sort_worker (A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_sort_worker (A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_sort_worker (A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_sort_worker (A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_sort_worker (A) ; + break ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (CHOLMOD(dump_sparse) (A, "sort:A output", Common) >= 0) ; + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_sort_worker.c b/CHOLMOD/Utility/t_cholmod_sort_worker.c new file mode 100644 index 000000000..add2200a7 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_sort_worker.c @@ -0,0 +1,229 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_sort_worker: sort all columns of a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +//------------------------------------------------------------------------------ +// variants for each xtype: pattern, real, complex, and zomplex +//------------------------------------------------------------------------------ + +#if defined ( PATTERN ) + + #define CM_PART(Ai,Ax,Az,n,seed) TEMPLATE(cm_part) (Ai, n, seed) + #define CM_QSRT(Ai,Ax,Az,p,n,seed) TEMPLATE(cm_qsrt) (Ai+p, n, seed) + #define CM_SWAP(a,b) \ + { \ + SWAP (Int, Ai, a, b) ; \ + } + +#elif defined ( REAL ) + + #define CM_PART(Ai,Ax,Az,n,seed) TEMPLATE(cm_part) (Ai, Ax, n, seed) + #define CM_QSRT(Ai,Ax,Az,p,n,seed) TEMPLATE(cm_qsrt) (Ai+p, Ax+p, n, seed) + #define CM_SWAP(a,b) \ + { \ + SWAP (Int, Ai, a, b) ; \ + SWAP (Real, Ax, a, b) ; \ + } + +#elif defined ( COMPLEX ) + + #define CM_PART(Ai,Ax,Az,n,seed) TEMPLATE(cm_part) (Ai, Ax, n, seed) + #define CM_QSRT(Ai,Ax,Az,p,n,seed) TEMPLATE(cm_qsrt) (Ai+p,Ax+2*p,n,seed) + #define CM_SWAP(a,b) \ + { \ + SWAP (Int, Ai, a, b) ; \ + SWAP (Real, Ax, 2*(a), 2*(b)) ; \ + SWAP (Real, Ax, 2*(a)+1, 2*(b)+1) ; \ + } + +#else + + #define CM_PART(Ai,Ax,Az,n,seed) TEMPLATE(cm_part) (Ai, Ax, Az, n, seed) + #define CM_QSRT(Ai,Ax,Az,p,n,seed) TEMPLATE(cm_qsrt) (Ai+p,Ax+p,Az+p,n,seed) + #define CM_SWAP(a,b) \ + { \ + SWAP (Int, Ai, a, b) ; \ + SWAP (Real, Ax, a, b) ; \ + SWAP (Real, Az, a, b) ; \ + } + +#endif + +//------------------------------------------------------------------------------ +// cm_part: use a pivot to partition an array +//------------------------------------------------------------------------------ + +// C.A.R Hoare partition method, partitions an array in-place via a pivot. +// k = partition (A, n) partitions A [0:n-1] such that all entries in +// A [0:k] are <= all entries in A [k+1:n-1]. + +// Ai [0:n-1] is the sort key, and Ax,Az [0:n-1] are satelite data. + + +static inline Int TEMPLATE (cm_part) +( + Int *Ai, // Ai [0..n-1]: indices to sort + #if !defined ( PATTERN ) + Real *Ax, // Ax [0..n-1]: values of A(:,j) + #endif + #if defined ( ZOMPLEX ) + Real *Az, // Az [0..n-1] + #endif + const Int n, // length of Ai, Ax, Az + uint64_t *seed // random number seed, modified on output +) +{ + + // select a pivot at random + Int p = ((n < CM_RAND_MAX) ? cm_rand15 (seed) : cm_rand (seed)) % n ; + + // get the pivot value + Int pivot = Ai [p] ; + + // At the top of the while loop, A [left+1...right-1] is considered, and + // entries outside this range are in their proper place and not touched. + // Since the input specification of this function is to partition A + // [0..n-1], left must start at -1 and right must start at n. + Int left = -1 ; + Int right = n ; + + // keep partitioning until the left and right sides meet + while (true) + { + // loop invariant: A [0..left] < pivot and A [right..n-1] > pivot, + // so the region to be considered is A [left+1 ... right-1]. + + // increment left until finding an entry A [left] >= pivot + do { left++ ; } while (Ai [left] < pivot) ; + + // decrement right until finding an entry A [right] <= pivot + do { right-- ; } while (pivot < Ai [right]) ; + + // now A [0..left-1] < pivot and A [right+1..n-1] > pivot, but + // A [left] > pivot and A [right] < pivot, so these two entries + // are out of place and must be swapped. + + // However, if the two sides have met, the partition is finished. + if (left >= right) + { + // A has been partitioned into A [0:right] and A [right+1:n-1]. + // k = right+1, so A is split into A [0:k-1] and A [k:n-1]. + return (right + 1) ; + } + + // since A [left] > pivot and A [right] < pivot, swap them + CM_SWAP (left, right) ; + + // after the swap this condition holds: + // A [0..left] < pivot and A [right..n-1] > pivot + } +} + +//------------------------------------------------------------------------------ +// cm_qsrt: recursive single-threaded quicksort +//------------------------------------------------------------------------------ + +static void TEMPLATE (cm_qsrt) // sort A [0:n-1] +( + Int *Ai, // Ai [0..n-1]: indices to sort + #if !defined ( PATTERN ) + Real *Ax, // Ax [0..n-1]: values of A(:,j) + #endif + #if defined ( ZOMPLEX ) + Real *Az, // Az [0..n-1] + #endif + const Int n, // length of Ai, Ax, Az + uint64_t *seed // random number seed +) +{ + + if (n < 20) + { + // in-place insertion sort on A [0:n-1], where n is small + for (Int k = 1 ; k < n ; k++) + { + for (Int j = k ; j > 0 && Ai [j] < Ai [j-1] ; j--) + { + // swap A [j-1] and A [j] + CM_SWAP (j-1, j) ; + } + } + } + else + { + // partition A [0:n-1] into A [0:k-1] and A [k:n-1] + Int k = CM_PART (Ai, Ax, Az, n, seed) ; + + // sort each partition + CM_QSRT (Ai, Ax, Ax, 0, k, seed) ; // sort A [0:k-1] + CM_QSRT (Ai, Ax, Az, k, n-k, seed) ; // sort A [k+1:n-1] + } +} + +//------------------------------------------------------------------------------ +// t_cholmod_sort_worker +//------------------------------------------------------------------------------ + +static void TEMPLATE (cholmod_sort_worker) +( + cholmod_sparse *A // matrix to sort in-place +) +{ + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int *Ap = (Int *) A->p ; + Int *Ai = (Int *) A->i ; + Int *Anz = (Int *) A->nz ; + Real *Ax = (Real *) A->x ; + Real *Az = (Real *) A->z ; + Int ncol = A->ncol ; + bool packed = A->packed ; + uint64_t seed = 42 ; + + for (Int j = 0 ; j < ncol ; j++) + { + + //---------------------------------------------------------------------- + // sort A(:,j) according to its row indices + //---------------------------------------------------------------------- + + Int pa = Ap [j] ; + Int pend = (packed) ? (Ap [j+1]) : (pa + Anz [j]) ; + Int ilast = EMPTY ; + for (Int p = pa ; p < pend ; p++) + { + Int i = Ai [p] ; + if (i < ilast) + { + // sort Ai, Ax, Ax [pa:pend-1] according to row index Ai + Int jnz = pend - pa ; + CM_QSRT (Ai, Ax, Az, pa, pend - pa, &seed) ; + break ; + } + ilast = i ; + } + } + + A->sorted = TRUE ; +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + +#undef CM_SWAP +#undef CM_PART +#undef CM_QSRT + diff --git a/CHOLMOD/Utility/t_cholmod_sparse_to_dense.c b/CHOLMOD/Utility/t_cholmod_sparse_to_dense.c new file mode 100644 index 000000000..5f05bc88b --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_sparse_to_dense.c @@ -0,0 +1,125 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_sparse_to_dense: convert a sparse matrix to dense +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Converts a sparse matrix (as input) to a new dense matrix (as output). +// The xtype and dtype are preserved, except if A->xtype is pattern. In that +// case, the output matrix X has an xtype of real, and consists of 1's and 0's. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_dense) (&X, Common) ; \ + return (NULL) ; \ + } + +//------------------------------------------------------------------------------ +// t_cholmod_sparse_to_dense_worker template +//------------------------------------------------------------------------------ + +#define DOUBLE +#define PATTERN +#include "t_cholmod_sparse_to_dense_worker.c" +#define REAL +#include "t_cholmod_sparse_to_dense_worker.c" +#define COMPLEX +#include "t_cholmod_sparse_to_dense_worker.c" +#define ZOMPLEX +#include "t_cholmod_sparse_to_dense_worker.c" + +#undef DOUBLE +#define SINGLE +#define PATTERN +#include "t_cholmod_sparse_to_dense_worker.c" +#define REAL +#include "t_cholmod_sparse_to_dense_worker.c" +#define COMPLEX +#include "t_cholmod_sparse_to_dense_worker.c" +#define ZOMPLEX +#include "t_cholmod_sparse_to_dense_worker.c" + +//------------------------------------------------------------------------------ +// cholmod_sparse_to_dense +//------------------------------------------------------------------------------ + +cholmod_dense *CHOLMOD(sparse_to_dense) // return a dense matrix +( + cholmod_sparse *A, // input matrix + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + RETURN_IF_SPARSE_MATRIX_INVALID (A, NULL) ; + Common->status = CHOLMOD_OK ; + ASSERT (CHOLMOD(dump_sparse) (A, "sparse_to_dense:A", Common) >= 0) ; + + //-------------------------------------------------------------------------- + // allocate an all-zero dense matrix + //-------------------------------------------------------------------------- + + int xxtype = (A->xtype == CHOLMOD_PATTERN)? CHOLMOD_REAL : A->xtype ; + cholmod_dense *X = CHOLMOD(zeros) (A->nrow, A->ncol, xxtype + A->dtype, + Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // copy A into X + //-------------------------------------------------------------------------- + + switch ((A->xtype + A->dtype) % 8) + { + + case CHOLMOD_SINGLE + CHOLMOD_PATTERN: + p_s_cholmod_sparse_to_dense_worker (X, A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_sparse_to_dense_worker (X, A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_sparse_to_dense_worker (X, A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_sparse_to_dense_worker (X, A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_PATTERN: + p_cholmod_sparse_to_dense_worker (X, A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_sparse_to_dense_worker (X, A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_sparse_to_dense_worker (X, A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_sparse_to_dense_worker (X, A) ; + break ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (CHOLMOD(dump_dense) (X, "sparse_to_dense:X", Common) >= 0) ; + return (X) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_sparse_to_dense_worker.c b/CHOLMOD/Utility/t_cholmod_sparse_to_dense_worker.c new file mode 100644 index 000000000..c0e6fc39b --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_sparse_to_dense_worker.c @@ -0,0 +1,124 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_sparse_to_dense_worker: sparse to dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_sparse_to_dense_worker) +( + cholmod_dense *X, // output dense matrix, already allocated + cholmod_sparse *A // input sparse matrix +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + ASSERT (X->d == X->nrow) ; + ASSERT (X->nrow == A->nrow) ; + ASSERT (X->ncol == A->ncol) ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Real *Xx = (Real *) X->x ; + Real *Xz = (Real *) X->z ; + + Int *Ap = (Int *) A->p ; + Int *Ai = (Int *) A->i ; + Int *Anz = (Int *) A->nz ; + Real *Ax = (Real *) A->x ; + Real *Az = (Real *) A->z ; + + Int nrow = (Int) A->nrow ; + Int ncol = (Int) A->ncol ; + bool packed = (bool) A->packed ; + bool upper = (A->stype > 0) ; + bool lower = (A->stype < 0) ; + + //-------------------------------------------------------------------------- + // copy a sparse matrix A into a dense matrix X + //-------------------------------------------------------------------------- + + for (Int j = 0, jx = 0 ; j < ncol ; j++, jx += nrow) + { + + //---------------------------------------------------------------------- + // copy A(:,j) into X(:,j) + //---------------------------------------------------------------------- + + Int p = Ap [j] ; + Int pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; + for ( ; p < pend ; p++) + { + + //------------------------------------------------------------------ + // get A(i,j) + //------------------------------------------------------------------ + + Int i = Ai [p] ; + Int q = i + jx ; + + if (upper) + { + + //-------------------------------------------------------------- + // A is symmetric with upper part stored + //-------------------------------------------------------------- + + if (i > j) continue ; + // X(i,j) = A(i,j) + ASSIGN2 (Xx, Xz, q, Ax, Az, p) ; + if (i < j) + { + // X(j,i) = conj (A(i,j)) + Int s = j + i*nrow ; + ASSIGN2_CONJ (Xx, Xz, s, Ax, Az, p) ; + } + + } + else if (lower) + { + + //-------------------------------------------------------------- + // A is symmetric with lower part stored + //-------------------------------------------------------------- + + if (i < j) continue ; + // X(i,j) = A(i,j) + ASSIGN2 (Xx, Xz, q, Ax, Az, p) ; + if (i > j) + { + // X(j,i) = conj (A(i,j)) + Int s = j + i*nrow ; + ASSIGN2_CONJ (Xx, Xz, s, Ax, Az, p) ; + } + + } + else + { + + //-------------------------------------------------------------- + // A and X are both unsymmetric + //-------------------------------------------------------------- + + // X(i,j) = A(i,j) + ASSIGN2 (Xx, Xz, q, Ax, Az, p) ; + } + } + } +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_sparse_to_triplet.c b/CHOLMOD/Utility/t_cholmod_sparse_to_triplet.c new file mode 100644 index 000000000..1ce6dc7d2 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_sparse_to_triplet.c @@ -0,0 +1,111 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_sparse_to_triplet: convert sparse to triplet +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +//------------------------------------------------------------------------------ +// t_cholmod_sparse_to_triplet_worker template +//------------------------------------------------------------------------------ + +#define PATTERN +#include "t_cholmod_sparse_to_triplet_worker.c" + +#define DOUBLE +#define REAL +#include "t_cholmod_sparse_to_triplet_worker.c" +#define COMPLEX +#include "t_cholmod_sparse_to_triplet_worker.c" +#define ZOMPLEX +#include "t_cholmod_sparse_to_triplet_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_sparse_to_triplet_worker.c" +#define COMPLEX +#include "t_cholmod_sparse_to_triplet_worker.c" +#define ZOMPLEX +#include "t_cholmod_sparse_to_triplet_worker.c" + +//------------------------------------------------------------------------------ +// cholmod_sparse_to_triplet: convert sparse matrix to triplet form +//------------------------------------------------------------------------------ + +cholmod_triplet *CHOLMOD(sparse_to_triplet) +( + cholmod_sparse *A, // matrix to copy into triplet form T + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + RETURN_IF_SPARSE_MATRIX_INVALID (A, NULL) ; + Common->status = CHOLMOD_OK ; + ASSERT (CHOLMOD(dump_sparse) (A, "sparse_triplet:A", Common) >= 0) ; + + //-------------------------------------------------------------------------- + // allocate triplet matrix + //-------------------------------------------------------------------------- + + size_t nz = (size_t) CHOLMOD(nnz) (A, Common) ; + cholmod_triplet *T = CHOLMOD(allocate_triplet) (A->nrow, A->ncol, nz, + A->stype, A->xtype + A->dtype, Common) ; + if (Common->status < CHOLMOD_OK) + { + return (NULL) ; + } + + //-------------------------------------------------------------------------- + // copy a sparse matrix A to a triplet matrix T + //-------------------------------------------------------------------------- + + switch ((A->xtype + A->dtype) % 8) + { + default: + p_cholmod_sparse_to_triplet_worker (T, A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_sparse_to_triplet_worker (T, A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_sparse_to_triplet_worker (T, A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_sparse_to_triplet_worker (T, A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_sparse_to_triplet_worker (T, A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_sparse_to_triplet_worker (T, A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_sparse_to_triplet_worker (T, A) ; + break ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (CHOLMOD(dump_triplet) (T, "sparse_to_triplet:T", Common)) ; + return (T) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_sparse_to_triplet_worker.c b/CHOLMOD/Utility/t_cholmod_sparse_to_triplet_worker.c new file mode 100644 index 000000000..a68b1faa7 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_sparse_to_triplet_worker.c @@ -0,0 +1,122 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_sparse_to_triplet_worker +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_sparse_to_triplet_worker) +( + cholmod_triplet *T, + cholmod_sparse *A +) +{ + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int nrow = A->nrow ; + Int ncol = A->ncol ; + bool packed = (bool) A->packed ; + Int *Ap = (Int *) A->p ; + Int *Ai = (Int *) A->i ; + Real *Ax = (Real *) A->x ; + Real *Az = (Real *) A->z ; + Int *Anz = (Int *) A->nz ; + + Int *Ti = (Int *) T->i ; + Int *Tj = (Int *) T->j ; + Real *Tx = (Real *) T->x ; + Real *Tz = (Real *) T->z ; + + Int k = 0 ; + + //-------------------------------------------------------------------------- + // copy entries from A into T + //-------------------------------------------------------------------------- + + #define COPY_ENTRY(entry_test) \ + if (entry_test) \ + { \ + Ti [k] = i ; \ + Tj [k] = j ; \ + /* Tx (k) = Ax (p) */ \ + ASSIGN (Tx, Tz, k, Ax, Az, p) ; \ + k++ ; \ + } + + if (A->stype == 0) + { + + //---------------------------------------------------------------------- + // A is unsymmetric + //---------------------------------------------------------------------- + + for (Int j = 0 ; j < ncol ; j++) + { + Int p = Ap [j] ; + Int pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; + for ( ; p < pend ; p++) + { + Int i = Ai [p] ; + COPY_ENTRY (true) ; + } + } + + } + else if (A->stype > 0) + { + + //---------------------------------------------------------------------- + // A is symmetric, with just upper triangular part stored + //---------------------------------------------------------------------- + + for (Int j = 0 ; j < ncol ; j++) + { + Int p = Ap [j] ; + Int pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; + for ( ; p < pend ; p++) + { + Int i = Ai [p] ; + COPY_ENTRY (i <= j) ; + } + } + + } + else + { + + //---------------------------------------------------------------------- + // A is symmetric, with just lower triangular part stored + //---------------------------------------------------------------------- + + for (Int j = 0 ; j < ncol ; j++) + { + Int p = Ap [j] ; + Int pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ; + for ( ; p < pend ; p++) + { + Int i = Ai [p] ; + COPY_ENTRY (i >= j) ; + } + } + } + + //-------------------------------------------------------------------------- + // log the number of entries in T + //-------------------------------------------------------------------------- + + T->nnz = k ; +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_speye.c b/CHOLMOD/Utility/t_cholmod_speye.c new file mode 100644 index 000000000..0c08e9a23 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_speye.c @@ -0,0 +1,121 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_speye: sparse identity matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Create a sparse identity matrix, possibly rectangular, of any xtype or +// dtype. The A->stype is zero (unsymmetric) but this can be modified by the +// caller to either +1 or -1, and the matrix will still be valid. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_sparse) (&A, Common) ; \ + return (NULL) ; \ + } + +//------------------------------------------------------------------------------ +// t_cholmod_speye_worker template +//------------------------------------------------------------------------------ + +#define PATTERN +#include "t_cholmod_speye_worker.c" + +#define DOUBLE +#define REAL +#include "t_cholmod_speye_worker.c" +#define COMPLEX +#include "t_cholmod_speye_worker.c" +#define ZOMPLEX +#include "t_cholmod_speye_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_speye_worker.c" +#define COMPLEX +#include "t_cholmod_speye_worker.c" +#define ZOMPLEX +#include "t_cholmod_speye_worker.c" + +//------------------------------------------------------------------------------ +// cholmod_speye: create a sparse identity matrix +//------------------------------------------------------------------------------ + +cholmod_sparse *CHOLMOD(speye) +( + size_t nrow, // # of rows + size_t ncol, // # of columns + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // allocate the matrix + //-------------------------------------------------------------------------- + + cholmod_sparse *A = CHOLMOD(allocate_sparse) (nrow, ncol, MIN (nrow, ncol), + /* A is sorted: */ TRUE, /* A is packed: */ TRUE, /* stype: */ 0, + xdtype, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // fill the matrix with all 1's on the diagonal + //-------------------------------------------------------------------------- + + switch (xdtype % 8) + { + default: + p_cholmod_speye_worker (A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_speye_worker (A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + c_s_cholmod_speye_worker (A) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + z_s_cholmod_speye_worker (A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_speye_worker (A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + c_cholmod_speye_worker (A) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + z_cholmod_speye_worker (A) ; + break ; + } + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (CHOLMOD(dump_sparse) (A, "speye:A", Common) >= 0) ; + return (A) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_speye_worker.c b/CHOLMOD/Utility/t_cholmod_speye_worker.c new file mode 100644 index 000000000..06a86ac77 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_speye_worker.c @@ -0,0 +1,57 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_speye_worker: sparse identity matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_speye_worker) +( + cholmod_sparse *A +) +{ + + //-------------------------------------------------------------------------- + // fill the matrix with all 1's on the diagonal + //-------------------------------------------------------------------------- + + Int *Ap = (Int *) A->p ; + Int *Ai = (Int *) A->i ; + Real *Ax = (Real *) A->x ; + Real *Az = (Real *) A->z ; + + Int ncol = (Int) A->ncol ; + Int nrow = (Int) A->nrow ; + Int n = MIN (nrow, ncol) ; + + Real onex [2] = {1,0} ; + Real onez [1] = {0} ; + + for (Int k = 0 ; k < n ; k++) + { + // A(k,k) = 1 + Ap [k] = k ; + Ai [k] = k ; + ASSIGN (Ax, Az, k, onex, onez, 0) ; + } + + //-------------------------------------------------------------------------- + // finish the rest of A->p for any remaining empty columns + //-------------------------------------------------------------------------- + + for (Int k = n ; k <= ncol ; k++) + { + Ap [k] = n ; + } +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_spzeros.c b/CHOLMOD/Utility/t_cholmod_spzeros.c new file mode 100644 index 000000000..44353cb17 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_spzeros.c @@ -0,0 +1,34 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_spzeros: all-zero sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Create a sparse matrix with no entries, of any xtype or dtype. The A->stype +// is zero (unsymmetric) but this can be modified by the caller to either +1 or +// -1, and the matrix will still be valid. + +#include "cholmod_internal.h" + +cholmod_sparse *CHOLMOD(spzeros) // return a sparse matrix with no entries +( + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t nzmax, // max # of entries the matrix can hold + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX) + cholmod_common *Common +) +{ + return (CHOLMOD(allocate_sparse) (nrow, ncol, nzmax, + /* A is sorted: */ TRUE, + /* A is packed: */ TRUE, + /* A is unsymmetric: */ 0, + xdtype, Common)) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_start.c b/CHOLMOD/Utility/t_cholmod_start.c new file mode 100644 index 000000000..02478cc0b --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_start.c @@ -0,0 +1,61 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_start: start CHOLMOD (int32/int64 version) +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +// cholmod_start or cholmod_l_start must be called once prior to calling any +// other CHOLMOD method. It contains workspace that must be freed by +// cholmod_finish or cholmod_l_finish. + +int CHOLMOD(start) (cholmod_common *Common) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + if (Common == NULL) return (FALSE) ; + + //-------------------------------------------------------------------------- + // settings required before CHOLMOD(defaults) + //-------------------------------------------------------------------------- + + memset ((void *) Common, 0, sizeof (struct cholmod_common_struct)) ; + Common->itype = ITYPE ; // CHOLMOD_INT or CHOLMOD_LONG + + //-------------------------------------------------------------------------- + // set defaults + //-------------------------------------------------------------------------- + + CHOLMOD(defaults) (Common) ; + + //-------------------------------------------------------------------------- + // initialize the rest of Common to various nonzero values + //-------------------------------------------------------------------------- + + Common->gpuMemorySize = 1 ; + Common->chunk = 128000 ; + Common->nthreads_max = SUITESPARSE_OPENMP_MAX_THREADS ; + + Common->modfl = EMPTY ; + Common->aatfl = EMPTY ; + Common->blas_ok = TRUE ; + + Common->SPQR_grain = 1 ; + Common->SPQR_small = 1e6 ; + Common->SPQR_shrink = 1 ; + + Common->mark = EMPTY ; + Common->fl = EMPTY ; + Common->lnz = EMPTY ; + + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_transpose.c b/CHOLMOD/Utility/t_cholmod_transpose.c new file mode 100644 index 000000000..3579c67dc --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_transpose.c @@ -0,0 +1,24 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_transpose: transpose a sparse matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +cholmod_sparse *CHOLMOD(transpose) +( + cholmod_sparse *A, // input matrix + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // <= 0: pattern (with diag) + cholmod_common *Common +) +{ + return (CHOLMOD(ptranspose) (A, mode, /* Perm: */ NULL, + /* fset: */ NULL, /* fsize: */ 0, Common)) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_transpose_sym.c b/CHOLMOD/Utility/t_cholmod_transpose_sym.c new file mode 100644 index 000000000..f2ca2ef5e --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_transpose_sym.c @@ -0,0 +1,241 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_transpose_sym: symmetric permuted transpose +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// C = A' or A(p,p)' if A is symmetric. The output matrix C must already be +// allocated, with enough space, and with the correct xtype (the same as A, +// or CHOLMOD_PATTERN if only the pattern of C is to be computed. The dtype +// of C and A must also match. A must be symmetric; and C is constructed as +// symmetric with the C->stype = -(A->stype). C->packed must be true. +// +// For a method that creates C itself, see cholmod_ptranspose instead. +// +// workspace: at most 2*nrow + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + return (FALSE) ; \ + } + +//------------------------------------------------------------------------------ +// t_cholmod_transpose_sym_worker template +//------------------------------------------------------------------------------ + +#define PATTERN +#include "t_cholmod_transpose_sym_worker.c" + +#define DOUBLE +#define REAL +#include "t_cholmod_transpose_sym_worker.c" + +#define COMPLEX +#include "t_cholmod_transpose_sym_worker.c" +#define COMPLEX +#define NCONJUGATE +#include "t_cholmod_transpose_sym_worker.c" + +#define ZOMPLEX +#include "t_cholmod_transpose_sym_worker.c" +#define ZOMPLEX +#define NCONJUGATE +#include "t_cholmod_transpose_sym_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_transpose_sym_worker.c" + +#define COMPLEX +#include "t_cholmod_transpose_sym_worker.c" +#define COMPLEX +#define NCONJUGATE +#include "t_cholmod_transpose_sym_worker.c" + +#define ZOMPLEX +#include "t_cholmod_transpose_sym_worker.c" +#define ZOMPLEX +#define NCONJUGATE +#include "t_cholmod_transpose_sym_worker.c" + +//------------------------------------------------------------------------------ + +int CHOLMOD(transpose_sym) +( + cholmod_sparse *A, // input matrix + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // <= 0: pattern (with diag) + Int *Perm, // permutation for C=A(p,p)', or NULL + cholmod_sparse *C, // output matrix, must be allocated on input + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_SPARSE_MATRIX_INVALID (A, FALSE) ; + RETURN_IF_NULL (C, FALSE) ; + Common->status = CHOLMOD_OK ; + + if (A->xtype == CHOLMOD_PATTERN || C->xtype == CHOLMOD_PATTERN) + { + // A or C is pattern: C must be pattern, so mode can only be zero + mode = 0 ; + } + + Int n = A->ncol ; + if (A->stype == 0 || n != A->nrow) + { + ERROR (CHOLMOD_INVALID, "A must be symmetric") ; + return (FALSE) ; + } + + if ((C->xtype != ((mode == 0) ? CHOLMOD_PATTERN : A->xtype)) || + (C->dtype != A->dtype) || (n != C->ncol) || (n != C->nrow) || + (!C->packed)) + { + ERROR (CHOLMOD_INVALID, "C is invalid") ; + return (FALSE) ; + } + + ASSERT (CHOLMOD(dump_sparse) (A, "transpose_sym:A", Common) >= 0) ; + + //-------------------------------------------------------------------------- + // allocate workspace + //-------------------------------------------------------------------------- + + CHOLMOD(allocate_work) (0, ((Perm == NULL) ? 1: 2) * n, 0, Common) ; + RETURN_IF_ERROR ; + + Int *Wi = (Int *) Common->Iwork ; // size n integers + Int *Pinv = NULL ; + memset (Wi, 0, n * sizeof (Int)) ; + + //-------------------------------------------------------------------------- + // compute Pinv and make sure Perm is valid + //-------------------------------------------------------------------------- + + if (Perm != NULL) + { + Pinv = Wi + n ; // size n + CHOLMOD(set_empty) (Pinv, n) ; + for (Int k = 0 ; k < n ; k++) + { + Int i = Perm [k] ; + if ((i < 0 || i > n) || (Pinv [i] >= 0)) + { + ERROR (CHOLMOD_INVALID, "invalid permutation") ; + return (FALSE) ; + } + Pinv [i] = k ; + } + } + + //-------------------------------------------------------------------------- + // count the # of entries in each column of C + //-------------------------------------------------------------------------- + + Int *Ap = (Int *) A->p ; + Int *Ai = (Int *) A->i ; + Int *Anz = (Int *) A->nz ; + + #include "t_cholmod_transpose_sym_template.c" + + //-------------------------------------------------------------------------- + // compute the column pointers of C + //-------------------------------------------------------------------------- + + if (CHOLMOD(cumsum) (C->p, Wi, n) > C->nzmax) + { + ERROR (CHOLMOD_INVALID, "C->nzmax is too small") ; + return (FALSE) ; + } + memcpy (Wi, C->p, n * sizeof (Int)) ; + + //-------------------------------------------------------------------------- + // compute the pattern and values of C + //-------------------------------------------------------------------------- + + bool conj = (mode >= 2) ; + + switch ((C->xtype + C->dtype) % 8) + { + + default: + p_cholmod_transpose_sym_worker (C, A, Pinv, Wi) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_transpose_sym_worker (C, A, Pinv, Wi) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + if (conj) + { + c_s_cholmod_transpose_sym_worker (C, A, Pinv, Wi) ; + } + else + { + ct_s_cholmod_transpose_sym_worker (C, A, Pinv, Wi) ; + } + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + if (conj) + { + z_s_cholmod_transpose_sym_worker (C, A, Pinv, Wi) ; + } + else + { + zt_s_cholmod_transpose_sym_worker (C, A, Pinv, Wi) ; + } + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_transpose_sym_worker (C, A, Pinv, Wi) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + if (conj) + { + c_cholmod_transpose_sym_worker (C, A, Pinv, Wi) ; + } + else + { + ct_cholmod_transpose_sym_worker (C, A, Pinv, Wi) ; + } + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + if (conj) + { + z_cholmod_transpose_sym_worker (C, A, Pinv, Wi) ; + } + else + { + zt_cholmod_transpose_sym_worker (C, A, Pinv, Wi) ; + } + break ; + } + + //-------------------------------------------------------------------------- + // finalize C and return result + //-------------------------------------------------------------------------- + + C->sorted = (Perm == NULL) ; + C->stype = - SIGN (A->stype) ; + ASSERT (CHOLMOD(dump_sparse) (C, "transpose_sym:C", Common) >= 0) ; + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_transpose_sym_permuted.c b/CHOLMOD/Utility/t_cholmod_transpose_sym_permuted.c new file mode 100644 index 000000000..26299b10c --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_transpose_sym_permuted.c @@ -0,0 +1,68 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_transpose_sym_permuted +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ +// C = A(p,p)' where A and C are symmetric +//------------------------------------------------------------------------------ + +// The including file must define or undef PACKED, NUMERIC, and LO. +// define PACKED: if A->packed is true, undefine if A->packed is false +// define LO: if A is symmetric lower, undefine it if A is upper +// define NUMERIC: if computing values and pattern of C, undefine it if +// computing just the column counts of C. + +//------------------------------------------------------------------------------ + +{ + for (Int jold = 0 ; jold < n ; jold++) + { + Int jnew = Pinv [jold] ; + Int pa = Ap [jold] ; + #ifdef PACKED + Int paend = Ap [jold+1] ; + #else + Int paend = pa + Anz [jold] ; + #endif + for ( ; pa < paend ; pa++) + { + // get A(iold,jold) + Int iold = Ai [pa] ; + Int inew = Pinv [iold] ; + #ifdef LO + // A is symmetric lower, C is symmetric upper + if (iold < jold) continue ; + if (inew > jnew) + #else + // A is symmetric upper, C is symmetric lower + if (iold > jold) continue ; + if (inew < jnew) + #endif + { + // C(jnew,inew) = conj (A(iold,jold)) + Int pc = Wi [inew]++ ; + #ifdef NUMERIC + ASSIGN_CONJ_OR_NCONJ (Cx, Cz, pc, Ax, Az, pa) ; + Ci [pc] = jnew ; + #endif + } + else + { + // C(inew,jnew) = A(iold,jold) + Int pc = Wi [jnew]++ ; + #ifdef NUMERIC + ASSIGN (Cx, Cz, pc, Ax, Az, pa) ; + Ci [pc] = inew ; + #endif + } + } + } +} + +#undef PACKED +#undef LO + diff --git a/CHOLMOD/Utility/t_cholmod_transpose_sym_template.c b/CHOLMOD/Utility/t_cholmod_transpose_sym_template.c new file mode 100644 index 000000000..82f5cafa0 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_transpose_sym_template.c @@ -0,0 +1,122 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_transpose_sym_template: +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ +// C = A' or A(p,p)', either symbolic or numeric phase +//------------------------------------------------------------------------------ + +// The including file must define or undef NUMERIC. +// define NUMERIC: if computing values and pattern of C, undefine it if +// computing just the column counts of C. + +//------------------------------------------------------------------------------ + +{ + if (Pinv == NULL) + { + + //---------------------------------------------------------------------- + // C = A', unpermuted transpose + //---------------------------------------------------------------------- + + if (A->stype < 0) + { + + //------------------------------------------------------------------ + // C = A', A is symmetric lower, C will be symmetric upper + //------------------------------------------------------------------ + + if (A->packed) + { + // A is packed + #define PACKED + #define LO + #include "t_cholmod_transpose_sym_unpermuted.c" + } + else + { + // A is unpacked + #define LO + #include "t_cholmod_transpose_sym_unpermuted.c" + } + + } + else + { + + //------------------------------------------------------------------ + // C = A', A is symmetric upper, C will be symmetric lower + //------------------------------------------------------------------ + + if (A->packed) + { + // A is packed + #define PACKED + #include "t_cholmod_transpose_sym_unpermuted.c" + } + else + { + // A is unpacked + #include "t_cholmod_transpose_sym_unpermuted.c" + } + } + + } + else + { + + //---------------------------------------------------------------------- + // C = A(p,p)', permuted transpose + //---------------------------------------------------------------------- + + if (A->stype < 0) + { + + //------------------------------------------------------------------ + // C = A(p,p)', A is symmetric lower, C will be symmetric upper + //------------------------------------------------------------------ + + if (A->packed) + { + // A is packed + #define PACKED + #define LO + #include "t_cholmod_transpose_sym_permuted.c" + } + else + { + // A is unpacked + #define LO + #include "t_cholmod_transpose_sym_permuted.c" + } + + } + else + { + + //------------------------------------------------------------------ + // C = A(p,p)', A is symmetric upper, C will be symmetric lower + //------------------------------------------------------------------ + + if (A->packed) + { + // A is packed + #define PACKED + #include "t_cholmod_transpose_sym_permuted.c" + } + else + { + // A is unpacked + #include "t_cholmod_transpose_sym_permuted.c" + } + } + } +} + +#undef NUMERIC + diff --git a/CHOLMOD/Utility/t_cholmod_transpose_sym_unpermuted.c b/CHOLMOD/Utility/t_cholmod_transpose_sym_unpermuted.c new file mode 100644 index 000000000..17811443e --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_transpose_sym_unpermuted.c @@ -0,0 +1,54 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_transpose_sym_unpermuted +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ +// C = A' where A and C are symmetric +//------------------------------------------------------------------------------ + +// The including file must define or undef PACKED, NUMERIC, and LO. +// define PACKED: if A->packed is true, undefine if A->packed is false +// define LO: if A is symmetric lower, undefine it if A is upper +// define NUMERIC: if computing values and pattern of C, undefine it if +// computing just the column counts of C. + +//------------------------------------------------------------------------------ + +{ + + for (Int j = 0 ; j < n ; j++) + { + Int pa = Ap [j] ; + #ifdef PACKED + Int paend = Ap [j+1] ; + #else + Int paend = pa + Anz [j] ; + #endif + for ( ; pa < paend ; pa++) + { + // get A(i,j) + Int i = Ai [pa] ; + #ifdef LO + // A is symmetric lower, C is symmetric upper + if (i < j) continue ; + #else + // A is symmetric upper, C is symmetric lower + if (i > j) continue ; + #endif + // C(j,i) = conj (A(i,j)) + Int pc = Wi [i]++ ; + #ifdef NUMERIC + ASSIGN_CONJ_OR_NCONJ (Cx, Cz, pc, Ax, Az, pa) ; + Ci [pc] = j ; + #endif + } + } +} + +#undef PACKED +#undef LO + diff --git a/CHOLMOD/Utility/t_cholmod_transpose_sym_worker.c b/CHOLMOD/Utility/t_cholmod_transpose_sym_worker.c new file mode 100644 index 000000000..e4377d7e7 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_transpose_sym_worker.c @@ -0,0 +1,53 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_transpose_sym_worker: C = A' or A(p,p)' +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_transpose_sym_worker) +( + cholmod_sparse *C, // output matrix of size n-by-n + cholmod_sparse *A, // input matrix of size n-by-n + Int *Pinv, // size n, inverse permutation, or NULL if none + Int *Wi // size n workspace; column pointers of C on input +) +{ + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int n = A->ncol ; + + Int *Ap = (Int *) A->p ; + Int *Ai = (Int *) A->i ; + Int *Anz = (Int *) A->nz ; + Real *Ax = (Real *) A->x ; + Real *Az = (Real *) A->z ; + + Int *Cp = (Int *) C->p ; + Int *Ci = (Int *) C->i ; + Real *Cx = (Real *) C->x ; + Real *Cz = (Real *) C->z ; + + //-------------------------------------------------------------------------- + // compute pattern and values of C + //-------------------------------------------------------------------------- + + #define NUMERIC + #include "t_cholmod_transpose_sym_template.c" + +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX +#undef NCONJUGATE + diff --git a/CHOLMOD/Utility/t_cholmod_transpose_unsym.c b/CHOLMOD/Utility/t_cholmod_transpose_unsym.c new file mode 100644 index 000000000..8bc9967ef --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_transpose_unsym.c @@ -0,0 +1,398 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_transpose_unsym: unsymmetric permuted transpose +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +// Creates C = A', A(:,f)' or A(p,f)' C must be already allocated on input. +// The matrices A and C are unsymmetric (with stype of zero). See +// cholmod_transpose and cholmod_ptranspose for methods with a simpler +// interface. + +// The notation A(:,f) and A(p,f) refers to a matrix of the same size as A, +// where p is a permutation vector and f is a vector fset of size fsize. +// Any column j not in the fset list still appears in A(:,f), just empty. +// p must be a permutation of 0:A->nrow-1, and f must be a permutation of +// a subset of 0:A->ncol-1. + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + return (FALSE) ; \ + } + +//------------------------------------------------------------------------------ +// t_cholmod_transpose_unsym_worker template +//------------------------------------------------------------------------------ + +#define NUMERIC + +#define PATTERN +#include "t_cholmod_transpose_unsym_worker.c" + +#define DOUBLE +#define REAL +#include "t_cholmod_transpose_unsym_worker.c" + +#define COMPLEX +#include "t_cholmod_transpose_unsym_worker.c" +#define COMPLEX +#define NCONJUGATE +#include "t_cholmod_transpose_unsym_worker.c" + +#define ZOMPLEX +#include "t_cholmod_transpose_unsym_worker.c" +#define ZOMPLEX +#define NCONJUGATE +#include "t_cholmod_transpose_unsym_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_transpose_unsym_worker.c" + +#define COMPLEX +#include "t_cholmod_transpose_unsym_worker.c" +#define COMPLEX +#define NCONJUGATE +#include "t_cholmod_transpose_unsym_worker.c" + +#define ZOMPLEX +#include "t_cholmod_transpose_unsym_worker.c" +#define ZOMPLEX +#define NCONJUGATE +#include "t_cholmod_transpose_unsym_worker.c" + +#undef NUMERIC + +//------------------------------------------------------------------------------ +// cm_copy_Cnz: copy Wi into Cnz +//------------------------------------------------------------------------------ + +static void cm_copy_Cnz (Int *Cnz, Int *Wi, Int *Perm, Int nrow) +{ + if (Perm == NULL) + { + // Cnz [0..nrow-1] = Wi [0..nrow-1] + memcpy (Cnz, Wi, nrow * sizeof (Int)) ; + } + else + { + // Cnz [0..nrow-1] = Wi [Perm [0..nrow-1]] + for (Int i = 0 ; i < nrow ; i++) + { + Cnz [i] = Wi [Perm [i]] ; + } + } +} + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +int CHOLMOD(transpose_unsym) +( + cholmod_sparse *A, // input matrix + int mode, // 2: numerical (conj), 1: numerical (non-conj.), + // <= 0: pattern (with diag) + Int *Perm, // permutation for C=A(p,f)', or NULL + Int *fset, // a list of column indices in range 0:A->ncol-1 + size_t fsize, // # of entries in fset + cholmod_sparse *C, // output matrix, must be allocated on input + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (FALSE) ; + RETURN_IF_SPARSE_MATRIX_INVALID (A, FALSE) ; + RETURN_IF_NULL (C, FALSE) ; + Common->status = CHOLMOD_OK ; + + if (A->xtype == CHOLMOD_PATTERN || C->xtype == CHOLMOD_PATTERN) + { + // A or C is pattern: C must be pattern, so mode can only be zero + mode = 0 ; + } + + Int nrow = A->nrow ; + Int ncol = A->ncol ; + + if (A->stype != 0) + { + ERROR (CHOLMOD_INVALID, "A is invalid") ; + return (FALSE) ; + } + + if ((C->xtype != ((mode <= 0) ? CHOLMOD_PATTERN : A->xtype)) || + (C->dtype != A->dtype) || (nrow != C->ncol) || (ncol != C->nrow) || + (C->stype != 0)) + { + ERROR (CHOLMOD_INVALID, "C is invalid") ; + return (FALSE) ; + } + + ASSERT (CHOLMOD(dump_sparse) (A, "transpose_unsym:A", Common) >= 0) ; + + //-------------------------------------------------------------------------- + // allocate workspace + //-------------------------------------------------------------------------- + + size_t iworksize = (fset == NULL) ? nrow : MAX (nrow, ncol) ; + CHOLMOD(allocate_work) (0, iworksize, 0, Common) ; + RETURN_IF_ERROR ; + Int *Wi = (Int *) Common->Iwork ; // size n integers + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int *Ap = (Int *) A->p ; + Int *Ai = (Int *) A->i ; + Int *Anz = (Int *) A->nz ; + + Int *Cp = (Int *) C->p ; + Int *Cnz = (Int *) C->nz ; + + //-------------------------------------------------------------------------- + // check Perm if present + //-------------------------------------------------------------------------- + + if (Perm != NULL) + { + memset (Wi, 0, nrow * sizeof (Int)) ; + for (Int k = 0 ; k < nrow ; k++) + { + Int i = Perm [k] ; + if (i < 0 || i > nrow || Wi [i] == 1) + { + ERROR (CHOLMOD_INVALID, "invalid permutation") ; + return (FALSE) ; + } + Wi [i] = 1 ; + } + } + + ASSERT (CHOLMOD(dump_perm) (Perm, nrow, nrow, "Perm", Common)) ; + + //-------------------------------------------------------------------------- + // check fset if present, and also determine if it's sorted + //-------------------------------------------------------------------------- + + Int nf = (Int) fsize ; + bool fsorted = true ; + if (fset != NULL) + { + Int jlast = EMPTY ; + memset (Wi, 0, ncol * sizeof (Int)) ; + for (Int k = 0 ; k < nf ; k++) + { + Int j = fset [k] ; + if (j < 0 || j > ncol || Wi [j] == 1) + { + ERROR (CHOLMOD_INVALID, "invalid fset") ; + return (FALSE) ; + } + Wi [j] = 1 ; + fsorted = fsorted && (j > jlast) ; + jlast = j ; + } + } + + ASSERT (CHOLMOD(dump_perm) (fset, fsize, ncol, "fset", Common)) ; + + //-------------------------------------------------------------------------- + // count entries in each row of A or A(:,f) + //-------------------------------------------------------------------------- + + memset (Wi, 0, nrow * sizeof (Int)) ; + + if (fset != NULL) + { + + //---------------------------------------------------------------------- + // count entries in rows of (A:,f) + //---------------------------------------------------------------------- + + if (A->packed) + { + #define PACKED + #define FSET + #include "t_cholmod_transpose_unsym_template.c" + } + else + { + #define FSET + #include "t_cholmod_transpose_unsym_template.c" + } + + //---------------------------------------------------------------------- + // save the nz counts if C is unpacked, and recount all of A + //---------------------------------------------------------------------- + + if (!(C->packed)) + { + + cm_copy_Cnz (Cnz, Wi, Perm, nrow) ; + + //------------------------------------------------------------------ + // count entries in rows of A + //------------------------------------------------------------------ + + memset (Wi, 0, nrow * sizeof (Int)) ; + if (A->packed) + { + #define PACKED + #include "t_cholmod_transpose_unsym_template.c" + } + else + { + #include "t_cholmod_transpose_unsym_template.c" + } + } + + } + else + { + + //---------------------------------------------------------------------- + // count entries in rows of A + //---------------------------------------------------------------------- + + if (A->packed) + { + #define PACKED + #include "t_cholmod_transpose_unsym_template.c" + } + else + { + #include "t_cholmod_transpose_unsym_template.c" + } + + //---------------------------------------------------------------------- + // save the nz counts if C is unpacked, and recount all of A + //---------------------------------------------------------------------- + + if (!(C->packed)) + { + cm_copy_Cnz (Cnz, Wi, Perm, nrow) ; + } + } + + //-------------------------------------------------------------------------- + // Compute Cp + //-------------------------------------------------------------------------- + + Int p = 0 ; + if (Perm == NULL) + { + // Cp = cumsum (Wi) + p = CHOLMOD(cumsum) (Cp, Wi, nrow) ; + // Wi [0..nrow-1] = Cp [0..nrow-1] + memcpy (Wi, Cp, nrow * sizeof (Int)) ; + } + else + { + // Cp = cumsum (Wi [Perm]) + for (Int i = 0 ; i < nrow ; i++) + { + Cp [i] = p ; + p += Wi [Perm [i]] ; + } + Cp [nrow] = p ; + // Wi [Perm [0..nrow-1]] = Cp [0..nrow-1] + for (Int i = 0 ; i < nrow ; i++) + { + Wi [Perm [i]] = Cp [i] ; + } + } + + if (p > (Int) C->nzmax) + { + ERROR (CHOLMOD_INVALID, "C is too small") ; + return (FALSE) ; + } + + //-------------------------------------------------------------------------- + // compute the pattern and values of C + //-------------------------------------------------------------------------- + + bool conj = (mode >= 2) ; + + switch ((C->xtype + C->dtype) % 8) + { + + default: + p_cholmod_transpose_unsym_worker (A, fset, nf, C, Wi) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + r_s_cholmod_transpose_unsym_worker (A, fset, nf, C, Wi) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + if (conj) + { + c_s_cholmod_transpose_unsym_worker (A, fset, nf, C, Wi) ; + } + else + { + ct_s_cholmod_transpose_unsym_worker (A, fset, nf, C, Wi) ; + } + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + if (conj) + { + z_s_cholmod_transpose_unsym_worker (A, fset, nf, C, Wi) ; + } + else + { + zt_s_cholmod_transpose_unsym_worker (A, fset, nf, C, Wi) ; + } + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + r_cholmod_transpose_unsym_worker (A, fset, nf, C, Wi) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + if (conj) + { + c_cholmod_transpose_unsym_worker (A, fset, nf, C, Wi) ; + } + else + { + ct_cholmod_transpose_unsym_worker (A, fset, nf, C, Wi) ; + } + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + if (conj) + { + z_cholmod_transpose_unsym_worker (A, fset, nf, C, Wi) ; + } + else + { + zt_cholmod_transpose_unsym_worker (A, fset, nf, C, Wi) ; + } + break ; + } + + //-------------------------------------------------------------------------- + // finalize C and return result + //-------------------------------------------------------------------------- + + C->sorted = fsorted ; + ASSERT (CHOLMOD(dump_sparse) (C, "transpose_unsym:C", Common) >= 0) ; + return (TRUE) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_transpose_unsym_template.c b/CHOLMOD/Utility/t_cholmod_transpose_unsym_template.c new file mode 100644 index 000000000..3a78d0fd2 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_transpose_unsym_template.c @@ -0,0 +1,74 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_transpose_unsym_template +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ +// C = A', C = A(:,f)', C = A(p,:)', or C = A(p,f)'; A and C are unsymmetric +//------------------------------------------------------------------------------ + +// The including file must define or undef PACKED, NUMERIC, and FSET + +// define PACKED: if A->packed is true, undefine if A->packed is false + +// define NUMERIC: if computing values and pattern of C, undefine it if +// computing just the column counts of C. + +//------------------------------------------------------------------------------ + +{ + + #undef N + #ifdef FSET + #define N nf + #else + #define N ncol + #endif + + for (Int k = 0 ; k < N ; k++) + { + + //---------------------------------------------------------------------- + // get the fset, if present + //---------------------------------------------------------------------- + + #ifdef FSET + Int j = fset [k] ; + #else + Int j = k ; + #endif + + //---------------------------------------------------------------------- + // get A(:,k) + //---------------------------------------------------------------------- + + Int p = Ap [j] ; + #ifdef PACKED + Int pend = Ap [j+1] ; + #else + Int pend = p + Anz [j] ; + #endif + + //---------------------------------------------------------------------- + // scan entries in A(:,k) + //---------------------------------------------------------------------- + + for ( ; p < pend ; p++) + { + // get A(i,j) and count it or get its place in C + Int pc = Wi [Ai [p]]++ ; + #ifdef NUMERIC + // C(j,i) = conj (A(i,j)) + ASSIGN_CONJ_OR_NCONJ (Cx, Cz, pc, Ax, Az, p) ; + Ci [pc] = j ; + #endif + } + } +} + +#undef FSET +#undef PACKED + diff --git a/CHOLMOD/Utility/t_cholmod_transpose_unsym_worker.c b/CHOLMOD/Utility/t_cholmod_transpose_unsym_worker.c new file mode 100644 index 000000000..f87b9a94b --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_transpose_unsym_worker.c @@ -0,0 +1,80 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_transpose_unsym_worker: C = A', A(:,f)', or A(p,f)' +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +static void TEMPLATE (cholmod_transpose_unsym_worker) +( + cholmod_sparse *A, // input matrix + Int *fset, // a list of column indices in range 0:A->ncol-1 + Int nf, // # of entries in fset + cholmod_sparse *C, // output matrix, must be allocated on input + Int *Wi // workspace of size nrow +) +{ + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int *Ap = (Int *) A->p ; + Int *Ai = (Int *) A->i ; + Int *Anz = (Int *) A->nz ; + Real *Ax = (Real *) A->x ; + Real *Az = (Real *) A->z ; + Int ncol = A->ncol ; + + Int *Cp = (Int *) C->p ; + Int *Ci = (Int *) C->i ; + Real *Cx = (Real *) C->x ; + Real *Cz = (Real *) C->z ; + + //-------------------------------------------------------------------------- + // compute the pattern and values of C + //-------------------------------------------------------------------------- + + if (fset != NULL) + { + if (A->packed) + { + // C = A (p,f)' or A(:,f)' where A is packed + #define PACKED + #define FSET + #include "t_cholmod_transpose_unsym_template.c" + } + else + { + // C = A (p,f)' or A(:,f)' where A is unpacked + #define FSET + #include "t_cholmod_transpose_unsym_template.c" + } + } + else + { + if (A->packed) + { + // C = A (p,:)' or A' where A is packed + #define PACKED + #include "t_cholmod_transpose_unsym_template.c" + } + else + { + // C = A (p,:)' or A' where A is unpacked + #include "t_cholmod_transpose_unsym_template.c" + } + } +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX +#undef NCONJUGATE + diff --git a/CHOLMOD/Utility/t_cholmod_triplet_to_sparse.c b/CHOLMOD/Utility/t_cholmod_triplet_to_sparse.c new file mode 100644 index 000000000..4b777a244 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_triplet_to_sparse.c @@ -0,0 +1,222 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_triplet_to_sparse: convert triplet to sparse +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +//------------------------------------------------------------------------------ +// t_cholmod_triplet_to_sparse_worker template +//------------------------------------------------------------------------------ + +#define PATTERN +#include "t_cholmod_triplet_to_sparse_worker.c" + +#define DOUBLE +#define REAL +#include "t_cholmod_triplet_to_sparse_worker.c" +#define COMPLEX +#include "t_cholmod_triplet_to_sparse_worker.c" +#define ZOMPLEX +#include "t_cholmod_triplet_to_sparse_worker.c" + +#undef DOUBLE +#define SINGLE +#define REAL +#include "t_cholmod_triplet_to_sparse_worker.c" +#define COMPLEX +#include "t_cholmod_triplet_to_sparse_worker.c" +#define ZOMPLEX +#include "t_cholmod_triplet_to_sparse_worker.c" + +//------------------------------------------------------------------------------ +// cholmod_triplet_to_sparse: convert triplet matrix to sparse matrix +//------------------------------------------------------------------------------ + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_sparse) (&A, Common) ; \ + CHOLMOD(free_sparse) (&R, Common) ; \ + return (NULL) ; \ + } + +// Converts a triplet matrix T into a sparse matrix A. The nzmax parameter +// can be used to add additional space in A for future entries. The # of +// entries that can be held in A is max (nnz (A), nzmax), so pass in nzmax +// as zero if you do not need any additional space for future growth. + +// workspace: Iwork (max (nrow,ncol)) + +cholmod_sparse *CHOLMOD(triplet_to_sparse) // return sparse matrix A +( + cholmod_triplet *T, // input triplet matrix + size_t nzmax, // allocate space for max(nzmax,nnz(A)) entries + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + RETURN_IF_TRIPLET_MATRIX_INVALID (T, NULL) ; + Common->status = CHOLMOD_OK ; + cholmod_sparse *A = NULL ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + size_t nrow = T->nrow ; + size_t ncol = T->ncol ; + size_t nz = T->nnz ; + Int *Ti = (Int *) T->i ; + Int *Tj = (Int *) T->j ; + int stype = T->stype ; + + //-------------------------------------------------------------------------- + // allocate temporary matrix R to hold the transpose of A + //-------------------------------------------------------------------------- + + // R is unpacked so that duplicates can be easily assembled in place. + // Note that the stype of R is negated, to hold the transpose of A. + cholmod_sparse *R = CHOLMOD(allocate_sparse) (ncol, nrow, nz, + /* R is unsorted: */ FALSE, /* R is unpacked: */ FALSE, + /* stype is flipped: */ -stype, T->xtype + T->dtype, Common) ; + RETURN_IF_ERROR ; + + Int *Rp = (Int *) R->p ; + Int *Rnz = (Int *) R->nz ; + + //-------------------------------------------------------------------------- + // count entries in each column of R, imcluding duplicates + //-------------------------------------------------------------------------- + + // Rnz [0..nrow-1] = 0 + memset (Rnz, 0, nrow * sizeof (Int)) ; + + for (Int k = 0 ; k < nz ; k++) + { + // get the entry T(i,j), which becomes R(j,i) + Int i = Ti [k] ; + Int j = Tj [k] ; + if (i < 0 || j < 0 || i >= nrow || j >= ncol) + { + ERROR (CHOLMOD_INVALID, "index out of range") ; + break ; + } + if (stype > 0) + { + // A will be symmetric, and only its upper triangular part is + // stored, so R must be lower triangular. Ensure that entries + // in the upper triangular part of R are transposed to the lower + // triangular part, by placing the entry T(i,j) in column + // MIN(i,j) of R. + Rnz [MIN (i,j)]++ ; + } + else if (stype < 0) + { + // See comment above; A is lower triangular so R must be upper. + Rnz [MAX (i,j)]++ ; + } + else + { + // T and A are unsymmetric + Rnz [i]++ ; + } + } + + RETURN_IF_ERROR ; // return if index out of range + + //-------------------------------------------------------------------------- + // Rp = cumulative sum of the row counts, Rnz + //-------------------------------------------------------------------------- + + CHOLMOD(cumsum) (Rp, Rnz, nrow) ; + + //-------------------------------------------------------------------------- + // allocate Iwork workspace for the template work, of size MAX (nrow,ncol) + //-------------------------------------------------------------------------- + + CHOLMOD(alloc_work) (0, MAX (nrow, ncol), 0, 0, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // R = T' using template worker + //-------------------------------------------------------------------------- + + size_t anz = 0 ; + + switch ((T->xtype + T->dtype) % 8) + { + default: + anz = p_cholmod_triplet_to_sparse_worker (T, R, Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_REAL: + anz = r_s_cholmod_triplet_to_sparse_worker (T, R, Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_COMPLEX: + anz = c_s_cholmod_triplet_to_sparse_worker (T, R, Common) ; + break ; + + case CHOLMOD_SINGLE + CHOLMOD_ZOMPLEX: + anz = z_s_cholmod_triplet_to_sparse_worker (T, R, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_REAL: + anz = r_cholmod_triplet_to_sparse_worker (T, R, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_COMPLEX: + anz = c_cholmod_triplet_to_sparse_worker (T, R, Common) ; + break ; + + case CHOLMOD_DOUBLE + CHOLMOD_ZOMPLEX: + anz = z_cholmod_triplet_to_sparse_worker (T, R, Common) ; + break ; + } + + //-------------------------------------------------------------------------- + // allocate the final output matrix A + //-------------------------------------------------------------------------- + + anz = MAX (anz, nzmax) ; + A = CHOLMOD(allocate_sparse) (nrow, ncol, anz, TRUE, TRUE, stype, + T->xtype + T->dtype, Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // A = R' + //-------------------------------------------------------------------------- + + // uses Iwork [0..ncol-1] workspace + if (stype == 0) + { + // unsymmetric transpose + CHOLMOD(transpose_unsym) (R, 1, NULL, NULL, 0, A, Common) ; + } + else + { + // symmetric array transpose (not conjugate tranpose if complex) + CHOLMOD(transpose_sym) (R, 1, NULL, A, Common) ; + } + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // free workspace and return result + //-------------------------------------------------------------------------- + + CHOLMOD(free_sparse) (&R, Common) ; + ASSERT (CHOLMOD(dump_sparse) (A, "triplet_to_sparse:A", Common) >= 0) ; + return (A) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_triplet_to_sparse_worker.c b/CHOLMOD/Utility/t_cholmod_triplet_to_sparse_worker.c new file mode 100644 index 000000000..c385f07fa --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_triplet_to_sparse_worker.c @@ -0,0 +1,189 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_triplet_to_sparse_worker +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_template.h" + +static size_t TEMPLATE (cholmod_triplet_to_sparse_worker) // return nnz(R) +( + cholmod_triplet *T, // input matrix + cholmod_sparse *R, // output matrix + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + + Int *Rp = (Int *) R->p ; + Int *Ri = (Int *) R->i ; + Int *Rnz = (Int *) R->nz ; + Real *Rx = (Real *) R->x ; + Real *Rz = (Real *) R->z ; + + Int *Ti = (Int *) T->i ; + Int *Tj = (Int *) T->j ; + Real *Tx = (Real *) T->x ; + Real *Tz = (Real *) T->z ; + size_t nrow = T->nrow ; + size_t ncol = T->ncol ; + Int nz = T->nnz ; + + //-------------------------------------------------------------------------- + // W [0..nrow-1] = Rp [0..nrow-1] using Iwork workspace + //-------------------------------------------------------------------------- + + // using W [0..nrow-1] as workspace for row pointers [ + Int *W = (Int *) Common->Iwork ; + memcpy (W, Rp, nrow * sizeof (Int)) ; + + //-------------------------------------------------------------------------- + // construct the matrix R, keeping duplicates for now + //-------------------------------------------------------------------------- + + // R is treated as if it is stored by row, in the comments below + + int stype = T->stype ; + + for (Int k = 0 ; k < nz ; k++) + { + // get the T (i,j) entry + Int i = Ti [k] ; + Int j = Tj [k] ; + Int p ; + if (stype > 0) + { + // T represents a symmetric matrix with upper part stored + if (i < j) + { + // R (i,j) = T (i,j), placed in row R (i,:) + Ri [p = W [i]++] = j ; + } + else + { + // R (j,i) = T (i,j), placed in row R (j,:) + Ri [p = W [j]++] = i ; + } + } + else if (stype < 0) + { + // T represents a symmetric matrix with lower part stored + if (i > j) + { + // R (i,j) = T (i,j), placed in row R (i,:) + Ri [p = W [i]++] = j ; + } + else + { + // R (j,i) = T (i,j), placed in row R (j,:) + Ri [p = W [j]++] = i ; + } + } + else + { + // T represents an unsymmetric matrix + // R (i,j) = T (i,j), placed in row R (i,:) + Ri [p = W [i]++] = j ; + } + ASSIGN (Rx, Rz, p, Tx, Tz, k) ; // Rx [p] = Tx [k] + } + + // no longer using W as temporary workspace for row pointers ] + + //-------------------------------------------------------------------------- + // assemble any duplicate entries + //-------------------------------------------------------------------------- + + // use W [0..ncol-1] for pointers to duplicates in each row of R [ + CHOLMOD(set_empty) (W, ncol) ; + + size_t rnz = 0 ; // total # of entries in R after assembling duplicates + + for (Int i = 0 ; i < nrow ; i++) + { + + //---------------------------------------------------------------------- + // get the location of R (i,:) before assemblying duplicates + //---------------------------------------------------------------------- + + // row R (i,:) is in located in Ri [pstart..pend-1]. If duplicates are + // detected, the new row i will be located in Ri [pstart..pp-1]. + + Int pstart = Rp [i] ; + Int pend = Rp [i+1] ; + Int pp = pstart ; + + // W [j] is the position in Ri of the last time column j was seen. + // Here, W [0..ncol-1] < pstart is true because R is stored by row, + // and any column j already seen will have been seen in an earlier + // row. If column j has never been seen, W [j] is EMPTY (-1). + + //---------------------------------------------------------------------- + // assemble duplicates in R (i,:) + //---------------------------------------------------------------------- + + for (Int p = pstart ; p < pend ; p++) + { + + //------------------------------------------------------------------ + // get R(i,j) + //------------------------------------------------------------------ + + Int j = Ri [p] ; + Int plastj = W [j] ; // last seen position of column index j + + //------------------------------------------------------------------ + // assemble R(i,j) + //------------------------------------------------------------------ + + if (plastj < pstart) + { + // column j has been seen for the first time in row R (i,:), + // at position pp. Move the entry to position pp, and keep + // track of it in case column j appears again in row R (i,:). + // Rx [pp] = Rx [p] + ASSIGN (Rx, Rz, pp, Rx, Rz, p) ; + Ri [pp] = j ; + // one more unique entry has been seen in R (i,:) + W [j] = pp++ ; + } + else + { + // column j has already been seen in this row R (i,;), at + // position plastj, so assemble this duplicate entry into that + // position. + // Rx [plastj] += Rx [p] + ASSEMBLE (Rx, Rz, plastj, Rx, Rz, p) ; + } + } + + //---------------------------------------------------------------------- + // count the number of entries in R (i,:) + //---------------------------------------------------------------------- + + Int rnz_i = pp - pstart ; + Rnz [i] = rnz_i ; + rnz += rnz_i ; + } + + // done using W [0..ncol-1] workspace ] + + //-------------------------------------------------------------------------- + // return result: # of entries in R after assembling duplicates + //-------------------------------------------------------------------------- + + return (rnz) ; +} + +#undef PATTERN +#undef REAL +#undef COMPLEX +#undef ZOMPLEX + diff --git a/CHOLMOD/Utility/t_cholmod_version.c b/CHOLMOD/Utility/t_cholmod_version.c new file mode 100644 index 000000000..7ac1d4ca7 --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_version.c @@ -0,0 +1,41 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_version: CHOLMOD version +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "cholmod_internal.h" + +int CHOLMOD(version) // returns CHOLMOD_VERSION +( + // if version is not NULL, then cholmod_version returns its contents as: + // version [0] = CHOLMOD_MAIN_VERSION + // version [1] = CHOLMOD_SUB_VERSION + // version [2] = CHOLMOD_SUBSUB_VERSION + int version [3] +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + if (version == NULL) + { + return (CHOLMOD_VERSION) ; + } + + //-------------------------------------------------------------------------- + // return the full version of CHOLMOD + //-------------------------------------------------------------------------- + + version [0] = CHOLMOD_MAIN_VERSION ; + version [1] = CHOLMOD_SUB_VERSION ; + version [2] = CHOLMOD_SUBSUB_VERSION ; + return (CHOLMOD_VERSION) ; +} + diff --git a/CHOLMOD/Utility/t_cholmod_zeros.c b/CHOLMOD/Utility/t_cholmod_zeros.c new file mode 100644 index 000000000..eff8dad7b --- /dev/null +++ b/CHOLMOD/Utility/t_cholmod_zeros.c @@ -0,0 +1,77 @@ +//------------------------------------------------------------------------------ +// CHOLMOD/Utility/t_cholmod_zeros: allocate an all-zero dense matrix +//------------------------------------------------------------------------------ + +// CHOLMOD/Utility Module. Copyright (C) 2023, Timothy A. Davis, All Rights +// Reserved. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +// Allocate a dense matrix. The space is set to zero. + +#include "cholmod_internal.h" + +#define RETURN_IF_ERROR \ + if (Common->status < CHOLMOD_OK) \ + { \ + CHOLMOD(free_dense) (&X, Common) ; \ + return (NULL) ; \ + } + +cholmod_dense *CHOLMOD(zeros) +( + size_t nrow, // # of rows + size_t ncol, // # of columns + int xdtype, // xtype + dtype of the matrix: + // (CHOLMOD_DOUBLE, _SINGLE) + + // (CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX) + cholmod_common *Common +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + RETURN_IF_NULL_COMMON (NULL) ; + Common->status = CHOLMOD_OK ; + + //-------------------------------------------------------------------------- + // allocate a dense matrix + //-------------------------------------------------------------------------- + + cholmod_dense *X = CHOLMOD(allocate_dense) (nrow, ncol, nrow, xdtype, + Common) ; + RETURN_IF_ERROR ; + + //-------------------------------------------------------------------------- + // get the xtype and dtype + //-------------------------------------------------------------------------- + + int xtype = xdtype & 3 ; // real, complex, or zomplex (not pattern) + int dtype = xdtype & 4 ; // double or single + + //-------------------------------------------------------------------------- + // get the sizes of the entries + //-------------------------------------------------------------------------- + + size_t e = (dtype == CHOLMOD_SINGLE) ? sizeof (float) : sizeof (double) ; + size_t ex = e * ((xtype == CHOLMOD_COMPLEX) ? 2 : 1) ; + size_t ez = e * ((xtype == CHOLMOD_ZOMPLEX) ? 1 : 0) ; + + //-------------------------------------------------------------------------- + // clear the contents + //-------------------------------------------------------------------------- + + if (X->x != NULL) memset (X->x, 0, X->nzmax * ex) ; + if (X->z != NULL) memset (X->z, 0, X->nzmax * ez) ; + + //-------------------------------------------------------------------------- + // return result + //-------------------------------------------------------------------------- + + ASSERT (CHOLMOD(dump_dense) (X, "zeros:X", Common) >= 0) ; + return (X) ; +} + diff --git a/CHOLMOD/Valgrind/Make.inc b/CHOLMOD/Valgrind/Make.inc deleted file mode 100644 index 08bdba2ae..000000000 --- a/CHOLMOD/Valgrind/Make.inc +++ /dev/null @@ -1,18 +0,0 @@ -# ------------------------------------------------------------------------------ -# CHOLMOD/Valgrind/Makefile -# ------------------------------------------------------------------------------ - -# ------------------------------------------------------------------------------ -# CHOLMOD/Valgrind Module. Copyright (C) 2005-2022, Timothy A. Davis. -# All Rights Reserved. -# SPDX-License-Identifier: GPL-2.0+ -# ------------------------------------------------------------------------------ - -# valgrind options -V = valgrind --suppressions=suppress --quiet - -# covall is not used -COVER = - -# no test coverage needed -CF = -O0 -g diff --git a/CHOLMOD/Valgrind/Makefile b/CHOLMOD/Valgrind/Makefile deleted file mode 100644 index 8717d253b..000000000 --- a/CHOLMOD/Valgrind/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# ------------------------------------------------------------------------------ -# CHOLMOD/Valgrind/Makefile -# ------------------------------------------------------------------------------ - -# ------------------------------------------------------------------------------ -# CHOLMOD/Valgrind Module. Copyright (C) 2005-2022, Timothy A. Davis. -# All Rights Reserved. -# SPDX-License-Identifier: GPL-2.0+ -# ------------------------------------------------------------------------------ - -doall: links go - -links: - touch links - ln -s ../Tcov/amdtest.c - ln -s ../Tcov/aug.c - ln -s ../Tcov/camdtest.c - ln -s ../Tcov/cctest.c - ln -s ../Tcov/cm.c - ln -s ../Tcov/cm.h - ln -s ../Tcov/cmread.c - ln -s ../Tcov/ctest.c - ln -s ../Tcov/huge.c - ln -s ../Tcov/leak.c - ln -s ../Tcov/lpdemo.c - ln -s ../Tcov/memory.c - ln -s ../Tcov/null2.c - ln -s ../Tcov/null.c - ln -s ../Tcov/raw_factor.c - ln -s ../Tcov/solve.c - ln -s ../Tcov/test_ops.c - ln -s ../Tcov/unpack.c - ln -s ../Tcov/comments.txt - ln -s ../Tcov/Matrix - -include ../Tcov/Makefile - -dopurge: distclean - - $(RM) amdtest.c aug.c camdtest.c cctest.c cm.c cm.h cmread.c \ - ctest.c huge.c leak.c lpdemo.c memory.c null2.c null.c \ - raw_factor.c solve.c test_ops.c unpack.c comments.txt \ - links Matrix - diff --git a/CHOLMOD/Valgrind/README.txt b/CHOLMOD/Valgrind/README.txt deleted file mode 100644 index e4d5bca7d..000000000 --- a/CHOLMOD/Valgrind/README.txt +++ /dev/null @@ -1,19 +0,0 @@ -Torture test for CHOLMOD, using valgrind. Requires Linux. -http://www.suitesparse.com - -Type "make" to compile and run CHOLMOMD with valgrind. -Every line of CHOLMOD will be exercised, and its results -checked. The line "All tests passed" should appear in each -output file (*.grind). Valgrind should report no errors, -and no malloc'd blocks should be in use at exit. - -Note that many, many error messages will appear in the -test output itself (tmp/*.out), because all of CHOLMOD's -error handling is checked as well. These errors are -expected. - -To remove all but the source files and output files from -this directory, type "make clean". To remove all but the -files in the original distribution and the symbolic links, -type "make distclean". To remove all but the files in -the original distribution, type "make dopurge". diff --git a/CHOLMOD/Valgrind/gpl.txt b/CHOLMOD/Valgrind/gpl.txt deleted file mode 100644 index 3912109b5..000000000 --- a/CHOLMOD/Valgrind/gpl.txt +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/CHOLMOD/Valgrind/tmp/.gitignore b/CHOLMOD/Valgrind/tmp/.gitignore deleted file mode 100644 index 5e7d2734c..000000000 --- a/CHOLMOD/Valgrind/tmp/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore diff --git a/ChangeLog b/ChangeLog index f0733f568..b87bf7edb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +Oct 23, 2023: version 7.3.0 + + * CHOLMOD 5.0.0: initial support for sparse single precision matries. + CHOLMOD:Core replaced with CHOLMOD:Utility + * updated to require CHOLMOD 5.0.0: + Example 1.4.3, GPUQREngine 3.3.3, KLU 2.2.2, SPQR 4.2.2, UMFPACK 6.2.2 + * SuiteSparseLAPACK.cmake: allow the use of BLIS/FLAME for LAPACK; + update from Theirry Thomas. + * build system: further updates to cmake, by Markus Muetzel. + +Oct 18, 2023: version 7.2.2 + + * CHOLMOD 4.2.2: bug fix to CHOLMOD/Supernodal (heuristic to determine + # threads to use for last supernode was incorrect) + Oct 7, 2023: version 7.2.1 * GraphBLAS 8.2.1: bug fix to GrB_mxm; incorrect handling of typecasting diff --git a/Example/CMakeLists.txt b/Example/CMakeLists.txt index 46f8af4ef..60f61fab9 100644 --- a/Example/CMakeLists.txt +++ b/Example/CMakeLists.txt @@ -12,10 +12,10 @@ cmake_minimum_required ( VERSION 3.20 ) # cmake inserts the date and version number into Include/my.h: -set ( MY_DATE "Oct 16, 2023" ) +set ( MY_DATE "Oct 23, 2023" ) set ( MY_VERSION_MAJOR 1 ) set ( MY_VERSION_MINOR 4 ) -set ( MY_VERSION_PATCH 2 ) +set ( MY_VERSION_PATCH 3 ) message ( STATUS "Building MY library version: v" ${MY_VERSION_MAJOR}. @@ -61,28 +61,28 @@ project ( my #------------------------------------------------------------------------------- # look for all SuiteSparse packages: -find_package ( SuiteSparse_config 7.2.2 REQUIRED ) +find_package ( SuiteSparse_config 7.3.0 REQUIRED ) find_package ( AMD 3.2.1 REQUIRED ) find_package ( BTF 2.2.1 REQUIRED ) find_package ( CAMD 3.2.1 REQUIRED ) find_package ( CCOLAMD 3.2.1 REQUIRED ) find_package ( COLAMD 3.2.1 REQUIRED ) -find_package ( CHOLMOD 4.2.2 REQUIRED ) +find_package ( CHOLMOD 5.0.0 REQUIRED ) find_package ( CXSparse 4.2.1 REQUIRED ) find_package ( GraphBLAS 8.2.1 ) -find_package ( KLU 2.2.1 REQUIRED ) -find_package ( KLU_CHOLMOD 2.2.1 REQUIRED ) +find_package ( KLU 2.2.2 REQUIRED ) +find_package ( KLU_CHOLMOD 2.2.2 REQUIRED ) find_package ( LDL 3.2.1 REQUIRED ) find_package ( Mongoose 3.2.1 REQUIRED ) find_package ( RBio 4.2.1 REQUIRED ) find_package ( SPEX 2.2.1 REQUIRED ) -find_package ( SPQR 4.2.1 REQUIRED ) -find_package ( UMFPACK 6.2.1 REQUIRED ) +find_package ( SPQR 4.2.2 REQUIRED ) +find_package ( UMFPACK 6.2.2 REQUIRED ) if ( TARGET CUDA::nvrtc ) # CHOLMOD and SPQR have been compiled with CUDA enabled. find_package ( SuiteSparse_GPURuntime 3.2.1 REQUIRED ) - find_package ( GPUQREngine 3.2.1 REQUIRED ) + find_package ( GPUQREngine 3.2.2 REQUIRED ) endif ( ) # look for all external libaries: diff --git a/Example/Include/my.h b/Example/Include/my.h index e7e86754c..5b10b7b33 100644 --- a/Example/Include/my.h +++ b/Example/Include/my.h @@ -11,10 +11,10 @@ // file, since it is constructed from Config/my.h.in by cmake. // version and date for example user library -#define MY_DATE "Sept 18, 2023" +#define MY_DATE "Oct 23, 2023" #define MY_MAJOR_VERSION 1 #define MY_MINOR_VERSION 4 -#define MY_PATCH_VERSION 1 +#define MY_PATCH_VERSION 3 #ifdef __cplusplus extern "C" { diff --git a/GPUQREngine/CMakeLists.txt b/GPUQREngine/CMakeLists.txt index 1a592b016..bf56f2e3f 100644 --- a/GPUQREngine/CMakeLists.txt +++ b/GPUQREngine/CMakeLists.txt @@ -12,10 +12,10 @@ cmake_minimum_required ( VERSION 3.20 ) -set ( GPUQRENGINE_DATE "Sept 18, 2023" ) +set ( GPUQRENGINE_DATE "Oct 23, 2023" ) set ( GPUQRENGINE_VERSION_MAJOR 3 ) set ( GPUQRENGINE_VERSION_MINOR 2 ) -set ( GPUQRENGINE_VERSION_SUB 1 ) +set ( GPUQRENGINE_VERSION_SUB 2 ) message ( STATUS "Building GPUQRENGINE version: v" ${GPUQRENGINE_VERSION_MAJOR}. @@ -54,17 +54,17 @@ endif ( ) #------------------------------------------------------------------------------- # for the library itself -find_package ( SuiteSparse_config 7.2.0 +find_package ( SuiteSparse_config 7.3.0 PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) - find_package ( SuiteSparse_config 7.2.0 REQUIRED ) + find_package ( SuiteSparse_config 7.3.0 REQUIRED ) endif ( ) if ( SUITESPARSE_CUDA ) - find_package ( SuiteSparse_GPURuntime 3.2.0 + find_package ( SuiteSparse_GPURuntime 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_GPURuntime/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::GPURuntime ) - find_package ( SuiteSparse_GPURuntime 3.2.0 REQUIRED ) + find_package ( SuiteSparse_GPURuntime 3.2.1 REQUIRED ) endif ( ) endif ( ) @@ -73,40 +73,40 @@ set ( DEMO_OK false ) if ( DEMO AND DEMO_OK ) # for the demo only: - find_package ( AMD 3.2.0 + find_package ( AMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../AMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::AMD ) - find_package ( AMD 3.2.0 ) + find_package ( AMD 3.2.1 ) endif ( ) - find_package ( COLAMD 3.2.0 + find_package ( COLAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../COLAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::COLAMD ) - find_package ( COLAMD 3.2.0 ) + find_package ( COLAMD 3.2.1 ) endif ( ) - find_package ( CAMD 3.2.0 + find_package ( CAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../CAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CAMD ) - find_package ( CAMD 3.2.0 ) + find_package ( CAMD 3.2.1 ) endif ( ) - find_package ( CCOLAMD 3.2.0 + find_package ( CCOLAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../CCOLAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CCOLAMD ) - find_package ( CCOLAMD 3.2.0 ) + find_package ( CCOLAMD 3.2.1 ) endif ( ) - find_package ( CHOLMOD 4.2.0 + find_package ( CHOLMOD 5.0.0 PATHS ${CMAKE_SOURCE_DIR}/../CHOLMOD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CHOLMOD ) - find_package ( CHOLMOD 4.2.0 ) + find_package ( CHOLMOD 5.0.0 ) endif ( ) - find_package ( CHOLMOD_CUDA 4.2.0 + find_package ( CHOLMOD_CUDA 5.0.0 PATHS ${CMAKE_SOURCE_DIR}/../CHOLMOD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CHOLMOD_CUDA ) - find_package ( CHOLMOD_CUDA 4.2.0 ) + find_package ( CHOLMOD_CUDA 5.0.0 ) endif ( ) endif ( ) diff --git a/GPUQREngine/Doc/ChangeLog b/GPUQREngine/Doc/ChangeLog index ee328927e..d6193cc51 100644 --- a/GPUQREngine/Doc/ChangeLog +++ b/GPUQREngine/Doc/ChangeLog @@ -1,3 +1,7 @@ +Oct 23, 2023: version 3.2.2 + + * for SuiteSparse 7.3.0: update for CHOLMOD 5.0.0 + Sept 18, 2023: version 3.2.1 * cmake update: add "None" build type, from Antonio Rojas, for Arch Linux diff --git a/GPUQREngine/Include/GPUQREngine.hpp b/GPUQREngine/Include/GPUQREngine.hpp index b262c9346..f35aff022 100644 --- a/GPUQREngine/Include/GPUQREngine.hpp +++ b/GPUQREngine/Include/GPUQREngine.hpp @@ -12,10 +12,10 @@ #define GPUQRENGINE_HPP // Version information: -#define GPUQRENGINE_DATE "Sept 18, 2023" +#define GPUQRENGINE_DATE "Oct 23, 2023" #define GPUQRENGINE_MAIN_VERSION 3 #define GPUQRENGINE_SUB_VERSION 2 -#define GPUQRENGINE_SUBSUB_VERSION 1 +#define GPUQRENGINE_SUBSUB_VERSION 2 #define GPUQRENGINE_VER_CODE(main,sub) ((main) * 1000 + (sub)) #define GPUQRENGINE_VERSION \ diff --git a/KLU/CMakeLists.txt b/KLU/CMakeLists.txt index 345b29f9c..6b21b8708 100644 --- a/KLU/CMakeLists.txt +++ b/KLU/CMakeLists.txt @@ -12,10 +12,10 @@ cmake_minimum_required ( VERSION 3.20 ) -set ( KLU_DATE "Sept 18, 2023" ) +set ( KLU_DATE "Oct 23, 2023" ) set ( KLU_VERSION_MAJOR 2 ) set ( KLU_VERSION_MINOR 2 ) -set ( KLU_VERSION_SUB 1 ) +set ( KLU_VERSION_SUB 2 ) message ( STATUS "Building KLU version: v" ${KLU_VERSION_MAJOR}. @@ -53,51 +53,51 @@ endif ( ) # find library dependencies #------------------------------------------------------------------------------- -find_package ( SuiteSparse_config 7.2.0 +find_package ( SuiteSparse_config 7.3.0 PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) - find_package ( SuiteSparse_config 7.2.0 REQUIRED ) + find_package ( SuiteSparse_config 7.3.0 REQUIRED ) endif ( ) -find_package ( BTF 2.2.0 +find_package ( BTF 2.2.1 PATHS ${CMAKE_SOURCE_DIR}/../BTF/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::BTF ) - find_package ( BTF 2.2.0 REQUIRED ) + find_package ( BTF 2.2.1 REQUIRED ) endif ( ) -find_package ( COLAMD 3.2.0 +find_package ( COLAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../COLAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::COLAMD ) - find_package ( COLAMD 3.2.0 REQUIRED ) + find_package ( COLAMD 3.2.1 REQUIRED ) endif ( ) -find_package ( AMD 3.2.0 +find_package ( AMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../AMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::AMD ) - find_package ( AMD 3.2.0 REQUIRED ) + find_package ( AMD 3.2.1 REQUIRED ) endif ( ) option ( NCHOLMOD "ON: do not use CHOLMOD. OFF (default): use CHOLMOD" off ) if ( NOT NCHOLMOD ) # look for CHOLMOD (optional fill-reducing orderings) - find_package ( CHOLMOD 4.2.0 + find_package ( CHOLMOD 5.0.0 PATHS ${CMAKE_SOURCE_DIR}/../CHOLMOD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CHOLMOD ) - find_package ( CHOLMOD 4.2.0 ) + find_package ( CHOLMOD 5.0.0 ) endif ( ) # look for CHOLMOD's dependencies: AMD and COLAMD are required. CAMD and # CCOLAMD are optional, but must be found if CHOLMOD was built with them. - find_package ( CAMD 3.2.0 + find_package ( CAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../CAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CAMD ) - find_package ( CAMD 3.2.0 ) + find_package ( CAMD 3.2.1 ) endif ( ) - find_package ( CCOLAMD 3.2.0 + find_package ( CCOLAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../CCOLAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CCOLAMD ) - find_package ( CCOLAMD 3.2.0 ) + find_package ( CCOLAMD 3.2.1 ) endif ( ) if ( NOT CHOLMOD_FOUND OR NOT AMD_FOUND OR NOT COLAMD_FOUND ) diff --git a/KLU/Doc/ChangeLog b/KLU/Doc/ChangeLog index f7c7aedee..2fabbdec2 100644 --- a/KLU/Doc/ChangeLog +++ b/KLU/Doc/ChangeLog @@ -1,3 +1,7 @@ +Oct 23, 2023: version 2.2.2 + + * for SuiteSparse 7.3.0: update for CHOLMOD 5.0.0 + Sept 18, 2023: version 2.2.1 * cmake update: add "None" build type, from Antonio Rojas, for Arch Linux diff --git a/KLU/Doc/KLU_UserGuide.pdf b/KLU/Doc/KLU_UserGuide.pdf index 1d4c9f925..15384afc1 100644 Binary files a/KLU/Doc/KLU_UserGuide.pdf and b/KLU/Doc/KLU_UserGuide.pdf differ diff --git a/KLU/Doc/klu_version.tex b/KLU/Doc/klu_version.tex index 750180267..6263661a9 100644 --- a/KLU/Doc/klu_version.tex +++ b/KLU/Doc/klu_version.tex @@ -1,2 +1,2 @@ % version of SuiteSparse/KLU -\date{VERSION 2.2.1, Sept 18, 2023} +\date{VERSION 2.2.2, Oct 23, 2023} diff --git a/KLU/Include/klu.h b/KLU/Include/klu.h index d855727f0..41c0d1f3e 100644 --- a/KLU/Include/klu.h +++ b/KLU/Include/klu.h @@ -814,10 +814,10 @@ void *klu_l_realloc (size_t, size_t, size_t, void *, klu_l_common *) ; * #endif */ -#define KLU_DATE "Sept 18, 2023" +#define KLU_DATE "Oct 23, 2023" #define KLU_MAIN_VERSION 2 #define KLU_SUB_VERSION 2 -#define KLU_SUBSUB_VERSION 1 +#define KLU_SUBSUB_VERSION 2 #define KLU_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) #define KLU_VERSION KLU_VERSION_CODE(KLU_MAIN_VERSION,KLU_SUB_VERSION) diff --git a/KLU/MATLAB/klu_make.m b/KLU/MATLAB/klu_make.m index 9a67326da..26bfc1e83 100644 --- a/KLU/MATLAB/klu_make.m +++ b/KLU/MATLAB/klu_make.m @@ -89,20 +89,77 @@ '../../CCOLAMD/Source/ccolamd_l' } ; cholmod_src = { - '../../CHOLMOD/Core/cholmod_l_aat', ... - '../../CHOLMOD/Core/cholmod_l_add', ... - '../../CHOLMOD/Core/cholmod_l_band', ... - '../../CHOLMOD/Core/cholmod_l_change_factor', ... - '../../CHOLMOD/Core/cholmod_l_common', ... - '../../CHOLMOD/Core/cholmod_l_complex', ... - '../../CHOLMOD/Core/cholmod_l_copy', ... - '../../CHOLMOD/Core/cholmod_l_dense', ... - '../../CHOLMOD/Core/cholmod_l_error', ... - '../../CHOLMOD/Core/cholmod_l_factor', ... - '../../CHOLMOD/Core/cholmod_l_memory', ... - '../../CHOLMOD/Core/cholmod_l_sparse', ... - '../../CHOLMOD/Core/cholmod_l_transpose', ... - '../../CHOLMOD/Core/cholmod_l_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_aat', ... + '../../CHOLMOD/Utility/cholmod_l_add', ... + '../../CHOLMOD/Utility/cholmod_l_add_size_t', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_dense', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_factor', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_work', ... + '../../CHOLMOD/Utility/cholmod_l_alloc_factor', ... + '../../CHOLMOD/Utility/cholmod_l_alloc_work', ... + '../../CHOLMOD/Utility/cholmod_l_band', ... + '../../CHOLMOD/Utility/cholmod_l_band_nnz', ... + '../../CHOLMOD/Utility/cholmod_l_calloc', ... + '../../CHOLMOD/Utility/cholmod_l_change_factor', ... + '../../CHOLMOD/Utility/cholmod_l_clear_flag', ... + '../../CHOLMOD/Utility/cholmod_l_copy', ... + '../../CHOLMOD/Utility/cholmod_l_copy_dense2', ... + '../../CHOLMOD/Utility/cholmod_l_copy_dense', ... + '../../CHOLMOD/Utility/cholmod_l_copy_factor', ... + '../../CHOLMOD/Utility/cholmod_l_copy_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_copy_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_cumsum', ... + '../../CHOLMOD/Utility/cholmod_l_dbound', ... + '../../CHOLMOD/Utility/cholmod_l_defaults', ... + '../../CHOLMOD/Utility/cholmod_l_dense_nnz', ... + '../../CHOLMOD/Utility/cholmod_l_dense_to_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_divcomplex', ... + '../../CHOLMOD/Utility/cholmod_l_ensure_dense', ... + '../../CHOLMOD/Utility/cholmod_l_error', ... + '../../CHOLMOD/Utility/cholmod_l_eye', ... + '../../CHOLMOD/Utility/cholmod_l_factor_to_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_finish', ... + '../../CHOLMOD/Utility/cholmod_l_free', ... + '../../CHOLMOD/Utility/cholmod_l_free_dense', ... + '../../CHOLMOD/Utility/cholmod_l_free_factor', ... + '../../CHOLMOD/Utility/cholmod_l_free_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_free_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_free_work', ... + '../../CHOLMOD/Utility/cholmod_l_hypot', ... + '../../CHOLMOD/Utility/cholmod_l_malloc', ... + '../../CHOLMOD/Utility/cholmod_l_maxrank', ... + '../../CHOLMOD/Utility/cholmod_l_mult_size_t', ... + '../../CHOLMOD/Utility/cholmod_l_nnz', ... + '../../CHOLMOD/Utility/cholmod_l_ones', ... + '../../CHOLMOD/Utility/cholmod_l_pack_factor', ... + '../../CHOLMOD/Utility/cholmod_l_ptranspose', ... + '../../CHOLMOD/Utility/cholmod_l_reallocate_column', ... + '../../CHOLMOD/Utility/cholmod_l_reallocate_factor', ... + '../../CHOLMOD/Utility/cholmod_l_reallocate_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_reallocate_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_realloc', ... + '../../CHOLMOD/Utility/cholmod_l_realloc_multiple', ... + '../../CHOLMOD/Utility/cholmod_l_sbound', ... + '../../CHOLMOD/Utility/cholmod_l_score_comp', ... + '../../CHOLMOD/Utility/cholmod_l_set_empty', ... + '../../CHOLMOD/Utility/cholmod_l_sort', ... + '../../CHOLMOD/Utility/cholmod_l_sparse_to_dense', ... + '../../CHOLMOD/Utility/cholmod_l_sparse_to_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_speye', ... + '../../CHOLMOD/Utility/cholmod_l_spzeros', ... + '../../CHOLMOD/Utility/cholmod_l_start', ... + '../../CHOLMOD/Utility/cholmod_l_transpose', ... + '../../CHOLMOD/Utility/cholmod_l_transpose_sym', ... + '../../CHOLMOD/Utility/cholmod_l_transpose_unsym', ... + '../../CHOLMOD/Utility/cholmod_l_triplet_to_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_version', ... + '../../CHOLMOD/Utility/cholmod_l_xtype', ... + '../../CHOLMOD/Utility/cholmod_l_zeros', ... + '../../CHOLMOD/Utility/cholmod_mult_uint64_t', ... + '../../CHOLMOD/Utility/cholmod_memdebug', ... + '../../CHOLMOD/Check/cholmod_l_check', ... '../../CHOLMOD/Cholesky/cholmod_l_amd', ... '../../CHOLMOD/Cholesky/cholmod_l_analyze', ... '../../CHOLMOD/Cholesky/cholmod_l_colamd', ... @@ -177,11 +234,7 @@ end if (pc) - % Windows does not have drand48 and srand48, required by METIS. Use - % drand48 and srand48 in CHOLMOD/MATLAB/Windows/rand48.c instead. obj_extension = '.obj' ; - cholmod_src = [cholmod_src {'../../CHOLMOD/MATLAB/Windows/rand48'}] ; - include = [include ' -I../../CHOLMOD/MATLAB/Windows'] ; else obj_extension = '.o' ; end diff --git a/KLU/User/klu_l_cholmod.c b/KLU/User/klu_l_cholmod.c index 8dd765b23..2ab55e378 100644 --- a/KLU/User/klu_l_cholmod.c +++ b/KLU/User/klu_l_cholmod.c @@ -43,7 +43,6 @@ int64_t klu_l_cholmod int64_t *P ; int64_t k ; int symmetric ; - printf ("------------------- KLU User\n") ; klu_l_common km ; klu_l_defaults (&km) ; @@ -65,7 +64,7 @@ int64_t klu_l_cholmod A->nzmax = Ap [n] ; /* with nzmax entries */ A->packed = TRUE ; /* there is no A->nz array */ A->stype = 0 ; /* A is unsymmetric */ - A->itype = CHOLMOD_INT ; + A->itype = CHOLMOD_LONG ; A->xtype = CHOLMOD_PATTERN ; A->dtype = CHOLMOD_DOUBLE ; A->nz = NULL ; diff --git a/LICENSE.txt b/LICENSE.txt index 0e51e9e0c..71525a680 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -235,14 +235,14 @@ found in the lists below. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -------------------------------------------------------------------------------- - ==> Core/License.txt <== + ==> Utility/License.txt <== -------------------------------------------------------------------------------- - CHOLMOD/Core Module. Copyright (C) 2005-2022, Univ. of Florida. Author: - Timothy A. Davis. CHOLMOD is also available under other licenses; contact - authors for details. http://suitesparse.com + CHOLMOD/Utility Module, Copyright (C) 2023, Timothy A. Davis. + CHOLMOD is also available under other licenses; contact authors for + details. http://suitesparse.com - Note that this license is for the CHOLMOD/Core module only. + Note that this license is for the CHOLMOD/Utility module only. All CHOLMOD modules are licensed separately. @@ -303,22 +303,9 @@ found in the lists below. contains definitions and prototypes: Include/cholmod.h LGPL - Include/cholmod_camd.h part of Partition module - Include/cholmod_check.h part of Check module - Include/cholmod_cholesky.h part of Cholesky module - Include/cholmod_complexity.h LGPL - Include/cholmod_config.h LGPL - Include/cholmod_core.h part of Core module - Include/cholmod_function.h no license; freely usable, no restrictions - Include/cholmod_gpu.h part of GPU module - Include/cholmod_gpu_kernels.h part of GPU module Include/cholmod_internal.h LGPL - Include/cholmod_io64.h LGPL - Include/cholmod_matrixops.h part of MatrixOps module - Include/cholmod_modify.h part of Modify module - Include/cholmod_partition.h part of Partition module - Include/cholmod_supernodal.h part of Supernodal module Include/cholmod_template.h LGPL + Include/cholmod_types.h -------------------------------------------------------------------------------- ==> MATLAB/License.txt <== diff --git a/README.md b/README.md index 1f09b5dee..65fac5cdd 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ SuiteSparse: A Suite of Sparse matrix packages at http://suitesparse.com ----------------------------------------------------------------------------- -Oct 15, 2023, SuiteSparse VERSION 7.2.2 +Oct 23, 2023, SuiteSparse VERSION 7.3.0 SuiteSparse is a set of sparse-matrix-related packages written or co-authored by Tim Davis, available at https://github.com/DrTimothyAldenDavis/SuiteSparse . diff --git a/SPQR/CMakeLists.txt b/SPQR/CMakeLists.txt index cb88165ba..abb0fb1ef 100644 --- a/SPQR/CMakeLists.txt +++ b/SPQR/CMakeLists.txt @@ -13,10 +13,10 @@ # cmake 3.22 is required to find the BLAS in SuiteSparsePolicy.cmake cmake_minimum_required ( VERSION 3.22 ) -set ( SPQR_DATE "Sept 18, 2023" ) +set ( SPQR_DATE "Oct 23, 2023" ) set ( SPQR_VERSION_MAJOR 4 ) set ( SPQR_VERSION_MINOR 2 ) -set ( SPQR_VERSION_SUB 1 ) +set ( SPQR_VERSION_SUB 2 ) message ( STATUS "Building SPQR version: v" ${SPQR_VERSION_MAJOR}. @@ -54,63 +54,63 @@ else ( ) find_package ( OpenMP ) endif ( ) -find_package ( SuiteSparse_config 7.2.0 +find_package ( SuiteSparse_config 7.3.0 PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) - find_package ( SuiteSparse_config 7.2.0 REQUIRED ) + find_package ( SuiteSparse_config 7.3.0 REQUIRED ) endif ( ) -find_package ( AMD 3.2.0 +find_package ( AMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../AMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::AMD ) - find_package ( AMD 3.2.0 REQUIRED ) + find_package ( AMD 3.2.1 REQUIRED ) endif ( ) -find_package ( COLAMD 3.2.0 +find_package ( COLAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../COLAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::COLAMD ) - find_package ( COLAMD 3.2.0 REQUIRED ) + find_package ( COLAMD 3.2.1 REQUIRED ) endif ( ) # It would be nice if just checking for CHOLMOD would automatically pull in # the targets for its dependencies. -find_package ( CHOLMOD 4.2.0 +find_package ( CHOLMOD 5.0.0 PATHS ${CMAKE_SOURCE_DIR}/../CHOLMOD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CHOLMOD ) - find_package ( CHOLMOD 4.2.0 REQUIRED ) + find_package ( CHOLMOD 5.0.0 REQUIRED ) endif ( ) # look for CHOLMOD's dependencies: AMD and COLAMD are required. CAMD and # CCOLAMD are optional, but must be found if CHOLMOD was built with them. -find_package ( CAMD 3.2.0 +find_package ( CAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../CAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CAMD ) - find_package ( CAMD 3.2.0 ) + find_package ( CAMD 3.2.1 ) endif ( ) -find_package ( CCOLAMD 3.2.0 +find_package ( CCOLAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../CCOLAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CCOLAMD ) - find_package ( CCOLAMD 3.2.0 ) + find_package ( CCOLAMD 3.2.1 ) endif ( ) if ( SUITESPARSE_CUDA ) - find_package ( SuiteSparse_GPURuntime 3.2.0 + find_package ( SuiteSparse_GPURuntime 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_GPURuntime/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::GPURuntime ) - find_package ( SuiteSparse_GPURuntime 3.2.0 REQUIRED ) + find_package ( SuiteSparse_GPURuntime 3.2.1 REQUIRED ) endif ( ) - find_package ( GPUQREngine 3.2.0 + find_package ( GPUQREngine 3.2.2 PATHS ${CMAKE_SOURCE_DIR}/../GPUQREngine/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::GPUQREngine ) - find_package ( GPUQREngine 3.2.0 REQUIRED ) + find_package ( GPUQREngine 3.2.2 REQUIRED ) endif ( ) - find_package ( CHOLMOD_CUDA 4.2.0 + find_package ( CHOLMOD_CUDA 5.0.0 PATHS ${CMAKE_SOURCE_DIR}/../CHOLMOD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CHOLMOD_CUDA ) - find_package ( CHOLMOD_CUDA 4.2.0 REQUIRED ) + find_package ( CHOLMOD_CUDA 5.0.0 REQUIRED ) endif ( ) endif ( ) diff --git a/SPQR/Doc/ChangeLog b/SPQR/Doc/ChangeLog index fe55a9fb5..ae16defb9 100644 --- a/SPQR/Doc/ChangeLog +++ b/SPQR/Doc/ChangeLog @@ -1,3 +1,7 @@ +Oct 23, 2023: version 4.2.2 + + * for SuiteSparse 7.3.0: update for CHOLMOD 5.0.0 + Sept 18, 2023: version 4.2.1 * cmake update: add "None" build type, from Antonio Rojas, for Arch Linux diff --git a/SPQR/Doc/spqr_user_guide.pdf b/SPQR/Doc/spqr_user_guide.pdf index 77727f5ec..799367147 100644 Binary files a/SPQR/Doc/spqr_user_guide.pdf and b/SPQR/Doc/spqr_user_guide.pdf differ diff --git a/SPQR/Doc/spqr_version.tex b/SPQR/Doc/spqr_version.tex index 63a04a715..56b54f903 100644 --- a/SPQR/Doc/spqr_version.tex +++ b/SPQR/Doc/spqr_version.tex @@ -1,2 +1,2 @@ % version of SuiteSparse/SPQR -\date{VERSION 4.2.1, Sept 18, 2023} +\date{VERSION 4.2.2, Oct 23, 2023} diff --git a/SPQR/Include/SuiteSparseQR_definitions.h b/SPQR/Include/SuiteSparseQR_definitions.h index 0dce203a9..5793d7976 100644 --- a/SPQR/Include/SuiteSparseQR_definitions.h +++ b/SPQR/Include/SuiteSparseQR_definitions.h @@ -62,10 +62,10 @@ #endif */ -#define SPQR_DATE "Sept 18, 2023" +#define SPQR_DATE "Oct 23, 2023" #define SPQR_MAIN_VERSION 4 #define SPQR_SUB_VERSION 2 -#define SPQR_SUBSUB_VERSION 1 +#define SPQR_SUBSUB_VERSION 2 #define SPQR_VER_CODE(main,sub) ((main) * 1000 + (sub)) #define SPQR_VERSION SPQR_VER_CODE(SPQR_MAIN_VERSION,SPQR_SUB_VERSION) diff --git a/SPQR/Include/spqr.hpp b/SPQR/Include/spqr.hpp index 5b62502d9..e7c454c16 100644 --- a/SPQR/Include/spqr.hpp +++ b/SPQR/Include/spqr.hpp @@ -118,11 +118,6 @@ { \ return (result) ; \ } \ - if (cc->dtype != DTYPE) \ - { \ - cc->status = CHOLMOD_INVALID ; \ - return (result) ; \ - } \ } #define RETURN_IF_XTYPE_INVALID(A,result) \ diff --git a/SPQR/MATLAB/spqr.cpp b/SPQR/MATLAB/spqr.cpp index 3d158c984..45a27dae0 100644 --- a/SPQR/MATLAB/spqr.cpp +++ b/SPQR/MATLAB/spqr.cpp @@ -311,14 +311,14 @@ void mexFunction if (B_is_sparse) { // B and C are both sparse and complex - SuiteSparseQR (order, tol, econ, A, Bsparse, + SuiteSparseQR (order, tol, econ, A, Bsparse, &Csparse, &R, &E, cc) ; pargout [0] = spqr_mx_put_sparse (&Csparse, cc) ; } else { // B and C are both dense and complex - SuiteSparseQR (order, tol, econ, A, Bdense, + SuiteSparseQR (order, tol, econ, A, Bdense, &Cdense, &R, &E, cc) ; pargout [0] = spqr_mx_put_dense (&Cdense, cc) ; } @@ -334,14 +334,14 @@ void mexFunction if (B_is_sparse) { // B and C are both sparse and real - SuiteSparseQR (order, tol, econ, A, Bsparse, + SuiteSparseQR (order, tol, econ, A, Bsparse, &Csparse, &R, &E, cc) ; pargout [0] = spqr_mx_put_sparse (&Csparse, cc) ; } else { // B and C are both dense and real - SuiteSparseQR (order, tol, econ, A, Bdense, + SuiteSparseQR (order, tol, econ, A, Bdense, &Cdense, &R, &E, cc) ; pargout [0] = spqr_mx_put_dense (&Cdense, cc) ; } @@ -359,11 +359,11 @@ void mexFunction if (is_complex) { - SuiteSparseQR (0, tol, econ, A, &R, NULL, cc) ; + SuiteSparseQR (0, tol, econ, A, &R, NULL, cc) ; } else { - SuiteSparseQR (0, tol, econ, A, &R, NULL, cc) ; + SuiteSparseQR (0, tol, econ, A, &R, NULL, cc) ; } pargout [0] = spqr_mx_put_sparse (&R, cc) ; @@ -384,11 +384,13 @@ void mexFunction if (is_complex) { - SuiteSparseQR (order, tol, econ, A, &R, &E, cc); + SuiteSparseQR (order, tol, econ, A, &R, &E, + cc); } else { - SuiteSparseQR (order, tol, econ, A, &R, &E, cc) ; + SuiteSparseQR (order, tol, econ, A, &R, &E, + cc) ; } pargout [0] = mxCreateDoubleMatrix (0, 0, mxREAL) ; @@ -402,11 +404,11 @@ void mexFunction if (is_complex) { - SuiteSparseQR (order, tol, econ, A, &Q, &R, &E, cc) ; + SuiteSparseQR (order, tol, econ, A, &Q, &R, &E, cc) ; } else { - SuiteSparseQR (order, tol, econ, A, &Q, &R, &E, cc) ; + SuiteSparseQR (order, tol, econ, A, &Q, &R, &E, cc) ; } pargout [0] = spqr_mx_put_sparse (&Q, cc) ; @@ -421,12 +423,12 @@ void mexFunction mxArray *Tau, *P, *Hmatlab ; if (is_complex) { - SuiteSparseQR (order, tol, econ, A, + SuiteSparseQR (order, tol, econ, A, &R, &E, &H, &HPinv, &HTau, cc) ; } else { - SuiteSparseQR (order, tol, econ, A, + SuiteSparseQR (order, tol, econ, A, &R, &E, &H, &HPinv, &HTau, cc) ; } diff --git a/SPQR/MATLAB/spqr_make.m b/SPQR/MATLAB/spqr_make.m index c5b83c1ad..fb33de591 100644 --- a/SPQR/MATLAB/spqr_make.m +++ b/SPQR/MATLAB/spqr_make.m @@ -133,10 +133,23 @@ '../../AMD/Source/amd_l_postorder', ... '../../AMD/Source/amd_l_post_tree', ... '../../AMD/Source/amd_l_preprocess', ... - '../../AMD/Source/amd_l_valid' } ; + '../../AMD/Source/amd_l_valid', ... + '../../AMD/Source/amd_1', ... + '../../AMD/Source/amd_2', ... + '../../AMD/Source/amd_aat', ... + '../../AMD/Source/amd_control', ... + '../../AMD/Source/amd_defaults', ... + '../../AMD/Source/amd_dump', ... + '../../AMD/Source/amd_info', ... + '../../AMD/Source/amd_order', ... + '../../AMD/Source/amd_postorder', ... + '../../AMD/Source/amd_post_tree', ... + '../../AMD/Source/amd_preprocess', ... + '../../AMD/Source/amd_valid' } ; colamd_c_src = { - '../../COLAMD/Source/colamd_l' } ; + '../../COLAMD/Source/colamd_l', ... + '../../COLAMD/Source/colamd' } ; % CAMD and CCOLAMD are not needed if we don't have METIS camd_c_src = { ... @@ -150,26 +163,95 @@ '../../CAMD/Source/camd_l_order', ... '../../CAMD/Source/camd_l_postorder', ... '../../CAMD/Source/camd_l_preprocess', ... - '../../CAMD/Source/camd_l_valid' } ; + '../../CAMD/Source/camd_l_valid', ... + '../../CAMD/Source/camd_1', ... + '../../CAMD/Source/camd_2', ... + '../../CAMD/Source/camd_aat', ... + '../../CAMD/Source/camd_control', ... + '../../CAMD/Source/camd_defaults', ... + '../../CAMD/Source/camd_dump', ... + '../../CAMD/Source/camd_info', ... + '../../CAMD/Source/camd_order', ... + '../../CAMD/Source/camd_postorder', ... + '../../CAMD/Source/camd_preprocess', ... + '../../CAMD/Source/camd_valid' } ; + ccolamd_c_src = { - '../../CCOLAMD/Source/ccolamd_l' } ; + '../../CCOLAMD/Source/ccolamd_l', ... + '../../CCOLAMD/Source/ccolamd' } ; cholmod_c_src = { - '../../CHOLMOD/Core/cholmod_l_aat', ... - '../../CHOLMOD/Core/cholmod_l_add', ... - '../../CHOLMOD/Core/cholmod_l_band', ... - '../../CHOLMOD/Core/cholmod_l_change_factor', ... - '../../CHOLMOD/Core/cholmod_l_common', ... - '../../CHOLMOD/Core/cholmod_l_complex', ... - '../../CHOLMOD/Core/cholmod_l_copy', ... - '../../CHOLMOD/Core/cholmod_l_dense', ... - '../../CHOLMOD/Core/cholmod_l_error', ... - '../../CHOLMOD/Core/cholmod_l_factor', ... - '../../CHOLMOD/Core/cholmod_l_memory', ... - '../../CHOLMOD/Core/cholmod_l_sparse', ... - '../../CHOLMOD/Core/cholmod_l_transpose', ... - '../../CHOLMOD/Core/cholmod_l_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_aat', ... + '../../CHOLMOD/Utility/cholmod_l_add', ... + '../../CHOLMOD/Utility/cholmod_l_add_size_t', ... + '../../CHOLMOD/Utility/cholmod_l_alloc_factor', ... + '../../CHOLMOD/Utility/cholmod_l_alloc_work', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_dense', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_factor', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_work', ... + '../../CHOLMOD/Utility/cholmod_l_band', ... + '../../CHOLMOD/Utility/cholmod_l_band_nnz', ... + '../../CHOLMOD/Utility/cholmod_l_calloc', ... + '../../CHOLMOD/Utility/cholmod_l_change_factor', ... + '../../CHOLMOD/Utility/cholmod_l_clear_flag', ... + '../../CHOLMOD/Utility/cholmod_l_copy', ... + '../../CHOLMOD/Utility/cholmod_l_copy_dense', ... + '../../CHOLMOD/Utility/cholmod_l_copy_dense2', ... + '../../CHOLMOD/Utility/cholmod_l_copy_factor', ... + '../../CHOLMOD/Utility/cholmod_l_copy_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_copy_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_cumsum', ... + '../../CHOLMOD/Utility/cholmod_l_dbound', ... + '../../CHOLMOD/Utility/cholmod_l_defaults', ... + '../../CHOLMOD/Utility/cholmod_l_dense_nnz', ... + '../../CHOLMOD/Utility/cholmod_l_dense_to_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_divcomplex', ... + '../../CHOLMOD/Utility/cholmod_l_ensure_dense', ... + '../../CHOLMOD/Utility/cholmod_l_error', ... + '../../CHOLMOD/Utility/cholmod_l_eye', ... + '../../CHOLMOD/Utility/cholmod_l_factor_to_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_finish', ... + '../../CHOLMOD/Utility/cholmod_l_free', ... + '../../CHOLMOD/Utility/cholmod_l_free_dense', ... + '../../CHOLMOD/Utility/cholmod_l_free_factor', ... + '../../CHOLMOD/Utility/cholmod_l_free_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_free_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_free_work', ... + '../../CHOLMOD/Utility/cholmod_l_hypot', ... + '../../CHOLMOD/Utility/cholmod_l_malloc', ... + '../../CHOLMOD/Utility/cholmod_l_maxrank', ... + '../../CHOLMOD/Utility/cholmod_l_mult_size_t', ... + '../../CHOLMOD/Utility/cholmod_l_nnz', ... + '../../CHOLMOD/Utility/cholmod_l_ones', ... + '../../CHOLMOD/Utility/cholmod_l_pack_factor', ... + '../../CHOLMOD/Utility/cholmod_l_ptranspose', ... + '../../CHOLMOD/Utility/cholmod_l_realloc', ... + '../../CHOLMOD/Utility/cholmod_l_realloc_multiple', ... + '../../CHOLMOD/Utility/cholmod_l_reallocate_column', ... + '../../CHOLMOD/Utility/cholmod_l_reallocate_factor', ... + '../../CHOLMOD/Utility/cholmod_l_reallocate_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_reallocate_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_sbound', ... + '../../CHOLMOD/Utility/cholmod_l_score_comp', ... + '../../CHOLMOD/Utility/cholmod_l_set_empty', ... + '../../CHOLMOD/Utility/cholmod_l_sort', ... + '../../CHOLMOD/Utility/cholmod_l_sparse_to_dense', ... + '../../CHOLMOD/Utility/cholmod_l_sparse_to_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_speye', ... + '../../CHOLMOD/Utility/cholmod_l_spzeros', ... + '../../CHOLMOD/Utility/cholmod_l_start', ... + '../../CHOLMOD/Utility/cholmod_l_transpose', ... + '../../CHOLMOD/Utility/cholmod_l_transpose_sym', ... + '../../CHOLMOD/Utility/cholmod_l_transpose_unsym', ... + '../../CHOLMOD/Utility/cholmod_l_triplet_to_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_version', ... + '../../CHOLMOD/Utility/cholmod_l_xtype', ... + '../../CHOLMOD/Utility/cholmod_l_zeros', ... + '../../CHOLMOD/Utility/cholmod_mult_uint64_t', ... + '../../CHOLMOD/Utility/cholmod_memdebug', ... '../../CHOLMOD/Check/cholmod_l_check', ... '../../CHOLMOD/Check/cholmod_l_read', ... '../../CHOLMOD/Check/cholmod_l_write', ... @@ -187,7 +269,93 @@ '../../CHOLMOD/Cholesky/cholmod_l_spsolve', ... '../../CHOLMOD/Supernodal/cholmod_l_super_numeric', ... '../../CHOLMOD/Supernodal/cholmod_l_super_solve', ... - '../../CHOLMOD/Supernodal/cholmod_l_super_symbolic' } ; + '../../CHOLMOD/Supernodal/cholmod_l_super_symbolic', ... + '../../CHOLMOD/Utility/cholmod_aat', ... + '../../CHOLMOD/Utility/cholmod_add', ... + '../../CHOLMOD/Utility/cholmod_add_size_t', ... + '../../CHOLMOD/Utility/cholmod_alloc_factor', ... + '../../CHOLMOD/Utility/cholmod_alloc_work', ... + '../../CHOLMOD/Utility/cholmod_allocate_dense', ... + '../../CHOLMOD/Utility/cholmod_allocate_factor', ... + '../../CHOLMOD/Utility/cholmod_allocate_sparse', ... + '../../CHOLMOD/Utility/cholmod_allocate_triplet', ... + '../../CHOLMOD/Utility/cholmod_allocate_work', ... + '../../CHOLMOD/Utility/cholmod_band', ... + '../../CHOLMOD/Utility/cholmod_band_nnz', ... + '../../CHOLMOD/Utility/cholmod_calloc', ... + '../../CHOLMOD/Utility/cholmod_change_factor', ... + '../../CHOLMOD/Utility/cholmod_clear_flag', ... + '../../CHOLMOD/Utility/cholmod_copy', ... + '../../CHOLMOD/Utility/cholmod_copy_dense', ... + '../../CHOLMOD/Utility/cholmod_copy_dense2', ... + '../../CHOLMOD/Utility/cholmod_copy_factor', ... + '../../CHOLMOD/Utility/cholmod_copy_sparse', ... + '../../CHOLMOD/Utility/cholmod_copy_triplet', ... + '../../CHOLMOD/Utility/cholmod_cumsum', ... + '../../CHOLMOD/Utility/cholmod_dbound', ... + '../../CHOLMOD/Utility/cholmod_defaults', ... + '../../CHOLMOD/Utility/cholmod_dense_nnz', ... + '../../CHOLMOD/Utility/cholmod_dense_to_sparse', ... + '../../CHOLMOD/Utility/cholmod_divcomplex', ... + '../../CHOLMOD/Utility/cholmod_ensure_dense', ... + '../../CHOLMOD/Utility/cholmod_error', ... + '../../CHOLMOD/Utility/cholmod_eye', ... + '../../CHOLMOD/Utility/cholmod_factor_to_sparse', ... + '../../CHOLMOD/Utility/cholmod_finish', ... + '../../CHOLMOD/Utility/cholmod_free', ... + '../../CHOLMOD/Utility/cholmod_free_dense', ... + '../../CHOLMOD/Utility/cholmod_free_factor', ... + '../../CHOLMOD/Utility/cholmod_free_sparse', ... + '../../CHOLMOD/Utility/cholmod_free_triplet', ... + '../../CHOLMOD/Utility/cholmod_free_work', ... + '../../CHOLMOD/Utility/cholmod_hypot', ... + '../../CHOLMOD/Utility/cholmod_malloc', ... + '../../CHOLMOD/Utility/cholmod_maxrank', ... + '../../CHOLMOD/Utility/cholmod_mult_size_t', ... + '../../CHOLMOD/Utility/cholmod_nnz', ... + '../../CHOLMOD/Utility/cholmod_ones', ... + '../../CHOLMOD/Utility/cholmod_pack_factor', ... + '../../CHOLMOD/Utility/cholmod_ptranspose', ... + '../../CHOLMOD/Utility/cholmod_realloc', ... + '../../CHOLMOD/Utility/cholmod_realloc_multiple', ... + '../../CHOLMOD/Utility/cholmod_reallocate_column', ... + '../../CHOLMOD/Utility/cholmod_reallocate_factor', ... + '../../CHOLMOD/Utility/cholmod_reallocate_sparse', ... + '../../CHOLMOD/Utility/cholmod_reallocate_triplet', ... + '../../CHOLMOD/Utility/cholmod_sbound', ... + '../../CHOLMOD/Utility/cholmod_score_comp', ... + '../../CHOLMOD/Utility/cholmod_set_empty', ... + '../../CHOLMOD/Utility/cholmod_sort', ... + '../../CHOLMOD/Utility/cholmod_sparse_to_dense', ... + '../../CHOLMOD/Utility/cholmod_sparse_to_triplet', ... + '../../CHOLMOD/Utility/cholmod_speye', ... + '../../CHOLMOD/Utility/cholmod_spzeros', ... + '../../CHOLMOD/Utility/cholmod_start', ... + '../../CHOLMOD/Utility/cholmod_transpose', ... + '../../CHOLMOD/Utility/cholmod_transpose_sym', ... + '../../CHOLMOD/Utility/cholmod_transpose_unsym', ... + '../../CHOLMOD/Utility/cholmod_triplet_to_sparse', ... + '../../CHOLMOD/Utility/cholmod_version', ... + '../../CHOLMOD/Utility/cholmod_xtype', ... + '../../CHOLMOD/Utility/cholmod_zeros', ... + '../../CHOLMOD/Check/cholmod_check', ... + '../../CHOLMOD/Check/cholmod_read', ... + '../../CHOLMOD/Check/cholmod_write', ... + '../../CHOLMOD/Cholesky/cholmod_amd', ... + '../../CHOLMOD/Cholesky/cholmod_analyze', ... + '../../CHOLMOD/Cholesky/cholmod_colamd', ... + '../../CHOLMOD/Cholesky/cholmod_etree', ... + '../../CHOLMOD/Cholesky/cholmod_factorize', ... + '../../CHOLMOD/Cholesky/cholmod_postorder', ... + '../../CHOLMOD/Cholesky/cholmod_rcond', ... + '../../CHOLMOD/Cholesky/cholmod_resymbol', ... + '../../CHOLMOD/Cholesky/cholmod_rowcolcounts', ... + '../../CHOLMOD/Cholesky/cholmod_rowfac', ... + '../../CHOLMOD/Cholesky/cholmod_solve', ... + '../../CHOLMOD/Cholesky/cholmod_spsolve', ... + '../../CHOLMOD/Supernodal/cholmod_super_numeric', ... + '../../CHOLMOD/Supernodal/cholmod_super_solve', ... + '../../CHOLMOD/Supernodal/cholmod_super_symbolic' } ; cholmod_c_partition_src = { '../../CHOLMOD/Partition/cholmod_l_ccolamd', ... @@ -195,22 +363,27 @@ '../../CHOLMOD/Partition/cholmod_l_camd', ... '../../CHOLMOD/Partition/cholmod_metis_wrapper', ... '../../CHOLMOD/Partition/cholmod_l_metis', ... - '../../CHOLMOD/Partition/cholmod_l_nesdis' } ; + '../../CHOLMOD/Partition/cholmod_l_nesdis', ... + '../../CHOLMOD/Partition/cholmod_ccolamd', ... + '../../CHOLMOD/Partition/cholmod_csymamd', ... + '../../CHOLMOD/Partition/cholmod_camd', ... + '../../CHOLMOD/Partition/cholmod_metis', ... + '../../CHOLMOD/Partition/cholmod_nesdis' } ; % SuiteSparseQR does not need the MatrixOps or Modify modules of CHOLMOD % cholmod_unused = { -% '../../CHOLMOD/MatrixOps/cholmod_drop', ... -% '../../CHOLMOD/MatrixOps/cholmod_horzcat', ... -% '../../CHOLMOD/MatrixOps/cholmod_norm', ... -% '../../CHOLMOD/MatrixOps/cholmod_scale', ... -% '../../CHOLMOD/MatrixOps/cholmod_sdmult', ... -% '../../CHOLMOD/MatrixOps/cholmod_ssmult', ... -% '../../CHOLMOD/MatrixOps/cholmod_submatrix', ... -% '../../CHOLMOD/MatrixOps/cholmod_vertcat', ... -% '../../CHOLMOD/MatrixOps/cholmod_symmetry', ... -% '../../CHOLMOD/Modify/cholmod_rowadd', ... -% '../../CHOLMOD/Modify/cholmod_rowdel', ... -% '../../CHOLMOD/Modify/cholmod_updown' } ; +% '../../CHOLMOD/MatrixOps/cholmod_l_drop', ... +% '../../CHOLMOD/MatrixOps/cholmod_l_horzcat', ... +% '../../CHOLMOD/MatrixOps/cholmod_l_norm', ... +% '../../CHOLMOD/MatrixOps/cholmod_l_scale', ... +% '../../CHOLMOD/MatrixOps/cholmod_l_sdmult', ... +% '../../CHOLMOD/MatrixOps/cholmod_l_ssmult', ... +% '../../CHOLMOD/MatrixOps/cholmod_l_submatrix', ... +% '../../CHOLMOD/MatrixOps/cholmod_l_vertcat', ... +% '../../CHOLMOD/MatrixOps/cholmod_l_symmetry', ... +% '../../CHOLMOD/Modify/cholmod_l_rowadd', ... +% '../../CHOLMOD/Modify/cholmod_l_rowdel', ... +% '../../CHOLMOD/Modify/cholmod_l_updown' } ; % SuiteSparseQR source code, and mex support file spqr_cpp_src = { @@ -253,6 +426,7 @@ '../Source/SuiteSparseQR_qmult', ... '../Source/SuiteSparseQR', ... '../Source/SuiteSparseQR_expert', ... + '../Source/spqr_cholmod_wrappers', ... '../MATLAB/spqr_mx' } ; % SuiteSparse C source code, for MATLAB error handling @@ -262,12 +436,7 @@ spqr_mex_cpp_src = { 'spqr', 'spqr_qmult', 'spqr_solve', 'spqr_singletons' } ; if (pc) - % Windows does not have drand48 and srand48, required by METIS. Use - % drand48 and srand48 in CHOLMOD/MATLAB/Windows/rand48.c instead. - % Also provide Windows with an empty include file. obj_extension = '.obj' ; - cholmod_c_src = [cholmod_c_src {'../../CHOLMOD/MATLAB/Windows/rand48'}] ; - include = [include ' -I../../CHOLMOD/MATLAB/Windows'] ; else obj_extension = '.o' ; end diff --git a/SPQR/MATLAB/spqr_mx.cpp b/SPQR/MATLAB/spqr_mx.cpp index d6f7f9c79..0aeb7d8c0 100644 --- a/SPQR/MATLAB/spqr_mx.cpp +++ b/SPQR/MATLAB/spqr_mx.cpp @@ -939,7 +939,7 @@ void spqr_mx_get_usage char spqr_mx_debug_string [200] ; // global variable; debugging only char *spqr_mx_id (int line) { - sprintf (spqr_mx_debug_string, "QR:Line_%d", line) ; + snprintf (spqr_mx_debug_string, 190, "QR:Line_%d", line) ; return (spqr_mx_debug_string) ; } diff --git a/SPQR/MATLAB/spqr_singletons.cpp b/SPQR/MATLAB/spqr_singletons.cpp index 61e92683a..3ea3f43ea 100644 --- a/SPQR/MATLAB/spqr_singletons.cpp +++ b/SPQR/MATLAB/spqr_singletons.cpp @@ -98,12 +98,12 @@ void mexFunction if (is_complex) { - spqr_1colamd (SPQR_ORDERING_NATURAL, tol, 0, A, + spqr_1colamd (SPQR_ORDERING_NATURAL, tol, 0, A, &Q, &Rp, &Pinv, &Y, &n1cols, &n1rows, cc) ; } else { - spqr_1colamd (SPQR_ORDERING_NATURAL, tol, 0, A, + spqr_1colamd (SPQR_ORDERING_NATURAL, tol, 0, A, &Q, &Rp, &Pinv, &Y, &n1cols, &n1rows, cc) ; } diff --git a/SPQR/MATLAB/spqr_solve.cpp b/SPQR/MATLAB/spqr_solve.cpp index 7a6e78c67..c17497fd6 100644 --- a/SPQR/MATLAB/spqr_solve.cpp +++ b/SPQR/MATLAB/spqr_solve.cpp @@ -283,9 +283,7 @@ void mexFunction rank = cc->SPQR_istat [4] ; if (rank < MIN (m,n)) { - // snprintf would be safer, but Windows is oblivious to safety ... - // (Visual Studio C++ 2008 does not recognize snprintf!) - sprintf (msg, "rank deficient. rank = %" PRId64 " tol = %g\n", + snprintf (msg, LEN, "rank deficient. rank = %" PRId64 " tol = %g\n", rank, cc->SPQR_tol_used) ; mexWarnMsgIdAndTxt ("MATLAB:rankDeficientMatrix", msg) ; } diff --git a/SPQR/Source/spqr_1colamd.cpp b/SPQR/Source/spqr_1colamd.cpp index f3b1d09ac..8c4d958b8 100644 --- a/SPQR/Source/spqr_1colamd.cpp +++ b/SPQR/Source/spqr_1colamd.cpp @@ -538,8 +538,12 @@ template int spqr_1colamd // TRUE if OK, FALSE o { // use CHOLMOD's interface to METIS to order A'*A (if installed) TEST_COVERAGE_PAUSE ; + #ifndef NPARTITION spqr_metis (AT, NULL, 0, TRUE, (Int *) (Q1fill + n1cols), cc) ; + #else + cc->status = CHOLMOD_NOT_INSTALLED ; + #endif TEST_COVERAGE_RESUME ; } else if (ordering == SPQR_ORDERING_CHOLMOD) diff --git a/SPQR/Source/spqr_cholmod_wrappers.cpp b/SPQR/Source/spqr_cholmod_wrappers.cpp index 37761c9b8..217d393ce 100644 --- a/SPQR/Source/spqr_cholmod_wrappers.cpp +++ b/SPQR/Source/spqr_cholmod_wrappers.cpp @@ -11,6 +11,10 @@ #include "spqr.hpp" +//============================================================================== +// CHOLMOD:Utility (required) +//============================================================================== + //------------------------------------------------------------------------------ // spqr_start //------------------------------------------------------------------------------ @@ -351,45 +355,6 @@ template <> int spqr_allocate_work return cholmod_l_allocate_work (nrow, iworksize, xworksize, Common) ; } -//------------------------------------------------------------------------------ -// spqr_amd -//------------------------------------------------------------------------------ - -template <> int spqr_amd -( - cholmod_sparse *A, int64_t *fset, size_t fsize, int64_t *Perm, cholmod_common *Common -) -{ - return cholmod_l_amd (A, fset, fsize, Perm, Common) ; -} -template <> int spqr_amd -( - cholmod_sparse *A, int32_t *fset, size_t fsize, int32_t *Perm, cholmod_common *Common -) -{ - return cholmod_amd (A, fset, fsize, Perm, Common) ; -} - -//------------------------------------------------------------------------------ -// spqr_metis -//------------------------------------------------------------------------------ - -template <> int spqr_metis -( - cholmod_sparse *A, int64_t *fset, size_t fsize, int postorder, int64_t *Perm, cholmod_common *Common -) -{ - return cholmod_l_metis (A, fset, fsize, postorder, Perm, Common) ; -} - -template <> int spqr_metis -( - cholmod_sparse *A, int32_t *fset, size_t fsize, int postorder, int32_t *Perm, cholmod_common *Common -) -{ - return cholmod_metis (A, fset, fsize, postorder, Perm, Common) ; -} - //------------------------------------------------------------------------------ // spqr_transpose //------------------------------------------------------------------------------ @@ -401,6 +366,7 @@ template <> cholmod_sparse *spqr_transpose { return cholmod_l_transpose (A, values, Common) ; } + template <> cholmod_sparse *spqr_transpose ( cholmod_sparse *A, int values, cholmod_common *Common @@ -409,113 +375,6 @@ template <> cholmod_sparse *spqr_transpose return cholmod_transpose (A, values, Common) ; } -//------------------------------------------------------------------------------ -// spqr_analyze_p2 -//------------------------------------------------------------------------------ - -template <> -cholmod_factor *spqr_analyze_p2 -( - /* ---- input ---- */ - int for_whom, /* FOR_SPQR (0): for SPQR but not GPU-accelerated - FOR_CHOLESKY (1): for Cholesky (GPU or not) - FOR_SPQRGPU (2): for SPQR with GPU acceleration */ - cholmod_sparse *A, /* matrix to order and analyze */ - int32_t *UserPerm, /* user-provided permutation, size A->nrow */ - int32_t *fset, /* subset of 0:(A->ncol)-1 */ - size_t fsize, /* size of fset */ - /* --------------- */ - cholmod_common *Common -) -{ - return cholmod_analyze_p2 (for_whom, A, UserPerm, fset, fsize, Common) ; -} -template <> -cholmod_factor *spqr_analyze_p2 -( - /* ---- input ---- */ - int for_whom, /* FOR_SPQR (0): for SPQR but not GPU-accelerated - FOR_CHOLESKY (1): for Cholesky (GPU or not) - FOR_SPQRGPU (2): for SPQR with GPU acceleration */ - cholmod_sparse *A, /* matrix to order and analyze */ - int64_t *UserPerm, /* user-provided permutation, size A->nrow */ - int64_t *fset, /* subset of 0:(A->ncol)-1 */ - size_t fsize, /* size of fset */ - /* --------------- */ - cholmod_common *Common -) -{ - return cholmod_l_analyze_p2 (for_whom, A, UserPerm, fset, fsize, Common) ; -} - -//------------------------------------------------------------------------------ -// spqr_colamd -//------------------------------------------------------------------------------ - -template <> int spqr_colamd -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to order */ - int32_t *fset, /* subset of 0:(A->ncol)-1 */ - size_t fsize, /* size of fset */ - int postorder, /* if TRUE, follow with a coletree postorder */ - /* ---- output --- */ - int32_t *Perm, /* size A->nrow, output permutation */ - /* --------------- */ - cholmod_common *Common -) -{ - return cholmod_colamd (A, fset, fsize, postorder, Perm, Common) ; -} -template <> int spqr_colamd -( - /* ---- input ---- */ - cholmod_sparse *A, /* matrix to order */ - int64_t *fset, /* subset of 0:(A->ncol)-1 */ - size_t fsize, /* size of fset */ - int postorder, /* if TRUE, follow with a coletree postorder */ - /* ---- output --- */ - int64_t *Perm, /* size A->nrow, output permutation */ - /* --------------- */ - cholmod_common *Common -) -{ - return cholmod_l_colamd (A, fset, fsize, postorder, Perm, Common) ; -} - -//------------------------------------------------------------------------------ -// spqr_postorder -//------------------------------------------------------------------------------ - -template <> int32_t spqr_postorder /* return # of nodes postordered */ -( - /* ---- input ---- */ - int32_t *Parent, /* size n. Parent [j] = p if p is the parent of j */ - size_t n, - int32_t *Weight_p, /* size n, optional. Weight [j] is weight of node j */ - /* ---- output --- */ - int32_t *Post, /* size n. Post [k] = j is kth in postordered tree */ - /* --------------- */ - cholmod_common *Common -) -{ - return cholmod_postorder (Parent, n, Weight_p, Post, Common) ; -} -template <> int64_t spqr_postorder /* return # of nodes postordered */ -( - /* ---- input ---- */ - int64_t *Parent, /* size n. Parent [j] = p if p is the parent of j */ - size_t n, - int64_t *Weight_p, /* size n, optional. Weight [j] is weight of node j */ - /* ---- output --- */ - int64_t *Post, /* size n. Post [k] = j is kth in postordered tree */ - /* --------------- */ - cholmod_common *Common -) -{ - return cholmod_l_postorder (Parent, n, Weight_p, Post, Common) ; -} - //------------------------------------------------------------------------------ // spqr_nnz //------------------------------------------------------------------------------ @@ -699,261 +558,432 @@ template <> cholmod_dense *spqr_ones } //------------------------------------------------------------------------------ -// spqr_ssmult +// spqr_ssadd //------------------------------------------------------------------------------ -template <> cholmod_sparse *spqr_ssmult +template <> cholmod_sparse *spqr_ssadd ( /* ---- input ---- */ - cholmod_sparse *A, /* left matrix to multiply */ - cholmod_sparse *B, /* right matrix to multiply */ - int stype, /* requested stype of C */ - int values, /* TRUE: do numerical values, FALSE: pattern only */ - int sorted, /* if TRUE then return C with sorted columns */ + cholmod_sparse *A, /* matrix to add */ + cholmod_sparse *B, /* matrix to add */ + double alpha [2], /* scale factor for A */ + double beta [2], /* scale factor for B */ + int values, /* if TRUE compute the numerical values of C */ + int sorted, /* if TRUE, sort columns of C */ /* --------------- */ cholmod_common *Common ) { - return cholmod_ssmult (A, B, stype, values, sorted, Common) ; + return cholmod_add (A, B, alpha, beta, values, sorted, Common) ; } -template <> cholmod_sparse *spqr_ssmult +template <> cholmod_sparse *spqr_ssadd ( /* ---- input ---- */ - cholmod_sparse *A, /* left matrix to multiply */ - cholmod_sparse *B, /* right matrix to multiply */ - int stype, /* requested stype of C */ - int values, /* TRUE: do numerical values, FALSE: pattern only */ - int sorted, /* if TRUE then return C with sorted columns */ + cholmod_sparse *A, /* matrix to add */ + cholmod_sparse *B, /* matrix to add */ + double alpha [2], /* scale factor for A */ + double beta [2], /* scale factor for B */ + int values, /* if TRUE compute the numerical values of C */ + int sorted, /* if TRUE, sort columns of C */ /* --------------- */ cholmod_common *Common ) { - return cholmod_l_ssmult (A, B, stype, values, sorted, Common) ; + return cholmod_l_add (A, B, alpha, beta, values, sorted, Common) ; } //------------------------------------------------------------------------------ -// spqr_ssadd +// spqr_copy_dense //------------------------------------------------------------------------------ -template <> cholmod_sparse *spqr_ssadd +template <> cholmod_dense *spqr_copy_dense ( /* ---- input ---- */ - cholmod_sparse *A, /* matrix to add */ - cholmod_sparse *B, /* matrix to add */ - double alpha [2], /* scale factor for A */ - double beta [2], /* scale factor for B */ - int values, /* if TRUE compute the numerical values of C */ - int sorted, /* if TRUE, sort columns of C */ + cholmod_dense *X, /* matrix to copy */ /* --------------- */ cholmod_common *Common ) { - return cholmod_add (A, B, alpha, beta, values, sorted, Common) ; + return cholmod_copy_dense (X, Common) ; } -template <> cholmod_sparse *spqr_ssadd +template <> cholmod_dense *spqr_copy_dense ( /* ---- input ---- */ - cholmod_sparse *A, /* matrix to add */ - cholmod_sparse *B, /* matrix to add */ - double alpha [2], /* scale factor for A */ - double beta [2], /* scale factor for B */ - int values, /* if TRUE compute the numerical values of C */ - int sorted, /* if TRUE, sort columns of C */ + cholmod_dense *X, /* matrix to copy */ /* --------------- */ cholmod_common *Common ) { - return cholmod_l_add (A, B, alpha, beta, values, sorted, Common) ; + return cholmod_l_copy_dense (X, Common) ; } //------------------------------------------------------------------------------ -// spqr_sdmult +// spqr_copy //------------------------------------------------------------------------------ -template <> int spqr_sdmult +template <> cholmod_sparse *spqr_copy ( /* ---- input ---- */ - cholmod_sparse *A, /* sparse matrix to multiply */ - int transpose, /* use A if 0, or A' otherwise */ - double alpha [2], /* scale factor for A */ - double beta [2], /* scale factor for Y */ - cholmod_dense *X, /* dense matrix to multiply */ - /* ---- in/out --- */ - cholmod_dense *Y, /* resulting dense matrix */ + cholmod_sparse *A, /* matrix to copy */ + int stype, /* requested stype of C */ + int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ /* --------------- */ cholmod_common *Common ) { - return cholmod_sdmult (A, transpose, alpha, beta, X, Y, Common) ; + return cholmod_copy (A, stype, mode, Common) ; } -template <> int spqr_sdmult +template <> cholmod_sparse *spqr_copy ( /* ---- input ---- */ - cholmod_sparse *A, /* sparse matrix to multiply */ - int transpose, /* use A if 0, or A' otherwise */ - double alpha [2], /* scale factor for A */ - double beta [2], /* scale factor for Y */ - cholmod_dense *X, /* dense matrix to multiply */ - /* ---- in/out --- */ - cholmod_dense *Y, /* resulting dense matrix */ + cholmod_sparse *A, /* matrix to copy */ + int stype, /* requested stype of C */ + int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ /* --------------- */ cholmod_common *Common ) { - return cholmod_l_sdmult (A, transpose, alpha, beta, X, Y, Common) ; + return cholmod_l_copy (A, stype, mode, Common) ; } //------------------------------------------------------------------------------ -// spqr_norm_sparse +// spqr_xtype //------------------------------------------------------------------------------ -template <> double spqr_norm_sparse +template <> int spqr_sparse_xtype ( /* ---- input ---- */ - cholmod_sparse *A, /* matrix to compute the norm of */ - int norm, /* type of norm: 0: inf. norm, 1: 1-norm */ + int to_xtype, /* requested xtype (pattern, real, complex, zomplex) */ + /* ---- in/out --- */ + cholmod_sparse *A, /* sparse matrix to change */ /* --------------- */ cholmod_common *Common ) { - return cholmod_norm_sparse (A, norm, Common) ; + return cholmod_sparse_xtype (to_xtype, A, Common) ; } - -template <> double spqr_norm_sparse +template <> int spqr_sparse_xtype ( /* ---- input ---- */ - cholmod_sparse *A, /* matrix to compute the norm of */ - int norm, /* type of norm: 0: inf. norm, 1: 1-norm */ + int to_xtype, /* requested xtype (pattern, real, complex, zomplex) */ + /* ---- in/out --- */ + cholmod_sparse *A, /* sparse matrix to change */ /* --------------- */ cholmod_common *Common ) { - return cholmod_l_norm_sparse (A, norm, Common) ; + return cholmod_l_sparse_xtype (to_xtype, A, Common) ; } +//============================================================================== +// CHOLMOD:Cholesky (required) +//============================================================================== + //------------------------------------------------------------------------------ -// spqr_norm_dense +// spqr_amd //------------------------------------------------------------------------------ -template <> double spqr_norm_dense +template <> int spqr_amd +( + cholmod_sparse *A, int64_t *fset, size_t fsize, int64_t *Perm, cholmod_common *Common +) +{ + return cholmod_l_amd (A, fset, fsize, Perm, Common) ; +} +template <> int spqr_amd +( + cholmod_sparse *A, int32_t *fset, size_t fsize, int32_t *Perm, cholmod_common *Common +) +{ + return cholmod_amd (A, fset, fsize, Perm, Common) ; +} + +//------------------------------------------------------------------------------ +// spqr_analyze_p2 +//------------------------------------------------------------------------------ + +template <> +cholmod_factor *spqr_analyze_p2 ( /* ---- input ---- */ - cholmod_dense *X, /* matrix to compute the norm of */ - int norm, /* type of norm: 0: inf. norm, 1: 1-norm, 2: 2-norm */ + int for_whom, /* FOR_SPQR (0): for SPQR but not GPU-accelerated + FOR_CHOLESKY (1): for Cholesky (GPU or not) + FOR_SPQRGPU (2): for SPQR with GPU acceleration */ + cholmod_sparse *A, /* matrix to order and analyze */ + int32_t *UserPerm, /* user-provided permutation, size A->nrow */ + int32_t *fset, /* subset of 0:(A->ncol)-1 */ + size_t fsize, /* size of fset */ /* --------------- */ cholmod_common *Common ) { - return cholmod_norm_dense (X, norm, Common) ; + return cholmod_analyze_p2 (for_whom, A, UserPerm, fset, fsize, Common) ; } - -template <> double spqr_norm_dense +template <> +cholmod_factor *spqr_analyze_p2 ( /* ---- input ---- */ - cholmod_dense *X, /* matrix to compute the norm of */ - int norm, /* type of norm: 0: inf. norm, 1: 1-norm, 2: 2-norm */ + int for_whom, /* FOR_SPQR (0): for SPQR but not GPU-accelerated + FOR_CHOLESKY (1): for Cholesky (GPU or not) + FOR_SPQRGPU (2): for SPQR with GPU acceleration */ + cholmod_sparse *A, /* matrix to order and analyze */ + int64_t *UserPerm, /* user-provided permutation, size A->nrow */ + int64_t *fset, /* subset of 0:(A->ncol)-1 */ + size_t fsize, /* size of fset */ /* --------------- */ cholmod_common *Common ) { - return cholmod_l_norm_dense (X, norm, Common) ; + return cholmod_l_analyze_p2 (for_whom, A, UserPerm, fset, fsize, Common) ; } //------------------------------------------------------------------------------ -// spqr_copy_dense +// spqr_colamd //------------------------------------------------------------------------------ -template <> cholmod_dense *spqr_copy_dense +template <> int spqr_colamd ( /* ---- input ---- */ - cholmod_dense *X, /* matrix to copy */ + cholmod_sparse *A, /* matrix to order */ + int32_t *fset, /* subset of 0:(A->ncol)-1 */ + size_t fsize, /* size of fset */ + int postorder, /* if TRUE, follow with a coletree postorder */ + /* ---- output --- */ + int32_t *Perm, /* size A->nrow, output permutation */ /* --------------- */ cholmod_common *Common ) { - return cholmod_copy_dense (X, Common) ; + return cholmod_colamd (A, fset, fsize, postorder, Perm, Common) ; +} +template <> int spqr_colamd +( + /* ---- input ---- */ + cholmod_sparse *A, /* matrix to order */ + int64_t *fset, /* subset of 0:(A->ncol)-1 */ + size_t fsize, /* size of fset */ + int postorder, /* if TRUE, follow with a coletree postorder */ + /* ---- output --- */ + int64_t *Perm, /* size A->nrow, output permutation */ + /* --------------- */ + cholmod_common *Common +) +{ + return cholmod_l_colamd (A, fset, fsize, postorder, Perm, Common) ; } -template <> cholmod_dense *spqr_copy_dense +//------------------------------------------------------------------------------ +// spqr_postorder +//------------------------------------------------------------------------------ + +template <> int32_t spqr_postorder /* return # of nodes postordered */ ( /* ---- input ---- */ - cholmod_dense *X, /* matrix to copy */ + int32_t *Parent, /* size n. Parent [j] = p if p is the parent of j */ + size_t n, + int32_t *Weight_p, /* size n, optional. Weight [j] is weight of node j */ + /* ---- output --- */ + int32_t *Post, /* size n. Post [k] = j is kth in postordered tree */ /* --------------- */ cholmod_common *Common ) { - return cholmod_l_copy_dense (X, Common) ; + return cholmod_postorder (Parent, n, Weight_p, Post, Common) ; } +template <> int64_t spqr_postorder /* return # of nodes postordered */ +( + /* ---- input ---- */ + int64_t *Parent, /* size n. Parent [j] = p if p is the parent of j */ + size_t n, + int64_t *Weight_p, /* size n, optional. Weight [j] is weight of node j */ + /* ---- output --- */ + int64_t *Post, /* size n. Post [k] = j is kth in postordered tree */ + /* --------------- */ + cholmod_common *Common +) +{ + return cholmod_l_postorder (Parent, n, Weight_p, Post, Common) ; +} + +//============================================================================== +// CHOLMOD:Partition (optional) +//============================================================================== + +#ifndef NPARTITION //------------------------------------------------------------------------------ -// spqr_copy +// spqr_metis //------------------------------------------------------------------------------ -template <> cholmod_sparse *spqr_copy +template <> int spqr_metis +( + cholmod_sparse *A, int64_t *fset, size_t fsize, int postorder, int64_t *Perm, cholmod_common *Common +) +{ + return cholmod_l_metis (A, fset, fsize, postorder, Perm, Common) ; +} + +template <> int spqr_metis +( + cholmod_sparse *A, int32_t *fset, size_t fsize, int postorder, int32_t *Perm, cholmod_common *Common +) +{ + return cholmod_metis (A, fset, fsize, postorder, Perm, Common) ; +} + +#endif + +//============================================================================== +// CHOLMOD:MatrixOps (optional) +//============================================================================== + +#ifndef NMATRIXOPS + +//------------------------------------------------------------------------------ +// spqr_ssmult +//------------------------------------------------------------------------------ + +template <> cholmod_sparse *spqr_ssmult ( /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ + cholmod_sparse *A, /* left matrix to multiply */ + cholmod_sparse *B, /* right matrix to multiply */ int stype, /* requested stype of C */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ + int values, /* TRUE: do numerical values, FALSE: pattern only */ + int sorted, /* if TRUE then return C with sorted columns */ /* --------------- */ cholmod_common *Common ) { - return cholmod_copy (A, stype, mode, Common) ; + return cholmod_ssmult (A, B, stype, values, sorted, Common) ; } -template <> cholmod_sparse *spqr_copy +template <> cholmod_sparse *spqr_ssmult ( /* ---- input ---- */ - cholmod_sparse *A, /* matrix to copy */ + cholmod_sparse *A, /* left matrix to multiply */ + cholmod_sparse *B, /* right matrix to multiply */ int stype, /* requested stype of C */ - int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */ + int values, /* TRUE: do numerical values, FALSE: pattern only */ + int sorted, /* if TRUE then return C with sorted columns */ /* --------------- */ cholmod_common *Common ) { - return cholmod_l_copy (A, stype, mode, Common) ; + return cholmod_l_ssmult (A, B, stype, values, sorted, Common) ; } //------------------------------------------------------------------------------ -// spqr_xtype +// spqr_sdmult //------------------------------------------------------------------------------ -template <> int spqr_sparse_xtype +template <> int spqr_sdmult ( /* ---- input ---- */ - int to_xtype, /* requested xtype (pattern, real, complex, zomplex) */ + cholmod_sparse *A, /* sparse matrix to multiply */ + int transpose, /* use A if 0, or A' otherwise */ + double alpha [2], /* scale factor for A */ + double beta [2], /* scale factor for Y */ + cholmod_dense *X, /* dense matrix to multiply */ /* ---- in/out --- */ - cholmod_sparse *A, /* sparse matrix to change */ + cholmod_dense *Y, /* resulting dense matrix */ /* --------------- */ cholmod_common *Common ) { - return cholmod_sparse_xtype (to_xtype, A, Common) ; + return cholmod_sdmult (A, transpose, alpha, beta, X, Y, Common) ; } -template <> int spqr_sparse_xtype +template <> int spqr_sdmult ( /* ---- input ---- */ - int to_xtype, /* requested xtype (pattern, real, complex, zomplex) */ + cholmod_sparse *A, /* sparse matrix to multiply */ + int transpose, /* use A if 0, or A' otherwise */ + double alpha [2], /* scale factor for A */ + double beta [2], /* scale factor for Y */ + cholmod_dense *X, /* dense matrix to multiply */ /* ---- in/out --- */ - cholmod_sparse *A, /* sparse matrix to change */ + cholmod_dense *Y, /* resulting dense matrix */ /* --------------- */ cholmod_common *Common ) { - return cholmod_l_sparse_xtype (to_xtype, A, Common) ; + return cholmod_l_sdmult (A, transpose, alpha, beta, X, Y, Common) ; } +//------------------------------------------------------------------------------ +// spqr_norm_sparse +//------------------------------------------------------------------------------ + +template <> double spqr_norm_sparse +( + /* ---- input ---- */ + cholmod_sparse *A, /* matrix to compute the norm of */ + int norm, /* type of norm: 0: inf. norm, 1: 1-norm */ + /* --------------- */ + cholmod_common *Common +) +{ + return cholmod_norm_sparse (A, norm, Common) ; +} + + +template <> double spqr_norm_sparse +( + /* ---- input ---- */ + cholmod_sparse *A, /* matrix to compute the norm of */ + int norm, /* type of norm: 0: inf. norm, 1: 1-norm */ + /* --------------- */ + cholmod_common *Common +) +{ + return cholmod_l_norm_sparse (A, norm, Common) ; +} + +//------------------------------------------------------------------------------ +// spqr_norm_dense +//------------------------------------------------------------------------------ + +template <> double spqr_norm_dense +( + /* ---- input ---- */ + cholmod_dense *X, /* matrix to compute the norm of */ + int norm, /* type of norm: 0: inf. norm, 1: 1-norm, 2: 2-norm */ + /* --------------- */ + cholmod_common *Common +) +{ + return cholmod_norm_dense (X, norm, Common) ; +} + +template <> double spqr_norm_dense +( + /* ---- input ---- */ + cholmod_dense *X, /* matrix to compute the norm of */ + int norm, /* type of norm: 0: inf. norm, 1: 1-norm, 2: 2-norm */ + /* --------------- */ + cholmod_common *Common +) +{ + return cholmod_l_norm_dense (X, norm, Common) ; +} + +#endif + +//============================================================================== +// CHOLMOD:GPU (optional) +//============================================================================== + //------------------------------------------------------------------------------ // spqr_gpu_memorysize //------------------------------------------------------------------------------ #ifdef SUITESPARSE_CUDA + template <> int spqr_gpu_memorysize ( size_t *total_mem, @@ -975,6 +1005,12 @@ template <> int spqr_gpu_memorysize } #endif +//============================================================================== +// CHOLMOD:Check (optional) +//============================================================================== + +#ifndef NCHECK + //------------------------------------------------------------------------------ // spqr_read_sparse //------------------------------------------------------------------------------ @@ -1001,4 +1037,5 @@ template <> cholmod_sparse *spqr_read_sparse return cholmod_l_read_sparse (f, Common) ; } +#endif diff --git a/SuiteSparse_config/CMakeLists.txt b/SuiteSparse_config/CMakeLists.txt index b7d06a140..752a7297f 100644 --- a/SuiteSparse_config/CMakeLists.txt +++ b/SuiteSparse_config/CMakeLists.txt @@ -14,10 +14,10 @@ cmake_minimum_required ( VERSION 3.22 ) # version of both SuiteSparse and SuiteSparse_config -set ( SUITESPARSE_DATE "Oct 15, 2023" ) +set ( SUITESPARSE_DATE "Oct 23, 2023" ) set ( SUITESPARSE_VERSION_MAJOR 7 ) -set ( SUITESPARSE_VERSION_MINOR 2 ) -set ( SUITESPARSE_VERSION_SUB 2 ) +set ( SUITESPARSE_VERSION_MINOR 3 ) +set ( SUITESPARSE_VERSION_SUB 0 ) message ( STATUS "Building SuiteSparse_config version: v" ${SUITESPARSE_VERSION_MAJOR}. diff --git a/SuiteSparse_config/SuiteSparse_config.h b/SuiteSparse_config/SuiteSparse_config.h index d255a695a..780f2bfec 100644 --- a/SuiteSparse_config/SuiteSparse_config.h +++ b/SuiteSparse_config/SuiteSparse_config.h @@ -409,10 +409,10 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION #define SUITESPARSE_HAS_VERSION_FUNCTION -#define SUITESPARSE_DATE "Oct 15, 2023" +#define SUITESPARSE_DATE "Oct 23, 2023" #define SUITESPARSE_MAIN_VERSION 7 -#define SUITESPARSE_SUB_VERSION 2 -#define SUITESPARSE_SUBSUB_VERSION 2 +#define SUITESPARSE_SUB_VERSION 3 +#define SUITESPARSE_SUBSUB_VERSION 0 #define SUITESPARSE_VER_CODE(main,sub) ((main) * 1000 + (sub)) #define SUITESPARSE_VERSION \ diff --git a/SuiteSparse_config/cmake_modules/SuiteSparseLAPACK.cmake b/SuiteSparse_config/cmake_modules/SuiteSparseLAPACK.cmake index 27ff73cad..2ffe53624 100644 --- a/SuiteSparse_config/cmake_modules/SuiteSparseLAPACK.cmake +++ b/SuiteSparse_config/cmake_modules/SuiteSparseLAPACK.cmake @@ -21,17 +21,12 @@ cmake_minimum_required ( VERSION 3.22 ) if ( BLA_VENDOR STREQUAL "FLAME" ) - # FLAME has the BLAS but not LAPACK - set ( BLA_VENDOR "Generic" ) - message ( STATUS "Looking for generic LAPACK to use with BLIS/FLAME BLAS" ) - - # look for the generic dynamic LAPACK library (usually liblagraph.so) find_library ( LAPACK_LIBRARY - NAMES lapack + NAMES flame PATH_SUFFIXES lib build ) - # look for the static LAPACK library (usually liblagraph.a) + # look for the static LAPACK library (usually liblapack.a) if ( MSVC ) set ( STATIC_SUFFIX .lib ) else ( ) diff --git a/UMFPACK/CMakeLists.txt b/UMFPACK/CMakeLists.txt index 56b4432b7..135d3d04d 100644 --- a/UMFPACK/CMakeLists.txt +++ b/UMFPACK/CMakeLists.txt @@ -12,10 +12,10 @@ # cmake 3.22 is required to find the BLAS in SuiteSparse_config cmake_minimum_required ( VERSION 3.22 ) -set ( UMFPACK_DATE "Sept 18, 2023" ) +set ( UMFPACK_DATE "Oct 23, 2023" ) set ( UMFPACK_VERSION_MAJOR 6 ) set ( UMFPACK_VERSION_MINOR 2 ) -set ( UMFPACK_VERSION_SUB 1 ) +set ( UMFPACK_VERSION_SUB 2 ) message ( STATUS "Building UMFPACK version: v" ${UMFPACK_VERSION_MAJOR}. @@ -61,15 +61,15 @@ else ( ) find_package ( OpenMP ) endif ( ) -find_package ( SuiteSparse_config 7.2.0 +find_package ( SuiteSparse_config 7.3.0 PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) - find_package ( SuiteSparse_config 7.2.0 REQUIRED ) + find_package ( SuiteSparse_config 7.3.0 REQUIRED ) endif ( ) -find_package ( AMD 3.2.0 +find_package ( AMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../AMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::AMD ) - find_package ( AMD 3.2.0 REQUIRED ) + find_package ( AMD 3.2.1 REQUIRED ) endif ( ) include ( SuiteSparseBLAS ) # requires cmake 3.22 @@ -77,30 +77,30 @@ option ( NCHOLMOD "ON: do not use CHOLMOD. OFF (default): use CHOLMOD" off ) if ( NOT NCHOLMOD ) # look for CHOLMOD (optional fill-reducing orderings) - find_package ( CHOLMOD 4.2.0 + find_package ( CHOLMOD 5.0.0 PATHS ${CMAKE_SOURCE_DIR}/../CHOLMOD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CHOLMOD ) - find_package ( CHOLMOD 4.2.0 ) + find_package ( CHOLMOD 5.0.0 ) endif ( ) # look for CHOLMOD's dependencies: AMD and COLAMD are required. CAMD and # CCOLAMD are optional, but must be found if CHOLMOD was built with them. - find_package ( COLAMD 3.2.0 + find_package ( COLAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../COLAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::COLAMD ) - find_package ( COLAMD 3.2.0 ) + find_package ( COLAMD 3.2.1 ) endif ( ) - find_package ( CAMD 3.2.0 + find_package ( CAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../CAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CAMD ) - find_package ( CAMD 3.2.0 ) + find_package ( CAMD 3.2.1 ) endif ( ) - find_package ( CCOLAMD 3.2.0 + find_package ( CCOLAMD 3.2.1 PATHS ${CMAKE_SOURCE_DIR}/../CCOLAMD/build NO_DEFAULT_PATH ) if ( NOT TARGET SuiteSparse::CCOLAMD ) - find_package ( CCOLAMD 3.2.0 ) + find_package ( CCOLAMD 3.2.1 ) endif ( ) if ( NOT CHOLMOD_FOUND OR NOT AMD_FOUND OR NOT COLAMD_FOUND ) diff --git a/UMFPACK/Doc/ChangeLog b/UMFPACK/Doc/ChangeLog index 564ddaa09..6a027a422 100644 --- a/UMFPACK/Doc/ChangeLog +++ b/UMFPACK/Doc/ChangeLog @@ -1,3 +1,7 @@ +Oct 23, 2023: version 6.2.2 + + * for SuiteSparse 7.3.0: update for CHOLMOD 5.0.0 + Sept 18, 2023: version 6.2.1 * cmake update: add "None" build type, from Antonio Rojas, for Arch Linux diff --git a/UMFPACK/Doc/UMFPACK_QuickStart.pdf b/UMFPACK/Doc/UMFPACK_QuickStart.pdf index 0521a0ec0..cf954032f 100644 Binary files a/UMFPACK/Doc/UMFPACK_QuickStart.pdf and b/UMFPACK/Doc/UMFPACK_QuickStart.pdf differ diff --git a/UMFPACK/Doc/UMFPACK_UserGuide.pdf b/UMFPACK/Doc/UMFPACK_UserGuide.pdf index 102284cce..6d20968f5 100644 Binary files a/UMFPACK/Doc/UMFPACK_UserGuide.pdf and b/UMFPACK/Doc/UMFPACK_UserGuide.pdf differ diff --git a/UMFPACK/Doc/umfpack_version.tex b/UMFPACK/Doc/umfpack_version.tex index 14737caa6..e33c0327a 100644 --- a/UMFPACK/Doc/umfpack_version.tex +++ b/UMFPACK/Doc/umfpack_version.tex @@ -1,2 +1,2 @@ % version of SuiteSparse/UMFPACK -\date{VERSION 6.2.1, Sept 18, 2023} +\date{VERSION 6.2.2, Oct 23, 2023} diff --git a/UMFPACK/Include/umfpack.h b/UMFPACK/Include/umfpack.h index 32b784404..e8c1c8046 100644 --- a/UMFPACK/Include/umfpack.h +++ b/UMFPACK/Include/umfpack.h @@ -82,10 +82,10 @@ extern "C" { * below. */ -#define UMFPACK_DATE "Sept 18, 2023" +#define UMFPACK_DATE "Oct 23, 2023" #define UMFPACK_MAIN_VERSION 6 #define UMFPACK_SUB_VERSION 2 -#define UMFPACK_SUBSUB_VERSION 1 +#define UMFPACK_SUBSUB_VERSION 2 #define UMFPACK_VER_CODE(main,sub) ((main) * 1000 + (sub)) #define UMFPACK_VER UMFPACK_VER_CODE(UMFPACK_MAIN_VERSION,UMFPACK_SUB_VERSION) diff --git a/UMFPACK/MATLAB/umfpack_make.m b/UMFPACK/MATLAB/umfpack_make.m index 945ca0dc4..87be8de11 100644 --- a/UMFPACK/MATLAB/umfpack_make.m +++ b/UMFPACK/MATLAB/umfpack_make.m @@ -191,44 +191,93 @@ '../../CCOLAMD/Source/ccolamd' } ; cholmod_src = { - '../../CHOLMOD/Core/cholmod_aat', ... - '../../CHOLMOD/Core/cholmod_add', ... - '../../CHOLMOD/Core/cholmod_band', ... - '../../CHOLMOD/Core/cholmod_change_factor', ... - '../../CHOLMOD/Core/cholmod_common', ... - '../../CHOLMOD/Core/cholmod_complex', ... - '../../CHOLMOD/Core/cholmod_copy', ... - '../../CHOLMOD/Core/cholmod_dense', ... - '../../CHOLMOD/Core/cholmod_error', ... - '../../CHOLMOD/Core/cholmod_factor', ... - '../../CHOLMOD/Core/cholmod_memory', ... - '../../CHOLMOD/Core/cholmod_sparse', ... - '../../CHOLMOD/Core/cholmod_transpose', ... - '../../CHOLMOD/Core/cholmod_triplet', ... - '../../CHOLMOD/Check/cholmod_check', ... - '../../CHOLMOD/Cholesky/cholmod_amd', ... - '../../CHOLMOD/Cholesky/cholmod_analyze', ... - '../../CHOLMOD/Cholesky/cholmod_colamd', ... - '../../CHOLMOD/Cholesky/cholmod_etree', ... - '../../CHOLMOD/Cholesky/cholmod_postorder', ... - '../../CHOLMOD/Cholesky/cholmod_rowcolcounts', ... - '../../CHOLMOD/Partition/cholmod_ccolamd', ... - '../../CHOLMOD/Partition/cholmod_csymamd', ... - '../../CHOLMOD/Partition/cholmod_camd', ... - '../../CHOLMOD/Partition/cholmod_metis', ... + '../../CHOLMOD/Utility/cholmod_l_aat', ... + '../../CHOLMOD/Utility/cholmod_l_add', ... + '../../CHOLMOD/Utility/cholmod_l_add_size_t', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_dense', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_factor', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_allocate_work', ... + '../../CHOLMOD/Utility/cholmod_l_alloc_factor', ... + '../../CHOLMOD/Utility/cholmod_l_alloc_work', ... + '../../CHOLMOD/Utility/cholmod_l_band', ... + '../../CHOLMOD/Utility/cholmod_l_band_nnz', ... + '../../CHOLMOD/Utility/cholmod_l_calloc', ... + '../../CHOLMOD/Utility/cholmod_l_change_factor', ... + '../../CHOLMOD/Utility/cholmod_l_clear_flag', ... + '../../CHOLMOD/Utility/cholmod_l_copy', ... + '../../CHOLMOD/Utility/cholmod_l_copy_dense2', ... + '../../CHOLMOD/Utility/cholmod_l_copy_dense', ... + '../../CHOLMOD/Utility/cholmod_l_copy_factor', ... + '../../CHOLMOD/Utility/cholmod_l_copy_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_copy_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_cumsum', ... + '../../CHOLMOD/Utility/cholmod_l_dbound', ... + '../../CHOLMOD/Utility/cholmod_l_defaults', ... + '../../CHOLMOD/Utility/cholmod_l_dense_nnz', ... + '../../CHOLMOD/Utility/cholmod_l_dense_to_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_divcomplex', ... + '../../CHOLMOD/Utility/cholmod_l_ensure_dense', ... + '../../CHOLMOD/Utility/cholmod_l_error', ... + '../../CHOLMOD/Utility/cholmod_l_eye', ... + '../../CHOLMOD/Utility/cholmod_l_factor_to_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_finish', ... + '../../CHOLMOD/Utility/cholmod_l_free', ... + '../../CHOLMOD/Utility/cholmod_l_free_dense', ... + '../../CHOLMOD/Utility/cholmod_l_free_factor', ... + '../../CHOLMOD/Utility/cholmod_l_free_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_free_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_free_work', ... + '../../CHOLMOD/Utility/cholmod_l_hypot', ... + '../../CHOLMOD/Utility/cholmod_l_malloc', ... + '../../CHOLMOD/Utility/cholmod_l_maxrank', ... + '../../CHOLMOD/Utility/cholmod_l_mult_size_t', ... + '../../CHOLMOD/Utility/cholmod_l_nnz', ... + '../../CHOLMOD/Utility/cholmod_l_ones', ... + '../../CHOLMOD/Utility/cholmod_l_pack_factor', ... + '../../CHOLMOD/Utility/cholmod_l_ptranspose', ... + '../../CHOLMOD/Utility/cholmod_l_reallocate_column', ... + '../../CHOLMOD/Utility/cholmod_l_reallocate_factor', ... + '../../CHOLMOD/Utility/cholmod_l_reallocate_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_reallocate_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_realloc', ... + '../../CHOLMOD/Utility/cholmod_l_realloc_multiple', ... + '../../CHOLMOD/Utility/cholmod_l_sbound', ... + '../../CHOLMOD/Utility/cholmod_l_score_comp', ... + '../../CHOLMOD/Utility/cholmod_l_set_empty', ... + '../../CHOLMOD/Utility/cholmod_l_sort', ... + '../../CHOLMOD/Utility/cholmod_l_sparse_to_dense', ... + '../../CHOLMOD/Utility/cholmod_l_sparse_to_triplet', ... + '../../CHOLMOD/Utility/cholmod_l_speye', ... + '../../CHOLMOD/Utility/cholmod_l_spzeros', ... + '../../CHOLMOD/Utility/cholmod_l_start', ... + '../../CHOLMOD/Utility/cholmod_l_transpose', ... + '../../CHOLMOD/Utility/cholmod_l_transpose_sym', ... + '../../CHOLMOD/Utility/cholmod_l_transpose_unsym', ... + '../../CHOLMOD/Utility/cholmod_l_triplet_to_sparse', ... + '../../CHOLMOD/Utility/cholmod_l_version', ... + '../../CHOLMOD/Utility/cholmod_l_xtype', ... + '../../CHOLMOD/Utility/cholmod_l_zeros', ... + '../../CHOLMOD/Utility/cholmod_mult_uint64_t', ... + '../../CHOLMOD/Utility/cholmod_memdebug', ... + '../../CHOLMOD/Check/cholmod_l_check', ... + '../../CHOLMOD/Cholesky/cholmod_l_amd', ... + '../../CHOLMOD/Cholesky/cholmod_l_analyze', ... + '../../CHOLMOD/Cholesky/cholmod_l_colamd', ... + '../../CHOLMOD/Cholesky/cholmod_l_etree', ... + '../../CHOLMOD/Cholesky/cholmod_l_postorder', ... + '../../CHOLMOD/Cholesky/cholmod_l_rowcolcounts', ... + '../../CHOLMOD/Partition/cholmod_l_ccolamd', ... + '../../CHOLMOD/Partition/cholmod_l_csymamd', ... + '../../CHOLMOD/Partition/cholmod_l_camd', ... + '../../CHOLMOD/Partition/cholmod_l_metis', ... '../../CHOLMOD/Partition/cholmod_metis_wrapper', ... - '../../CHOLMOD/Partition/cholmod_nesdis' } ; + '../../CHOLMOD/Partition/cholmod_l_nesdis' } ; other_source = [other_source cholmod_src ordering_src] ; end -if (pc && with_cholmod) - % Windows does not have drand48 and srand48, required by METIS. Use - % drand48 and srand48 in CHOLMOD/MATLAB/Windows/rand48.c instead. - other_source = [other_source {'../../CHOLMOD/MATLAB/Windows/rand48'}] ; - incdir = [incdir ' -I../../CHOLMOD/MATLAB/Windows'] ; -end - %------------------------------------------------------------------------------- % mex command %-------------------------------------------------------------------------------