/* ========================================================================== */ /* === qrtestc_template ===================================================== */ /* ========================================================================== */ // SPQR, Copyright (c) 2008-2023, Timothy A Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0+ //------------------------------------------------------------------------------ // QRTESTC: test the SPQR C API //------------------------------------------------------------------------------ // The #include'ing file must define the following macros: // QRTEST: the name of the function // Real: double or float (only double currently supported) // CHOLMOD_INT64: int64_t if defined, int32_t otherwise #include "cholmod_types.h" static void QRTESTC ( cholmod_sparse *A, Real anorm, Real errs [5], Real maxresid [2][2], cholmod_common *cc ) { cholmod_dense *B, *X, *Resid ; cholmod_sparse *Bsparse, *Xsparse ; SuiteSparseQR_C_factorization *QR ; Real resid, one [2] = {1,0}, minusone [2] = {-1,0} ; Int m, n ; #ifndef NEXPERT cholmod_dense *Y ; int split ; #endif m = A->nrow ; n = A->ncol ; B = CHOLMOD (ones (m, 1, A->xtype, cc)) ; /* X = A\B */ X = SuiteSparseQR_C_backslash_default (A, B, cc) ; /* Resid = A*X - B */ Resid = CHOLMOD (copy_dense (B, cc)) ; CHOLMOD (sdmult (A, 0, one, minusone, X, Resid, cc)) ; /* resid = norm (Resid,1) */ resid = CHOLMOD (norm_dense (Resid, 1, cc)) / MAX (anorm, 1) ; resid = (resid < 0 || resid != resid) ? 9e99 : resid ; CHOLMOD (free_dense (&Resid, cc)) ; CHOLMOD (free_dense (&X, cc)) ; maxresid [m>n][0] = MAX (maxresid [m>n][0], resid) ; printf ("Resid_C1 %d : %g\n", m>n, resid) ; /* X = A\B */ Bsparse = CHOLMOD (dense_to_sparse (B, 1, cc)) ; Xsparse = SuiteSparseQR_C_backslash_sparse (2, -2, A, Bsparse, cc) ; X = CHOLMOD (sparse_to_dense (Xsparse, cc)) ; CHOLMOD (free_sparse (&Bsparse, cc)) ; CHOLMOD (free_sparse (&Xsparse, cc)) ; /* Resid = A*X - B */ Resid = CHOLMOD (copy_dense (B, cc)) ; CHOLMOD (sdmult (A, 0, one, minusone, X, Resid, cc)) ; /* resid = norm (Resid,1) */ resid = CHOLMOD (norm_dense (Resid, 1, cc)) / MAX (anorm, 1) ; resid = (resid < 0 || resid != resid) ? 9e99 : resid ; CHOLMOD (free_dense (&Resid, cc)) ; CHOLMOD (free_dense (&X, cc)) ; maxresid [m>n][0] = MAX (maxresid [m>n][0], resid) ; printf ("Resid_C2 %d : %g\n", m>n, resid) ; #ifndef NEXPERT for (split = 0 ; split <= 1 ; split++) { if (split) { /* split symbolic/numeric QR factorization */ QR = SuiteSparseQR_C_symbolic (2, 1, A, cc) ; SuiteSparseQR_C_numeric (-2, A, QR, cc) ; } else { /* QR factorization, single pass */ QR = SuiteSparseQR_C_factorize (2, -2, A, cc) ; } /* Y = Q'*B */ Y = SuiteSparseQR_C_qmult (0, QR, B, cc) ; /* X = E*(R\Y) */ X = SuiteSparseQR_C_solve (1, QR, Y, cc) ; /* Resid = A*X - B */ Resid = CHOLMOD (copy_dense (B, cc)) ; CHOLMOD (sdmult (A, 0, one, minusone, X, Resid, cc)) ; /* resid = norm (Resid,1) */ resid = CHOLMOD (norm_dense (Resid, 1, cc)) / MAX (anorm, 1) ; resid = (resid < 0 || resid != resid) ? 9e99 : resid ; CHOLMOD (free_dense (&Resid, cc)) ; CHOLMOD (free_dense (&X, cc)) ; maxresid [m>n][0] = MAX (maxresid [m>n][0], resid) ; printf ("Resid_C3 %d : %g\n", m>n, resid) ; CHOLMOD (free_dense (&Y, cc)) ; SuiteSparseQR_C_free (&QR, cc) ; } #endif CHOLMOD (free_dense (&B, cc)) ; }