From e687e793e6b668228213ca4a94113fd6da73994a Mon Sep 17 00:00:00 2001 From: Tim Davis Date: Sat, 2 Dec 2023 15:57:21 -0600 Subject: [PATCH] Adding *_version functions to all packages --- AMD/Config/amd.h.in | 4 + AMD/Demo/amd_demo.c | 15 +- AMD/Demo/amd_l_demo.c | 15 +- AMD/Doc/AMD_UserGuide.pdf | Bin 251354 -> 281699 bytes AMD/Doc/AMD_UserGuide.tex | 16 +- AMD/Doc/ChangeLog | 1 + AMD/Include/amd.h | 4 + AMD/Source/amd_version.c | 19 + BTF/Config/btf.h.in | 6 + BTF/Doc/ChangeLog | 1 + BTF/Include/btf.h | 6 + BTF/Source/btf_version.c | 19 + CAMD/Config/camd.h.in | 4 + CAMD/Demo/camd_demo.c | 14 +- CAMD/Demo/camd_demo.out | 2 +- CAMD/Demo/camd_l_demo.c | 14 +- CAMD/Demo/camd_l_demo.out | 2 +- CAMD/Doc/CAMD_UserGuide.tex | 16 +- CAMD/Doc/ChangeLog | 1 + CAMD/Include/camd.h | 4 + CAMD/Source/camd_version.c | 19 + CCOLAMD/Config/ccolamd.h.in | 1 + CCOLAMD/Demo/ccolamd_example.c | 15 + CCOLAMD/Demo/ccolamd_example.out | 1 + CCOLAMD/Demo/ccolamd_l_example.c | 15 + CCOLAMD/Demo/ccolamd_l_example.out | 1 + CCOLAMD/Doc/ChangeLog | 1 + CCOLAMD/Include/ccolamd.h | 1 + CCOLAMD/Source/ccolamd.c | 13 + CHOLMOD/Demo/cholmod_demo.h | 6 + CHOLMOD/Demo/cholmod_di_demo.c | 46 +- CHOLMOD/Demo/cholmod_dl_demo.c | 46 +- CHOLMOD/Demo/cholmod_si_demo.c | 46 +- CHOLMOD/Demo/cholmod_sl_demo.c | 46 +- CHOLMOD/Tcov/t_amdtest.c | 23 +- CHOLMOD/Tcov/t_camdtest.c | 23 +- COLAMD/Config/colamd.h.in | 2 + COLAMD/Demo/colamd_example.c | 15 + COLAMD/Demo/colamd_example.out | 1 + COLAMD/Demo/colamd_l_example.c | 15 + COLAMD/Demo/colamd_l_example.out | 1 + COLAMD/Doc/ChangeLog | 1 + COLAMD/Include/colamd.h | 2 + COLAMD/Source/colamd.c | 14 +- CSparse/Config/cs.h.in | 2 + CSparse/Demo/cs_demo.out | 173 ++--- CSparse/Demo/cs_demo1.c | 10 + CSparse/Doc/ChangeLog | 1 + CSparse/Include/cs.h | 2 + CSparse/Source/cs_version.c | 10 + CXSparse/Config/cs.h.in | 2 + CXSparse/Demo/cs_ci_demo1.c | 12 +- CXSparse/Demo/cs_cl_demo1.c | 12 +- CXSparse/Demo/cs_demo.c | 2 +- CXSparse/Demo/cs_demo.out | 787 +++++++++----------- CXSparse/Demo/cs_demo1.c | 12 +- CXSparse/Demo/cs_demo2.c | 2 +- CXSparse/Demo/cs_demo3.c | 2 +- CXSparse/Demo/cs_di_demo1.c | 12 +- CXSparse/Demo/cs_dl_demo1.c | 12 +- CXSparse/Doc/ChangeLog | 1 + CXSparse/Include/cs.h | 2 + CXSparse/Source/cs_version.c | 10 + ChangeLog | 3 + Example/Config/my.h.in | 7 +- Example/Demo/my_demo.c | 15 +- Example/Include/my.h | 7 +- Example/Include/my_internal.h | 86 ++- Example/Source/my.c | 191 +++-- Example/Source/my_cxx.cc | 25 +- KLU/Config/klu.h.in | 6 + KLU/Demo/kludemo.c | 20 + KLU/Demo/kluldemo.c | 20 + KLU/Doc/ChangeLog | 1 + KLU/Include/klu.h | 6 + KLU/Source/klu_version.c | 19 + LDL/Config/ldl.h.in | 2 + LDL/Demo/ldlamd.out | 75 +- LDL/Demo/ldllamd.out | 75 +- LDL/Demo/ldllmain.out | 75 +- LDL/Demo/ldlmain.c | 16 + LDL/Demo/ldlmain.out | 75 +- LDL/Doc/ChangeLog | 1 + LDL/Include/ldl.h | 2 + LDL/Source/ldl.c | 14 + Mongoose/Tests/Mongoose_Test_Memory_exe.cpp | 9 + RBio/Config/RBio.h.in | 2 + RBio/Demo/RBdemo.c | 18 + RBio/Demo/RBdemo.out | 79 +- RBio/Doc/ChangeLog | 1 + RBio/Include/RBio.h | 2 + RBio/Source/RBio.c | 8 + SPEX/Config/SPEX.h.in | 6 + SPEX/Doc/ChangeLog | 1 + SPEX/Include/SPEX.h | 6 + SPEX/SPEX_Util/Source/SPEX_version.c | 19 + SPQR/Doc/ChangeLog | 2 + SPQR/Include/SuiteSparseQR.hpp | 8 +- SPQR/Include/SuiteSparseQR_C.h | 2 + SPQR/Source/SuiteSparseQR.cpp | 12 + SPQR/Source/SuiteSparseQR_C.cpp | 11 + UMFPACK/Config/umfpack.h.in | 6 + UMFPACK/Doc/ChangeLog | 1 + UMFPACK/Include/umfpack.h | 6 + UMFPACK/Source2/umfpack_version.c | 18 + 105 files changed, 1664 insertions(+), 877 deletions(-) create mode 100644 AMD/Source/amd_version.c create mode 100644 BTF/Source/btf_version.c create mode 100644 CAMD/Source/camd_version.c create mode 100644 CSparse/Source/cs_version.c create mode 100644 CXSparse/Source/cs_version.c create mode 100644 KLU/Source/klu_version.c create mode 100644 SPEX/SPEX_Util/Source/SPEX_version.c create mode 100644 UMFPACK/Source2/umfpack_version.c diff --git a/AMD/Config/amd.h.in b/AMD/Config/amd.h.in index fe403677d..885ca1ac7 100644 --- a/AMD/Config/amd.h.in +++ b/AMD/Config/amd.h.in @@ -313,6 +313,10 @@ void amd_l_control (double Control [ ]) ; void amd_info (double Info [ ]) ; void amd_l_info (double Info [ ]) ; +// amd_version: return AMD version. The version array is returned with +// version [0..2] = {AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION} +void amd_version (int version [3]) ; + #ifdef __cplusplus } #endif diff --git a/AMD/Demo/amd_demo.c b/AMD/Demo/amd_demo.c index 507ab7ccf..b599d06df 100644 --- a/AMD/Demo/amd_demo.c +++ b/AMD/Demo/amd_demo.c @@ -52,14 +52,17 @@ int main (void) double Control [AMD_CONTROL], Info [AMD_INFO] ; char A [24][24] ; - /* here is an example of how to use AMD_VERSION. This code will work in - * any version of AMD. */ -#if defined(AMD_VERSION) && (AMD_VERSION >= AMD_VERSION_CODE(1,2)) printf ("AMD version %d.%d.%d, date: %s\n", AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION, AMD_DATE) ; -#else - printf ("AMD version: 1.1 or earlier\n") ; -#endif + int version [3] ; + amd_version (version) ; + if ((version [0] != AMD_MAIN_VERSION) || + (version [1] != AMD_SUB_VERSION) || + (version [2] != AMD_SUBSUB_VERSION)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } printf ("AMD demo, with the 24-by-24 Harwell/Boeing matrix, can_24:\n") ; diff --git a/AMD/Demo/amd_l_demo.c b/AMD/Demo/amd_l_demo.c index 7def82c7a..ff5816ae8 100644 --- a/AMD/Demo/amd_l_demo.c +++ b/AMD/Demo/amd_l_demo.c @@ -53,14 +53,17 @@ int main (void) double Control [AMD_CONTROL], Info [AMD_INFO] ; char A [24][24] ; - /* here is an example of how to use AMD_VERSION. This code will work in - * any version of AMD. */ -#if defined(AMD_VERSION) && (AMD_VERSION >= AMD_VERSION_CODE(1,2)) printf ("AMD version %d.%d.%d, date: %s\n", AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION, AMD_DATE) ; -#else - printf ("AMD version: 1.1 or earlier\n") ; -#endif + int version [3] ; + amd_version (version) ; + if ((version [0] != AMD_MAIN_VERSION) || + (version [1] != AMD_SUB_VERSION) || + (version [2] != AMD_SUBSUB_VERSION)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } printf ("AMD demo, with the 24-by-24 Harwell/Boeing matrix, can_24:\n") ; diff --git a/AMD/Doc/AMD_UserGuide.pdf b/AMD/Doc/AMD_UserGuide.pdf index 3fc5b136be3de895e929f61c42836e549740055d..da7a9c9590cfef2702cd9548d4598a6c60a98c84 100644 GIT binary patch delta 113147 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

