Mercurial > octave
changeset 32287:dde186dc7b4c stable
Fix getting number of non-zero elements in SuiteSparse matrices.
Based on changes by @DrTimothyAldenDavis on GitHub:
https://github.com/DrTimothyAldenDavis/SuiteSparse/issues/221#issuecomment-1710586946
* liboctave/numeric/sparse-qr.cc (rcs2ros, ccs2cos): Add cholmod_common as
input argument. Use "cholmod_l_nnz" to get number of non-zero matrix elements.
(sparse_qr<T>::sparse_qr_rep::V): Pass cholmod_common to conversion function.
Get correct number of non-zero matrix elements.
(sparse_qr<T>::sparse_qr_rep::R): Use "cholmod_l_nnz" to get number of non-zero
matrix elements. Get correct number of non-zero matrix elements.
(sparse_qr<T>::sparse_qr_rep::tall_solve): Use "cholmod_l_nnz" to get number of
non-zero matrix elements.
(sparse_qr<T>::min2norm_solve): Pass cholmod_common to conversion function.
* liboctave/numeric/sparse-qr.cc (parse_chol<chol_type>::L): Use
"cholmod_[l_]nnz" to get number of non-zero matrix elements.
* liboctave/array/CSparse.cc, dSparse.cc (fsolve): Use "cholmod_[l_]nnz" to get
number of non-zero matrix elements.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Thu, 07 Sep 2023 21:29:43 +0200 |
parents | 6fa106924c19 |
children | 197dc8992606 b262966c853c |
files | liboctave/array/CSparse.cc liboctave/array/dSparse.cc liboctave/numeric/sparse-chol.cc liboctave/numeric/sparse-qr.cc |
diffstat | 4 files changed, 50 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/array/CSparse.cc Mon Aug 28 11:44:31 2023 +0200 +++ b/liboctave/array/CSparse.cc Thu Sep 07 21:29:43 2023 +0200 @@ -6042,12 +6042,14 @@ retval = SparseComplexMatrix (static_cast<octave_idx_type> (X->nrow), static_cast<octave_idx_type> (X->ncol), - static_cast<octave_idx_type> (X->nzmax)); + octave::from_suitesparse_long (CHOLMOD_NAME(nnz) + (X, cm))); for (octave_idx_type j = 0; j <= static_cast<octave_idx_type> (X->ncol); j++) retval.xcidx (j) = static_cast<octave_idx_type *>(X->p)[j]; for (octave_idx_type j = 0; - j < static_cast<octave_idx_type> (X->nzmax); j++) + j < octave::from_suitesparse_long (CHOLMOD_NAME(nnz) (X, cm)); + j++) { retval.xridx (j) = static_cast<octave_idx_type *>(X->i)[j]; retval.xdata (j) = static_cast<Complex *>(X->x)[j]; @@ -6550,12 +6552,14 @@ retval = SparseComplexMatrix (static_cast<octave_idx_type> (X->nrow), static_cast<octave_idx_type> (X->ncol), - static_cast<octave_idx_type> (X->nzmax)); + octave::from_suitesparse_long (CHOLMOD_NAME(nnz) + (X, cm))); for (octave_idx_type j = 0; j <= static_cast<octave_idx_type> (X->ncol); j++) retval.xcidx (j) = static_cast<octave_idx_type *>(X->p)[j]; for (octave_idx_type j = 0; - j < static_cast<octave_idx_type> (X->nzmax); j++) + j < octave::from_suitesparse_long (CHOLMOD_NAME(nnz) (X, cm)); + j++) { retval.xridx (j) = static_cast<octave_idx_type *>(X->i)[j]; retval.xdata (j) = static_cast<Complex *>(X->x)[j];
--- a/liboctave/array/dSparse.cc Mon Aug 28 11:44:31 2023 +0200 +++ b/liboctave/array/dSparse.cc Thu Sep 07 21:29:43 2023 +0200 @@ -6053,14 +6053,17 @@ cholmod_sparse *X = CHOLMOD_NAME(spsolve) (CHOLMOD_A, L, B, cm); - retval = SparseMatrix (static_cast<octave_idx_type> (X->nrow), - static_cast<octave_idx_type> (X->ncol), - static_cast<octave_idx_type> (X->nzmax)); + retval = SparseMatrix + (static_cast<octave_idx_type> (X->nrow), + static_cast<octave_idx_type> (X->ncol), + octave::from_suitesparse_long (CHOLMOD_NAME(nnz) + (X, cm))); for (octave_idx_type j = 0; j <= static_cast<octave_idx_type> (X->ncol); j++) retval.xcidx (j) = static_cast<octave_idx_type *>(X->p)[j]; for (octave_idx_type j = 0; - j < static_cast<octave_idx_type> (X->nzmax); j++) + j < octave::from_suitesparse_long (CHOLMOD_NAME(nnz) (X, cm)); + j++) { retval.xridx (j) = static_cast<octave_idx_type *>(X->i)[j]; retval.xdata (j) = static_cast<double *>(X->x)[j]; @@ -6548,12 +6551,14 @@ retval = SparseComplexMatrix (static_cast<octave_idx_type> (X->nrow), static_cast<octave_idx_type> (X->ncol), - static_cast<octave_idx_type> (X->nzmax)); + octave::from_suitesparse_long (CHOLMOD_NAME(nnz) + (X, cm))); for (octave_idx_type j = 0; j <= static_cast<octave_idx_type> (X->ncol); j++) retval.xcidx (j) = static_cast<octave_idx_type *>(X->p)[j]; for (octave_idx_type j = 0; - j < static_cast<octave_idx_type> (X->nzmax); j++) + j < octave::from_suitesparse_long (CHOLMOD_NAME(nnz) (X, cm)); + j++) { retval.xridx (j) = static_cast<octave_idx_type *>(X->i)[j]; retval.xdata (j) = static_cast<Complex *>(X->x)[j];
--- a/liboctave/numeric/sparse-chol.cc Mon Aug 28 11:44:31 2023 +0200 +++ b/liboctave/numeric/sparse-chol.cc Thu Sep 07 21:29:43 2023 +0200 @@ -97,6 +97,13 @@ { return m_L; } + + cholmod_common *cc (void) const + { + cholmod_common *ret = const_cast<cholmod_common *> (&m_common); + return ret; + } + #endif octave_idx_type P (void) const @@ -421,7 +428,8 @@ cholmod_sparse *m = m_rep->L (); octave_idx_type nc = m->ncol; - octave_idx_type nnz = m->nzmax; + octave_idx_type nnz + = from_suitesparse_long (CHOLMOD_NAME(nnz) (m, m_rep->cc ())); chol_type ret (m->nrow, nc, nnz);
--- a/liboctave/numeric/sparse-qr.cc Mon Aug 28 11:44:31 2023 +0200 +++ b/liboctave/numeric/sparse-qr.cc Thu Sep 07 21:29:43 2023 +0200 @@ -371,11 +371,13 @@ // Convert real sparse cholmod matrix to real sparse octave matrix. // Returns a "shallow" copy of y. static SparseMatrix -rcs2ros (const cholmod_sparse *y) +rcs2ros (cholmod_sparse *y, const cholmod_common *cc1) { octave_idx_type nrow = from_size_t (y->nrow); octave_idx_type ncol = from_size_t (y->ncol); - octave_idx_type nz = from_size_t (y->nzmax); + octave_idx_type nz + = from_suitesparse_long + (cholmod_l_nnz (y, const_cast<cholmod_common *> (cc1))); SparseMatrix ret (nrow, ncol, nz); SuiteSparse_long *y_p = reinterpret_cast<SuiteSparse_long *> (y->p); @@ -396,11 +398,11 @@ // Convert complex sparse cholmod matrix to complex sparse octave matrix. // Returns a "deep" copy of a. static SparseComplexMatrix -ccs2cos (const cholmod_sparse *a) +ccs2cos (cholmod_sparse *a, cholmod_common *cc1) { octave_idx_type nrow = from_size_t (a->nrow); octave_idx_type ncol = from_size_t (a->ncol); - octave_idx_type nz = from_size_t (a->nzmax); + octave_idx_type nz = from_suitesparse_long (cholmod_l_nnz (a, cc1)); SparseComplexMatrix ret (nrow, ncol, nz); SuiteSparse_long *a_p = reinterpret_cast<SuiteSparse_long *> (a->p); @@ -595,7 +597,7 @@ { #if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD)) - return rcs2ros (m_H); + return rcs2ros (m_H, &m_cc); #elif defined (HAVE_CXSPARSE) @@ -609,7 +611,7 @@ CXSPARSE_DNAME (_spfree) (D); octave_idx_type nc = N->L->n; - octave_idx_type nz = N->L->nzmax; + octave_idx_type nz = N->L->p[nc]; SparseMatrix ret (N->L->m, nc, nz); for (octave_idx_type j = 0; j < nc+1; j++) @@ -638,7 +640,9 @@ octave_idx_type nr = static_cast<octave_idx_type> (m_R->nrow); octave_idx_type nc = static_cast<octave_idx_type> (m_R->ncol); - octave_idx_type nz = static_cast<octave_idx_type> (m_R->nzmax); + octave_idx_type nz + = from_suitesparse_long + (cholmod_l_nnz (m_R, const_cast<cholmod_common *> (&m_cc))); // FIXME: Does this work if econ = true? SparseMatrix ret ((econ ? (nc > nr ? nr : nc) : nr), nc, nz); @@ -668,7 +672,7 @@ CXSPARSE_DNAME (_spfree) (D); octave_idx_type nc = N->U->n; - octave_idx_type nz = N->U->nzmax; + octave_idx_type nz = N->U->p[nc]; SparseMatrix ret ((econ ? (nc > nrows ? nrows : nc) : nrows), nc, nz); @@ -942,7 +946,7 @@ for (octave_idx_type i = 0; i < ncols+1; i++) R2_p[i] = suitesparse_long_to_suitesparse_integer (R_p[i]); R2.p = R2_p; - octave_idx_type nnz = m_R->nzmax; + octave_idx_type nnz = from_suitesparse_long (cholmod_l_nnz (m_R, &m_cc)); R2_i = new suitesparse_integer[nnz]; SuiteSparse_long *R_i = reinterpret_cast<SuiteSparse_long *> (m_R->i); for (octave_idx_type i = 0; i < nnz; i++) @@ -1542,7 +1546,7 @@ CXSPARSE_ZNAME (_spfree) (D); octave_idx_type nc = N->L->n; - octave_idx_type nz = N->L->nzmax; + octave_idx_type nz = N->L->p[nc]; SparseComplexMatrix ret (N->L->m, nc, nz); for (octave_idx_type j = 0; j < nc+1; j++) @@ -1571,7 +1575,9 @@ octave_idx_type nr = from_size_t (m_R->nrow); octave_idx_type nc = from_size_t (m_R->ncol); - octave_idx_type nz = from_size_t (m_R->nzmax); + octave_idx_type nz + = from_suitesparse_long + (cholmod_l_nnz (m_R, const_cast<cholmod_common *> (&m_cc))); // FIXME: Does this work if econ = true? SparseComplexMatrix ret ((econ ? (nc > nr ? nr : nc) : nr), nc, nz); @@ -1601,7 +1607,7 @@ CXSPARSE_ZNAME (_spfree) (D); octave_idx_type nc = N->U->n; - octave_idx_type nz = N->U->nzmax; + octave_idx_type nz = N->U->p[nc]; SparseComplexMatrix ret ((econ ? (nc > nrows ? nrows : nc) : nrows), nc, nz); @@ -2822,7 +2828,7 @@ delete [] reinterpret_cast<SuiteSparse_long *> (B.i); } - x = rcs2ros (X); + x = rcs2ros (X, &cc); cholmod_l_finish (&cc); info = 0; @@ -2897,7 +2903,7 @@ } cholmod_l_finish (&cc); - SparseComplexMatrix ret = ccs2cos(X); + SparseComplexMatrix ret = ccs2cos (X, &cc); info = 0; @@ -3022,7 +3028,7 @@ info = 0; - return ccs2cos (X); + return ccs2cos (X, &cc); } @@ -3047,7 +3053,7 @@ X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, &A, B, &cc); spqr_error_handler (&cc); - SparseComplexMatrix ret = ccs2cos(X); + SparseComplexMatrix ret = ccs2cos (X, &cc); if (sizeof (octave_idx_type) != sizeof (SuiteSparse_long)) {