Dg9*m_u|8OK7k@WX7hY>e<1{kU; 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 TJUKcK`>VW%MoTN9D2eu8mN-q; delta 83714 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ŊFH*D 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 e;-T #define TRUE 1 #define FALSE 0 diff --git a/CHOLMOD/Demo/cholmod_di_demo.c b/CHOLMOD/Demo/cholmod_di_demo.c index fbd27bf50..b99ecd9b0 100644 --- a/CHOLMOD/Demo/cholmod_di_demo.c +++ b/CHOLMOD/Demo/cholmod_di_demo.c @@ -55,6 +55,19 @@ static void my_handler (int status, const char *file, int line, } } +static void check_version (char *package, int ver [3], + int major, int minor, int patch) +{ + printf ("%s version %d.%d.%d\n", package, ver [0], ver [1], ver [2]) ; + if (ver [0] != major || ver [1] != minor || ver [2] != patch) + { + printf ("header version differs (%d,%d,%d) from library\n", + major, minor, patch) ; + my_handler (CHOLMOD_INVALID, __FILE__, __LINE__, + "version mismatch") ; + } +} + int main (int argc, char **argv) { double @@ -136,14 +149,41 @@ int main (int argc, char **argv) beta [1] = 0 ; //-------------------------------------------------------------------------- - // read in a matrix + // check versions //-------------------------------------------------------------------------- printf ("\n---------------------------------- cholmod_di_demo:\n") ; + cholmod_version (ver) ; - printf ("cholmod version %d.%d.%d\n", ver [0], ver [1], ver [2]) ; + check_version ("cholmod", ver, CHOLMOD_MAIN_VERSION, + CHOLMOD_SUB_VERSION, CHOLMOD_SUBSUB_VERSION) ; + SuiteSparse_version (ver) ; - printf ("SuiteSparse version %d.%d.%d\n", ver [0], ver [1], ver [2]) ; + check_version ("SuiteSparse", ver, SUITESPARSE_MAIN_VERSION, + SUITESPARSE_SUB_VERSION, SUITESPARSE_SUBSUB_VERSION) ; + + amd_version (ver) ; + check_version ("AMD", ver, AMD_MAIN_VERSION, + AMD_SUB_VERSION, AMD_SUBSUB_VERSION) ; + + colamd_version (ver) ; + check_version ("COLAMD", ver, COLAMD_MAIN_VERSION, + COLAMD_SUB_VERSION, COLAMD_SUBSUB_VERSION) ; + + #ifndef NCAMD + camd_version (ver) ; + check_version ("CAMD", ver, CAMD_MAIN_VERSION, + CAMD_SUB_VERSION, CAMD_SUBSUB_VERSION) ; + + ccolamd_version (ver) ; + check_version ("CCOLAMD", ver, CCOLAMD_MAIN_VERSION, + CCOLAMD_SUB_VERSION, CCOLAMD_SUBSUB_VERSION) ; + #endif + + //-------------------------------------------------------------------------- + // read in a matrix + //-------------------------------------------------------------------------- + A = cholmod_read_sparse2 (f, CHOLMOD_DOUBLE, cm) ; if (ff != NULL) { diff --git a/CHOLMOD/Demo/cholmod_dl_demo.c b/CHOLMOD/Demo/cholmod_dl_demo.c index 906fda8f5..f932ff80b 100644 --- a/CHOLMOD/Demo/cholmod_dl_demo.c +++ b/CHOLMOD/Demo/cholmod_dl_demo.c @@ -55,6 +55,19 @@ static void my_handler (int status, const char *file, int line, } } +static void check_version (char *package, int ver [3], + int major, int minor, int patch) +{ + printf ("%s version %d.%d.%d\n", package, ver [0], ver [1], ver [2]) ; + if (ver [0] != major || ver [1] != minor || ver [2] != patch) + { + printf ("header version differs (%d,%d,%d) from library\n", + major, minor, patch) ; + my_handler (CHOLMOD_INVALID, __FILE__, __LINE__, + "version mismatch") ; + } +} + int main (int argc, char **argv) { double @@ -136,14 +149,41 @@ int main (int argc, char **argv) beta [1] = 0 ; //-------------------------------------------------------------------------- - // read in a matrix + // check versions //-------------------------------------------------------------------------- printf ("\n---------------------------------- cholmod_dl_demo:\n") ; + cholmod_l_version (ver) ; - printf ("cholmod version %d.%d.%d\n", ver [0], ver [1], ver [2]) ; + check_version ("cholmod", ver, CHOLMOD_MAIN_VERSION, + CHOLMOD_SUB_VERSION, CHOLMOD_SUBSUB_VERSION) ; + SuiteSparse_version (ver) ; - printf ("SuiteSparse version %d.%d.%d\n", ver [0], ver [1], ver [2]) ; + check_version ("SuiteSparse", ver, SUITESPARSE_MAIN_VERSION, + SUITESPARSE_SUB_VERSION, SUITESPARSE_SUBSUB_VERSION) ; + + amd_version (ver) ; + check_version ("AMD", ver, AMD_MAIN_VERSION, + AMD_SUB_VERSION, AMD_SUBSUB_VERSION) ; + + colamd_version (ver) ; + check_version ("COLAMD", ver, COLAMD_MAIN_VERSION, + COLAMD_SUB_VERSION, COLAMD_SUBSUB_VERSION) ; + + #ifndef NCAMD + camd_version (ver) ; + check_version ("CAMD", ver, CAMD_MAIN_VERSION, + CAMD_SUB_VERSION, CAMD_SUBSUB_VERSION) ; + + ccolamd_version (ver) ; + check_version ("CCOLAMD", ver, CCOLAMD_MAIN_VERSION, + CCOLAMD_SUB_VERSION, CCOLAMD_SUBSUB_VERSION) ; + #endif + + //-------------------------------------------------------------------------- + // read in a matrix + //-------------------------------------------------------------------------- + A = cholmod_l_read_sparse2 (f, CHOLMOD_DOUBLE, cm) ; if (ff != NULL) { diff --git a/CHOLMOD/Demo/cholmod_si_demo.c b/CHOLMOD/Demo/cholmod_si_demo.c index 8026f4130..2b4151ead 100644 --- a/CHOLMOD/Demo/cholmod_si_demo.c +++ b/CHOLMOD/Demo/cholmod_si_demo.c @@ -55,6 +55,19 @@ static void my_handler (int status, const char *file, int line, } } +static void check_version (char *package, int ver [3], + int major, int minor, int patch) +{ + printf ("%s version %d.%d.%d\n", package, ver [0], ver [1], ver [2]) ; + if (ver [0] != major || ver [1] != minor || ver [2] != patch) + { + printf ("header version differs (%d,%d,%d) from library\n", + major, minor, patch) ; + my_handler (CHOLMOD_INVALID, __FILE__, __LINE__, + "version mismatch") ; + } +} + int main (int argc, char **argv) { double @@ -136,14 +149,41 @@ int main (int argc, char **argv) beta [1] = 0 ; //-------------------------------------------------------------------------- - // read in a matrix + // check versions //-------------------------------------------------------------------------- printf ("\n---------------------------------- cholmod_si_demo:\n") ; + cholmod_version (ver) ; - printf ("cholmod version %d.%d.%d\n", ver [0], ver [1], ver [2]) ; + check_version ("cholmod", ver, CHOLMOD_MAIN_VERSION, + CHOLMOD_SUB_VERSION, CHOLMOD_SUBSUB_VERSION) ; + SuiteSparse_version (ver) ; - printf ("SuiteSparse version %d.%d.%d\n", ver [0], ver [1], ver [2]) ; + check_version ("SuiteSparse", ver, SUITESPARSE_MAIN_VERSION, + SUITESPARSE_SUB_VERSION, SUITESPARSE_SUBSUB_VERSION) ; + + amd_version (ver) ; + check_version ("AMD", ver, AMD_MAIN_VERSION, + AMD_SUB_VERSION, AMD_SUBSUB_VERSION) ; + + colamd_version (ver) ; + check_version ("COLAMD", ver, COLAMD_MAIN_VERSION, + COLAMD_SUB_VERSION, COLAMD_SUBSUB_VERSION) ; + + #ifndef NCAMD + camd_version (ver) ; + check_version ("CAMD", ver, CAMD_MAIN_VERSION, + CAMD_SUB_VERSION, CAMD_SUBSUB_VERSION) ; + + ccolamd_version (ver) ; + check_version ("CCOLAMD", ver, CCOLAMD_MAIN_VERSION, + CCOLAMD_SUB_VERSION, CCOLAMD_SUBSUB_VERSION) ; + #endif + + //-------------------------------------------------------------------------- + // read in a matrix + //-------------------------------------------------------------------------- + A = cholmod_read_sparse2 (f, CHOLMOD_SINGLE, cm) ; if (ff != NULL) { diff --git a/CHOLMOD/Demo/cholmod_sl_demo.c b/CHOLMOD/Demo/cholmod_sl_demo.c index 71b3ad237..348407bc2 100644 --- a/CHOLMOD/Demo/cholmod_sl_demo.c +++ b/CHOLMOD/Demo/cholmod_sl_demo.c @@ -55,6 +55,19 @@ static void my_handler (int status, const char *file, int line, } } +static void check_version (char *package, int ver [3], + int major, int minor, int patch) +{ + printf ("%s version %d.%d.%d\n", package, ver [0], ver [1], ver [2]) ; + if (ver [0] != major || ver [1] != minor || ver [2] != patch) + { + printf ("header version differs (%d,%d,%d) from library\n", + major, minor, patch) ; + my_handler (CHOLMOD_INVALID, __FILE__, __LINE__, + "version mismatch") ; + } +} + int main (int argc, char **argv) { double @@ -136,14 +149,41 @@ int main (int argc, char **argv) beta [1] = 0 ; //-------------------------------------------------------------------------- - // read in a matrix + // check versions //-------------------------------------------------------------------------- printf ("\n---------------------------------- cholmod_sl_demo:\n") ; + cholmod_l_version (ver) ; - printf ("cholmod version %d.%d.%d\n", ver [0], ver [1], ver [2]) ; + check_version ("cholmod", ver, CHOLMOD_MAIN_VERSION, + CHOLMOD_SUB_VERSION, CHOLMOD_SUBSUB_VERSION) ; + SuiteSparse_version (ver) ; - printf ("SuiteSparse version %d.%d.%d\n", ver [0], ver [1], ver [2]) ; + check_version ("SuiteSparse", ver, SUITESPARSE_MAIN_VERSION, + SUITESPARSE_SUB_VERSION, SUITESPARSE_SUBSUB_VERSION) ; + + amd_version (ver) ; + check_version ("AMD", ver, AMD_MAIN_VERSION, + AMD_SUB_VERSION, AMD_SUBSUB_VERSION) ; + + colamd_version (ver) ; + check_version ("COLAMD", ver, COLAMD_MAIN_VERSION, + COLAMD_SUB_VERSION, COLAMD_SUBSUB_VERSION) ; + + #ifndef NCAMD + camd_version (ver) ; + check_version ("CAMD", ver, CAMD_MAIN_VERSION, + CAMD_SUB_VERSION, CAMD_SUBSUB_VERSION) ; + + ccolamd_version (ver) ; + check_version ("CCOLAMD", ver, CCOLAMD_MAIN_VERSION, + CCOLAMD_SUB_VERSION, CCOLAMD_SUBSUB_VERSION) ; + #endif + + //-------------------------------------------------------------------------- + // read in a matrix + //-------------------------------------------------------------------------- + A = cholmod_l_read_sparse2 (f, CHOLMOD_SINGLE, cm) ; if (ff != NULL) { diff --git a/CHOLMOD/Tcov/t_amdtest.c b/CHOLMOD/Tcov/t_amdtest.c index 866b9d1d2..e026af401 100644 --- a/CHOLMOD/Tcov/t_amdtest.c +++ b/CHOLMOD/Tcov/t_amdtest.c @@ -10,6 +10,7 @@ #undef ASSERT #include "amd.h" +#include "colamd.h" #include "amd_internal.h" #undef FLIP @@ -30,11 +31,31 @@ void amdtest (cholmod_sparse *A) Int i, j, n, nrow, ncol, ok, cnz, bnz, p, trial, sorted ; //-------------------------------------------------------------------------- - // get inputs + // check version //-------------------------------------------------------------------------- printf ("\nAMD test\n") ; + printf ("AMD version %d.%d.%d, date: %s\n", + AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION, AMD_DATE) ; + int version [3] ; + amd_version (version) ; + OK ((version [0] == AMD_MAIN_VERSION) && + (version [1] == AMD_SUB_VERSION) && + (version [2] == AMD_SUBSUB_VERSION)) ; + + printf ("COLAMD version %d.%d.%d, date: %s\n", + COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_SUBSUB_VERSION, + COLAMD_DATE) ; + colamd_version (version) ; + OK ((version [0] == COLAMD_MAIN_VERSION) && + (version [1] == COLAMD_SUB_VERSION) && + (version [2] == COLAMD_SUBSUB_VERSION)) ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + if (A == NULL) { return ; diff --git a/CHOLMOD/Tcov/t_camdtest.c b/CHOLMOD/Tcov/t_camdtest.c index 9ed047651..dd5e4b7fd 100644 --- a/CHOLMOD/Tcov/t_camdtest.c +++ b/CHOLMOD/Tcov/t_camdtest.c @@ -16,6 +16,7 @@ #undef ASSERT #ifndef NCAMD #include "camd.h" +#include "ccolamd.h" #include "camd_internal.h" //------------------------------------------------------------------------------ @@ -32,11 +33,31 @@ void camdtest (cholmod_sparse *A) Int i, j, n, nrow, ncol, ok, cnz, bnz, p, trial, sorted ; //-------------------------------------------------------------------------- - // get inputs + // check version //-------------------------------------------------------------------------- printf ("\nCAMD test\n") ; + printf ("CAMD version %d.%d.%d, date: %s\n", + CAMD_MAIN_VERSION, CAMD_SUB_VERSION, CAMD_SUBSUB_VERSION, CAMD_DATE) ; + int version [3] ; + camd_version (version) ; + OK ((version [0] == CAMD_MAIN_VERSION) && + (version [1] == CAMD_SUB_VERSION) && + (version [2] == CAMD_SUBSUB_VERSION)) ; + + printf ("CCOLAMD version %d.%d.%d, date: %s\n", + CCOLAMD_MAIN_VERSION, CCOLAMD_SUB_VERSION, CCOLAMD_SUBSUB_VERSION, + CCOLAMD_DATE) ; + ccolamd_version (version) ; + OK ((version [0] == CCOLAMD_MAIN_VERSION) && + (version [1] == CCOLAMD_SUB_VERSION) && + (version [2] == CCOLAMD_SUBSUB_VERSION)) ; + + //-------------------------------------------------------------------------- + // get inputs + //-------------------------------------------------------------------------- + if (A == NULL) { return ; diff --git a/COLAMD/Config/colamd.h.in b/COLAMD/Config/colamd.h.in index ac509df7a..9740501a5 100644 --- a/COLAMD/Config/colamd.h.in +++ b/COLAMD/Config/colamd.h.in @@ -234,6 +234,8 @@ void symamd_l_report int64_t stats [COLAMD_STATS] ) ; +void colamd_version (int version [3]) ; + #ifdef __cplusplus } #endif diff --git a/COLAMD/Demo/colamd_example.c b/COLAMD/Demo/colamd_example.c index e478f7d21..b64ca33e9 100644 --- a/COLAMD/Demo/colamd_example.c +++ b/COLAMD/Demo/colamd_example.c @@ -98,6 +98,21 @@ int main (void) int row, col, pp, length, ok ; + //-------------------------------------------------------------------------- + // colamd version + //-------------------------------------------------------------------------- + + int version [3] ; + colamd_version (version) ; + printf ("COLAMD v%d.%d.%d\n", version [0], version [1], version [2]) ; + if ((version [0] != COLAMD_MAIN_VERSION) || + (version [1] != COLAMD_SUB_VERSION) || + (version [2] != COLAMD_SUBSUB_VERSION)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } + /* ====================================================================== */ /* dump the input matrix A */ /* ====================================================================== */ diff --git a/COLAMD/Demo/colamd_example.out b/COLAMD/Demo/colamd_example.out index ecfaac7c6..04e46e022 100644 --- a/COLAMD/Demo/colamd_example.out +++ b/COLAMD/Demo/colamd_example.out @@ -1,3 +1,4 @@ +COLAMD v3.3.0 colamd 5-by-4 input matrix: Column 0, with 3 entries: row 0 diff --git a/COLAMD/Demo/colamd_l_example.c b/COLAMD/Demo/colamd_l_example.c index b48a55bff..3bf4c18ca 100644 --- a/COLAMD/Demo/colamd_l_example.c +++ b/COLAMD/Demo/colamd_l_example.c @@ -99,6 +99,21 @@ int main (void) int64_t row, col, pp, length ; int ok ; + //-------------------------------------------------------------------------- + // colamd version + //-------------------------------------------------------------------------- + + int version [3] ; + colamd_version (version) ; + printf ("COLAMD v%d.%d.%d\n", version [0], version [1], version [2]) ; + if ((version [0] != COLAMD_MAIN_VERSION) || + (version [1] != COLAMD_SUB_VERSION) || + (version [2] != COLAMD_SUBSUB_VERSION)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } + /* ====================================================================== */ /* dump the input matrix A */ /* ====================================================================== */ diff --git a/COLAMD/Demo/colamd_l_example.out b/COLAMD/Demo/colamd_l_example.out index 479ac3d75..a284430c4 100644 --- a/COLAMD/Demo/colamd_l_example.out +++ b/COLAMD/Demo/colamd_l_example.out @@ -1,3 +1,4 @@ +COLAMD v3.3.0 colamd 5-by-4 input matrix: Column 0, with 3 entries: row 0 diff --git a/COLAMD/Doc/ChangeLog b/COLAMD/Doc/ChangeLog index 7ca85dfc2..778aac9cd 100644 --- a/COLAMD/Doc/ChangeLog +++ b/COLAMD/Doc/ChangeLog @@ -1,6 +1,7 @@ Dec 30, 2023: version 3.3.0 * major change to build system: by Markus Mützel + * colamd_version: added to return version of COLAMD Sept 18, 2023: version 3.2.1 diff --git a/COLAMD/Include/colamd.h b/COLAMD/Include/colamd.h index 405cff873..2ced53788 100644 --- a/COLAMD/Include/colamd.h +++ b/COLAMD/Include/colamd.h @@ -234,6 +234,8 @@ void symamd_l_report int64_t stats [COLAMD_STATS] ) ; +void colamd_version (int version [3]) ; + #ifdef __cplusplus } #endif diff --git a/COLAMD/Source/colamd.c b/COLAMD/Source/colamd.c index af5b27f7a..bc4160bb4 100644 --- a/COLAMD/Source/colamd.c +++ b/COLAMD/Source/colamd.c @@ -974,6 +974,19 @@ PRIVATE void debug_structures /* === USER-CALLABLE ROUTINES: ============================================== */ /* ========================================================================== */ +//------------------------------------------------------------------------------ +// colamd_version: return COLAMD version +//------------------------------------------------------------------------------ + +#ifndef DLONG +void colamd_version (int version [3]) +{ + version [0] = COLAMD_MAIN_VERSION ; + version [1] = COLAMD_SUB_VERSION ; + version [2] = COLAMD_SUBSUB_VERSION ; +} +#endif + /* ========================================================================== */ /* === colamd_recommended =================================================== */ /* ========================================================================== */ @@ -1046,7 +1059,6 @@ size_t COLAMD_recommended /* returns recommended value of Alen. */ return (ok ? s : 0) ; } - /* ========================================================================== */ /* === colamd_set_defaults ================================================== */ /* ========================================================================== */ diff --git a/CSparse/Config/cs.h.in b/CSparse/Config/cs.h.in index 4be5cca39..920dfe9e8 100644 --- a/CSparse/Config/cs.h.in +++ b/CSparse/Config/cs.h.in @@ -22,6 +22,8 @@ #define csi int64_t #endif +void csparse_version (int version [3]) ; // return version number + /* --- primary CSparse routines and data structures ------------------------- */ typedef struct cs_sparse /* matrix in compressed-column or triplet form */ { diff --git a/CSparse/Demo/cs_demo.out b/CSparse/Demo/cs_demo.out index ea926068d..923eebb45 100644 --- a/CSparse/Demo/cs_demo.out +++ b/CSparse/Demo/cs_demo.out @@ -1,72 +1,35 @@ ( cd build && cmake .. && cmake --build . --config Release -j8 ) -- Building CSparse version: v4.3.0 (Dec 30, 2023) --- Source: /home/davis/dev2/SuiteSparse/CSparse --- Build: /home/davis/dev2/SuiteSparse/CSparse/build +-- Source: /Users/davis/dev2/SuiteSparse/CSparse +-- Build: /Users/davis/dev2/SuiteSparse/CSparse/build -- Build type: Release -- Also compiling the demos in CSparse/Demo --- Configuring done --- Generating done --- Build files have been written to: /home/davis/dev2/SuiteSparse/CSparse/build -make[1]: Entering directory '/home/davis/dev2/SuiteSparse/CSparse/build' -make[2]: Entering directory '/home/davis/dev2/SuiteSparse/CSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CSparse/build' -Consolidate compiler generated dependencies of target csparse -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CSparse/build' -Consolidate compiler generated dependencies of target csparse_static -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CSparse/build' -[ 46%] Built target csparse +-- Configuring done (0.0s) +-- Generating done (0.0s) +-- Build files have been written to: /Users/davis/dev2/SuiteSparse/CSparse/build +[ 93%] Built target csparse [ 93%] Built target csparse_static -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CSparse/build' -Consolidate compiler generated dependencies of target cs_demo2 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CSparse/build' -Consolidate compiler generated dependencies of target cs_demo3 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CSparse/build' -Consolidate compiler generated dependencies of target cs_demo1 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CSparse/build' -[ 96%] Built target cs_demo2 -[ 98%] Built target cs_demo3 -[100%] Built target cs_demo1 -make[2]: Leaving directory '/home/davis/dev2/SuiteSparse/CSparse/build' -make[1]: Leaving directory '/home/davis/dev2/SuiteSparse/CSparse/build' +[ 99%] Built target cs_demo3 +[ 99%] Built target cs_demo1 +[100%] Built target cs_demo2 ( cd build && cmake -DDEMO=1 .. && cmake --build . --config Release -j8 ) -- Building CSparse version: v4.3.0 (Dec 30, 2023) --- Source: /home/davis/dev2/SuiteSparse/CSparse --- Build: /home/davis/dev2/SuiteSparse/CSparse/build +-- Source: /Users/davis/dev2/SuiteSparse/CSparse +-- Build: /Users/davis/dev2/SuiteSparse/CSparse/build -- Build type: Release -- Also compiling the demos in CSparse/Demo --- Configuring done --- Generating done --- Build files have been written to: /home/davis/dev2/SuiteSparse/CSparse/build -make[1]: Entering directory '/home/davis/dev2/SuiteSparse/CSparse/build' -make[2]: Entering directory '/home/davis/dev2/SuiteSparse/CSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CSparse/build' -Consolidate compiler generated dependencies of target csparse_static -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CSparse/build' -Consolidate compiler generated dependencies of target csparse -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CSparse/build' -[ 47%] Built target csparse_static -[ 93%] Built target csparse -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CSparse/build' -Consolidate compiler generated dependencies of target cs_demo3 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CSparse/build' -Consolidate compiler generated dependencies of target cs_demo2 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CSparse/build' -Consolidate compiler generated dependencies of target cs_demo1 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CSparse/build' -[ 95%] Built target cs_demo3 -[ 97%] Built target cs_demo1 +-- Configuring done (0.0s) +-- Generating done (0.0s) +-- Build files have been written to: /Users/davis/dev2/SuiteSparse/CSparse/build +[ 92%] Built target csparse +[ 93%] Built target csparse_static +[100%] Built target cs_demo1 [100%] Built target cs_demo2 -make[2]: Leaving directory '/home/davis/dev2/SuiteSparse/CSparse/build' -make[1]: Leaving directory '/home/davis/dev2/SuiteSparse/CSparse/build' +[100%] Built target cs_demo3 ./build/cs_demo1 < ./Matrix/t1 +CSparse v4.3.0 T: -CSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 triplet: 4-by-4, nzmax: 16 nnz: 10 2 2 : 3 1 0 : 3.1 @@ -79,7 +42,7 @@ triplet: 4-by-4, nzmax: 16 nnz: 10 0 0 : 4.5 2 1 : 1.7 A: -CSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 11.1 col 0 : locations 0 to 2 1 : 3.1 @@ -96,7 +59,7 @@ CSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 3 : 1 1 : 0.9 AT: -CSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 7.7 col 0 : locations 0 to 1 0 : 4.5 @@ -113,7 +76,7 @@ CSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : 0.4 3 : 1 D: -CSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 16 nnz: 16, 1-norm: 139.58 col 0 : locations 0 to 3 1 : 13.95 @@ -139,12 +102,12 @@ CSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 --- Matrix: 4-by-4, nnz: 10 (sym: 0: nnz 0), norm: 1.11e+01 blocks: 1 singletons: 0 structural rank: 4 -QR natural time: 0.00 resid: 3.06e-17 -QR amd(A'*A) time: 0.00 resid: 3.06e-17 -LU natural time: 0.00 resid: 1.53e-17 -LU amd(A+A') time: 0.00 resid: 1.53e-17 -LU amd(S'*S) time: 0.00 resid: 0.00e+00 -LU amd(A'*A) time: 0.00 resid: 1.53e-17 +QR natural time: 0.00 resid: 1.15e-17 +QR amd(A'*A) time: 0.00 resid: 1.53e-17 +LU natural time: 0.00 resid: 1.04e-17 +LU amd(A+A') time: 0.00 resid: 4.94e-18 +LU amd(S'*S) time: 0.00 resid: 4.94e-18 +LU amd(A'*A) time: 0.00 resid: 4.94e-18 ./build/cs_demo2 < ./Matrix/ash219 --- Matrix: 219-by-85, nnz: 438 (sym: 0: nnz 0), norm: 9.00e+00 @@ -155,57 +118,57 @@ QR amd(A'*A) time: 0.00 resid: 1.61e-02 --- Matrix: 48-by-48, nnz: 224 (sym: -1: nnz 400), norm: 3.57e+09 blocks: 1 singletons: 0 structural rank: 48 -QR natural time: 0.00 resid: 2.62e-19 -QR amd(A'*A) time: 0.00 resid: 5.27e-19 -LU natural time: 0.00 resid: 2.17e-19 -LU amd(A+A') time: 0.00 resid: 1.87e-19 -LU amd(S'*S) time: 0.00 resid: 2.38e-19 -LU amd(A'*A) time: 0.00 resid: 2.38e-19 -Chol natural time: 0.00 resid: 2.64e-19 -Chol amd(A+A') time: 0.00 resid: 2.55e-19 +QR natural time: 0.00 resid: 3.98e-19 +QR amd(A'*A) time: 0.00 resid: 3.07e-19 +LU natural time: 0.00 resid: 2.63e-19 +LU amd(A+A') time: 0.00 resid: 8.21e-20 +LU amd(S'*S) time: 0.00 resid: 1.96e-19 +LU amd(A'*A) time: 0.00 resid: 1.96e-19 +Chol natural time: 0.00 resid: 2.03e-19 +Chol amd(A+A') time: 0.00 resid: 2.01e-19 ./build/cs_demo2 < ./Matrix/fs_183_1 --- Matrix: 183-by-183, nnz: 988 (sym: 0: nnz 0), norm: 1.70e+09 zero entries dropped: 71 tiny entries dropped: 10 blocks: 38 singletons: 37 structural rank: 183 -QR natural time: 0.01 resid: 6.84e-28 -QR amd(A'*A) time: 0.00 resid: 9.38e-28 -LU natural time: 0.00 resid: 6.20e-28 -LU amd(A+A') time: 0.00 resid: 1.55e-27 -LU amd(S'*S) time: 0.00 resid: 6.98e-28 -LU amd(A'*A) time: 0.00 resid: 6.98e-28 +QR natural time: 0.00 resid: 7.33e-28 +QR amd(A'*A) time: 0.00 resid: 1.88e-27 +LU natural time: 0.00 resid: 4.65e-28 +LU amd(A+A') time: 0.00 resid: 1.51e-27 +LU amd(S'*S) time: 0.00 resid: 7.82e-28 +LU amd(A'*A) time: 0.00 resid: 7.82e-28 ./build/cs_demo2 < ./Matrix/mbeacxc --- Matrix: 492-by-490, nnz: 49920 (sym: 0: nnz 0), norm: 9.29e-01 blocks: 10 singletons: 8 structural rank: 448 -QR natural time: 0.11 resid: nan -QR amd(A'*A) time: 0.14 resid: nan +QR natural time: 0.03 resid: nan +QR amd(A'*A) time: 0.04 resid: nan ./build/cs_demo2 < ./Matrix/west0067 --- Matrix: 67-by-67, nnz: 294 (sym: 0: nnz 0), norm: 6.14e+00 blocks: 2 singletons: 1 structural rank: 67 -QR natural time: 0.00 resid: 7.14e-17 -QR amd(A'*A) time: 0.00 resid: 3.10e-17 -LU natural time: 0.00 resid: 3.89e-17 -LU amd(A+A') time: 0.00 resid: 2.27e-17 -LU amd(S'*S) time: 0.00 resid: 1.95e-17 -LU amd(A'*A) time: 0.00 resid: 2.60e-17 +QR natural time: 0.00 resid: 4.31e-17 +QR amd(A'*A) time: 0.00 resid: 2.56e-17 +LU natural time: 0.00 resid: 2.18e-17 +LU amd(A+A') time: 0.00 resid: 2.90e-17 +LU amd(S'*S) time: 0.00 resid: 2.20e-17 +LU amd(A'*A) time: 0.00 resid: 2.20e-17 ./build/cs_demo2 < ./Matrix/lp_afiro --- Matrix: 27-by-51, nnz: 102 (sym: 0: nnz 0), norm: 3.43e+00 blocks: 1 singletons: 0 structural rank: 27 -QR natural time: 0.00 resid: 3.96e-16 -QR amd(A'*A) time: 0.00 resid: 2.25e-16 +QR natural time: 0.00 resid: 4.17e-16 +QR amd(A'*A) time: 0.00 resid: 4.27e-16 ./build/cs_demo2 < ./Matrix/bcsstk16 --- Matrix: 4884-by-4884, nnz: 147631 (sym: -1: nnz 290378), norm: 7.01e+09 blocks: 75 singletons: 74 structural rank: 4884 -QR amd(A'*A) time: 1.41 resid: 1.39e-22 -LU amd(A+A') time: 0.81 resid: 1.10e-22 -LU amd(S'*S) time: 0.79 resid: 1.28e-22 -LU amd(A'*A) time: 0.83 resid: 1.78e-22 -Chol amd(A+A') time: 0.25 resid: 1.19e-22 +QR amd(A'*A) time: 0.39 resid: 1.34e-22 +LU amd(A+A') time: 0.18 resid: 1.07e-22 +LU amd(S'*S) time: 0.17 resid: 1.25e-22 +LU amd(A'*A) time: 0.18 resid: 1.91e-22 +Chol amd(A+A') time: 0.05 resid: 1.15e-22 ./build/cs_demo3 < ./Matrix/bcsstk01 --- Matrix: 48-by-48, nnz: 224 (sym: -1: nnz 400), norm: 3.57e+09 @@ -214,23 +177,23 @@ chol then update/downdate amd(A+A') symbolic chol time 0.00 numeric chol time 0.00 solve chol time 0.00 -original: resid: 2.55e-19 +original: resid: 2.01e-19 update: time: 0.00 -update: time: 0.00 (incl solve) resid: 9.66e-19 -rechol: time: 0.00 (incl solve) resid: 1.55e-18 +update: time: 0.00 (incl solve) resid: 3.21e-18 +rechol: time: 0.00 (incl solve) resid: 3.07e-18 downdate: time: 0.00 -downdate: time: 0.00 (incl solve) resid: 3.74e-17 +downdate: time: 0.00 (incl solve) resid: 4.46e-17 ./build/cs_demo3 < ./Matrix/bcsstk16 --- Matrix: 4884-by-4884, nnz: 147631 (sym: -1: nnz 290378), norm: 7.01e+09 chol then update/downdate amd(A+A') -symbolic chol time 0.02 -numeric chol time 0.22 +symbolic chol time 0.00 +numeric chol time 0.05 solve chol time 0.00 -original: resid: 1.19e-22 +original: resid: 1.15e-22 update: time: 0.00 -update: time: 0.00 (incl solve) resid: 1.12e-23 -rechol: time: 0.23 (incl solve) resid: 1.17e-23 +update: time: 0.00 (incl solve) resid: 1.31e-23 +rechol: time: 0.05 (incl solve) resid: 1.44e-23 downdate: time: 0.00 -downdate: time: 0.01 (incl solve) resid: 4.09e-22 +downdate: time: 0.00 (incl solve) resid: 1.25e-21 diff --git a/CSparse/Demo/cs_demo1.c b/CSparse/Demo/cs_demo1.c index 0786e3e18..5ca3bc132 100644 --- a/CSparse/Demo/cs_demo1.c +++ b/CSparse/Demo/cs_demo1.c @@ -6,6 +6,16 @@ int main (void) { cs *T, *A, *Eye, *AT, *C, *D ; csi i, m ; + int version [3] ; + csparse_version (version) ; + printf ("CSparse v%d.%d.%d\n", version [0], version [1], version [2]) ; + if ((version [0] != CS_VER) || (version [1] != CS_SUBVER) || + (version [2] != CS_SUBSUB)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } + T = cs_load (stdin) ; /* load triplet matrix T from stdin */ printf ("T:\n") ; cs_print (T, 0) ; /* print T */ A = cs_compress (T) ; /* A = compressed-column form of T */ diff --git a/CSparse/Doc/ChangeLog b/CSparse/Doc/ChangeLog index 5ce89a86e..ba86929c6 100644 --- a/CSparse/Doc/ChangeLog +++ b/CSparse/Doc/ChangeLog @@ -1,6 +1,7 @@ Dec 30, 2023: version 4.3.0 * major change to build system: by Markus Mützel + * csparse_version: added to return CSparse version Sept 8, 2023: version 4.2.0 diff --git a/CSparse/Include/cs.h b/CSparse/Include/cs.h index 74f93d884..176347d1b 100644 --- a/CSparse/Include/cs.h +++ b/CSparse/Include/cs.h @@ -22,6 +22,8 @@ #define csi int64_t #endif +void csparse_version (int version [3]) ; // return version number + /* --- primary CSparse routines and data structures ------------------------- */ typedef struct cs_sparse /* matrix in compressed-column or triplet form */ { diff --git a/CSparse/Source/cs_version.c b/CSparse/Source/cs_version.c new file mode 100644 index 000000000..018269f8b --- /dev/null +++ b/CSparse/Source/cs_version.c @@ -0,0 +1,10 @@ +// CSparse/Source/csparse_version: return CSparse version +// CSparse, Copyright (c) 2006-2023, Timothy A. Davis. All Rights Reserved. +// SPDX-License-Identifier: LGPL-2.1+ +#include "cs.h" +void csparse_version (int version [3]) +{ + version [0] = CS_VER ; + version [1] = CS_SUBVER ; + version [2] = CS_SUBSUB ; +} diff --git a/CXSparse/Config/cs.h.in b/CXSparse/Config/cs.h.in index b2b4a34b5..f8c14e5cc 100644 --- a/CXSparse/Config/cs.h.in +++ b/CXSparse/Config/cs.h.in @@ -57,6 +57,8 @@ extern "C" { #endif +void cxsparse_version (int version [3]) ; // return version + /* -------------------------------------------------------------------------- */ /* double/int32_t version of CXSparse */ /* -------------------------------------------------------------------------- */ diff --git a/CXSparse/Demo/cs_ci_demo1.c b/CXSparse/Demo/cs_ci_demo1.c index e67fecb27..b07939d9e 100644 --- a/CXSparse/Demo/cs_ci_demo1.c +++ b/CXSparse/Demo/cs_ci_demo1.c @@ -1,4 +1,4 @@ -// CSparse/Demo/cs_demo1: demo program for CXSparse +// CXSparse/Demo/cs_demo1: demo program for CXSparse // CXSparse, Copyright (c) 2006-2022, Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: LGPL-2.1+ #include "cs.h" @@ -6,6 +6,16 @@ int main (void) { cs_ci *T, *A, *Eye, *AT, *C, *D ; int i, m ; + int version [3] ; + cxsparse_version (version) ; + printf ("CXSparse v%d.%d.%d\n", version [0], version [1], version [2]) ; + if ((version [0] != CS_VER) || (version [1] != CS_SUBVER) || + (version [2] != CS_SUBSUB)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } + T = cs_ci_load (stdin) ; /* load triplet matrix T from stdin */ printf ("T:\n") ; cs_ci_print (T, 0) ; /* print T */ A = cs_ci_compress (T) ; /* A = compressed-column form of T */ diff --git a/CXSparse/Demo/cs_cl_demo1.c b/CXSparse/Demo/cs_cl_demo1.c index 39f393a7f..9f8ba7298 100644 --- a/CXSparse/Demo/cs_cl_demo1.c +++ b/CXSparse/Demo/cs_cl_demo1.c @@ -1,4 +1,4 @@ -// CSparse/Demo/cs_cl_demo1: demo program for CXSparse (complex int64_t) +// CXSparse/Demo/cs_cl_demo1: demo program for CXSparse (complex int64_t) // CXSparse, Copyright (c) 2006-2022, Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: LGPL-2.1+ #include "cs.h" @@ -6,6 +6,16 @@ int main (void) { cs_cl *T, *A, *Eye, *AT, *C, *D ; int64_t i, m ; + int version [3] ; + cxsparse_version (version) ; + printf ("CXSparse v%d.%d.%d\n", version [0], version [1], version [2]) ; + if ((version [0] != CS_VER) || (version [1] != CS_SUBVER) || + (version [2] != CS_SUBSUB)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } + T = cs_cl_load (stdin) ; /* load triplet matrix T from stdin */ printf ("T:\n") ; cs_cl_print (T, 0) ; /* print T */ A = cs_cl_compress (T) ; /* A = compressed-column form of T */ diff --git a/CXSparse/Demo/cs_demo.c b/CXSparse/Demo/cs_demo.c index 29034afdf..6adc27ee4 100644 --- a/CXSparse/Demo/cs_demo.c +++ b/CXSparse/Demo/cs_demo.c @@ -1,4 +1,4 @@ -// CSparse/Demo/cs_demo: demo utilities for CXSparse (complex int32_t) +// CSparse/Demo/cs_demo: demo utilities for CXSparse (double int32_t) // CXSparse, Copyright (c) 2006-2022, Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: LGPL-2.1+ #include "cs_demo.h" diff --git a/CXSparse/Demo/cs_demo.out b/CXSparse/Demo/cs_demo.out index 6666552ab..8e289b7b7 100644 --- a/CXSparse/Demo/cs_demo.out +++ b/CXSparse/Demo/cs_demo.out @@ -1,21 +1,21 @@ ( cd build && cmake -DDEMO=1 .. && cmake --build . --config Release -j8 ) -- Building CXSparse version: v4.3.0 (Dec 30, 2023) --- Source: /home/davis/dev2/SuiteSparse/CXSparse --- Build: /home/davis/dev2/SuiteSparse/CXSparse/build +-- Source: /Users/davis/dev2/SuiteSparse/CXSparse +-- Build: /Users/davis/dev2/SuiteSparse/CXSparse/build -- Install lib: lib -- Install include: include -- Install bin: bin -- Install pkg-file: lib -- Install rpath: --- Build rpath: /home/davis/dev2/SuiteSparse/CXSparse/build +-- Build rpath: /Users/davis/dev2/SuiteSparse/CXSparse/build -- Build type: Release --- Fortran: /usr/bin/f95 +-- Fortran: /opt/homebrew/bin/gfortran -- CUDA: not enabled -- complex data type: enabled -- SuiteSparse_config version: 7.4.0 --- SuiteSparse_config include: /home/davis/dev2/SuiteSparse/SuiteSparse_config --- SuiteSparse_config library: /home/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.so.7.4.0 --- SuiteSparse_config static: /home/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.a +-- SuiteSparse_config include: /Users/davis/dev2/SuiteSparse/SuiteSparse_config +-- SuiteSparse_config library: /Users/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.7.4.0.dylib +-- SuiteSparse_config static: /Users/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.a -- Also compiling the demos in CXSparse/Demo -- ------------------------------------------------------------------------ -- SuiteSparse CMAKE report for: cxsparse @@ -26,101 +26,41 @@ -- BUILD_SHARED_LIBS: ON -- BUILD_STATIC_LIBS: ON -- use OpenMP: no --- C compiler: /usr/bin/cc +-- C compiler: /Library/Developer/CommandLineTools/usr/bin/cc -- C flags: -- C++ compiler: -- C++ flags: -- C Flags release: -O3 -DNDEBUG -- C++ Flags release: --- Fortran compiler: /usr/bin/f95 +-- Fortran compiler: /opt/homebrew/bin/gfortran -- compile definitions: -- ------------------------------------------------------------------------ --- Configuring done --- Generating done --- Build files have been written to: /home/davis/dev2/SuiteSparse/CXSparse/build -make[1]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[2]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target CXSparse_static -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target CXSparse -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -[ 45%] Built target CXSparse_static -[ 89%] Built target CXSparse -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_dl_demo1 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_demo1 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_di_demo3 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_demo2 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_dl_demo2 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_demo3 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_di_demo2 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_di_demo1 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -[ 90%] Built target cs_dl_demo1 -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -[ 90%] Built target cs_demo3 -[ 92%] Built target cs_di_demo3 -[ 93%] Built target cs_dl_demo2 -[ 91%] Built target cs_demo1 -[ 93%] Built target cs_demo2 -[ 93%] Built target cs_di_demo1 -[ 94%] Built target cs_di_demo2 -Consolidate compiler generated dependencies of target cs_dl_demo3 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_cl_demo2 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_ci_demo1 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' +-- Configuring done (0.0s) +-- Generating done (0.1s) +-- Build files have been written to: /Users/davis/dev2/SuiteSparse/CXSparse/build +[ 82%] Built target CXSparse +[ 89%] Built target CXSparse_static +[ 89%] Built target cs_di_demo1 +[ 90%] Built target cs_di_demo2 +[ 90%] Built target cs_demo1 +[ 91%] Built target cs_demo3 +[ 92%] Built target cs_dl_demo2 +[ 94%] Built target cs_di_demo3 +[ 94%] Built target cs_demo2 +[ 94%] Built target cs_dl_demo1 [ 95%] Built target cs_dl_demo3 -Consolidate compiler generated dependencies of target cs_ci_demo2 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_cl_demo3 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_cl_demo1 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_idemo -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_ci_demo3 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -[ 96%] Built target cs_ci_demo1 -[ 96%] Built target cs_cl_demo1 -[ 97%] Built target cs_cl_demo2 -[ 98%] Built target cs_cl_demo3 -Consolidate compiler generated dependencies of target cs_ldemo -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -[ 98%] Built target cs_ci_demo2 -[ 99%] Built target cs_ci_demo3 +[ 95%] Built target cs_ci_demo2 +[ 96%] Built target cs_ci_demo3 +[ 97%] Built target cs_cl_demo3 +[ 98%] Built target cs_ci_demo1 +[ 98%] Built target cs_cl_demo2 +[ 99%] Built target cs_cl_demo1 [ 99%] Built target cs_idemo [100%] Built target cs_ldemo -make[2]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[1]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' ./build/cs_demo1 < Matrix/t1 +CXSparse v4.3.0 T: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 triplet: 4-by-4, nzmax: 16 nnz: 10 2 2 : 3 1 0 : 3.1 @@ -133,7 +73,7 @@ triplet: 4-by-4, nzmax: 16 nnz: 10 0 0 : 4.5 2 1 : 1.7 A: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 11.1 col 0 : locations 0 to 2 1 : 3.1 @@ -150,7 +90,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 3 : 1 1 : 0.9 AT: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 7.7 col 0 : locations 0 to 1 0 : 4.5 @@ -167,7 +107,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : 0.4 3 : 1 D: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 16 nnz: 16, 1-norm: 139.58 col 0 : locations 0 to 3 1 : 13.95 @@ -193,40 +133,40 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 --- Matrix: 4-by-4, nnz: 10 (sym: 0: nnz 0), norm: 1.11e+01 blocks: 1 singletons: 0 structural rank: 4 -QR natural time: 0.00 resid: 3.06e-17 -QR amd(A'*A) time: 0.00 resid: 2.30e-17 -LU natural time: 0.00 resid: 1.53e-17 -LU amd(A+A') time: 0.00 resid: 1.53e-17 -LU amd(S'*S) time: 0.00 resid: 0.00e+00 -LU amd(A'*A) time: 0.00 resid: 1.53e-17 +QR natural time: 0.00 resid: 2.87e-17 +QR amd(A'*A) time: 0.00 resid: 1.04e-17 +LU natural time: 0.00 resid: 1.04e-17 +LU amd(A+A') time: 0.00 resid: 4.94e-18 +LU amd(S'*S) time: 0.00 resid: 4.94e-18 +LU amd(A'*A) time: 0.00 resid: 4.94e-18 ./build/cs_demo2 < Matrix/fs_183_1 --- Matrix: 183-by-183, nnz: 988 (sym: 0: nnz 0), norm: 1.70e+09 zero entries dropped: 71 tiny entries dropped: 10 blocks: 38 singletons: 37 structural rank: 183 -QR natural time: 0.01 resid: 1.42e-27 -QR amd(A'*A) time: 0.00 resid: 3.35e-28 -LU natural time: 0.00 resid: 6.20e-28 -LU amd(A+A') time: 0.00 resid: 1.55e-27 -LU amd(S'*S) time: 0.00 resid: 6.98e-28 -LU amd(A'*A) time: 0.00 resid: 6.98e-28 +QR natural time: 0.00 resid: 1.16e-27 +QR amd(A'*A) time: 0.00 resid: 6.82e-28 +LU natural time: 0.00 resid: 4.65e-28 +LU amd(A+A') time: 0.00 resid: 1.51e-27 +LU amd(S'*S) time: 0.00 resid: 7.82e-28 +LU amd(A'*A) time: 0.00 resid: 7.82e-28 ./build/cs_demo2 < Matrix/west0067 --- Matrix: 67-by-67, nnz: 294 (sym: 0: nnz 0), norm: 6.14e+00 blocks: 2 singletons: 1 structural rank: 67 -QR natural time: 0.00 resid: 5.19e-17 -QR amd(A'*A) time: 0.00 resid: 3.25e-17 -LU natural time: 0.00 resid: 3.89e-17 -LU amd(A+A') time: 0.00 resid: 2.27e-17 -LU amd(S'*S) time: 0.00 resid: 1.95e-17 -LU amd(A'*A) time: 0.00 resid: 2.60e-17 +QR natural time: 0.00 resid: 4.46e-17 +QR amd(A'*A) time: 0.00 resid: 5.76e-17 +LU natural time: 0.00 resid: 2.18e-17 +LU amd(A+A') time: 0.00 resid: 2.90e-17 +LU amd(S'*S) time: 0.00 resid: 2.20e-17 +LU amd(A'*A) time: 0.00 resid: 2.20e-17 ./build/cs_demo2 < Matrix/lp_afiro --- Matrix: 27-by-51, nnz: 102 (sym: 0: nnz 0), norm: 3.43e+00 blocks: 1 singletons: 0 structural rank: 27 -QR natural time: 0.00 resid: 3.85e-16 -QR amd(A'*A) time: 0.00 resid: 1.50e-16 +QR natural time: 0.00 resid: 1.71e-16 +QR amd(A'*A) time: 0.00 resid: 9.63e-17 ./build/cs_demo2 < Matrix/ash219 --- Matrix: 219-by-85, nnz: 438 (sym: 0: nnz 0), norm: 9.00e+00 @@ -237,20 +177,20 @@ QR amd(A'*A) time: 0.00 resid: 1.61e-02 --- Matrix: 492-by-490, nnz: 49920 (sym: 0: nnz 0), norm: 9.29e-01 blocks: 10 singletons: 8 structural rank: 448 -QR natural time: 0.11 resid: nan -QR amd(A'*A) time: 0.14 resid: nan +QR natural time: 0.03 resid: nan +QR amd(A'*A) time: 0.04 resid: nan ./build/cs_demo2 < Matrix/bcsstk01 --- Matrix: 48-by-48, nnz: 224 (sym: -1: nnz 400), norm: 3.57e+09 blocks: 1 singletons: 0 structural rank: 48 -QR natural time: 0.00 resid: 3.65e-19 -QR amd(A'*A) time: 0.00 resid: 4.02e-19 -LU natural time: 0.00 resid: 2.17e-19 -LU amd(A+A') time: 0.00 resid: 1.87e-19 -LU amd(S'*S) time: 0.00 resid: 2.38e-19 -LU amd(A'*A) time: 0.00 resid: 2.38e-19 -Chol natural time: 0.00 resid: 2.64e-19 -Chol amd(A+A') time: 0.00 resid: 2.55e-19 +QR natural time: 0.00 resid: 3.01e-19 +QR amd(A'*A) time: 0.00 resid: 5.05e-19 +LU natural time: 0.00 resid: 2.63e-19 +LU amd(A+A') time: 0.00 resid: 8.21e-20 +LU amd(S'*S) time: 0.00 resid: 1.96e-19 +LU amd(A'*A) time: 0.00 resid: 1.96e-19 +Chol natural time: 0.00 resid: 2.03e-19 +Chol amd(A+A') time: 0.00 resid: 2.01e-19 ./build/cs_demo3 < Matrix/bcsstk01 --- Matrix: 48-by-48, nnz: 224 (sym: -1: nnz 400), norm: 3.57e+09 @@ -259,38 +199,39 @@ chol then update/downdate amd(A+A') symbolic chol time 0.00 numeric chol time 0.00 solve chol time 0.00 -original: resid: 2.55e-19 +original: resid: 2.01e-19 update: time: 0.00 -update: time: 0.00 (incl solve) resid: 9.66e-19 -rechol: time: 0.00 (incl solve) resid: 1.55e-18 +update: time: 0.00 (incl solve) resid: 3.21e-18 +rechol: time: 0.00 (incl solve) resid: 3.07e-18 downdate: time: 0.00 -downdate: time: 0.00 (incl solve) resid: 3.74e-17 +downdate: time: 0.00 (incl solve) resid: 4.46e-17 ./build/cs_demo2 < Matrix/bcsstk16 --- Matrix: 4884-by-4884, nnz: 147631 (sym: -1: nnz 290378), norm: 7.01e+09 blocks: 75 singletons: 74 structural rank: 4884 -QR amd(A'*A) time: 1.38 resid: 2.01e-22 -LU amd(A+A') time: 0.89 resid: 1.10e-22 -LU amd(S'*S) time: 0.84 resid: 1.28e-22 -LU amd(A'*A) time: 0.86 resid: 1.78e-22 -Chol amd(A+A') time: 0.26 resid: 1.19e-22 +QR amd(A'*A) time: 0.38 resid: 1.79e-22 +LU amd(A+A') time: 0.17 resid: 1.07e-22 +LU amd(S'*S) time: 0.17 resid: 1.25e-22 +LU amd(A'*A) time: 0.17 resid: 1.91e-22 +Chol amd(A+A') time: 0.05 resid: 1.15e-22 ./build/cs_demo3 < Matrix/bcsstk16 --- Matrix: 4884-by-4884, nnz: 147631 (sym: -1: nnz 290378), norm: 7.01e+09 chol then update/downdate amd(A+A') -symbolic chol time 0.02 -numeric chol time 0.23 +symbolic chol time 0.00 +numeric chol time 0.04 solve chol time 0.00 -original: resid: 1.19e-22 +original: resid: 1.15e-22 update: time: 0.00 -update: time: 0.01 (incl solve) resid: 1.12e-23 -rechol: time: 0.24 (incl solve) resid: 1.17e-23 +update: time: 0.00 (incl solve) resid: 1.31e-23 +rechol: time: 0.04 (incl solve) resid: 1.44e-23 downdate: time: 0.00 -downdate: time: 0.00 (incl solve) resid: 4.09e-22 +downdate: time: 0.00 (incl solve) resid: 1.25e-21 ./build/cs_di_demo1 < Matrix/t1 +CXSparse v4.3.0 T: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 triplet: 4-by-4, nzmax: 16 nnz: 10 2 2 : 3 1 0 : 3.1 @@ -303,7 +244,7 @@ triplet: 4-by-4, nzmax: 16 nnz: 10 0 0 : 4.5 2 1 : 1.7 A: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 11.1 col 0 : locations 0 to 2 1 : 3.1 @@ -320,7 +261,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 3 : 1 1 : 0.9 AT: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 7.7 col 0 : locations 0 to 1 0 : 4.5 @@ -337,7 +278,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : 0.4 3 : 1 D: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 16 nnz: 16, 1-norm: 139.58 col 0 : locations 0 to 3 1 : 13.95 @@ -363,40 +304,40 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 --- Matrix: 4-by-4, nnz: 10 (sym: 0: nnz 0), norm: 1.11e+01 blocks: 1 singletons: 0 structural rank: 4 -QR natural time: 0.00 resid: 3.06e-17 -QR amd(A'*A) time: 0.00 resid: 2.30e-17 -LU natural time: 0.00 resid: 1.53e-17 -LU amd(A+A') time: 0.00 resid: 1.53e-17 -LU amd(S'*S) time: 0.00 resid: 0.00e+00 -LU amd(A'*A) time: 0.00 resid: 1.53e-17 +QR natural time: 0.00 resid: 2.87e-17 +QR amd(A'*A) time: 0.00 resid: 1.04e-17 +LU natural time: 0.00 resid: 1.04e-17 +LU amd(A+A') time: 0.00 resid: 4.94e-18 +LU amd(S'*S) time: 0.00 resid: 4.94e-18 +LU amd(A'*A) time: 0.00 resid: 4.94e-18 ./build/cs_di_demo2 < Matrix/fs_183_1 --- Matrix: 183-by-183, nnz: 988 (sym: 0: nnz 0), norm: 1.70e+09 zero entries dropped: 71 tiny entries dropped: 10 blocks: 38 singletons: 37 structural rank: 183 -QR natural time: 0.01 resid: 1.42e-27 -QR amd(A'*A) time: 0.00 resid: 3.35e-28 -LU natural time: 0.00 resid: 6.20e-28 -LU amd(A+A') time: 0.00 resid: 1.55e-27 -LU amd(S'*S) time: 0.00 resid: 6.98e-28 -LU amd(A'*A) time: 0.00 resid: 6.98e-28 +QR natural time: 0.00 resid: 1.16e-27 +QR amd(A'*A) time: 0.00 resid: 6.82e-28 +LU natural time: 0.00 resid: 4.65e-28 +LU amd(A+A') time: 0.00 resid: 1.51e-27 +LU amd(S'*S) time: 0.00 resid: 7.82e-28 +LU amd(A'*A) time: 0.00 resid: 7.82e-28 ./build/cs_di_demo2 < Matrix/west0067 --- Matrix: 67-by-67, nnz: 294 (sym: 0: nnz 0), norm: 6.14e+00 blocks: 2 singletons: 1 structural rank: 67 -QR natural time: 0.00 resid: 5.19e-17 -QR amd(A'*A) time: 0.00 resid: 3.25e-17 -LU natural time: 0.00 resid: 3.89e-17 -LU amd(A+A') time: 0.00 resid: 2.27e-17 -LU amd(S'*S) time: 0.00 resid: 1.95e-17 -LU amd(A'*A) time: 0.00 resid: 2.60e-17 +QR natural time: 0.00 resid: 4.46e-17 +QR amd(A'*A) time: 0.00 resid: 5.76e-17 +LU natural time: 0.00 resid: 2.18e-17 +LU amd(A+A') time: 0.00 resid: 2.90e-17 +LU amd(S'*S) time: 0.00 resid: 2.20e-17 +LU amd(A'*A) time: 0.00 resid: 2.20e-17 ./build/cs_di_demo2 < Matrix/lp_afiro --- Matrix: 27-by-51, nnz: 102 (sym: 0: nnz 0), norm: 3.43e+00 blocks: 1 singletons: 0 structural rank: 27 -QR natural time: 0.00 resid: 3.85e-16 -QR amd(A'*A) time: 0.00 resid: 1.50e-16 +QR natural time: 0.00 resid: 1.71e-16 +QR amd(A'*A) time: 0.00 resid: 9.63e-17 ./build/cs_di_demo2 < Matrix/ash219 --- Matrix: 219-by-85, nnz: 438 (sym: 0: nnz 0), norm: 9.00e+00 @@ -407,20 +348,20 @@ QR amd(A'*A) time: 0.00 resid: 1.61e-02 --- Matrix: 492-by-490, nnz: 49920 (sym: 0: nnz 0), norm: 9.29e-01 blocks: 10 singletons: 8 structural rank: 448 -QR natural time: 0.11 resid: nan -QR amd(A'*A) time: 0.14 resid: nan +QR natural time: 0.03 resid: nan +QR amd(A'*A) time: 0.04 resid: nan ./build/cs_di_demo2 < Matrix/bcsstk01 --- Matrix: 48-by-48, nnz: 224 (sym: -1: nnz 400), norm: 3.57e+09 blocks: 1 singletons: 0 structural rank: 48 -QR natural time: 0.00 resid: 3.65e-19 -QR amd(A'*A) time: 0.00 resid: 4.02e-19 -LU natural time: 0.00 resid: 2.17e-19 -LU amd(A+A') time: 0.00 resid: 1.87e-19 -LU amd(S'*S) time: 0.00 resid: 2.38e-19 -LU amd(A'*A) time: 0.00 resid: 2.38e-19 -Chol natural time: 0.00 resid: 2.64e-19 -Chol amd(A+A') time: 0.00 resid: 2.55e-19 +QR natural time: 0.00 resid: 3.01e-19 +QR amd(A'*A) time: 0.00 resid: 5.05e-19 +LU natural time: 0.00 resid: 2.63e-19 +LU amd(A+A') time: 0.00 resid: 8.21e-20 +LU amd(S'*S) time: 0.00 resid: 1.96e-19 +LU amd(A'*A) time: 0.00 resid: 1.96e-19 +Chol natural time: 0.00 resid: 2.03e-19 +Chol amd(A+A') time: 0.00 resid: 2.01e-19 ./build/cs_di_demo3 < Matrix/bcsstk01 --- Matrix: 48-by-48, nnz: 224 (sym: -1: nnz 400), norm: 3.57e+09 @@ -429,38 +370,39 @@ chol then update/downdate amd(A+A') symbolic chol time 0.00 numeric chol time 0.00 solve chol time 0.00 -original: resid: 2.55e-19 +original: resid: 2.01e-19 update: time: 0.00 -update: time: 0.00 (incl solve) resid: 9.66e-19 -rechol: time: 0.00 (incl solve) resid: 1.55e-18 +update: time: 0.00 (incl solve) resid: 3.21e-18 +rechol: time: 0.00 (incl solve) resid: 3.07e-18 downdate: time: 0.00 -downdate: time: 0.00 (incl solve) resid: 3.74e-17 +downdate: time: 0.00 (incl solve) resid: 4.46e-17 ./build/cs_di_demo2 < Matrix/bcsstk16 --- Matrix: 4884-by-4884, nnz: 147631 (sym: -1: nnz 290378), norm: 7.01e+09 blocks: 75 singletons: 74 structural rank: 4884 -QR amd(A'*A) time: 1.38 resid: 2.01e-22 -LU amd(A+A') time: 0.81 resid: 1.10e-22 -LU amd(S'*S) time: 0.83 resid: 1.28e-22 -LU amd(A'*A) time: 0.86 resid: 1.78e-22 -Chol amd(A+A') time: 0.25 resid: 1.19e-22 +QR amd(A'*A) time: 0.38 resid: 1.79e-22 +LU amd(A+A') time: 0.17 resid: 1.07e-22 +LU amd(S'*S) time: 0.16 resid: 1.25e-22 +LU amd(A'*A) time: 0.17 resid: 1.91e-22 +Chol amd(A+A') time: 0.05 resid: 1.15e-22 ./build/cs_di_demo3 < Matrix/bcsstk16 --- Matrix: 4884-by-4884, nnz: 147631 (sym: -1: nnz 290378), norm: 7.01e+09 chol then update/downdate amd(A+A') -symbolic chol time 0.02 -numeric chol time 0.22 +symbolic chol time 0.00 +numeric chol time 0.04 solve chol time 0.00 -original: resid: 1.19e-22 +original: resid: 1.15e-22 update: time: 0.00 -update: time: 0.01 (incl solve) resid: 1.12e-23 -rechol: time: 0.23 (incl solve) resid: 1.17e-23 +update: time: 0.00 (incl solve) resid: 1.31e-23 +rechol: time: 0.04 (incl solve) resid: 1.44e-23 downdate: time: 0.00 -downdate: time: 0.01 (incl solve) resid: 4.09e-22 +downdate: time: 0.00 (incl solve) resid: 1.25e-21 ./build/cs_dl_demo1 < Matrix/t1 +CXSparse v4.3.0 T: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 triplet: 4-by-4, nzmax: 16 nnz: 10 2 2 : 3 1 0 : 3.1 @@ -473,7 +415,7 @@ triplet: 4-by-4, nzmax: 16 nnz: 10 0 0 : 4.5 2 1 : 1.7 A: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 11.1 col 0 : locations 0 to 2 1 : 3.1 @@ -490,7 +432,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 3 : 1 1 : 0.9 AT: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 7.7 col 0 : locations 0 to 1 0 : 4.5 @@ -507,7 +449,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : 0.4 3 : 1 D: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 16 nnz: 16, 1-norm: 139.58 col 0 : locations 0 to 3 1 : 13.95 @@ -533,40 +475,40 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 --- Matrix: 4-by-4, nnz: 10 (sym: 0: nnz 0), norm: 1.11e+01 blocks: 1 singletons: 0 structural rank: 4 -QR natural time: 0.00 resid: 3.06e-17 -QR amd(A'*A) time: 0.00 resid: 2.30e-17 -LU natural time: 0.00 resid: 1.53e-17 -LU amd(A+A') time: 0.00 resid: 1.53e-17 -LU amd(S'*S) time: 0.00 resid: 0.00e+00 -LU amd(A'*A) time: 0.00 resid: 1.53e-17 +QR natural time: 0.00 resid: 2.87e-17 +QR amd(A'*A) time: 0.00 resid: 1.04e-17 +LU natural time: 0.00 resid: 1.04e-17 +LU amd(A+A') time: 0.00 resid: 4.94e-18 +LU amd(S'*S) time: 0.00 resid: 4.94e-18 +LU amd(A'*A) time: 0.00 resid: 4.94e-18 ./build/cs_dl_demo2 < Matrix/fs_183_1 --- Matrix: 183-by-183, nnz: 988 (sym: 0: nnz 0), norm: 1.70e+09 zero entries dropped: 71 tiny entries dropped: 10 blocks: 38 singletons: 37 structural rank: 183 -QR natural time: 0.01 resid: 1.42e-27 -QR amd(A'*A) time: 0.00 resid: 3.35e-28 -LU natural time: 0.00 resid: 6.20e-28 -LU amd(A+A') time: 0.00 resid: 1.55e-27 -LU amd(S'*S) time: 0.00 resid: 6.98e-28 -LU amd(A'*A) time: 0.00 resid: 6.98e-28 +QR natural time: 0.00 resid: 1.16e-27 +QR amd(A'*A) time: 0.00 resid: 6.82e-28 +LU natural time: 0.00 resid: 4.65e-28 +LU amd(A+A') time: 0.00 resid: 1.51e-27 +LU amd(S'*S) time: 0.00 resid: 7.82e-28 +LU amd(A'*A) time: 0.00 resid: 7.82e-28 ./build/cs_dl_demo2 < Matrix/west0067 --- Matrix: 67-by-67, nnz: 294 (sym: 0: nnz 0), norm: 6.14e+00 blocks: 2 singletons: 1 structural rank: 67 -QR natural time: 0.00 resid: 5.19e-17 -QR amd(A'*A) time: 0.00 resid: 3.25e-17 -LU natural time: 0.00 resid: 3.89e-17 -LU amd(A+A') time: 0.00 resid: 2.27e-17 -LU amd(S'*S) time: 0.00 resid: 1.95e-17 -LU amd(A'*A) time: 0.00 resid: 2.60e-17 +QR natural time: 0.00 resid: 4.46e-17 +QR amd(A'*A) time: 0.00 resid: 5.76e-17 +LU natural time: 0.00 resid: 2.18e-17 +LU amd(A+A') time: 0.00 resid: 2.90e-17 +LU amd(S'*S) time: 0.00 resid: 2.20e-17 +LU amd(A'*A) time: 0.00 resid: 2.20e-17 ./build/cs_dl_demo2 < Matrix/lp_afiro --- Matrix: 27-by-51, nnz: 102 (sym: 0: nnz 0), norm: 3.43e+00 blocks: 1 singletons: 0 structural rank: 27 -QR natural time: 0.00 resid: 3.85e-16 -QR amd(A'*A) time: 0.00 resid: 1.50e-16 +QR natural time: 0.00 resid: 1.71e-16 +QR amd(A'*A) time: 0.00 resid: 9.63e-17 ./build/cs_dl_demo2 < Matrix/ash219 --- Matrix: 219-by-85, nnz: 438 (sym: 0: nnz 0), norm: 9.00e+00 @@ -577,20 +519,20 @@ QR amd(A'*A) time: 0.00 resid: 1.61e-02 --- Matrix: 492-by-490, nnz: 49920 (sym: 0: nnz 0), norm: 9.29e-01 blocks: 10 singletons: 8 structural rank: 448 -QR natural time: 0.11 resid: nan -QR amd(A'*A) time: 0.13 resid: nan +QR natural time: 0.03 resid: nan +QR amd(A'*A) time: 0.04 resid: nan ./build/cs_dl_demo2 < Matrix/bcsstk01 --- Matrix: 48-by-48, nnz: 224 (sym: -1: nnz 400), norm: 3.57e+09 blocks: 1 singletons: 0 structural rank: 48 -QR natural time: 0.00 resid: 3.65e-19 -QR amd(A'*A) time: 0.00 resid: 4.02e-19 -LU natural time: 0.00 resid: 2.17e-19 -LU amd(A+A') time: 0.00 resid: 1.87e-19 -LU amd(S'*S) time: 0.00 resid: 2.38e-19 -LU amd(A'*A) time: 0.00 resid: 2.38e-19 -Chol natural time: 0.00 resid: 2.64e-19 -Chol amd(A+A') time: 0.00 resid: 2.55e-19 +QR natural time: 0.00 resid: 3.01e-19 +QR amd(A'*A) time: 0.00 resid: 5.05e-19 +LU natural time: 0.00 resid: 2.63e-19 +LU amd(A+A') time: 0.00 resid: 8.21e-20 +LU amd(S'*S) time: 0.00 resid: 1.96e-19 +LU amd(A'*A) time: 0.00 resid: 1.96e-19 +Chol natural time: 0.00 resid: 2.03e-19 +Chol amd(A+A') time: 0.00 resid: 2.01e-19 ./build/cs_dl_demo3 < Matrix/bcsstk01 --- Matrix: 48-by-48, nnz: 224 (sym: -1: nnz 400), norm: 3.57e+09 @@ -599,53 +541,53 @@ chol then update/downdate amd(A+A') symbolic chol time 0.00 numeric chol time 0.00 solve chol time 0.00 -original: resid: 2.55e-19 +original: resid: 2.01e-19 update: time: 0.00 -update: time: 0.00 (incl solve) resid: 9.66e-19 -rechol: time: 0.00 (incl solve) resid: 1.55e-18 +update: time: 0.00 (incl solve) resid: 3.21e-18 +rechol: time: 0.00 (incl solve) resid: 3.07e-18 downdate: time: 0.00 -downdate: time: 0.00 (incl solve) resid: 3.74e-17 +downdate: time: 0.00 (incl solve) resid: 4.46e-17 ./build/cs_dl_demo2 < Matrix/bcsstk16 --- Matrix: 4884-by-4884, nnz: 147631 (sym: -1: nnz 290378), norm: 7.01e+09 blocks: 75 singletons: 74 structural rank: 4884 -QR amd(A'*A) time: 1.42 resid: 2.01e-22 -LU amd(A+A') time: 0.80 resid: 1.10e-22 -LU amd(S'*S) time: 0.80 resid: 1.28e-22 -LU amd(A'*A) time: 0.83 resid: 1.78e-22 -Chol amd(A+A') time: 0.24 resid: 1.19e-22 +QR amd(A'*A) time: 0.39 resid: 1.79e-22 +LU amd(A+A') time: 0.18 resid: 1.07e-22 +LU amd(S'*S) time: 0.18 resid: 1.25e-22 +LU amd(A'*A) time: 0.18 resid: 1.91e-22 +Chol amd(A+A') time: 0.05 resid: 1.15e-22 ./build/cs_dl_demo3 < Matrix/bcsstk16 --- Matrix: 4884-by-4884, nnz: 147631 (sym: -1: nnz 290378), norm: 7.01e+09 chol then update/downdate amd(A+A') -symbolic chol time 0.02 -numeric chol time 0.23 +symbolic chol time 0.00 +numeric chol time 0.05 solve chol time 0.00 -original: resid: 1.19e-22 +original: resid: 1.15e-22 update: time: 0.00 -update: time: 0.01 (incl solve) resid: 1.12e-23 -rechol: time: 0.23 (incl solve) resid: 1.17e-23 +update: time: 0.00 (incl solve) resid: 1.31e-23 +rechol: time: 0.05 (incl solve) resid: 1.44e-23 downdate: time: 0.00 -downdate: time: 0.01 (incl solve) resid: 4.09e-22 +downdate: time: 0.00 (incl solve) resid: 1.25e-21 ( cd build && cmake -DDEMO=1 .. && cmake --build . --config Release -j8 ) -- Building CXSparse version: v4.3.0 (Dec 30, 2023) --- Source: /home/davis/dev2/SuiteSparse/CXSparse --- Build: /home/davis/dev2/SuiteSparse/CXSparse/build +-- Source: /Users/davis/dev2/SuiteSparse/CXSparse +-- Build: /Users/davis/dev2/SuiteSparse/CXSparse/build -- Install lib: lib -- Install include: include -- Install bin: bin -- Install pkg-file: lib -- Install rpath: --- Build rpath: /home/davis/dev2/SuiteSparse/CXSparse/build +-- Build rpath: /Users/davis/dev2/SuiteSparse/CXSparse/build -- Build type: Release --- Fortran: /usr/bin/f95 +-- Fortran: /opt/homebrew/bin/gfortran -- CUDA: not enabled -- complex data type: enabled -- SuiteSparse_config version: 7.4.0 --- SuiteSparse_config include: /home/davis/dev2/SuiteSparse/SuiteSparse_config --- SuiteSparse_config library: /home/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.so.7.4.0 --- SuiteSparse_config static: /home/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.a +-- SuiteSparse_config include: /Users/davis/dev2/SuiteSparse/SuiteSparse_config +-- SuiteSparse_config library: /Users/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.7.4.0.dylib +-- SuiteSparse_config static: /Users/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.a -- Also compiling the demos in CXSparse/Demo -- ------------------------------------------------------------------------ -- SuiteSparse CMAKE report for: cxsparse @@ -656,104 +598,43 @@ downdate: time: 0.01 (incl solve) resid: 4.09e-22 -- BUILD_SHARED_LIBS: ON -- BUILD_STATIC_LIBS: ON -- use OpenMP: no --- C compiler: /usr/bin/cc +-- C compiler: /Library/Developer/CommandLineTools/usr/bin/cc -- C flags: -- C++ compiler: -- C++ flags: -- C Flags release: -O3 -DNDEBUG -- C++ Flags release: --- Fortran compiler: /usr/bin/f95 +-- Fortran compiler: /opt/homebrew/bin/gfortran -- compile definitions: -- ------------------------------------------------------------------------ --- Configuring done --- Generating done --- Build files have been written to: /home/davis/dev2/SuiteSparse/CXSparse/build -make[1]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[2]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target CXSparse -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target CXSparse_static -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -[ 44%] Built target CXSparse -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_dl_demo1 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_di_demo2 -Consolidate compiler generated dependencies of target cs_di_demo1 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_demo1 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_demo2 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_di_demo3 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_demo3 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' +-- Configuring done (0.0s) +-- Generating done (0.1s) +-- Build files have been written to: /Users/davis/dev2/SuiteSparse/CXSparse/build +[ 89%] Built target CXSparse [ 89%] Built target CXSparse_static -[ 89%] Built target cs_dl_demo1 -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' [ 89%] Built target cs_di_demo1 -[ 90%] Built target cs_di_demo2 -[ 90%] Built target cs_demo1 -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -[ 91%] Built target cs_demo2 -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -[ 92%] Built target cs_demo3 -Consolidate compiler generated dependencies of target cs_dl_demo3 -Consolidate compiler generated dependencies of target cs_dl_demo2 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' +[ 90%] Built target cs_demo3 +[ 91%] Built target cs_di_demo2 +[ 91%] Built target cs_demo1 +[ 92%] Built target cs_dl_demo2 [ 93%] Built target cs_di_demo3 -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_ci_demo1 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_cl_demo1 -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_ci_demo2 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_ci_demo3 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_cl_demo3 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -[ 94%] Built target cs_dl_demo3 -[ 95%] Built target cs_ci_demo1 -[ 96%] Built target cs_dl_demo2 -[ 96%] Built target cs_ci_demo2 -Consolidate compiler generated dependencies of target cs_cl_demo2 -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/CXSparse/build' +[ 94%] Built target cs_demo2 +[ 94%] Built target cs_dl_demo1 +[ 95%] Built target cs_dl_demo3 [ 97%] Built target cs_cl_demo1 -[ 97%] Built target cs_ci_demo3 -[ 98%] Built target cs_cl_demo2 +[ 97%] Built target cs_ci_demo1 +[ 97%] Built target cs_ci_demo2 +[ 98%] Built target cs_ci_demo3 +[ 97%] Built target cs_idemo [ 99%] Built target cs_cl_demo3 -Consolidate compiler generated dependencies of target cs_idemo -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -Consolidate compiler generated dependencies of target cs_ldemo -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -[ 99%] Built target cs_idemo +[ 99%] Built target cs_cl_demo2 [100%] Built target cs_ldemo -make[2]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' -make[1]: Leaving directory '/home/davis/dev2/SuiteSparse/CXSparse/build' ./build/cs_idemo < Matrix/t2 --- cs_idemo, size of CS_INT: 4 T: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 triplet: 4-by-4, nzmax: 16 nnz: 10 2 2 : (3, 3.14159) 1 0 : (3.1, 42) @@ -767,7 +648,7 @@ triplet: 4-by-4, nzmax: 16 nnz: 10 2 1 : (1.7, 1) Treal: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 triplet: 4-by-4, nzmax: 16 nnz: 10 2 2 : 3 1 0 : 3.1 @@ -781,7 +662,7 @@ triplet: 4-by-4, nzmax: 16 nnz: 10 2 1 : 1.7 Timag: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 triplet: 4-by-4, nzmax: 16 nnz: 10 2 2 : 3.14159 1 0 : 42 @@ -795,7 +676,7 @@ triplet: 4-by-4, nzmax: 16 nnz: 10 2 1 : 1 A: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 106.075 col 0 : locations 0 to 2 1 : (3.1, 42) @@ -813,7 +694,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : (0.9, 99) C1 = real(A): -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 11.1 col 0 : locations 0 to 2 1 : 3.1 @@ -831,7 +712,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : 0.9 C2 = imag(A): -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 106 col 0 : locations 0 to 2 1 : 42 @@ -849,7 +730,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : 99 A1: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 11.1 col 0 : locations 0 to 2 1 : (3.1, 0) @@ -867,7 +748,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : (0.9, 0) A2: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 106 col 0 : locations 0 to 2 1 : (0, 42) @@ -885,7 +766,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : (0, 99) B = conj(A): -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 106.075 col 0 : locations 0 to 2 1 : (3.1, -42) @@ -906,7 +787,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 --- cs_ldemo, size of CS_INT: 8 T: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 triplet: 4-by-4, nzmax: 16 nnz: 10 2 2 : (3, 3.14159) 1 0 : (3.1, 42) @@ -920,7 +801,7 @@ triplet: 4-by-4, nzmax: 16 nnz: 10 2 1 : (1.7, 1) Treal: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 triplet: 4-by-4, nzmax: 16 nnz: 10 2 2 : 3 1 0 : 3.1 @@ -934,7 +815,7 @@ triplet: 4-by-4, nzmax: 16 nnz: 10 2 1 : 1.7 Timag: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 triplet: 4-by-4, nzmax: 16 nnz: 10 2 2 : 3.14159 1 0 : 42 @@ -948,7 +829,7 @@ triplet: 4-by-4, nzmax: 16 nnz: 10 2 1 : 1 A: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 106.075 col 0 : locations 0 to 2 1 : (3.1, 42) @@ -966,7 +847,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : (0.9, 99) C1 = real(A): -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 11.1 col 0 : locations 0 to 2 1 : 3.1 @@ -984,7 +865,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : 0.9 C2 = imag(A): -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 106 col 0 : locations 0 to 2 1 : 42 @@ -1002,7 +883,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : 99 A1: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 11.1 col 0 : locations 0 to 2 1 : (3.1, 0) @@ -1020,7 +901,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : (0.9, 0) A2: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 106 col 0 : locations 0 to 2 1 : (0, 42) @@ -1038,7 +919,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : (0, 99) B = conj(A): -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 106.075 col 0 : locations 0 to 2 1 : (3.1, -42) @@ -1055,8 +936,9 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 3 : (1, -7) 1 : (0.9, -99) ./build/cs_ci_demo1 < Matrix/t2 +CXSparse v4.3.0 T: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 triplet: 4-by-4, nzmax: 16 nnz: 10 2 2 : (3, 3.14159) 1 0 : (3.1, 42) @@ -1069,7 +951,7 @@ triplet: 4-by-4, nzmax: 16 nnz: 10 0 0 : (4.5, 6) 2 1 : (1.7, 1) A: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 106.075 col 0 : locations 0 to 2 1 : (3.1, 42) @@ -1086,7 +968,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 3 : (1, 7) 1 : (0.9, 99) AT: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 144.296 col 0 : locations 0 to 1 0 : (4.5, -6) @@ -1103,7 +985,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : (0.4, -2.71828) 3 : (1, -7) D: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 16 nnz: 16, 1-norm: 25308.3 col 0 : locations 0 to 3 1 : (265.95, 170.4) @@ -1129,24 +1011,24 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 --- Matrix: 4-by-4, nnz: 10 (sym: 0: nnz 0), norm: 1.06e+02 blocks: 1 singletons: 0 structural rank: 4 -QR natural time: 0.00 resid: 2.06e-17 -QR amd(A'*A) time: 0.00 resid: 6.36e-18 -LU natural time: 0.00 resid: 4.88e-18 -LU amd(A+A') time: 0.00 resid: 2.11e-18 -LU amd(S'*S) time: 0.00 resid: 6.36e-18 -LU amd(A'*A) time: 0.00 resid: 2.11e-18 +QR natural time: 0.00 resid: 2.02e-17 +QR amd(A'*A) time: 0.00 resid: 7.71e-18 +LU natural time: 0.00 resid: 4.43e-18 +LU amd(A+A') time: 0.00 resid: 6.17e-18 +LU amd(S'*S) time: 0.00 resid: 8.98e-18 +LU amd(A'*A) time: 0.00 resid: 6.17e-18 ./build/cs_ci_demo2 < Matrix/t3 --- Matrix: 3-by-4, nnz: 12 (sym: 0: nnz 0), norm: 3.06e+00 blocks: 1 singletons: 0 structural rank: 3 -QR natural time: 0.00 resid: 1.05e-16 -QR amd(A'*A) time: 0.00 resid: 1.05e-16 +QR natural time: 0.00 resid: 6.29e-17 +QR amd(A'*A) time: 0.00 resid: 6.29e-17 ./build/cs_ci_demo2 < Matrix/t4 --- Matrix: 2-by-2, nnz: 3 (sym: 1: nnz 4), norm: 2.83e+00 blocks: 1 singletons: 0 structural rank: 2 -QR natural time: 0.00 resid: 5.65e-17 -QR amd(A'*A) time: 0.00 resid: 5.65e-17 +QR natural time: 0.00 resid: 1.11e-16 +QR amd(A'*A) time: 0.00 resid: 1.11e-16 LU natural time: 0.00 resid: 0.00e+00 LU amd(A+A') time: 0.00 resid: 0.00e+00 LU amd(S'*S) time: 0.00 resid: 0.00e+00 @@ -1157,58 +1039,58 @@ Chol amd(A+A') time: 0.00 (failed) --- Matrix: 67-by-67, nnz: 294 (sym: 0: nnz 0), norm: 6.17e+00 blocks: 2 singletons: 1 structural rank: 67 -QR natural time: 0.00 resid: 8.16e-17 -QR amd(A'*A) time: 0.00 resid: 5.34e-17 -LU natural time: 0.00 resid: 4.54e-17 -LU amd(A+A') time: 0.00 resid: 5.90e-17 -LU amd(S'*S) time: 0.00 resid: 5.28e-17 -LU amd(A'*A) time: 0.00 resid: 4.76e-17 +QR natural time: 0.00 resid: 5.78e-17 +QR amd(A'*A) time: 0.00 resid: 4.76e-17 +LU natural time: 0.00 resid: 1.07e-16 +LU amd(A+A') time: 0.00 resid: 9.01e-17 +LU amd(S'*S) time: 0.00 resid: 4.37e-17 +LU amd(A'*A) time: 0.00 resid: 5.81e-17 ./build/cs_ci_demo2 < Matrix/c_mbeacxc --- Matrix: 492-by-490, nnz: 49920 (sym: 0: nnz 0), norm: 9.29e-01 blocks: 10 singletons: 8 structural rank: 448 -QR natural time: 0.43 resid: nan -QR amd(A'*A) time: 0.53 resid: nan +QR natural time: 0.04 resid: nan +QR amd(A'*A) time: 0.05 resid: nan ./build/cs_ci_demo2 < Matrix/young1c --- Matrix: 841-by-841, nnz: 4089 (sym: 0: nnz 0), norm: 7.30e+02 blocks: 1 singletons: 0 structural rank: 841 -QR natural time: 0.03 resid: 1.81e-16 -QR amd(A'*A) time: 0.02 resid: 1.57e-16 -LU natural time: 0.01 resid: 1.39e-16 -LU amd(A+A') time: 0.01 resid: 2.95e-16 -LU amd(S'*S) time: 0.01 resid: 3.37e-16 -LU amd(A'*A) time: 0.01 resid: 3.37e-16 +QR natural time: 0.00 resid: 1.53e-16 +QR amd(A'*A) time: 0.00 resid: 1.39e-16 +LU natural time: 0.00 resid: 1.16e-16 +LU amd(A+A') time: 0.00 resid: 3.20e-16 +LU amd(S'*S) time: 0.00 resid: 2.34e-16 +LU amd(A'*A) time: 0.00 resid: 2.34e-16 ./build/cs_ci_demo2 < Matrix/qc324 --- Matrix: 324-by-324, nnz: 26730 (sym: 0: nnz 0), norm: 1.71e+00 blocks: 1 singletons: 0 structural rank: 324 -QR natural time: 0.07 resid: 9.42e-17 -QR amd(A'*A) time: 0.09 resid: 8.94e-17 -LU natural time: 0.03 resid: 6.01e-17 -LU amd(A+A') time: 0.03 resid: 4.05e-17 -LU amd(S'*S) time: 0.04 resid: 4.71e-17 -LU amd(A'*A) time: 0.04 resid: 4.71e-17 +QR natural time: 0.01 resid: 8.03e-17 +QR amd(A'*A) time: 0.01 resid: 8.22e-17 +LU natural time: 0.00 resid: 4.86e-17 +LU amd(A+A') time: 0.00 resid: 3.83e-17 +LU amd(S'*S) time: 0.01 resid: 4.86e-17 +LU amd(A'*A) time: 0.01 resid: 4.86e-17 ./build/cs_ci_demo2 < Matrix/neumann --- Matrix: 1600-by-1600, nnz: 7840 (sym: 0: nnz 0), norm: 1.41e+01 blocks: 1 singletons: 0 structural rank: 1600 -QR amd(A'*A) time: 0.05 resid: 1.04e-15 -LU amd(A+A') time: 0.01 resid: 3.55e-16 -LU amd(S'*S) time: 0.02 resid: 4.03e-16 -LU amd(A'*A) time: 0.02 resid: 4.03e-16 +QR amd(A'*A) time: 0.01 resid: 1.07e-15 +LU amd(A+A') time: 0.00 resid: 4.59e-16 +LU amd(S'*S) time: 0.00 resid: 4.56e-16 +LU amd(A'*A) time: 0.00 resid: 4.56e-16 ./build/cs_ci_demo2 < Matrix/c4 --- Matrix: 4-by-4, nnz: 10 (sym: -1: nnz 16), norm: 7.37e+01 blocks: 1 singletons: 0 structural rank: 4 QR natural time: 0.00 resid: 5.85e-17 QR amd(A'*A) time: 0.00 resid: 5.85e-17 -LU natural time: 0.00 resid: 2.29e-17 -LU amd(A+A') time: 0.00 resid: 2.29e-17 -LU amd(S'*S) time: 0.00 resid: 2.29e-17 -LU amd(A'*A) time: 0.00 resid: 2.29e-17 -Chol natural time: 0.00 resid: 6.88e-17 -Chol amd(A+A') time: 0.00 resid: 6.88e-17 +LU natural time: 0.00 resid: 6.88e-17 +LU amd(A+A') time: 0.00 resid: 6.88e-17 +LU amd(S'*S) time: 0.00 resid: 6.88e-17 +LU amd(A'*A) time: 0.00 resid: 6.88e-17 +Chol natural time: 0.00 resid: 9.17e-17 +Chol amd(A+A') time: 0.00 resid: 9.17e-17 ./build/cs_ci_demo3 < Matrix/c4 --- Matrix: 4-by-4, nnz: 10 (sym: -1: nnz 16), norm: 7.37e+01 @@ -1217,21 +1099,21 @@ chol then update/downdate amd(A+A') symbolic chol time 0.00 numeric chol time 0.00 solve chol time 0.00 -original: resid: 6.88e-17 +original: resid: 9.17e-17 update: time: 0.00 -update: time: 0.00 (incl solve) resid: 6.49e-17 -rechol: time: 0.00 (incl solve) resid: 6.49e-17 +update: time: 0.00 (incl solve) resid: 7.03e-17 +rechol: time: 0.00 (incl solve) resid: 4.83e-17 downdate: time: 0.00 -downdate: time: 0.00 (incl solve) resid: 5.85e-17 +downdate: time: 0.00 (incl solve) resid: 9.17e-17 ./build/cs_ci_demo2 < Matrix/mhd1280b --- Matrix: 1280-by-1280, nnz: 11963 (sym: -1: nnz 22646), norm: 8.00e+01 tiny entries dropped: 66 blocks: 20 singletons: 14 structural rank: 1280 -QR amd(A'*A) time: 0.01 resid: 6.15e-25 -LU amd(A+A') time: 0.01 resid: 2.33e-25 -LU amd(S'*S) time: 0.01 resid: 3.96e-25 -LU amd(A'*A) time: 0.01 resid: 3.96e-25 +QR amd(A'*A) time: 0.00 resid: 5.96e-25 +LU amd(A+A') time: 0.00 resid: 2.33e-25 +LU amd(S'*S) time: 0.00 resid: 2.45e-25 +LU amd(A'*A) time: 0.00 resid: 2.45e-25 Chol amd(A+A') time: 0.00 resid: 1.58e-25 ./build/cs_ci_demo3 < Matrix/mhd1280b @@ -1241,15 +1123,16 @@ chol then update/downdate amd(A+A') symbolic chol time 0.00 numeric chol time 0.00 solve chol time 0.00 -original: resid: 1.51e-25 +original: resid: 2.14e-25 update: time: 0.00 -update: time: 0.00 (incl solve) resid: 1.75e-25 -rechol: time: 0.00 (incl solve) resid: 1.71e-25 +update: time: 0.00 (incl solve) resid: 2.14e-25 +rechol: time: 0.00 (incl solve) resid: 2.14e-25 downdate: time: 0.00 -downdate: time: 0.00 (incl solve) resid: 5.85e-25 +downdate: time: 0.00 (incl solve) resid: 6.66e-25 ./build/cs_cl_demo1 < Matrix/t2 +CXSparse v4.3.0 T: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 triplet: 4-by-4, nzmax: 16 nnz: 10 2 2 : (3, 3.14159) 1 0 : (3.1, 42) @@ -1262,7 +1145,7 @@ triplet: 4-by-4, nzmax: 16 nnz: 10 0 0 : (4.5, 6) 2 1 : (1.7, 1) A: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 106.075 col 0 : locations 0 to 2 1 : (3.1, 42) @@ -1279,7 +1162,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 3 : (1, 7) 1 : (0.9, 99) AT: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 10 nnz: 10, 1-norm: 144.296 col 0 : locations 0 to 1 0 : (4.5, -6) @@ -1296,7 +1179,7 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 1 : (0.4, -2.71828) 3 : (1, -7) D: -CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 +CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2023 4-by-4, nzmax: 16 nnz: 16, 1-norm: 25308.3 col 0 : locations 0 to 3 1 : (265.95, 170.4) @@ -1322,24 +1205,24 @@ CXSparse Version 4.3.0, Dec 30, 2023. Copyright (c) Timothy A. Davis, 2006-2022 --- Matrix: 4-by-4, nnz: 10 (sym: 0: nnz 0), norm: 1.06e+02 blocks: 1 singletons: 0 structural rank: 4 -QR natural time: 0.00 resid: 2.06e-17 -QR amd(A'*A) time: 0.00 resid: 6.36e-18 -LU natural time: 0.00 resid: 4.88e-18 -LU amd(A+A') time: 0.00 resid: 2.11e-18 -LU amd(S'*S) time: 0.00 resid: 6.36e-18 -LU amd(A'*A) time: 0.00 resid: 2.11e-18 +QR natural time: 0.00 resid: 2.02e-17 +QR amd(A'*A) time: 0.00 resid: 7.71e-18 +LU natural time: 0.00 resid: 4.43e-18 +LU amd(A+A') time: 0.00 resid: 6.17e-18 +LU amd(S'*S) time: 0.00 resid: 8.98e-18 +LU amd(A'*A) time: 0.00 resid: 6.17e-18 ./build/cs_cl_demo2 < Matrix/t3 --- Matrix: 3-by-4, nnz: 12 (sym: 0: nnz 0), norm: 3.06e+00 blocks: 1 singletons: 0 structural rank: 3 -QR natural time: 0.00 resid: 1.05e-16 -QR amd(A'*A) time: 0.00 resid: 1.05e-16 +QR natural time: 0.00 resid: 6.29e-17 +QR amd(A'*A) time: 0.00 resid: 6.29e-17 ./build/cs_cl_demo2 < Matrix/t4 --- Matrix: 2-by-2, nnz: 3 (sym: 1: nnz 4), norm: 2.83e+00 blocks: 1 singletons: 0 structural rank: 2 -QR natural time: 0.00 resid: 5.65e-17 -QR amd(A'*A) time: 0.00 resid: 5.65e-17 +QR natural time: 0.00 resid: 1.11e-16 +QR amd(A'*A) time: 0.00 resid: 1.11e-16 LU natural time: 0.00 resid: 0.00e+00 LU amd(A+A') time: 0.00 resid: 0.00e+00 LU amd(S'*S) time: 0.00 resid: 0.00e+00 @@ -1350,58 +1233,58 @@ Chol amd(A+A') time: 0.00 (failed) --- Matrix: 67-by-67, nnz: 294 (sym: 0: nnz 0), norm: 6.17e+00 blocks: 2 singletons: 1 structural rank: 67 -QR natural time: 0.00 resid: 8.16e-17 -QR amd(A'*A) time: 0.00 resid: 5.34e-17 -LU natural time: 0.00 resid: 4.54e-17 -LU amd(A+A') time: 0.00 resid: 5.90e-17 -LU amd(S'*S) time: 0.00 resid: 5.28e-17 -LU amd(A'*A) time: 0.00 resid: 4.76e-17 +QR natural time: 0.00 resid: 5.78e-17 +QR amd(A'*A) time: 0.00 resid: 4.76e-17 +LU natural time: 0.00 resid: 1.07e-16 +LU amd(A+A') time: 0.00 resid: 9.01e-17 +LU amd(S'*S) time: 0.00 resid: 4.37e-17 +LU amd(A'*A) time: 0.00 resid: 5.81e-17 ./build/cs_cl_demo2 < Matrix/c_mbeacxc --- Matrix: 492-by-490, nnz: 49920 (sym: 0: nnz 0), norm: 9.29e-01 blocks: 10 singletons: 8 structural rank: 448 -QR natural time: 0.42 resid: nan -QR amd(A'*A) time: 0.46 resid: nan +QR natural time: 0.04 resid: nan +QR amd(A'*A) time: 0.05 resid: nan ./build/cs_cl_demo2 < Matrix/young1c --- Matrix: 841-by-841, nnz: 4089 (sym: 0: nnz 0), norm: 7.30e+02 blocks: 1 singletons: 0 structural rank: 841 -QR natural time: 0.03 resid: 1.81e-16 -QR amd(A'*A) time: 0.02 resid: 1.57e-16 -LU natural time: 0.01 resid: 1.39e-16 -LU amd(A+A') time: 0.01 resid: 2.95e-16 -LU amd(S'*S) time: 0.01 resid: 3.37e-16 -LU amd(A'*A) time: 0.01 resid: 3.37e-16 +QR natural time: 0.00 resid: 1.53e-16 +QR amd(A'*A) time: 0.00 resid: 1.39e-16 +LU natural time: 0.00 resid: 1.16e-16 +LU amd(A+A') time: 0.00 resid: 3.20e-16 +LU amd(S'*S) time: 0.00 resid: 2.34e-16 +LU amd(A'*A) time: 0.00 resid: 2.34e-16 ./build/cs_cl_demo2 < Matrix/qc324 --- Matrix: 324-by-324, nnz: 26730 (sym: 0: nnz 0), norm: 1.71e+00 blocks: 1 singletons: 0 structural rank: 324 -QR natural time: 0.07 resid: 9.42e-17 -QR amd(A'*A) time: 0.08 resid: 8.94e-17 -LU natural time: 0.03 resid: 6.01e-17 -LU amd(A+A') time: 0.03 resid: 4.05e-17 -LU amd(S'*S) time: 0.03 resid: 4.71e-17 -LU amd(A'*A) time: 0.03 resid: 4.71e-17 +QR natural time: 0.01 resid: 8.03e-17 +QR amd(A'*A) time: 0.01 resid: 8.22e-17 +LU natural time: 0.00 resid: 4.86e-17 +LU amd(A+A') time: 0.00 resid: 3.83e-17 +LU amd(S'*S) time: 0.01 resid: 4.86e-17 +LU amd(A'*A) time: 0.01 resid: 4.86e-17 ./build/cs_cl_demo2 < Matrix/neumann --- Matrix: 1600-by-1600, nnz: 7840 (sym: 0: nnz 0), norm: 1.41e+01 blocks: 1 singletons: 0 structural rank: 1600 -QR amd(A'*A) time: 0.04 resid: 1.04e-15 -LU amd(A+A') time: 0.01 resid: 3.55e-16 -LU amd(S'*S) time: 0.02 resid: 4.03e-16 -LU amd(A'*A) time: 0.02 resid: 4.03e-16 +QR amd(A'*A) time: 0.01 resid: 1.07e-15 +LU amd(A+A') time: 0.00 resid: 4.59e-16 +LU amd(S'*S) time: 0.00 resid: 4.56e-16 +LU amd(A'*A) time: 0.00 resid: 4.56e-16 ./build/cs_cl_demo2 < Matrix/c4 --- Matrix: 4-by-4, nnz: 10 (sym: -1: nnz 16), norm: 7.37e+01 blocks: 1 singletons: 0 structural rank: 4 QR natural time: 0.00 resid: 5.85e-17 QR amd(A'*A) time: 0.00 resid: 5.85e-17 -LU natural time: 0.00 resid: 2.29e-17 -LU amd(A+A') time: 0.00 resid: 2.29e-17 -LU amd(S'*S) time: 0.00 resid: 2.29e-17 -LU amd(A'*A) time: 0.00 resid: 2.29e-17 -Chol natural time: 0.00 resid: 6.88e-17 -Chol amd(A+A') time: 0.00 resid: 6.88e-17 +LU natural time: 0.00 resid: 6.88e-17 +LU amd(A+A') time: 0.00 resid: 6.88e-17 +LU amd(S'*S) time: 0.00 resid: 6.88e-17 +LU amd(A'*A) time: 0.00 resid: 6.88e-17 +Chol natural time: 0.00 resid: 9.17e-17 +Chol amd(A+A') time: 0.00 resid: 9.17e-17 ./build/cs_cl_demo3 < Matrix/c4 --- Matrix: 4-by-4, nnz: 10 (sym: -1: nnz 16), norm: 7.37e+01 @@ -1410,21 +1293,21 @@ chol then update/downdate amd(A+A') symbolic chol time 0.00 numeric chol time 0.00 solve chol time 0.00 -original: resid: 6.88e-17 +original: resid: 9.17e-17 update: time: 0.00 -update: time: 0.00 (incl solve) resid: 6.49e-17 -rechol: time: 0.00 (incl solve) resid: 6.49e-17 +update: time: 0.00 (incl solve) resid: 7.03e-17 +rechol: time: 0.00 (incl solve) resid: 4.83e-17 downdate: time: 0.00 -downdate: time: 0.00 (incl solve) resid: 5.85e-17 +downdate: time: 0.00 (incl solve) resid: 9.17e-17 ./build/cs_cl_demo2 < Matrix/mhd1280b --- Matrix: 1280-by-1280, nnz: 11963 (sym: -1: nnz 22646), norm: 8.00e+01 tiny entries dropped: 66 blocks: 20 singletons: 14 structural rank: 1280 -QR amd(A'*A) time: 0.01 resid: 6.15e-25 -LU amd(A+A') time: 0.01 resid: 2.33e-25 -LU amd(S'*S) time: 0.01 resid: 3.96e-25 -LU amd(A'*A) time: 0.01 resid: 3.96e-25 +QR amd(A'*A) time: 0.00 resid: 5.96e-25 +LU amd(A+A') time: 0.00 resid: 2.33e-25 +LU amd(S'*S) time: 0.00 resid: 2.45e-25 +LU amd(A'*A) time: 0.00 resid: 2.45e-25 Chol amd(A+A') time: 0.00 resid: 1.58e-25 ./build/cs_cl_demo3 < Matrix/mhd1280b @@ -1434,9 +1317,9 @@ chol then update/downdate amd(A+A') symbolic chol time 0.00 numeric chol time 0.00 solve chol time 0.00 -original: resid: 1.51e-25 +original: resid: 2.14e-25 update: time: 0.00 -update: time: 0.00 (incl solve) resid: 1.75e-25 -rechol: time: 0.00 (incl solve) resid: 1.71e-25 +update: time: 0.00 (incl solve) resid: 2.14e-25 +rechol: time: 0.00 (incl solve) resid: 2.14e-25 downdate: time: 0.00 -downdate: time: 0.00 (incl solve) resid: 5.85e-25 +downdate: time: 0.00 (incl solve) resid: 6.66e-25 diff --git a/CXSparse/Demo/cs_demo1.c b/CXSparse/Demo/cs_demo1.c index 2e7a7754b..9f7754a11 100644 --- a/CXSparse/Demo/cs_demo1.c +++ b/CXSparse/Demo/cs_demo1.c @@ -1,4 +1,4 @@ -// CSparse/Demo/cs_demo1: demo program for CXSparse (complex int32_t) +// CXSparse/Demo/cs_demo1: demo program for CXSparse (double int32_t) // CXSparse, Copyright (c) 2006-2022, Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: LGPL-2.1+ #include "cs.h" @@ -6,6 +6,16 @@ int main (void) { cs *T, *A, *Eye, *AT, *C, *D ; int i, m ; + int version [3] ; + cxsparse_version (version) ; + printf ("CXSparse v%d.%d.%d\n", version [0], version [1], version [2]) ; + if ((version [0] != CS_VER) || (version [1] != CS_SUBVER) || + (version [2] != CS_SUBSUB)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } + T = cs_load (stdin) ; /* load triplet matrix T from stdin */ printf ("T:\n") ; cs_print (T, 0) ; /* print T */ A = cs_compress (T) ; /* A = compressed-column form of T */ diff --git a/CXSparse/Demo/cs_demo2.c b/CXSparse/Demo/cs_demo2.c index 4c3f24bd5..4c0aac7b4 100644 --- a/CXSparse/Demo/cs_demo2.c +++ b/CXSparse/Demo/cs_demo2.c @@ -1,4 +1,4 @@ -// CSparse/Demo/cs_demo2: demo program for CXSparse (complex int32_t) +// CSparse/Demo/cs_demo2: demo program for CXSparse (double int32_t) // CXSparse, Copyright (c) 2006-2022, Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: LGPL-2.1+ #include "cs_demo.h" diff --git a/CXSparse/Demo/cs_demo3.c b/CXSparse/Demo/cs_demo3.c index 73b287047..2908e46bb 100644 --- a/CXSparse/Demo/cs_demo3.c +++ b/CXSparse/Demo/cs_demo3.c @@ -1,4 +1,4 @@ -// CSparse/Demo/cs_demo3: demo program for CXSparse (complex int32_t) +// CSparse/Demo/cs_demo3: demo program for CXSparse (double int32_t) // CXSparse, Copyright (c) 2006-2022, Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: LGPL-2.1+ #include "cs_demo.h" diff --git a/CXSparse/Demo/cs_di_demo1.c b/CXSparse/Demo/cs_di_demo1.c index 36545be48..111bce157 100644 --- a/CXSparse/Demo/cs_di_demo1.c +++ b/CXSparse/Demo/cs_di_demo1.c @@ -1,4 +1,4 @@ -// CSparse/Demo/cs_di_demo1: demo program for CXSparse (double int32_t) +// CXSparse/Demo/cs_di_demo1: demo program for CXSparse (double int32_t) // CXSparse, Copyright (c) 2006-2022, Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: LGPL-2.1+ #include "cs.h" @@ -6,6 +6,16 @@ int main (void) { cs_di *T, *A, *Eye, *AT, *C, *D ; int i, m ; + int version [3] ; + cxsparse_version (version) ; + printf ("CXSparse v%d.%d.%d\n", version [0], version [1], version [2]) ; + if ((version [0] != CS_VER) || (version [1] != CS_SUBVER) || + (version [2] != CS_SUBSUB)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } + T = cs_di_load (stdin) ; /* load triplet matrix T from stdin */ printf ("T:\n") ; cs_di_print (T, 0) ; /* print T */ A = cs_di_compress (T) ; /* A = compressed-column form of T */ diff --git a/CXSparse/Demo/cs_dl_demo1.c b/CXSparse/Demo/cs_dl_demo1.c index 6bba4c5e0..15ce85fed 100644 --- a/CXSparse/Demo/cs_dl_demo1.c +++ b/CXSparse/Demo/cs_dl_demo1.c @@ -1,4 +1,4 @@ -// CSparse/Demo/cs_dl_demo1: demo program for CXSparse (double int64_t) +// CXSparse/Demo/cs_dl_demo1: demo program for CXSparse (double int64_t) // CXSparse, Copyright (c) 2006-2022, Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: LGPL-2.1+ #include "cs.h" @@ -6,6 +6,16 @@ int main (void) { cs_dl *T, *A, *Eye, *AT, *C, *D ; int64_t i, m ; + int version [3] ; + cxsparse_version (version) ; + printf ("CXSparse v%d.%d.%d\n", version [0], version [1], version [2]) ; + if ((version [0] != CS_VER) || (version [1] != CS_SUBVER) || + (version [2] != CS_SUBSUB)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } + T = cs_dl_load (stdin) ; /* load triplet matrix T from stdin */ printf ("T:\n") ; cs_dl_print (T, 0) ; /* print T */ A = cs_dl_compress (T) ; /* A = compressed-column form of T */ diff --git a/CXSparse/Doc/ChangeLog b/CXSparse/Doc/ChangeLog index c3071038a..66cca6534 100644 --- a/CXSparse/Doc/ChangeLog +++ b/CXSparse/Doc/ChangeLog @@ -1,6 +1,7 @@ Dec 30, 2023: version 4.3.0 * major change to build system: by Markus Mützel + * cxsparse_version: added to return CXSparse version Sept 18, 2023: version 4.2.1 diff --git a/CXSparse/Include/cs.h b/CXSparse/Include/cs.h index e9ec43c04..b27b34aaf 100644 --- a/CXSparse/Include/cs.h +++ b/CXSparse/Include/cs.h @@ -57,6 +57,8 @@ extern "C" { #endif +void cxsparse_version (int version [3]) ; // return version + /* -------------------------------------------------------------------------- */ /* double/int32_t version of CXSparse */ /* -------------------------------------------------------------------------- */ diff --git a/CXSparse/Source/cs_version.c b/CXSparse/Source/cs_version.c new file mode 100644 index 000000000..7919ac9c3 --- /dev/null +++ b/CXSparse/Source/cs_version.c @@ -0,0 +1,10 @@ +// CXSparse/Source/cxsparse_version: return CXSparse version +// CXSparse, Copyright (c) 2006-2023, Timothy A. Davis. All Rights Reserved. +// SPDX-License-Identifier: LGPL-2.1+ +#include "cs.h" +void cxsparse_version (int version [3]) +{ + version [0] = CS_VER ; + version [1] = CS_SUBVER ; + version [2] = CS_SUBSUB ; +} diff --git a/ChangeLog b/ChangeLog index b9b2561ea..c3a9d88df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,9 @@ Dec 30, 2023: version 7.4.0 * AMD 3.3.0: minor change for CHOLMOD 5.1.0 tests * CAMD 3.3.0: minor change for CHOLMOD 5.1.0 tests * SuiteSparse_config 7.4.0: added wrappers for single-precision BLAS/LAPACK + * *_version: added methods to all package that didn't have them: + AMD, CAMD, COLAMD, CCOLAMD, BTF, CSparse, CXSparse, KLU, BTF, RBio, + SPEX, SPQR, and UMFPACK. Oct 31, 2023: version 7.3.1 diff --git a/Example/Config/my.h.in b/Example/Config/my.h.in index 2aa853943..5e43c5dfc 100644 --- a/Example/Config/my.h.in +++ b/Example/Config/my.h.in @@ -20,9 +20,12 @@ extern "C" { #endif -void my_library (int version [3], char date [128]) ; -void my_function (void) ; +void my_version (int version [3], char date [128]) ; +int my_function (void) ; +int my_check_version (const char *package, int major, int minor, int patch, + const char *date, int version [3]) ; #ifdef __cplusplus } #endif + diff --git a/Example/Demo/my_demo.c b/Example/Demo/my_demo.c index 018ec6db2..90b433ec0 100644 --- a/Example/Demo/my_demo.c +++ b/Example/Demo/my_demo.c @@ -1,3 +1,12 @@ +//------------------------------------------------------------------------------ +// SuiteSparse/Example/Demo/my_demo.c +//------------------------------------------------------------------------------ + +// Copyright (c) 2022-2023, Timothy A. Davis, All Rights Reserved. +// SPDX-License-Identifier: BSD-3-clause + +//------------------------------------------------------------------------------ + // Example user program #include @@ -10,7 +19,7 @@ int main (void) printf ("My demo\n") ; int version [3] ; char date [128] ; - my_library (version, date) ; + my_version (version, date) ; printf ("Date from #include 'my.h': %s\n", MY_DATE) ; printf ("Date from compiled library: %s\n", date) ; printf ("version from #include 'my.h.': %d.%d.%d\n", @@ -18,7 +27,7 @@ int main (void) printf ("version from compiled library: %d.%d.%d\n", version [0], version [1], version [2]) ; - my_function ( ) ; - return (0) ; + int result = my_function ( ) ; + return (result) ; } diff --git a/Example/Include/my.h b/Example/Include/my.h index 3366eb880..393e2b0b5 100644 --- a/Example/Include/my.h +++ b/Example/Include/my.h @@ -20,9 +20,12 @@ extern "C" { #endif -void my_library (int version [3], char date [128]) ; -void my_function (void) ; +void my_version (int version [3], char date [128]) ; +int my_function (void) ; +int my_check_version (const char *package, int major, int minor, int patch, + const char *date, int version [3]) ; #ifdef __cplusplus } #endif + diff --git a/Example/Include/my_internal.h b/Example/Include/my_internal.h index 54acc778b..46af56c36 100644 --- a/Example/Include/my_internal.h +++ b/Example/Include/my_internal.h @@ -10,34 +10,108 @@ // Example include file for a user library. // SuiteSparse include files for C/C++: +#include "SuiteSparse_config.h" +#if !defined (SUITESPARSE_VERSION) || \ + (SUITESPARSE_VERSION < SUITESPARSE_VER_CODE(7,4)) +#error "This library requires SuiteSparse_config 7.4.0 or later" +#endif + #include "amd.h" +#if AMD_VERSION < SUITESPARSE_VER_CODE(3,3) +#error "This library requires AMD 3.3.0 or later" +#endif + #include "btf.h" +#if AMD_VERSION < SUITESPARSE_VER_CODE(3,3) +#error "This library requires BTF 3.3.0 or later" +#endif + #include "camd.h" +#if CAMD_VERSION < SUITESPARSE_VER_CODE(3,3) +#error "This library requires CAMD 3.3.0 or later" +#endif + #include "ccolamd.h" +#if CCOLAMD_VERSION < SUITESPARSE_VER_CODE(3,3) +#error "This library requires CCOLAMD 3.3.0 or later" +#endif + #include "cholmod.h" +#if CHOLMOD_VERSION < SUITESPARSE_VER_CODE(3,3) +#error "This library requires CHOLMOD 5.1.0 or later" +#endif + #include "colamd.h" +#if COLAMD_VERSION < SUITESPARSE_VER_CODE(3,3) +#error "This library requires COLAMD 3.3.0 or later" +#endif + #include "cs.h" +// #if ! defined (CXSPARSE) || (CS_VERSION < SUITESPARSE_VER_CODE(3,3)) +// #error "This library requires CXSparse 3.3.0 or later" +// #endif + #if ! defined (NO_GRAPHBLAS) -# include "GraphBLAS.h" + #include "GraphBLAS.h" + #if !defined ( GxB_SUITESPARSE_GRAPHBLAS ) || \ + GxB_IMPLEMENTATION < GxB_VERSION(8,3,0) + #error "This library requires SuiteSparse:GraphBLAS 8.3.0 or later" + #endif #endif + #if ! defined (NO_LAGRAPH) -# include "LAGraph.h" + #include "LAGraph.h" + #if GxB_VERSION (LAGRAPH_VERSION_MAJOR,LAGRAPH_VERSION_MINOR, \ + LAGRAPH_VERSION_UPDATE) < GxB_VERSION(1,1,0) + #error "This library requires LAGraph 1.1.0 or later" + #endif #endif + #include "klu.h" -#include "klu.h" +#if KLU_VERSION < SUITESPARSE_VER_CODE(2,3) +#error "This library requires KLU 2.3.0 or later" +#endif + #include "ldl.h" +#if LDL_VERSION < SUITESPARSE_VER_CODE(3,3) +#error "This library requires LDL 3.3.0 or later" +#endif + #include "RBio.h" +#if RBIO_VERSION < SUITESPARSE_VER_CODE(4,3) +#error "This library requires RBio 4.3.0 or later" +#endif + #include "SPEX.h" +#if GxB_VERSION (SPEX_VERSION_MAJOR,SPEX_VERSION_MINOR, \ + SPEX_VERSION_SUB) < GxB_VERSION(2,3,0) +#error "This library requires SPEX 2.3.0 or later" +#endif + #include "SuiteSparseQR_C.h" +#if SPQR_VERSION < SUITESPARSE_VER_CODE(4,3) +#error "This library requires SPQR 4.3.0 or later" +#endif + #include "umfpack.h" +#if UMFPACK_VER < SUITESPARSE_VER_CODE(4,3) +#error "This library requires UMFPACK 6.3.0 or later" +#endif -#ifdef __cplusplus // SuiteSparse include files for C++: -# include "SuiteSparseQR.hpp" -# include "Mongoose.hpp" +#ifdef __cplusplus + #include "SuiteSparseQR.hpp" + + #include "Mongoose.hpp" + #if GxB_VERSION (Mongoose_VERSION_MAJOR,Mongoose_VERSION_MINOR, \ + Mongoose_VERSION_PATCH) < GxB_VERSION(3,3,0) + #error "This library requires Mongoose 3.3.0 or later" + #endif + #endif // OpenMP include file: #include #include "my.h" + diff --git a/Example/Source/my.c b/Example/Source/my.c index 73a9a9595..6da684e0e 100644 --- a/Example/Source/my.c +++ b/Example/Source/my.c @@ -1,3 +1,12 @@ +//------------------------------------------------------------------------------ +// SuiteSparse/Example/Source/my.c +//------------------------------------------------------------------------------ + +// Copyright (c) 2022-2023, Timothy A. Davis, All Rights Reserved. +// SPDX-License-Identifier: BSD-3-clause + +//------------------------------------------------------------------------------ + // Example library that relies on SuiteSparse packages // ANSI C include files: @@ -7,14 +16,23 @@ #include "my_internal.h" -#define OK(result) \ - if (!(result)) \ - { \ - printf ("abort line %d\n", __LINE__) ; \ - abort ( ) ; \ +//------------------------------------------------------------------------------ +// OK: check a result and return an error if it fails +//------------------------------------------------------------------------------ + +#define OK(result) \ + if (!(result)) \ + { \ + printf ("FAILURE file: %s line %d\n", \ + __FILE__, __LINE__) ; \ + return (-1) ; \ } -void my_library (int version [3], char date [128]) +//------------------------------------------------------------------------------ +// my_version: version of MY library +//------------------------------------------------------------------------------ + +void my_version (int version [3], char date [128]) { // get the version of this library strncpy (date, MY_DATE, 127) ; @@ -23,27 +41,68 @@ void my_library (int version [3], char date [128]) version [2] = MY_PATCH_VERSION ; } -void my_function (void) +//------------------------------------------------------------------------------ +// my_check_version: check library version +//------------------------------------------------------------------------------ + +int my_check_version (const char *package, int major, int minor, int patch, + const char *date, int version [3]) { + // version and date in package header file: + printf ("\n------------------------------------------------------------" + "\n%s: v%d.%d.%d (%s)\n", package, major, minor, patch, date) ; + + // version in library itself: + printf ("%s: v%d.%d.%d (in library)\n", package, + version [0], version [1], version [2]) ; + + // make sure the versions match + int ok = (major == version [0]) && + (minor == version [1]) && + (patch == version [2]) ; + if (!ok) printf ("%s: version in header (%d.%d.%d) " + "does not match library (%d.%d.%d)\n", package, + major, minor, patch, version [0], version [1], version [2]) ; + return (ok) ; +} + +//------------------------------------------------------------------------------ +// my_function: try each library in SuiteSparse +//------------------------------------------------------------------------------ + +int my_function (void) // returns 0 on success, -1 on failure +{ + + int version [3] ; + + //-------------------------------------------------------------------------- + // My package + //-------------------------------------------------------------------------- + + char my_date [128] ; + my_version (version, my_date) ; + OK (my_check_version ("MY", MY_MAJOR_VERSION, MY_MINOR_VERSION, + MY_PATCH_VERSION, MY_DATE, version)) ; + printf ("MY date: %s\n", my_date) ; + OK (strcmp (my_date, MY_DATE) == 0) ; //-------------------------------------------------------------------------- // SuiteSparse_config //-------------------------------------------------------------------------- - printf ("SuiteSparse: v%d.%d.%d (%s)\n", - SUITESPARSE_MAIN_VERSION, SUITESPARSE_SUB_VERSION, - SUITESPARSE_SUBSUB_VERSION, SUITESPARSE_DATE) ; - int version [3] ; int v = SuiteSparse_version (version) ; - printf ("SuiteSparse: v%d.%d.%d (in library)\n", - version [0], version [1], version [2]) ; + OK (my_check_version ("SuiteSparse_config", + SUITESPARSE_MAIN_VERSION, SUITESPARSE_SUB_VERSION, + SUITESPARSE_SUBSUB_VERSION, SUITESPARSE_DATE, version)) ; //-------------------------------------------------------------------------- // CXSparse //-------------------------------------------------------------------------- - printf ("CXSparse: v%d.%d.%d (%s)\n", - CS_VER, CS_SUBVER, CS_SUBSUB, CS_DATE) ; + cxsparse_version (version) ; + OK (my_check_version ("CXSparse", CS_VER, CS_SUBVER, CS_SUBSUB, CS_DATE, + version)) ; + cs_dl *A = NULL ; // create a dense 2-by-2 matrix @@ -68,8 +127,11 @@ void my_function (void) // AMD //-------------------------------------------------------------------------- - printf ("AMD: v%d.%d.%d (%s)\n", - AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION, AMD_DATE) ; + amd_version (version) ; + OK (my_check_version ("AMD", + AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION, AMD_DATE, + version)) ; + int64_t P [N] ; OK (amd_l_order (n, Ap, Ai, P, NULL, NULL) == AMD_OK) ; for (int k = 0 ; k < n ; k++) printf ("P [%d] = %d\n", k, (int) P [k]) ; @@ -78,8 +140,11 @@ void my_function (void) // BTF //-------------------------------------------------------------------------- - printf ("BTF: v%d.%d.%d (%s)\n", - BTF_MAIN_VERSION, BTF_SUB_VERSION, BTF_SUBSUB_VERSION, BTF_DATE) ; + btf_version (version) ; + OK (my_check_version ("BTF", + BTF_MAIN_VERSION, BTF_SUB_VERSION, BTF_SUBSUB_VERSION, BTF_DATE, + version)) ; + double work ; int64_t nmatch ; int64_t Q [N], R [N+1], Work [5*N] ; @@ -94,8 +159,11 @@ void my_function (void) // CAMD //-------------------------------------------------------------------------- - printf ("CAMD: v%d.%d.%d (%s)\n", - CAMD_MAIN_VERSION, CAMD_SUB_VERSION, CAMD_SUBSUB_VERSION, CAMD_DATE) ; + camd_version (version) ; + OK (my_check_version ("CAMD", + CAMD_MAIN_VERSION, CAMD_SUB_VERSION, CAMD_SUBSUB_VERSION, CAMD_DATE, + version)) ; + int64_t Cmem [N] ; for (int k = 0 ; k < n ; k++) Cmem [k] = 0 ; OK (camd_l_order (n, Ap, Ai, P, NULL, NULL, Cmem) == CAMD_OK) ; @@ -105,9 +173,11 @@ void my_function (void) // CCOLAMD //-------------------------------------------------------------------------- - printf ("CCOLAMD: v%d.%d.%d (%s)\n", + ccolamd_version (version) ; + OK (my_check_version ("CCOLAMD", CCOLAMD_MAIN_VERSION, CCOLAMD_SUB_VERSION, CCOLAMD_SUBSUB_VERSION, - CCOLAMD_DATE) ; + CCOLAMD_DATE, version)) ; + int64_t Alen = ccolamd_l_recommended (NNZ, n, n) ; int64_t *Awork = malloc (Alen * sizeof (int64_t)) ; OK (Awork != NULL) ; @@ -120,9 +190,11 @@ void my_function (void) // COLAMD //-------------------------------------------------------------------------- - printf ("COLAMD: v%d.%d.%d (%s)\n", + colamd_version (version) ; + OK (my_check_version ("COLAMD", COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_SUBSUB_VERSION, - COLAMD_DATE) ; + COLAMD_DATE, version)) ; + Alen = ccolamd_l_recommended (NNZ, n, n) ; Awork = malloc (Alen * sizeof (int64_t)) ; OK (Awork != NULL) ; @@ -135,12 +207,11 @@ void my_function (void) // CHOLMOD //-------------------------------------------------------------------------- - printf ("CHOLMOD: v%d.%d.%d (%s)\n", - CHOLMOD_MAIN_VERSION, CHOLMOD_SUB_VERSION, CHOLMOD_SUBSUB_VERSION, - CHOLMOD_DATE) ; v = cholmod_l_version (version) ; - printf ("CHOLMOD: v%d.%d.%d (in library)\n", - version [0], version [1], version [2]) ; + OK (my_check_version ("CHOLMOD", + CHOLMOD_MAIN_VERSION, CHOLMOD_SUB_VERSION, CHOLMOD_SUBSUB_VERSION, + CHOLMOD_DATE, version)) ; + cholmod_common cc ; OK (cholmod_l_start (&cc)) ; @@ -150,12 +221,10 @@ void my_function (void) #if ! defined (NO_GRAPHBLAS) OK (GrB_init (GrB_NONBLOCKING) == GrB_SUCCESS) ; - printf ("GraphBLAS: v%d.%d.%d (%s)\n", - GxB_IMPLEMENTATION_MAJOR, GxB_IMPLEMENTATION_MINOR, - GxB_IMPLEMENTATION_SUB, GxB_IMPLEMENTATION_DATE) ; OK (GxB_Global_Option_get (GxB_LIBRARY_VERSION, version) == GrB_SUCCESS) ; - printf ("GraphBLAS: v%d.%d.%d (in library)\n", - version [0], version [1], version [2]) ; + OK (my_check_version ("GraphBLAS", + GxB_IMPLEMENTATION_MAJOR, GxB_IMPLEMENTATION_MINOR, + GxB_IMPLEMENTATION_SUB, GxB_IMPLEMENTATION_DATE, version)) ; OK (GrB_finalize ( ) == GrB_SUCCESS) ; #endif @@ -165,13 +234,11 @@ void my_function (void) #if ! defined (NO_LAGRAPH) char msg [LAGRAPH_MSG_LEN], verstring [LAGRAPH_MSG_LEN] ; - printf ("LAGraph: v%d.%d.%d (%s)\n", - LAGRAPH_VERSION_MAJOR, LAGRAPH_VERSION_MINOR, LAGRAPH_VERSION_UPDATE, - LAGRAPH_DATE) ; OK (LAGraph_Init (msg) == GrB_SUCCESS) ; OK (LAGraph_Version (version, verstring, msg) == GrB_SUCCESS) ; - printf ("LAGraph: v%d.%d.%d (%s) (in library)\n", - version [0], version [1], version [2], verstring) ; + OK (my_check_version ("LAGraph", + LAGRAPH_VERSION_MAJOR, LAGRAPH_VERSION_MINOR, LAGRAPH_VERSION_UPDATE, + LAGRAPH_DATE, version)) ; OK (LAGraph_Finalize (msg) == GrB_SUCCESS) ; #endif @@ -179,8 +246,11 @@ void my_function (void) // KLU //-------------------------------------------------------------------------- - printf ("KLU: v%d.%d.%d (%s)\n", - KLU_MAIN_VERSION, KLU_SUB_VERSION, KLU_SUBSUB_VERSION, KLU_DATE) ; + klu_version (version) ; + OK (my_check_version ("KLU", + KLU_MAIN_VERSION, KLU_SUB_VERSION, KLU_SUBSUB_VERSION, + KLU_DATE, version)) ; + double b [N] = {8., 45.} ; double xgood [N] = {36.4, -32.7} ; double x [N] ; @@ -210,8 +280,11 @@ void my_function (void) // LDL //-------------------------------------------------------------------------- - printf ("LDL: v%d.%d.%d (%s)\n", - LDL_MAIN_VERSION, LDL_SUB_VERSION, LDL_SUBSUB_VERSION, LDL_DATE) ; + ldl_version (version) ; + OK (my_check_version ("LDL", + LDL_MAIN_VERSION, LDL_SUB_VERSION, LDL_SUBSUB_VERSION, + LDL_DATE, version)) ; + double x2 [N] ; P [0] = 0 ; P [1] = 1 ; @@ -229,8 +302,11 @@ void my_function (void) // RBio //-------------------------------------------------------------------------- - printf ("RBio: v%d.%d.%d (%s)\n", - RBIO_MAIN_VERSION, RBIO_SUB_VERSION, RBIO_SUBSUB_VERSION, RBIO_DATE) ; + RBio_version (version) ; + OK (my_check_version ("RBio", + RBIO_MAIN_VERSION, RBIO_SUB_VERSION, RBIO_SUBSUB_VERSION, + RBIO_DATE, version)) ; + char mtype [4], key [8], title [80] ; strncpy (key, "simple", 8) ; strncpy (title, "2-by-2 matrix", 80) ; @@ -261,17 +337,22 @@ void my_function (void) // SPEX //-------------------------------------------------------------------------- - printf ("SPEX: v%d.%d.%d (%s)\n", - SPEX_VERSION_MAJOR, SPEX_VERSION_MINOR, SPEX_VERSION_SUB, SPEX_DATE) ; OK (SPEX_initialize ( ) == SPEX_OK) ; + SPEX_version (version) ; + OK (my_check_version ("SPEX", + SPEX_VERSION_MAJOR, SPEX_VERSION_MINOR, SPEX_VERSION_SUB, SPEX_DATE, + version)) ; OK (SPEX_finalize ( ) == SPEX_OK) ; //-------------------------------------------------------------------------- // SPQR //-------------------------------------------------------------------------- - printf ("SPQR: v%d.%d.%d (%s)\n", - SPQR_MAIN_VERSION, SPQR_SUB_VERSION, SPQR_SUBSUB_VERSION, SPQR_DATE) ; + SuiteSparseQR_C_version (version) ; + OK (my_check_version ("SuiteSparseQR", + SPQR_MAIN_VERSION, SPQR_SUB_VERSION, SPQR_SUBSUB_VERSION, SPQR_DATE, + version)) ; + cholmod_sparse *A2, A2_struct ; cholmod_dense *B2, B2_struct ; cholmod_dense *X2 ; @@ -314,9 +395,10 @@ void my_function (void) // UMFPACK //-------------------------------------------------------------------------- - printf ("UMFPACK: v%d.%d.%d (%s)\n", + umfpack_version (version) ; + OK (my_check_version ("UMFPACK", UMFPACK_MAIN_VERSION, UMFPACK_SUB_VERSION, UMFPACK_SUBSUB_VERSION, - UMFPACK_DATE) ; + UMFPACK_DATE, version)) ; printf ("%s\n", UMFPACK_VERSION) ; printf ("%s", UMFPACK_COPYRIGHT) ; @@ -334,7 +416,7 @@ void my_function (void) (void) umfpack_dl_symbolic (n, n, Ap, Ai, Ax, &Sym, Control, Info) ; (void) umfpack_dl_numeric (Ap, Ai, Ax, Sym, &Num, Control, Info) ; umfpack_dl_free_symbolic (&Sym) ; - result = umfpack_dl_solve (UMFPACK_A, Ap, Ai, Ax, x, b, Num, Control, Info) ; + result = umfpack_dl_solve (UMFPACK_A, Ap, Ai, Ax, x, b, Num, Control, Info); umfpack_dl_free_numeric (&Num) ; for (int i = 0 ; i < n ; i++) printf ("x [%d] = %g\n", i, x [i]) ; err = 0 ; @@ -348,11 +430,12 @@ void my_function (void) umfpack_dl_report_info (Control, Info) ; //-------------------------------------------------------------------------- - // free workspace + // free workspace and return result //-------------------------------------------------------------------------- cs_dl_spfree (A) ; A = NULL ; OK (cholmod_l_finish (&cc)) ; + return (0) ; } diff --git a/Example/Source/my_cxx.cc b/Example/Source/my_cxx.cc index f2935b6ec..9e9840599 100644 --- a/Example/Source/my_cxx.cc +++ b/Example/Source/my_cxx.cc @@ -1,11 +1,22 @@ -// Example library that relies on SuiteSparse packages +//------------------------------------------------------------------------------ +// SuiteSparse/Example/Source/my_cxx.cc +//------------------------------------------------------------------------------ + +// Copyright (c) 2022-2023, Timothy A. Davis, All Rights Reserved. +// SPDX-License-Identifier: BSD-3-clause + +//------------------------------------------------------------------------------ + +// Example C++ library that relies on SuiteSparse packages #include #include #include +// FIXME: use another filename #include "my_internal.h" +// FIXME: return -1 #define OK(result) \ if (!(result)) \ { \ @@ -13,7 +24,8 @@ abort ( ) ; \ } -void my_library (int version [3], char date [128]) +// FIXME: use the C code? or rename? +void my_version (int version [3], char date [128]) { // get the version of this library strncpy (date, MY_DATE, 127) ; @@ -22,7 +34,8 @@ void my_library (int version [3], char date [128]) version [2] = MY_PATCH_VERSION ; } -void my_function (void) +// FIXME: rename? +int my_function (void) { //-------------------------------------------------------------------------- @@ -135,7 +148,7 @@ void my_function (void) int64_t *Awork = (int64_t *) malloc (Alen * sizeof (int64_t)) ; OK (Awork != nullptr) ; memcpy (Awork, Ai, NNZ * sizeof (int64_t)) ; - OK (ccolamd_l (n, n, Alen, Awork, P, nullptr, nullptr, Cmem) == CCOLAMD_OK) ; + OK (ccolamd_l (n, n, Alen, Awork, P, nullptr, nullptr, Cmem) == CCOLAMD_OK); for (int k = 0 ; k < n ; k++) std::cout << "P [" << k << "] = " << P [k] << std::endl; free (Awork) ; @@ -394,7 +407,7 @@ void my_function (void) (void) umfpack_dl_symbolic (n, n, Ap, Ai, Ax, &Sym, Control, Info) ; (void) umfpack_dl_numeric (Ap, Ai, Ax, Sym, &Num, Control, Info) ; umfpack_dl_free_symbolic (&Sym) ; - result = umfpack_dl_solve (UMFPACK_A, Ap, Ai, Ax, x, b, Num, Control, Info) ; + result = umfpack_dl_solve (UMFPACK_A, Ap, Ai, Ax, x, b, Num, Control, Info); umfpack_dl_free_numeric (&Num) ; for (int i = 0 ; i < n ; i++) std::cout << "x [" << i << "] = " << x [i] << std::endl; @@ -415,4 +428,6 @@ void my_function (void) cs_dl_spfree (A) ; A = nullptr ; OK (cholmod_l_finish (&cc)) ; + return (0) ; } + diff --git a/KLU/Config/klu.h.in b/KLU/Config/klu.h.in index 284d72dc6..fc7e88711 100644 --- a/KLU/Config/klu.h.in +++ b/KLU/Config/klu.h.in @@ -795,6 +795,12 @@ void *klu_l_free (void *, size_t, size_t, klu_l_common *) ; void *klu_l_realloc (size_t, size_t, size_t, void *, klu_l_common *) ; +//------------------------------------------------------------------------------ +// klu_version: return KLU version +//------------------------------------------------------------------------------ + +void klu_version (int version [3]) ; + #ifdef __cplusplus } #endif diff --git a/KLU/Demo/kludemo.c b/KLU/Demo/kludemo.c index 348b0d474..e51f477e4 100644 --- a/KLU/Demo/kludemo.c +++ b/KLU/Demo/kludemo.c @@ -319,6 +319,26 @@ static void klu_demo (int n, int *Ap, int *Ai, double *Ax, int isreal, int main (void) { + + //-------------------------------------------------------------------------- + // klu version + //-------------------------------------------------------------------------- + + int version [3] ; + klu_version (version) ; + printf ("KLU v%d.%d.%d\n", version [0], version [1], version [2]) ; + if ((version [0] != KLU_MAIN_VERSION) || + (version [1] != KLU_SUB_VERSION) || + (version [2] != KLU_SUBSUB_VERSION)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } + + //-------------------------------------------------------------------------- + // read in a matrix and solve Ax=b + //-------------------------------------------------------------------------- + cholmod_sparse *A ; cholmod_common ch ; cholmod_start (&ch) ; diff --git a/KLU/Demo/kluldemo.c b/KLU/Demo/kluldemo.c index 2b799cadf..91833fe29 100644 --- a/KLU/Demo/kluldemo.c +++ b/KLU/Demo/kluldemo.c @@ -320,6 +320,26 @@ static void klu_l_demo (int64_t n, int64_t *Ap, int64_t *Ai, double *Ax, int main (void) { + + //-------------------------------------------------------------------------- + // klu version + //-------------------------------------------------------------------------- + + int version [3] ; + klu_version (version) ; + printf ("KLU v%d.%d.%d\n", version [0], version [1], version [2]) ; + if ((version [0] != KLU_MAIN_VERSION) || + (version [1] != KLU_SUB_VERSION) || + (version [2] != KLU_SUBSUB_VERSION)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } + + //-------------------------------------------------------------------------- + // read in a matrix and solve Ax=b + //-------------------------------------------------------------------------- + cholmod_sparse *A ; cholmod_common ch ; cholmod_l_start (&ch) ; diff --git a/KLU/Doc/ChangeLog b/KLU/Doc/ChangeLog index cb7d2ef3c..d2d242795 100644 --- a/KLU/Doc/ChangeLog +++ b/KLU/Doc/ChangeLog @@ -1,6 +1,7 @@ Dec 30, 2023: version 2.3.0 * major change to build system: by Markus Mützel + * klu_version: added to return version of KLU Oct 23, 2023: version 2.2.2 diff --git a/KLU/Include/klu.h b/KLU/Include/klu.h index 4fb413b27..902613839 100644 --- a/KLU/Include/klu.h +++ b/KLU/Include/klu.h @@ -795,6 +795,12 @@ void *klu_l_free (void *, size_t, size_t, klu_l_common *) ; void *klu_l_realloc (size_t, size_t, size_t, void *, klu_l_common *) ; +//------------------------------------------------------------------------------ +// klu_version: return KLU version +//------------------------------------------------------------------------------ + +void klu_version (int version [3]) ; + #ifdef __cplusplus } #endif diff --git a/KLU/Source/klu_version.c b/KLU/Source/klu_version.c new file mode 100644 index 000000000..e96215f58 --- /dev/null +++ b/KLU/Source/klu_version.c @@ -0,0 +1,19 @@ +//------------------------------------------------------------------------------ +// KLU/Source/klu_version: return KLU version +//------------------------------------------------------------------------------ + +// KLU, Copyright (c) 2004-2023, University of Florida. All Rights Reserved. +// Authors: Timothy A. Davis and Ekanathan Palamadai. +// SPDX-License-Identifier: LGPL-2.1+ + +//------------------------------------------------------------------------------ + +#include "klu_internal.h" + +void klu_version (int version [3]) +{ + version [0] = KLU_MAIN_VERSION ; + version [1] = KLU_SUB_VERSION ; + version [2] = KLU_SUBSUB_VERSION ; +} + diff --git a/LDL/Config/ldl.h.in b/LDL/Config/ldl.h.in index 7fce97a02..574e4cd02 100644 --- a/LDL/Config/ldl.h.in +++ b/LDL/Config/ldl.h.in @@ -47,6 +47,8 @@ extern "C" { #endif +void ldl_version (int version [3]) ; + /* ========================================================================== */ /* === int32_t version ====================================================== */ /* ========================================================================== */ diff --git a/LDL/Demo/ldlamd.out b/LDL/Demo/ldlamd.out index f9b1fe4bf..57defd464 100644 --- a/LDL/Demo/ldlamd.out +++ b/LDL/Demo/ldlamd.out @@ -1,3 +1,4 @@ +LDL version 3.3.0, date: Dec 30, 2023 -------------------------------------------------------- @@ -107,10 +108,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 0 +relative maxnorm of residual: 1.97627e-17 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 0 +relative maxnorm of residual: 1.97627e-17 -------------------------------------------------------- @@ -158,10 +159,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 8.32667e-17 +relative maxnorm of residual: 5.51017e-17 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 8.32667e-17 +relative maxnorm of residual: 5.51017e-17 -------------------------------------------------------- @@ -209,10 +210,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 5.55112e-17 +relative maxnorm of residual: 2.53452e-17 Factorize A=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 5.55112e-17 +relative maxnorm of residual: 2.53452e-17 -------------------------------------------------------- @@ -260,10 +261,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.08019e-16 Factorize A=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.08019e-16 -------------------------------------------------------- @@ -311,10 +312,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.5077e-16 Factorize A=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.5077e-16 -------------------------------------------------------- @@ -362,10 +363,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.38778e-16 +relative maxnorm of residual: 1.27147e-16 Factorize A=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.38778e-16 +relative maxnorm of residual: 1.27147e-16 -------------------------------------------------------- @@ -515,10 +516,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 126 Flop count: 954 -relative maxnorm of residual: 2.59625e-10 +relative maxnorm of residual: 1.95957e-10 Factorize A=LDL' and solve Ax=b Nz in L: 276 Flop count: 4206 -relative maxnorm of residual: 2.72848e-10 +relative maxnorm of residual: 2.29324e-10 -------------------------------------------------------- @@ -566,10 +567,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 126 Flop count: 954 -relative maxnorm of residual: 3.27418e-10 +relative maxnorm of residual: 2.56588e-10 Factorize A=LDL' and solve Ax=b Nz in L: 276 Flop count: 4206 -relative maxnorm of residual: 2.32376e-10 +relative maxnorm of residual: 2.49687e-10 -------------------------------------------------------- @@ -617,10 +618,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 441 Flop count: 5961 -relative maxnorm of residual: 2.38712e-13 +relative maxnorm of residual: 1.85693e-13 Factorize A=LDL' and solve Ax=b Nz in L: 829 Flop count: 20103 -relative maxnorm of residual: 2.27374e-13 +relative maxnorm of residual: 3.17781e-13 -------------------------------------------------------- @@ -668,10 +669,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 441 Flop count: 5961 -relative maxnorm of residual: 2.27374e-13 +relative maxnorm of residual: 2.75176e-13 Factorize A=LDL' and solve Ax=b Nz in L: 829 Flop count: 20103 -relative maxnorm of residual: 3.83693e-13 +relative maxnorm of residual: 3.12705e-13 -------------------------------------------------------- @@ -821,10 +822,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 288 Flop count: 2630 -relative maxnorm of residual: 5.96745e-16 +relative maxnorm of residual: 5.6363e-16 Factorize A=LDL' and solve Ax=b Nz in L: 511 Flop count: 7383 -relative maxnorm of residual: 6.93889e-16 +relative maxnorm of residual: 7.07792e-16 -------------------------------------------------------- @@ -872,10 +873,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 288 Flop count: 2630 -relative maxnorm of residual: 5.55112e-16 +relative maxnorm of residual: 5.57005e-16 Factorize A=LDL' and solve Ax=b Nz in L: 511 Flop count: 7383 -relative maxnorm of residual: 5.55112e-16 +relative maxnorm of residual: 8.6996e-16 -------------------------------------------------------- @@ -923,10 +924,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 226 Flop count: 1472 -relative maxnorm of residual: 5.55112e-16 +relative maxnorm of residual: 5.39685e-16 Factorize A=LDL' and solve Ax=b Nz in L: 662 Flop count: 11350 -relative maxnorm of residual: 1.11022e-15 +relative maxnorm of residual: 8.70386e-16 -------------------------------------------------------- @@ -974,10 +975,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 226 Flop count: 1472 -relative maxnorm of residual: 5.68434e-14 +relative maxnorm of residual: 3.00082e-14 Factorize A=LDL' and solve Ax=b Nz in L: 662 Flop count: 11350 -relative maxnorm of residual: 2.15827e-12 +relative maxnorm of residual: 1.64732e-12 -------------------------------------------------------- @@ -1025,10 +1026,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 7.50219e-13 +relative maxnorm of residual: 6.01798e-13 Factorize A=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 7.50219e-13 +relative maxnorm of residual: 6.01798e-13 -------------------------------------------------------- @@ -1076,10 +1077,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 8.59759e-13 +relative maxnorm of residual: 5.76924e-13 Factorize A=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 8.59759e-13 +relative maxnorm of residual: 5.76924e-13 -------------------------------------------------------- @@ -1127,10 +1128,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 -------------------------------------------------------- @@ -1178,10 +1179,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 -------------------------------------------------------- @@ -1231,6 +1232,6 @@ name: Dense/3 n: 3 entries: 9 (invalid Ai) ldlamd: invalid matrix and/or permutation -Largest residual during all tests: 3.27418e-10 +Largest residual during all tests: 2.56588e-10 ldlamd: all tests passed diff --git a/LDL/Demo/ldllamd.out b/LDL/Demo/ldllamd.out index d29221108..704115a34 100644 --- a/LDL/Demo/ldllamd.out +++ b/LDL/Demo/ldllamd.out @@ -1,3 +1,4 @@ +LDL version 3.3.0, date: Dec 30, 2023 -------------------------------------------------------- @@ -107,10 +108,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 0 +relative maxnorm of residual: 1.97627e-17 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 0 +relative maxnorm of residual: 1.97627e-17 -------------------------------------------------------- @@ -158,10 +159,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 8.32667e-17 +relative maxnorm of residual: 5.51017e-17 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 8.32667e-17 +relative maxnorm of residual: 5.51017e-17 -------------------------------------------------------- @@ -209,10 +210,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 5.55112e-17 +relative maxnorm of residual: 2.53452e-17 Factorize A=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 5.55112e-17 +relative maxnorm of residual: 2.53452e-17 -------------------------------------------------------- @@ -260,10 +261,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.08019e-16 Factorize A=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.08019e-16 -------------------------------------------------------- @@ -311,10 +312,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.5077e-16 Factorize A=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.5077e-16 -------------------------------------------------------- @@ -362,10 +363,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.38778e-16 +relative maxnorm of residual: 1.27147e-16 Factorize A=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.38778e-16 +relative maxnorm of residual: 1.27147e-16 -------------------------------------------------------- @@ -515,10 +516,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 126 Flop count: 954 -relative maxnorm of residual: 2.59625e-10 +relative maxnorm of residual: 1.95957e-10 Factorize A=LDL' and solve Ax=b Nz in L: 276 Flop count: 4206 -relative maxnorm of residual: 2.72848e-10 +relative maxnorm of residual: 2.29324e-10 -------------------------------------------------------- @@ -566,10 +567,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 126 Flop count: 954 -relative maxnorm of residual: 3.27418e-10 +relative maxnorm of residual: 2.56588e-10 Factorize A=LDL' and solve Ax=b Nz in L: 276 Flop count: 4206 -relative maxnorm of residual: 2.32376e-10 +relative maxnorm of residual: 2.49687e-10 -------------------------------------------------------- @@ -617,10 +618,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 441 Flop count: 5961 -relative maxnorm of residual: 2.38712e-13 +relative maxnorm of residual: 1.85693e-13 Factorize A=LDL' and solve Ax=b Nz in L: 829 Flop count: 20103 -relative maxnorm of residual: 2.27374e-13 +relative maxnorm of residual: 3.17781e-13 -------------------------------------------------------- @@ -668,10 +669,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 441 Flop count: 5961 -relative maxnorm of residual: 2.27374e-13 +relative maxnorm of residual: 2.75176e-13 Factorize A=LDL' and solve Ax=b Nz in L: 829 Flop count: 20103 -relative maxnorm of residual: 3.83693e-13 +relative maxnorm of residual: 3.12705e-13 -------------------------------------------------------- @@ -821,10 +822,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 288 Flop count: 2630 -relative maxnorm of residual: 5.96745e-16 +relative maxnorm of residual: 5.6363e-16 Factorize A=LDL' and solve Ax=b Nz in L: 511 Flop count: 7383 -relative maxnorm of residual: 6.93889e-16 +relative maxnorm of residual: 7.07792e-16 -------------------------------------------------------- @@ -872,10 +873,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 288 Flop count: 2630 -relative maxnorm of residual: 5.55112e-16 +relative maxnorm of residual: 5.57005e-16 Factorize A=LDL' and solve Ax=b Nz in L: 511 Flop count: 7383 -relative maxnorm of residual: 5.55112e-16 +relative maxnorm of residual: 8.6996e-16 -------------------------------------------------------- @@ -923,10 +924,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 226 Flop count: 1472 -relative maxnorm of residual: 5.55112e-16 +relative maxnorm of residual: 5.39685e-16 Factorize A=LDL' and solve Ax=b Nz in L: 662 Flop count: 11350 -relative maxnorm of residual: 1.11022e-15 +relative maxnorm of residual: 8.70386e-16 -------------------------------------------------------- @@ -974,10 +975,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 226 Flop count: 1472 -relative maxnorm of residual: 5.68434e-14 +relative maxnorm of residual: 3.00082e-14 Factorize A=LDL' and solve Ax=b Nz in L: 662 Flop count: 11350 -relative maxnorm of residual: 2.15827e-12 +relative maxnorm of residual: 1.64732e-12 -------------------------------------------------------- @@ -1025,10 +1026,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 7.50219e-13 +relative maxnorm of residual: 6.01798e-13 Factorize A=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 7.50219e-13 +relative maxnorm of residual: 6.01798e-13 -------------------------------------------------------- @@ -1076,10 +1077,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 8.59759e-13 +relative maxnorm of residual: 5.76924e-13 Factorize A=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 8.59759e-13 +relative maxnorm of residual: 5.76924e-13 -------------------------------------------------------- @@ -1127,10 +1128,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 -------------------------------------------------------- @@ -1178,10 +1179,10 @@ AMD version 3.3.0, Dec 30, 2023, results: Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 -------------------------------------------------------- @@ -1231,6 +1232,6 @@ name: Dense/3 n: 3 entries: 9 (invalid Ai) ldlamd: invalid matrix and/or permutation -Largest residual during all tests: 3.27418e-10 +Largest residual during all tests: 2.56588e-10 ldlamd: all tests passed diff --git a/LDL/Demo/ldllmain.out b/LDL/Demo/ldllmain.out index 7080fca09..5e8f82491 100644 --- a/LDL/Demo/ldllmain.out +++ b/LDL/Demo/ldllmain.out @@ -1,3 +1,4 @@ +LDL version 3.3.0, date: Dec 30, 2023 -------------------------------------------------------- @@ -33,10 +34,10 @@ name: Dense/1 n: 1 entries: 1 Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 0 +relative maxnorm of residual: 1.97627e-17 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 0 +relative maxnorm of residual: 1.97627e-17 -------------------------------------------------------- @@ -46,10 +47,10 @@ name: Dense/1 n: 1 entries: 2 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 8.32667e-17 +relative maxnorm of residual: 5.51017e-17 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 8.32667e-17 +relative maxnorm of residual: 5.51017e-17 -------------------------------------------------------- @@ -59,10 +60,10 @@ name: Dense/2 n: 2 entries: 4 Factorize PAP'=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 5.55112e-17 +relative maxnorm of residual: 2.53452e-17 Factorize A=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 5.55112e-17 +relative maxnorm of residual: 2.53452e-17 -------------------------------------------------------- @@ -72,10 +73,10 @@ name: Dense/2 n: 2 entries: 5 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.08019e-16 Factorize A=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.08019e-16 -------------------------------------------------------- @@ -85,10 +86,10 @@ name: Dense/3 n: 3 entries: 9 Factorize PAP'=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.5077e-16 Factorize A=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.5077e-16 -------------------------------------------------------- @@ -98,10 +99,10 @@ name: Dense/3 n: 3 entries: 11 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.38778e-16 +relative maxnorm of residual: 1.27147e-16 Factorize A=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.38778e-16 +relative maxnorm of residual: 1.27147e-16 -------------------------------------------------------- @@ -137,10 +138,10 @@ name: FIDAP/ex5 n: 27 entries: 279 Factorize PAP'=LDL' and solve Ax=b Nz in L: 126 Flop count: 954 -relative maxnorm of residual: 2.59625e-10 +relative maxnorm of residual: 1.95957e-10 Factorize A=LDL' and solve Ax=b Nz in L: 276 Flop count: 4206 -relative maxnorm of residual: 2.72848e-10 +relative maxnorm of residual: 2.29324e-10 -------------------------------------------------------- @@ -150,10 +151,10 @@ name: FIDAP/ex5 n: 27 entries: 325 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 126 Flop count: 954 -relative maxnorm of residual: 3.27418e-10 +relative maxnorm of residual: 2.56588e-10 Factorize A=LDL' and solve Ax=b Nz in L: 276 Flop count: 4206 -relative maxnorm of residual: 2.32376e-10 +relative maxnorm of residual: 2.49687e-10 -------------------------------------------------------- @@ -163,10 +164,10 @@ name: HB/bcsstk01 n: 48 entries: 400 Factorize PAP'=LDL' and solve Ax=b Nz in L: 441 Flop count: 5961 -relative maxnorm of residual: 2.38712e-13 +relative maxnorm of residual: 1.85693e-13 Factorize A=LDL' and solve Ax=b Nz in L: 829 Flop count: 20103 -relative maxnorm of residual: 2.27374e-13 +relative maxnorm of residual: 3.17781e-13 -------------------------------------------------------- @@ -176,10 +177,10 @@ name: HB/bcsstk01 n: 48 entries: 472 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 441 Flop count: 5961 -relative maxnorm of residual: 2.27374e-13 +relative maxnorm of residual: 2.75176e-13 Factorize A=LDL' and solve Ax=b Nz in L: 829 Flop count: 20103 -relative maxnorm of residual: 3.83693e-13 +relative maxnorm of residual: 3.12705e-13 -------------------------------------------------------- @@ -215,10 +216,10 @@ name: Pothen/mesh1e1 n: 48 entries: 306 Factorize PAP'=LDL' and solve Ax=b Nz in L: 288 Flop count: 2630 -relative maxnorm of residual: 5.96745e-16 +relative maxnorm of residual: 5.6363e-16 Factorize A=LDL' and solve Ax=b Nz in L: 511 Flop count: 7383 -relative maxnorm of residual: 6.93889e-16 +relative maxnorm of residual: 7.07792e-16 -------------------------------------------------------- @@ -228,10 +229,10 @@ name: Pothen/mesh1e1 n: 48 entries: 359 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 288 Flop count: 2630 -relative maxnorm of residual: 5.55112e-16 +relative maxnorm of residual: 5.57005e-16 Factorize A=LDL' and solve Ax=b Nz in L: 511 Flop count: 7383 -relative maxnorm of residual: 5.55112e-16 +relative maxnorm of residual: 8.6996e-16 -------------------------------------------------------- @@ -241,10 +242,10 @@ name: Bai/bfwb62 n: 62 entries: 342 Factorize PAP'=LDL' and solve Ax=b Nz in L: 226 Flop count: 1472 -relative maxnorm of residual: 5.55112e-16 +relative maxnorm of residual: 5.39685e-16 Factorize A=LDL' and solve Ax=b Nz in L: 662 Flop count: 11350 -relative maxnorm of residual: 1.11022e-15 +relative maxnorm of residual: 8.70386e-16 -------------------------------------------------------- @@ -254,10 +255,10 @@ name: Bai/bfwb62 n: 62 entries: 407 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 226 Flop count: 1472 -relative maxnorm of residual: 5.68434e-14 +relative maxnorm of residual: 3.00082e-14 Factorize A=LDL' and solve Ax=b Nz in L: 662 Flop count: 11350 -relative maxnorm of residual: 2.15827e-12 +relative maxnorm of residual: 1.64732e-12 -------------------------------------------------------- @@ -267,10 +268,10 @@ name: HB/bcsstk02 n: 66 entries: 4356 Factorize PAP'=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 7.50219e-13 +relative maxnorm of residual: 6.01798e-13 Factorize A=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 7.50219e-13 +relative maxnorm of residual: 6.01798e-13 -------------------------------------------------------- @@ -280,10 +281,10 @@ name: HB/bcsstk02 n: 66 entries: 5175 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 8.59759e-13 +relative maxnorm of residual: 5.76924e-13 Factorize A=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 8.59759e-13 +relative maxnorm of residual: 5.76924e-13 -------------------------------------------------------- @@ -293,10 +294,10 @@ name: HB/bcsstm02 n: 66 entries: 66 Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 -------------------------------------------------------- @@ -306,10 +307,10 @@ name: HB/bcsstm02 n: 66 entries: 72 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 -------------------------------------------------------- @@ -359,6 +360,6 @@ name: Dense/3 n: 3 entries: 9 (invalid Ai) ldlmain: invalid matrix and/or permutation -Largest residual during all tests: 3.27418e-10 +Largest residual during all tests: 2.56588e-10 ldlmain: all tests passed diff --git a/LDL/Demo/ldlmain.c b/LDL/Demo/ldlmain.c index e8c116142..29da7515b 100644 --- a/LDL/Demo/ldlmain.c +++ b/LDL/Demo/ldlmain.c @@ -101,6 +101,22 @@ int main (void) FILE *f ; char s [LEN], filename [LEN] ; + //-------------------------------------------------------------------------- + // check the LDL version + //-------------------------------------------------------------------------- + + printf ("LDL version %d.%d.%d, date: %s\n", + LDL_MAIN_VERSION, LDL_SUB_VERSION, LDL_SUBSUB_VERSION, LDL_DATE) ; + int version [3] ; + ldl_version (version) ; + if ((version [0] != LDL_MAIN_VERSION) || + (version [1] != LDL_SUB_VERSION) || + (version [2] != LDL_SUBSUB_VERSION)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } + /* ---------------------------------------------------------------------- */ /* check the error-checking routines with null matrices */ /* ---------------------------------------------------------------------- */ diff --git a/LDL/Demo/ldlmain.out b/LDL/Demo/ldlmain.out index 7080fca09..5e8f82491 100644 --- a/LDL/Demo/ldlmain.out +++ b/LDL/Demo/ldlmain.out @@ -1,3 +1,4 @@ +LDL version 3.3.0, date: Dec 30, 2023 -------------------------------------------------------- @@ -33,10 +34,10 @@ name: Dense/1 n: 1 entries: 1 Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 0 +relative maxnorm of residual: 1.97627e-17 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 0 +relative maxnorm of residual: 1.97627e-17 -------------------------------------------------------- @@ -46,10 +47,10 @@ name: Dense/1 n: 1 entries: 2 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 8.32667e-17 +relative maxnorm of residual: 5.51017e-17 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 8.32667e-17 +relative maxnorm of residual: 5.51017e-17 -------------------------------------------------------- @@ -59,10 +60,10 @@ name: Dense/2 n: 2 entries: 4 Factorize PAP'=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 5.55112e-17 +relative maxnorm of residual: 2.53452e-17 Factorize A=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 5.55112e-17 +relative maxnorm of residual: 2.53452e-17 -------------------------------------------------------- @@ -72,10 +73,10 @@ name: Dense/2 n: 2 entries: 5 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.08019e-16 Factorize A=LDL' and solve Ax=b Nz in L: 1 Flop count: 3 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.08019e-16 -------------------------------------------------------- @@ -85,10 +86,10 @@ name: Dense/3 n: 3 entries: 9 Factorize PAP'=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.5077e-16 Factorize A=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.11022e-16 +relative maxnorm of residual: 1.5077e-16 -------------------------------------------------------- @@ -98,10 +99,10 @@ name: Dense/3 n: 3 entries: 11 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.38778e-16 +relative maxnorm of residual: 1.27147e-16 Factorize A=LDL' and solve Ax=b Nz in L: 3 Flop count: 11 -relative maxnorm of residual: 1.38778e-16 +relative maxnorm of residual: 1.27147e-16 -------------------------------------------------------- @@ -137,10 +138,10 @@ name: FIDAP/ex5 n: 27 entries: 279 Factorize PAP'=LDL' and solve Ax=b Nz in L: 126 Flop count: 954 -relative maxnorm of residual: 2.59625e-10 +relative maxnorm of residual: 1.95957e-10 Factorize A=LDL' and solve Ax=b Nz in L: 276 Flop count: 4206 -relative maxnorm of residual: 2.72848e-10 +relative maxnorm of residual: 2.29324e-10 -------------------------------------------------------- @@ -150,10 +151,10 @@ name: FIDAP/ex5 n: 27 entries: 325 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 126 Flop count: 954 -relative maxnorm of residual: 3.27418e-10 +relative maxnorm of residual: 2.56588e-10 Factorize A=LDL' and solve Ax=b Nz in L: 276 Flop count: 4206 -relative maxnorm of residual: 2.32376e-10 +relative maxnorm of residual: 2.49687e-10 -------------------------------------------------------- @@ -163,10 +164,10 @@ name: HB/bcsstk01 n: 48 entries: 400 Factorize PAP'=LDL' and solve Ax=b Nz in L: 441 Flop count: 5961 -relative maxnorm of residual: 2.38712e-13 +relative maxnorm of residual: 1.85693e-13 Factorize A=LDL' and solve Ax=b Nz in L: 829 Flop count: 20103 -relative maxnorm of residual: 2.27374e-13 +relative maxnorm of residual: 3.17781e-13 -------------------------------------------------------- @@ -176,10 +177,10 @@ name: HB/bcsstk01 n: 48 entries: 472 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 441 Flop count: 5961 -relative maxnorm of residual: 2.27374e-13 +relative maxnorm of residual: 2.75176e-13 Factorize A=LDL' and solve Ax=b Nz in L: 829 Flop count: 20103 -relative maxnorm of residual: 3.83693e-13 +relative maxnorm of residual: 3.12705e-13 -------------------------------------------------------- @@ -215,10 +216,10 @@ name: Pothen/mesh1e1 n: 48 entries: 306 Factorize PAP'=LDL' and solve Ax=b Nz in L: 288 Flop count: 2630 -relative maxnorm of residual: 5.96745e-16 +relative maxnorm of residual: 5.6363e-16 Factorize A=LDL' and solve Ax=b Nz in L: 511 Flop count: 7383 -relative maxnorm of residual: 6.93889e-16 +relative maxnorm of residual: 7.07792e-16 -------------------------------------------------------- @@ -228,10 +229,10 @@ name: Pothen/mesh1e1 n: 48 entries: 359 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 288 Flop count: 2630 -relative maxnorm of residual: 5.55112e-16 +relative maxnorm of residual: 5.57005e-16 Factorize A=LDL' and solve Ax=b Nz in L: 511 Flop count: 7383 -relative maxnorm of residual: 5.55112e-16 +relative maxnorm of residual: 8.6996e-16 -------------------------------------------------------- @@ -241,10 +242,10 @@ name: Bai/bfwb62 n: 62 entries: 342 Factorize PAP'=LDL' and solve Ax=b Nz in L: 226 Flop count: 1472 -relative maxnorm of residual: 5.55112e-16 +relative maxnorm of residual: 5.39685e-16 Factorize A=LDL' and solve Ax=b Nz in L: 662 Flop count: 11350 -relative maxnorm of residual: 1.11022e-15 +relative maxnorm of residual: 8.70386e-16 -------------------------------------------------------- @@ -254,10 +255,10 @@ name: Bai/bfwb62 n: 62 entries: 407 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 226 Flop count: 1472 -relative maxnorm of residual: 5.68434e-14 +relative maxnorm of residual: 3.00082e-14 Factorize A=LDL' and solve Ax=b Nz in L: 662 Flop count: 11350 -relative maxnorm of residual: 2.15827e-12 +relative maxnorm of residual: 1.64732e-12 -------------------------------------------------------- @@ -267,10 +268,10 @@ name: HB/bcsstk02 n: 66 entries: 4356 Factorize PAP'=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 7.50219e-13 +relative maxnorm of residual: 6.01798e-13 Factorize A=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 7.50219e-13 +relative maxnorm of residual: 6.01798e-13 -------------------------------------------------------- @@ -280,10 +281,10 @@ name: HB/bcsstk02 n: 66 entries: 5175 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 8.59759e-13 +relative maxnorm of residual: 5.76924e-13 Factorize A=LDL' and solve Ax=b Nz in L: 2145 Flop count: 97955 -relative maxnorm of residual: 8.59759e-13 +relative maxnorm of residual: 5.76924e-13 -------------------------------------------------------- @@ -293,10 +294,10 @@ name: HB/bcsstm02 n: 66 entries: 66 Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 -------------------------------------------------------- @@ -306,10 +307,10 @@ name: HB/bcsstm02 n: 66 entries: 72 (jumbled version) Factorize PAP'=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 Factorize A=LDL' and solve Ax=b Nz in L: 0 Flop count: 0 -relative maxnorm of residual: 2.22045e-16 +relative maxnorm of residual: 1.3857e-16 -------------------------------------------------------- @@ -359,6 +360,6 @@ name: Dense/3 n: 3 entries: 9 (invalid Ai) ldlmain: invalid matrix and/or permutation -Largest residual during all tests: 3.27418e-10 +Largest residual during all tests: 2.56588e-10 ldlmain: all tests passed diff --git a/LDL/Doc/ChangeLog b/LDL/Doc/ChangeLog index 4dbeee00e..4193d13d0 100644 --- a/LDL/Doc/ChangeLog +++ b/LDL/Doc/ChangeLog @@ -1,6 +1,7 @@ Dec 30, 2023: version 3.3.0 * major change to build system: by Markus Mützel + * ldl_version: added to return version of LDL Sept 18, 2023: version 3.2.1 diff --git a/LDL/Include/ldl.h b/LDL/Include/ldl.h index 0a11f4d42..05bbbf89c 100644 --- a/LDL/Include/ldl.h +++ b/LDL/Include/ldl.h @@ -47,6 +47,8 @@ extern "C" { #endif +void ldl_version (int version [3]) ; + /* ========================================================================== */ /* === int32_t version ====================================================== */ /* ========================================================================== */ diff --git a/LDL/Source/ldl.c b/LDL/Source/ldl.c index d431bdc0c..8654f3805 100644 --- a/LDL/Source/ldl.c +++ b/LDL/Source/ldl.c @@ -507,3 +507,17 @@ LDL_int LDL_valid_matrix } return (1) ; /* matrix is valid */ } + +//------------------------------------------------------------------------------ +// ldl_version: return the LDL version +//------------------------------------------------------------------------------ + +#ifndef LDL_LONG +void ldl_version (int version [3]) +{ + version [0] = LDL_MAIN_VERSION ; + version [1] = LDL_SUB_VERSION ; + version [2] = LDL_SUBSUB_VERSION ; +} +#endif + diff --git a/Mongoose/Tests/Mongoose_Test_Memory_exe.cpp b/Mongoose/Tests/Mongoose_Test_Memory_exe.cpp index 4670f9026..61d0f88dd 100644 --- a/Mongoose/Tests/Mongoose_Test_Memory_exe.cpp +++ b/Mongoose/Tests/Mongoose_Test_Memory_exe.cpp @@ -10,6 +10,7 @@ //------------------------------------------------------------------------------ +#include "Mongoose.hpp" #include "Mongoose_Test.hpp" using namespace Mongoose; @@ -25,6 +26,14 @@ using namespace Mongoose; int main(int argn, const char **argv) { + + if ((major_version ( ) != Mongoose_VERSION_MAJOR) || + (minor_version ( ) != Mongoose_VERSION_MINOR) || + (patch_version ( ) != Mongoose_VERSION_PATCH)) + { + return EXIT_FAILURE; + } + SuiteSparse_start(); if (argn != 2) diff --git a/RBio/Config/RBio.h.in b/RBio/Config/RBio.h.in index 8f6356ce6..15a86be5a 100644 --- a/RBio/Config/RBio.h.in +++ b/RBio/Config/RBio.h.in @@ -292,6 +292,8 @@ int RBok (int64_t nrow, int64_t ncol, void RBerror (int status) ; /* only for MATLAB mexFunctions */ #endif +void RBio_version (int version [3]) ; + #ifdef __cplusplus } #endif diff --git a/RBio/Demo/RBdemo.c b/RBio/Demo/RBdemo.c index 524a52c01..389aa8924 100644 --- a/RBio/Demo/RBdemo.c +++ b/RBio/Demo/RBdemo.c @@ -24,6 +24,24 @@ int main (int argc, char **argv) fem, xsize, nelnz, nnz ; char title [73], key [9], mtype [4], mtype2 [4], *filename ; + //-------------------------------------------------------------------------- + // check the RBio version + //-------------------------------------------------------------------------- + + printf ("RBio version %d.%d.%d, date: %s\n", + RBIO_MAIN_VERSION, RBIO_SUB_VERSION, RBIO_SUBSUB_VERSION, RBIO_DATE) ; + int version [3] ; + RBio_version (version) ; + if ((version [0] != RBIO_MAIN_VERSION) || + (version [1] != RBIO_SUB_VERSION) || + (version [2] != RBIO_SUBSUB_VERSION)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } + + //-------------------------------------------------------------------------- + /* initialize the memory allocation functions */ SuiteSparse_start ( ) ; diff --git a/RBio/Demo/RBdemo.out b/RBio/Demo/RBdemo.out index 2e966c46e..8e4242ec0 100644 --- a/RBio/Demo/RBdemo.out +++ b/RBio/Demo/RBdemo.out @@ -1,20 +1,20 @@ ( cd build && cmake .. && cmake --build . --config Release -j8 ) -- Building RBIO version: v4.3.0 (Dec 30, 2023) --- Source: /home/davis/dev2/SuiteSparse/RBio --- Build: /home/davis/dev2/SuiteSparse/RBio/build +-- Source: /Users/davis/dev2/SuiteSparse/RBio +-- Build: /Users/davis/dev2/SuiteSparse/RBio/build -- Install lib: lib -- Install include: include -- Install bin: bin -- Install pkg-file: lib -- Install rpath: --- Build rpath: /home/davis/dev2/SuiteSparse/RBio/build +-- Build rpath: /Users/davis/dev2/SuiteSparse/RBio/build -- Build type: Release --- Fortran: /usr/bin/f95 +-- Fortran: /opt/homebrew/bin/gfortran -- CUDA: not enabled -- SuiteSparse_config version: 7.4.0 --- SuiteSparse_config include: /home/davis/dev2/SuiteSparse/SuiteSparse_config --- SuiteSparse_config library: /home/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.so.7.4.0 --- SuiteSparse_config static: /home/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.a +-- SuiteSparse_config include: /Users/davis/dev2/SuiteSparse/SuiteSparse_config +-- SuiteSparse_config library: /Users/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.7.4.0.dylib +-- SuiteSparse_config static: /Users/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.a -- Also compiling the demos in RBio/Demo -- ------------------------------------------------------------------------ -- SuiteSparse CMAKE report for: rbio @@ -25,51 +25,38 @@ -- BUILD_SHARED_LIBS: ON -- BUILD_STATIC_LIBS: ON -- use OpenMP: no --- C compiler: /usr/bin/cc +-- C compiler: /Library/Developer/CommandLineTools/usr/bin/cc -- C flags: -- C++ compiler: -- C++ flags: -- C Flags release: -O3 -DNDEBUG -- C++ Flags release: --- Fortran compiler: /usr/bin/f95 +-- Fortran compiler: /opt/homebrew/bin/gfortran -- compile definitions: -- ------------------------------------------------------------------------ --- Configuring done --- Generating done --- Build files have been written to: /home/davis/dev2/SuiteSparse/RBio/build -make[1]: Entering directory '/home/davis/dev2/SuiteSparse/RBio/build' -make[2]: Entering directory '/home/davis/dev2/SuiteSparse/RBio/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/RBio/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/RBio/build' -Consolidate compiler generated dependencies of target RBio -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/RBio/build' -Consolidate compiler generated dependencies of target RBio_static -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/RBio/build' -[ 37%] Built target RBio_static +-- Configuring done (0.0s) +-- Generating done (0.0s) +-- Build files have been written to: /Users/davis/dev2/SuiteSparse/RBio/build [ 75%] Built target RBio -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/RBio/build' -Consolidate compiler generated dependencies of target RBdemo -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/RBio/build' +[ 75%] Built target RBio_static [100%] Built target RBdemo -make[2]: Leaving directory '/home/davis/dev2/SuiteSparse/RBio/build' -make[1]: Leaving directory '/home/davis/dev2/SuiteSparse/RBio/build' ( cd build && cmake -DDEMO=1 .. && cmake --build . --config Release -j8 ) -- Building RBIO version: v4.3.0 (Dec 30, 2023) --- Source: /home/davis/dev2/SuiteSparse/RBio --- Build: /home/davis/dev2/SuiteSparse/RBio/build +-- Source: /Users/davis/dev2/SuiteSparse/RBio +-- Build: /Users/davis/dev2/SuiteSparse/RBio/build -- Install lib: lib -- Install include: include -- Install bin: bin -- Install pkg-file: lib -- Install rpath: --- Build rpath: /home/davis/dev2/SuiteSparse/RBio/build +-- Build rpath: /Users/davis/dev2/SuiteSparse/RBio/build -- Build type: Release --- Fortran: /usr/bin/f95 +-- Fortran: /opt/homebrew/bin/gfortran -- CUDA: not enabled -- SuiteSparse_config version: 7.4.0 --- SuiteSparse_config include: /home/davis/dev2/SuiteSparse/SuiteSparse_config --- SuiteSparse_config library: /home/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.so.7.4.0 --- SuiteSparse_config static: /home/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.a +-- SuiteSparse_config include: /Users/davis/dev2/SuiteSparse/SuiteSparse_config +-- SuiteSparse_config library: /Users/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.7.4.0.dylib +-- SuiteSparse_config static: /Users/davis/dev2/SuiteSparse/SuiteSparse_config/build/libsuitesparseconfig.a -- Also compiling the demos in RBio/Demo -- ------------------------------------------------------------------------ -- SuiteSparse CMAKE report for: rbio @@ -80,35 +67,23 @@ make[1]: Leaving directory '/home/davis/dev2/SuiteSparse/RBio/build' -- BUILD_SHARED_LIBS: ON -- BUILD_STATIC_LIBS: ON -- use OpenMP: no --- C compiler: /usr/bin/cc +-- C compiler: /Library/Developer/CommandLineTools/usr/bin/cc -- C flags: -- C++ compiler: -- C++ flags: -- C Flags release: -O3 -DNDEBUG -- C++ Flags release: --- Fortran compiler: /usr/bin/f95 +-- Fortran compiler: /opt/homebrew/bin/gfortran -- compile definitions: -- ------------------------------------------------------------------------ --- Configuring done --- Generating done --- Build files have been written to: /home/davis/dev2/SuiteSparse/RBio/build -make[1]: Entering directory '/home/davis/dev2/SuiteSparse/RBio/build' -make[2]: Entering directory '/home/davis/dev2/SuiteSparse/RBio/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/RBio/build' -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/RBio/build' -Consolidate compiler generated dependencies of target RBio_static -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/RBio/build' -Consolidate compiler generated dependencies of target RBio -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/RBio/build' -[ 37%] Built target RBio_static +-- Configuring done (0.0s) +-- Generating done (0.0s) +-- Build files have been written to: /Users/davis/dev2/SuiteSparse/RBio/build [ 75%] Built target RBio -make[3]: Entering directory '/home/davis/dev2/SuiteSparse/RBio/build' -Consolidate compiler generated dependencies of target RBdemo -make[3]: Leaving directory '/home/davis/dev2/SuiteSparse/RBio/build' +[ 75%] Built target RBio_static [100%] Built target RBdemo -make[2]: Leaving directory '/home/davis/dev2/SuiteSparse/RBio/build' -make[1]: Leaving directory '/home/davis/dev2/SuiteSparse/RBio/build' ./build/RBdemo < ./RBio/private/west0479.rua +RBio version 4.3.0, date: Dec 30, 2023 =========================================================== title: [1U 8 STAGE COLUMN SECTION, ALL SECTIONS RIGOROUS ( CHEM. ENG. )] diff --git a/RBio/Doc/ChangeLog b/RBio/Doc/ChangeLog index b4808f148..3f9fdd717 100644 --- a/RBio/Doc/ChangeLog +++ b/RBio/Doc/ChangeLog @@ -1,6 +1,7 @@ Dec 30, 2023: version 4.3.0 * major change to build system: by Markus Mützel + * RBio_version: added to return version of RBio Sept 18, 2023: version 4.2.1 diff --git a/RBio/Include/RBio.h b/RBio/Include/RBio.h index d5f079bf1..e7f581593 100644 --- a/RBio/Include/RBio.h +++ b/RBio/Include/RBio.h @@ -292,6 +292,8 @@ int RBok (int64_t nrow, int64_t ncol, void RBerror (int status) ; /* only for MATLAB mexFunctions */ #endif +void RBio_version (int version [3]) ; + #ifdef __cplusplus } #endif diff --git a/RBio/Source/RBio.c b/RBio/Source/RBio.c index 0e1c2c415..86b8a1a70 100644 --- a/RBio/Source/RBio.c +++ b/RBio/Source/RBio.c @@ -345,6 +345,14 @@ PRIVATE void RB(skipheader) /* === functions ============================================================ */ /* ========================================================================== */ +#ifdef INT +void RBio_version (int version [3]) +{ + version [0] = RBIO_MAIN_VERSION ; + version [1] = RBIO_SUB_VERSION ; + version [2] = RBIO_SUBSUB_VERSION ; +} +#endif /* -------------------------------------------------------------------------- */ /* RBget_entry: get numerical entry in the matrix at position p */ diff --git a/SPEX/Config/SPEX.h.in b/SPEX/Config/SPEX.h.in index 583da5dc0..c15be1032 100644 --- a/SPEX/Config/SPEX.h.in +++ b/SPEX/Config/SPEX.h.in @@ -275,6 +275,12 @@ extern "C" { #endif +//------------------------------------------------------------------------------ +// version +//------------------------------------------------------------------------------ + +void SPEX_version (int version [3]) ; + //------------------------------------------------------------------------------ // Error codes //------------------------------------------------------------------------------ diff --git a/SPEX/Doc/ChangeLog b/SPEX/Doc/ChangeLog index b69fba018..97a7498e5 100644 --- a/SPEX/Doc/ChangeLog +++ b/SPEX/Doc/ChangeLog @@ -1,6 +1,7 @@ Dec 30, 2023: version 2.3.0 * major change to build system: by Markus Mützel + * SPEX_version: added to return version of SPEX Sept 18, 2023: version 2.2.1 diff --git a/SPEX/Include/SPEX.h b/SPEX/Include/SPEX.h index 7c3419bda..c84cbc01a 100644 --- a/SPEX/Include/SPEX.h +++ b/SPEX/Include/SPEX.h @@ -275,6 +275,12 @@ extern "C" { #endif +//------------------------------------------------------------------------------ +// version +//------------------------------------------------------------------------------ + +void SPEX_version (int version [3]) ; + //------------------------------------------------------------------------------ // Error codes //------------------------------------------------------------------------------ diff --git a/SPEX/SPEX_Util/Source/SPEX_version.c b/SPEX/SPEX_Util/Source/SPEX_version.c new file mode 100644 index 000000000..2687e3a98 --- /dev/null +++ b/SPEX/SPEX_Util/Source/SPEX_version.c @@ -0,0 +1,19 @@ +//------------------------------------------------------------------------------ +// SPEX/Source/amd_version: return SPEX version +//------------------------------------------------------------------------------ + +// SPEX_Util: (c) 2019-2023, Chris Lourenco (US Naval Academy), Jinhao Chen, +// Erick Moreno-Centeno, Timothy A. Davis, Texas A&M. All Rights Reserved. +// SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later + +//------------------------------------------------------------------------------ + +#include "spex_util_internal.h" + +void SPEX_version (int version [3]) +{ + version [0] = SPEX_VERSION_MAJOR ; + version [1] = SPEX_VERSION_MINOR ; + version [2] = SPEX_VERSION_SUB ; +} + diff --git a/SPQR/Doc/ChangeLog b/SPQR/Doc/ChangeLog index ab1592730..e00b72cf7 100644 --- a/SPQR/Doc/ChangeLog +++ b/SPQR/Doc/ChangeLog @@ -3,6 +3,8 @@ Dec 30, 2023: version 4.3.0 * major change to build system: by Markus Mützel * dependent packages: GPUQREngine and SuiteSparse_GPURuntime moved into SPQR as dependent packages, only used in SPQR. + * SuiteSparseQR_C_version and SuiteSparseQR_version: added to return + version of SPQR Oct 23, 2023: version 4.2.2 diff --git a/SPQR/Include/SuiteSparseQR.hpp b/SPQR/Include/SuiteSparseQR.hpp index 32c9756f0..72417b15f 100644 --- a/SPQR/Include/SuiteSparseQR.hpp +++ b/SPQR/Include/SuiteSparseQR.hpp @@ -20,9 +20,9 @@ #define SUITESPARSE_GPU_EXTERN_ON extern "C" { -#include "SuiteSparse_config.h" -#include "cholmod.h" -#include "SuiteSparseQR_definitions.h" + #include "SuiteSparse_config.h" + #include "cholmod.h" + #include "SuiteSparseQR_definitions.h" } #undef SUITESPARSE_GPU_EXTERN_ON @@ -368,6 +368,8 @@ template struct SuiteSparseQR_factoriza // === Simple user-callable SuiteSparseQR functions ============================ // ============================================================================= +void SuiteSparseQR_version (int version [3]) ; + // SuiteSparseQR Sparse QR factorization and solve // SuiteSparseQR_qmult Q'*X, Q*X, X*Q', or X*Q for X full or sparse diff --git a/SPQR/Include/SuiteSparseQR_C.h b/SPQR/Include/SuiteSparseQR_C.h index 9d40a5e8c..7f47db401 100644 --- a/SPQR/Include/SuiteSparseQR_C.h +++ b/SPQR/Include/SuiteSparseQR_C.h @@ -242,6 +242,8 @@ cholmod_dense *SuiteSparseQR_C_qmult /* returns Y, or NULL on failure */ #endif +void SuiteSparseQR_C_version (int version [3]) ; + /* ========================================================================== */ #ifdef __cplusplus diff --git a/SPQR/Source/SuiteSparseQR.cpp b/SPQR/Source/SuiteSparseQR.cpp index 02e01d45a..ab4073504 100644 --- a/SPQR/Source/SuiteSparseQR.cpp +++ b/SPQR/Source/SuiteSparseQR.cpp @@ -1893,3 +1893,15 @@ template struct spqr_numeric ; template struct spqr_numeric ; template struct spqr_numeric ; + +// ----------------------------------------------------------------------------- +// SuiteSparseQR_version +// ----------------------------------------------------------------------------- + +void SuiteSparseQR_version (int version [3]) +{ + version [0] = SPQR_MAIN_VERSION ; + version [1] = SPQR_SUB_VERSION ; + version [2] = SPQR_SUBSUB_VERSION ; +} + diff --git a/SPQR/Source/SuiteSparseQR_C.cpp b/SPQR/Source/SuiteSparseQR_C.cpp index c373e0e71..d44b7dac4 100644 --- a/SPQR/Source/SuiteSparseQR_C.cpp +++ b/SPQR/Source/SuiteSparseQR_C.cpp @@ -547,6 +547,17 @@ cholmod_dense *SuiteSparseQR_C_qmult } } +// ============================================================================= +// === SuiteSparseQR_C_version ================================================= +// ============================================================================= + +void SuiteSparseQR_C_version (int version [3]) +{ + version [0] = SPQR_MAIN_VERSION ; + version [1] = SPQR_SUB_VERSION ; + version [2] = SPQR_SUBSUB_VERSION ; +} + #endif // ============================================================================= diff --git a/UMFPACK/Config/umfpack.h.in b/UMFPACK/Config/umfpack.h.in index 60562915d..336aad217 100644 --- a/UMFPACK/Config/umfpack.h.in +++ b/UMFPACK/Config/umfpack.h.in @@ -391,6 +391,12 @@ extern "C" { #endif +//------------------------------------------------------------------------------ +// umfpack_version +//------------------------------------------------------------------------------ + +void umfpack_version (int version [3]) ; + //------------------------------------------------------------------------------ // umfpack_symbolic //------------------------------------------------------------------------------ diff --git a/UMFPACK/Doc/ChangeLog b/UMFPACK/Doc/ChangeLog index b91aaca09..605165d78 100644 --- a/UMFPACK/Doc/ChangeLog +++ b/UMFPACK/Doc/ChangeLog @@ -2,6 +2,7 @@ Dec 30, 2023: version 6.3.0 * major change to build system: by Markus Mützel * AMD: amd_internal.h removed from UMFPACK/Source. + * umfpack_version: added to return version of UMFPACK Oct 23, 2023: version 6.2.2 diff --git a/UMFPACK/Include/umfpack.h b/UMFPACK/Include/umfpack.h index f6625214f..67cded215 100644 --- a/UMFPACK/Include/umfpack.h +++ b/UMFPACK/Include/umfpack.h @@ -391,6 +391,12 @@ extern "C" { #endif +//------------------------------------------------------------------------------ +// umfpack_version +//------------------------------------------------------------------------------ + +void umfpack_version (int version [3]) ; + //------------------------------------------------------------------------------ // umfpack_symbolic //------------------------------------------------------------------------------ diff --git a/UMFPACK/Source2/umfpack_version.c b/UMFPACK/Source2/umfpack_version.c new file mode 100644 index 000000000..c410f7ce0 --- /dev/null +++ b/UMFPACK/Source2/umfpack_version.c @@ -0,0 +1,18 @@ +//------------------------------------------------------------------------------ +// UMFPACK/Source/umfpack_version: return UMFPACK version +//------------------------------------------------------------------------------ + +// UMFPACK, Copyright (c) 2005-2023, Timothy A. Davis, All Rights Reserved. +// SPDX-License-Identifier: GPL-2.0+ + +//------------------------------------------------------------------------------ + +#include "umf_internal.h" + +void umfpack_version (int version [3]) +{ + version [0] = UMFPACK_MAIN_VERSION ; + version [1] = UMFPACK_SUB_VERSION ; + version [2] = UMFPACK_SUBSUB_VERSION ; +} +