Mercurial > octave-libtiff
changeset 29274:fed765133d53
sparse-qr.cc: Use correct integer types (bug #57033).
* liboctave/numeric/sparse-qr.cc (sparse_qr_rep): Use correct integer types for
members. Use cholmod types with SuiteSparse_long for SPQR. Check when
converting to narrower integer types. Do not static_cast pointer types.
(ros2rcs, cos2ccs, rod2ccd, cod2ccd, rcs2ros, ccs2cos, ros2ccs): Move
functions from oct-sparse.cc and use cholmod types with SuiteSparse_long.
Check when converting to narrower integer types. Do not static_cast pointer
types. Copy arrays to correct integer pointer type when necessary.
* liboctave/util/oct-sparse.h (from_suitesparse_long, from_size_t): New
functions.
* liboctave/util/oct-sparse.cc (ros2rcs, cos2ccs, rod2ccd, cod2ccd, rcs2ros,
ccs2cos, ros2ccs): Remove functions that were moved to sparse-qr.cc.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Thu, 07 Jan 2021 00:19:21 +0100 |
parents | 11bc1b22b29f |
children | 881bbfaddd25 |
files | liboctave/numeric/sparse-qr.cc liboctave/util/oct-sparse.cc liboctave/util/oct-sparse.h |
diffstat | 3 files changed, 498 insertions(+), 400 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/numeric/sparse-qr.cc Wed Jan 06 17:13:54 2021 -0500 +++ b/liboctave/numeric/sparse-qr.cc Thu Jan 07 00:19:21 2021 +0100 @@ -142,10 +142,10 @@ cholmod_common m_cc; cholmod_sparse *m_R; // R factor // Column permutation for A. Fill-reducing ordering. - suitesparse_integer *m_E; + SuiteSparse_long *m_E; cholmod_sparse *m_H; // Householder vectors cholmod_dense *m_Htau; // beta scalars - suitesparse_integer *m_HPinv; + SuiteSparse_long *m_HPinv; #endif }; @@ -180,7 +180,7 @@ // FIXME: Is ret.xelem (m_HPinv[i]) = i + 1 correct? for (octave_idx_type i = 0; i < nrows; i++) - ret.xelem (m_HPinv[i]) = i + 1; + ret.xelem (from_suitesparse_long (m_HPinv[i])) = i + 1; return ret; @@ -209,7 +209,7 @@ ColumnVector ret (ncols); for (octave_idx_type i = 0; i < ncols; i++) - ret(i) = static_cast<octave_idx_type> (m_E[i]) + 1; + ret(i) = from_suitesparse_long (m_E[i]) + 1; return ret; @@ -220,6 +220,255 @@ #endif } +#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD)) + + // Convert real sparse octave matrix to real sparse cholmod matrix. + // Returns a "shallow" copy of a. + static cholmod_sparse + ros2rcs (const SparseMatrix& a) + { + cholmod_sparse A; + + octave_idx_type ncols = a.cols (); + octave_idx_type nnz = a.nnz (); + + A.ncol = ncols; + A.nrow = a.rows (); + A.itype = CHOLMOD_LONG; + A.nzmax = nnz; + A.sorted = 0; + A.packed = 1; + A.stype = 0; + A.xtype = CHOLMOD_REAL; + A.dtype = CHOLMOD_DOUBLE; + A.nz = nullptr; + A.z = nullptr; + if (sizeof (octave_idx_type) == sizeof (SuiteSparse_long)) + { + A.p = reinterpret_cast<SuiteSparse_long *> (a.cidx ()); + A.i = reinterpret_cast<SuiteSparse_long *> (a.ridx ()); + } + else + { + SuiteSparse_long *A_p; + A_p = new SuiteSparse_long[ncols+1]; + for (octave_idx_type i = 0; i < ncols+1; i++) + A_p[i] = a.cidx (i); + A.p = A_p; + SuiteSparse_long *A_i; + A_i = new SuiteSparse_long[nnz]; + for (octave_idx_type i = 0; i < nnz; i++) + A_i[i] = a.ridx (i); + A.i = A_i; + } + A.x = const_cast<double *> (a.data ()); + + return A; + } + + // Convert complex sparse octave matrix to complex sparse cholmod matrix. + // Returns a "shallow" copy of a. + static cholmod_sparse + cos2ccs (const SparseComplexMatrix& a) + { + cholmod_sparse A; + + octave_idx_type ncols = a.cols (); + octave_idx_type nnz = a.nnz (); + + A.ncol = ncols; + A.nrow = a.rows (); + A.itype = CHOLMOD_LONG; + A.nzmax = nnz; + A.sorted = 0; + A.packed = 1; + A.stype = 0; + A.xtype = CHOLMOD_COMPLEX; + A.dtype = CHOLMOD_DOUBLE; + A.nz = nullptr; + A.z = nullptr; + if (sizeof (octave_idx_type) == sizeof (SuiteSparse_long)) + { + A.p = reinterpret_cast<SuiteSparse_long *> (a.cidx ()); + A.i = reinterpret_cast<SuiteSparse_long *> (a.ridx ()); + } + else + { + SuiteSparse_long *A_p; + A_p = new SuiteSparse_long[ncols+1]; + for (octave_idx_type i = 0; i < ncols+1; i++) + A_p[i] = a.cidx (i); + A.p = A_p; + SuiteSparse_long *A_i; + A_i = new SuiteSparse_long[nnz]; + for (octave_idx_type i = 0; i < nnz; i++) + A_i[i] = a.ridx (i); + A.i = A_i; + } + A.x = const_cast<Complex *> + (reinterpret_cast<const Complex *> (a.data ())); + + return A; + } + + // Convert real dense octave matrix to complex dense cholmod matrix. + // Returns a "deep" copy of a. + static cholmod_dense* + rod2ccd (const MArray<double>& a, cholmod_common *cc1) + { + cholmod_dense *A + = cholmod_l_allocate_dense (a.rows (), a.cols (), a.rows(), + CHOLMOD_COMPLEX, cc1); + + const double *a_x = a.data (); + + Complex *A_x = reinterpret_cast<Complex *> (A->x); + for (octave_idx_type j = 0; j < a.cols() * a.rows() ; j++) + A_x[j] = Complex (a_x[j], 0.0); + + return A; + } + + // Convert real dense octave matrix to real dense cholmod matrix. + // Returns a "shallow" copy of a. + static cholmod_dense + rod2rcd (const MArray<double> &a) + { + cholmod_dense A; + + A.ncol = a.cols (); + A.nrow = a.rows (); + A.nzmax = a.cols () * a.rows (); + A.xtype = CHOLMOD_REAL; + A.dtype = CHOLMOD_DOUBLE; + A.z = nullptr; + A.d = a.rows (); + A.x = const_cast<double *> (a.data ()); + + return A; + } + + // Convert complex dense octave matrix to complex dense cholmod matrix. + // Returns a "shallow" copy of a. + static cholmod_dense + cod2ccd (const ComplexMatrix &a) + { + cholmod_dense A; + + A.ncol = a.cols (); + A.nrow = a.rows (); + A.nzmax = a.cols () * a.rows (); + A.xtype = CHOLMOD_COMPLEX; + A.dtype = CHOLMOD_DOUBLE; + A.z = nullptr; + A.d = a.rows (); + A.x = const_cast<Complex*> (reinterpret_cast<const Complex*> (a.data ())); + + return A; + } + + // Convert real sparse cholmod matrix to real sparse octave matrix. + // Returns a "shallow" copy of y. + static SparseMatrix + rcs2ros (const cholmod_sparse* y) + { + 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); + SparseMatrix ret (nrow, ncol, nz); + + SuiteSparse_long *y_p = reinterpret_cast<SuiteSparse_long *> (y->p); + for (octave_idx_type j = 0; j < ncol + 1; j++) + ret.xcidx (j) = from_suitesparse_long (y_p[j]); + + SuiteSparse_long *y_i = reinterpret_cast<SuiteSparse_long *> (y->i); + double *y_x = reinterpret_cast<double *> (y->x); + for (octave_idx_type j = 0; j < nz; j++) + { + ret.xridx (j) = from_suitesparse_long (y_i[j]); + ret.xdata (j) = y_x[j]; + } + + return ret; + } + + // Convert complex sparse cholmod matrix to complex sparse octave matrix. + // Returns a "deep" copy of a. + static SparseComplexMatrix + ccs2cos (const cholmod_sparse *a) + { + 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); + SparseComplexMatrix ret (nrow, ncol, nz); + + SuiteSparse_long *a_p = reinterpret_cast<SuiteSparse_long *> (a->p); + for (octave_idx_type j = 0; j < ncol + 1; j++) + ret.xcidx(j) = from_suitesparse_long (a_p[j]); + + SuiteSparse_long *a_i = reinterpret_cast<SuiteSparse_long *> (a->i); + Complex *a_x = reinterpret_cast<Complex *> (a->x); + for (octave_idx_type j = 0; j < nz; j++) + { + ret.xridx(j) = from_suitesparse_long (a_i[j]); + ret.xdata(j) = a_x[j]; + } + + return ret; + } + + // Convert real sparse octave matrix to complex sparse cholmod matrix. + // Returns a "deep" copy of a. + static cholmod_sparse* + ros2ccs (const SparseMatrix& a, cholmod_common *cc) + { + cholmod_sparse *A + = cholmod_l_allocate_sparse (a.rows (), a.cols (), a.nnz (), 0, 1, 0, + CHOLMOD_COMPLEX, cc); + + octave_idx_type ncol = a.cols (); + SuiteSparse_long *A_p = reinterpret_cast<SuiteSparse_long *> (A->p); + for (octave_idx_type j = 0; j < ncol + 1; j++) + A_p[j] = a.cidx(j); + + const double *a_x = a.data (); + Complex *A_x = reinterpret_cast<Complex *> (A->x); + SuiteSparse_long *A_i = reinterpret_cast<SuiteSparse_long *> (A->i); + for (octave_idx_type j = 0; j < a.nnz (); j++) + { + A_x[j] = Complex (a_x[j], 0.0); + A_i[j] = a.ridx(j); + } + return A; + } + + static void + spqr_error_handler (const cholmod_common *cc) + { + if (cc->status >= 0) + return; + + switch (cc->status) + { + case CHOLMOD_OUT_OF_MEMORY: + (*current_liboctave_error_handler) + ("sparse_qr: sparse matrix QR factorization failed" + " - out of memory"); + case CHOLMOD_TOO_LARGE: + (*current_liboctave_error_handler) + ("sparse_qr: sparse matrix QR factorization failed" + " - integer overflow occurred"); + default: + (*current_liboctave_error_handler) + ("sparse_qr: sparse matrix QR factorization failed" + " - error %d", cc->status); + } + + // FIXME: Free memory? + // FIXME: Can cc-status > 0 (CHOLMOD_NOT_POSDEF, CHOLMOD_DSMALL) occur? + } +#endif + // Specializations. // Real-valued matrices. @@ -256,15 +505,21 @@ (*current_liboctave_error_handler) ("ordering %d is not supported by SPQR", order); - CHOLMOD_NAME (start) (&m_cc); - const cholmod_sparse A = ros2rcs (a); + cholmod_l_start (&m_cc); + cholmod_sparse A = ros2rcs (a); BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - SuiteSparseQR<double> (order, SPQR_DEFAULT_TOL, A.nrow, - const_cast<cholmod_sparse*> (&A), &m_R, &m_E, &m_H, - &m_HPinv, &m_Htau, &m_cc); + SuiteSparseQR<double> (order, static_cast<double> (SPQR_DEFAULT_TOL), + static_cast<SuiteSparse_long> (A.nrow), + &A, &m_R, &m_E, &m_H, &m_HPinv, &m_Htau, &m_cc); spqr_error_handler (&m_cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + + if (sizeof (octave_idx_type) != sizeof (SuiteSparse_long)) + { + delete [] reinterpret_cast<SuiteSparse_long *> (A.p); + delete [] reinterpret_cast<SuiteSparse_long *> (A.i); + } } #elif defined (HAVE_CXSPARSE) @@ -311,12 +566,12 @@ { #if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD)) - CHOLMOD_NAME (free_sparse) (&m_R, &m_cc); - CHOLMOD_NAME (free_sparse) (&m_H, &m_cc); - CHOLMOD_NAME (free_dense) (&m_Htau, &m_cc); + cholmod_l_free_sparse (&m_R, &m_cc); + cholmod_l_free_sparse (&m_H, &m_cc); + cholmod_l_free_dense (&m_Htau, &m_cc); free (m_E); // FIXME: use cholmod_l_free free (m_HPinv); - CHOLMOD_NAME (finish) (&m_cc); + cholmod_l_finish (&m_cc); #elif defined (HAVE_CXSPARSE) @@ -381,18 +636,16 @@ // FIXME: Does this work if econ = true? SparseMatrix ret ((econ ? (nc > nr ? nr : nc) : nr), nc, nz); - octave_idx_type *Rp = to_octave_idx_type_ptr - (static_cast<suitesparse_integer*> (m_R->p)); - octave_idx_type *Ri = to_octave_idx_type_ptr - (static_cast<suitesparse_integer*> (m_R->i)); + SuiteSparse_long *Rp = reinterpret_cast<SuiteSparse_long *> (m_R->p); + SuiteSparse_long *Ri = reinterpret_cast<SuiteSparse_long *> (m_R->i); for (octave_idx_type j = 0; j < nc + 1; j++) - ret.xcidx (j) = Rp[j]; + ret.xcidx (j) = from_suitesparse_long (Rp[j]); for (octave_idx_type j = 0; j < nz; j++) { - ret.xridx (j) = Ri[j]; - ret.xdata (j) = (static_cast<double*> (m_R->x))[j]; + ret.xridx (j) = from_suitesparse_long (Ri[j]); + ret.xdata (j) = (reinterpret_cast<double *> (m_R->x))[j]; } return ret; @@ -455,21 +708,21 @@ ("sparse_qr: matrix dimension with negative or zero size"); cholmod_dense *QTB; // Q' * B - const cholmod_dense B = rod2rcd (b); + cholmod_dense B = rod2rcd (b); BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - QTB = SuiteSparseQR_qmult<double> (SPQR_QTX, m_H, m_Htau, m_HPinv, - const_cast<cholmod_dense*> (&B), &m_cc); + QTB = SuiteSparseQR_qmult<double> (SPQR_QTX, m_H, m_Htau, m_HPinv, &B, + &m_cc); spqr_error_handler (&m_cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; // copy QTB into ret - double *QTB_x = static_cast<double*> (QTB->x); - double *ret_vec = static_cast<double*> (ret.fortran_vec ()); + double *QTB_x = reinterpret_cast<double *> (QTB->x); + double *ret_vec = reinterpret_cast<double *> (ret.fortran_vec ()); for (octave_idx_type j = 0; j < b_nc; j++) for (octave_idx_type i = 0; i < nr; i++) ret_vec[j * nr + i] = QTB_x[j * b_nr + i]; - CHOLMOD_NAME (free_dense) (&QTB, &m_cc); + cholmod_l_free_dense (&QTB, &m_cc); return ret; @@ -553,29 +806,28 @@ cholmod_dense *q; // I is nrows x nrows identity matrix - cholmod_dense *I = static_cast<cholmod_dense*> - (CHOLMOD_NAME (allocate_dense) - (nrows, nrows, nrows, CHOLMOD_REAL, &m_cc)); + cholmod_dense *I + = cholmod_l_allocate_dense (nrows, nrows, nrows, CHOLMOD_REAL, &m_cc); for (octave_idx_type i = 0; i < nrows * nrows; i++) - (static_cast<double*> (I->x))[i] = 0.0; + (reinterpret_cast<double *> (I->x))[i] = 0.0; for (octave_idx_type i = 0; i < nrows; i++) - (static_cast<double*> (I->x))[i * nrows + i] = 1.0; + (reinterpret_cast<double *> (I->x))[i * nrows + i] = 1.0; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; q = SuiteSparseQR_qmult<double> (SPQR_QX, m_H, m_Htau, m_HPinv, I, &m_cc); spqr_error_handler (&m_cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - double *q_x = static_cast<double*> (q->x); - double *ret_vec = const_cast<double*> (ret.fortran_vec ()); + double *q_x = reinterpret_cast<double *> (q->x); + double *ret_vec = const_cast<double *> (ret.fortran_vec ()); for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nrows; i++) ret_vec[j * nrows + i] = q_x[j * nrows + i]; - CHOLMOD_NAME (free_dense) (&q, &m_cc); - CHOLMOD_NAME (free_dense) (&I, &m_cc); + cholmod_l_free_dense (&q, &m_cc); + cholmod_l_free_dense (&I, &m_cc); return ret; @@ -645,6 +897,18 @@ #endif } + static suitesparse_integer + suitesparse_long_to_suitesparse_integer (SuiteSparse_long x) + { + if (x < std::numeric_limits<suitesparse_integer>::min () + || x > std::numeric_limits<suitesparse_integer>::max ()) + (*current_liboctave_error_handler) + ("integer dimension or index out of range for SuiteSparse's indexing type"); + + return static_cast<suitesparse_integer> (x); + } + + template <> template <> Matrix @@ -667,14 +931,13 @@ (*current_liboctave_error_handler) ("matrix dimension mismatch"); cholmod_dense *QTB; // Q' * B - const cholmod_dense B = rod2rcd (b); + cholmod_dense B = rod2rcd (b); BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; // FIXME: Process b column by column as in the CXSPARSE version below. // This avoids a large dense matrix Q' * B in memory. - QTB = SuiteSparseQR_qmult<double> - (SPQR_QTX, m_H, m_Htau, m_HPinv, const_cast<cholmod_dense*> (&B), - &m_cc); + QTB = SuiteSparseQR_qmult<double> (SPQR_QTX, m_H, m_Htau, m_HPinv, &B, + &m_cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; spqr_error_handler (&m_cc); @@ -684,26 +947,60 @@ R2.n = ncols; R2.m = ncols; R2.nzmax = m_R->nzmax; - R2.x = static_cast<double*> (m_R->x); - R2.i = static_cast<suitesparse_integer*> (m_R->i); - R2.p = static_cast<suitesparse_integer*> (m_R->p); + R2.x = reinterpret_cast<double *> (m_R->x); + suitesparse_integer *R2_p; + suitesparse_integer *R2_i; + if (sizeof (suitesparse_integer) == sizeof (SuiteSparse_long)) + { + R2.p = reinterpret_cast<suitesparse_integer *> (m_R->p); + R2.i = reinterpret_cast<suitesparse_integer *> (m_R->i); + } + else + { + R2_p = new suitesparse_integer[ncols+1]; + SuiteSparse_long * R_p = reinterpret_cast<SuiteSparse_long *> (m_R->p); + 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; + 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++) + R2_i[i] = suitesparse_long_to_suitesparse_integer (R_i[i]); + R2.i = R2_i; + } R2.nz = -1; - double *x_vec = const_cast<double*> (x.fortran_vec ()); + double *x_vec = const_cast<double *> (x.fortran_vec ()); + suitesparse_integer *E; + if (sizeof (suitesparse_integer) != sizeof (SuiteSparse_long)) + { + E = new suitesparse_integer [ncols]; + for (octave_idx_type i = 0; i < ncols; i++) + E[i] = suitesparse_long_to_suitesparse_integer (m_E[i]); + } + else + E = reinterpret_cast<suitesparse_integer *> (m_E); for (volatile octave_idx_type j = 0; j < b_nc; j++) { // fill x(:,j) BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; // solve (m_R\(Q'*B(:,j)) and store result in QTB(:,j) CXSPARSE_DNAME (_usolve) - (&R2, &(static_cast<double*> (QTB->x)[j * b_nr])); + (&R2, &(reinterpret_cast<double *> (QTB->x)[j * b_nr])); // x(:,j) = m_E' * (m_R\(Q'*B(:,j)) CXSPARSE_DNAME (_ipvec) - (m_E, &(static_cast<double*> (QTB->x)[j * b_nr]), &x_vec[j * ncols], - ncols); + (E, &(reinterpret_cast<double *> (QTB->x)[j * b_nr]), + &x_vec[j * ncols], ncols); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; } - CHOLMOD_NAME (free_dense) (&QTB, &m_cc); + if (sizeof (suitesparse_integer) != sizeof (SuiteSparse_long)) + { + delete [] R2_p; + delete [] R2_i; + delete [] E; + } + cholmod_l_free_dense (&QTB, &m_cc); info = 0; @@ -1224,15 +1521,22 @@ (*current_liboctave_error_handler) ("ordering %d is not supported by SPQR", order); - CHOLMOD_NAME (start) (&m_cc); - const cholmod_sparse A = cos2ccs (a); + cholmod_l_start (&m_cc); + cholmod_sparse A = cos2ccs (a); BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - SuiteSparseQR<Complex> (order, SPQR_DEFAULT_TOL, A.nrow, - const_cast<cholmod_sparse*>(&A), &m_R, &m_E, &m_H, + SuiteSparseQR<Complex> (order, static_cast<double> (SPQR_DEFAULT_TOL), + static_cast<SuiteSparse_long> (A.nrow), + &A, &m_R, &m_E, &m_H, &m_HPinv, &m_Htau, &m_cc); spqr_error_handler (&m_cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + + if (sizeof (octave_idx_type) != sizeof (SuiteSparse_long)) + { + delete [] reinterpret_cast<SuiteSparse_long *> (A.p); + delete [] reinterpret_cast<SuiteSparse_long *> (A.i); + } } #elif defined (HAVE_CXSPARSE) @@ -1280,12 +1584,12 @@ { #if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD)) - CHOLMOD_NAME (free_sparse) (&m_R, &m_cc); - CHOLMOD_NAME (free_sparse) (&m_H, &m_cc); - CHOLMOD_NAME (free_dense) (&m_Htau, &m_cc); + cholmod_l_free_sparse (&m_R, &m_cc); + cholmod_l_free_sparse (&m_H, &m_cc); + cholmod_l_free_dense (&m_Htau, &m_cc); free (m_E); // FIXME: use cholmod_l_free free (m_HPinv); - CHOLMOD_NAME (finish) (&m_cc); + cholmod_l_finish (&m_cc); #elif defined (HAVE_CXSPARSE) @@ -1321,7 +1625,7 @@ for (octave_idx_type j = 0; j < nz; j++) { ret.xridx (j) = N->L->i[j]; - ret.xdata (j) = reinterpret_cast<Complex *>(N->L->x)[j]; + ret.xdata (j) = reinterpret_cast<Complex *> (N->L->x)[j]; } return ret; @@ -1339,24 +1643,22 @@ { #if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD)) - 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 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); // FIXME: Does this work if econ = true? SparseComplexMatrix ret ((econ ? (nc > nr ? nr : nc) : nr), nc, nz); - octave_idx_type *Rp = to_octave_idx_type_ptr - (static_cast<suitesparse_integer*> (m_R->p)); - octave_idx_type *Ri = to_octave_idx_type_ptr - (static_cast<suitesparse_integer*> (m_R->i)); + SuiteSparse_long *Rp = reinterpret_cast<SuiteSparse_long *> (m_R->p); + SuiteSparse_long *Ri = reinterpret_cast<SuiteSparse_long *> (m_R->i); for (octave_idx_type j = 0; j < nc + 1; j++) - ret.xcidx (j) = Rp[j]; + ret.xcidx (j) = from_suitesparse_long (Rp[j]); for (octave_idx_type j = 0; j < nz; j++) { - ret.xridx (j) = Ri[j]; - ret.xdata (j) = (static_cast<Complex*> (m_R->x))[j]; + ret.xridx (j) = from_suitesparse_long (Ri[j]); + ret.xdata (j) = (reinterpret_cast<Complex *> (m_R->x))[j]; } return ret; @@ -1423,23 +1725,22 @@ ("matrix dimension with negative or zero size"); cholmod_dense *QTB; // Q' * B - const cholmod_dense B = cod2ccd (b); + cholmod_dense B = cod2ccd (b); BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - QTB = SuiteSparseQR_qmult<Complex> (SPQR_QTX, m_H, m_Htau, m_HPinv, - const_cast<cholmod_dense*> (&B), + QTB = SuiteSparseQR_qmult<Complex> (SPQR_QTX, m_H, m_Htau, m_HPinv, &B, &m_cc); spqr_error_handler (&m_cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; // copy QTB into ret - Complex *QTB_x = static_cast<Complex*> (QTB->x); - Complex *ret_vec = static_cast<Complex*> (ret.fortran_vec ()); + Complex *QTB_x = reinterpret_cast<Complex *> (QTB->x); + Complex *ret_vec = reinterpret_cast<Complex *> (ret.fortran_vec ()); for (octave_idx_type j = 0; j < b_nc; j++) for (octave_idx_type i = 0; i < nr; i++) ret_vec[j * nr + i] = QTB_x[j * b_nr + i]; - CHOLMOD_NAME (free_dense) (&QTB, &m_cc); + cholmod_l_free_dense (&QTB, &m_cc); return ret; @@ -1521,15 +1822,15 @@ cholmod_dense *q; // I is nrows x nrows identity matrix - cholmod_dense *I = static_cast<cholmod_dense*> - (CHOLMOD_NAME (allocate_dense) - (nrows, nrows, nrows, CHOLMOD_COMPLEX, &m_cc)); + cholmod_dense *I + = reinterpret_cast<cholmod_dense *> + (cholmod_l_allocate_dense (nrows, nrows, nrows, CHOLMOD_COMPLEX, &m_cc)); for (octave_idx_type i = 0; i < nrows * nrows; i++) - (static_cast<Complex*> (I->x))[i] = 0.0; + (reinterpret_cast<Complex *> (I->x))[i] = 0.0; for (octave_idx_type i = 0; i < nrows; i++) - (static_cast<Complex*> (I->x))[i * nrows + i] = 1.0; + (reinterpret_cast<Complex *> (I->x))[i * nrows + i] = 1.0; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; q = SuiteSparseQR_qmult<Complex> (SPQR_QX, m_H, m_Htau, m_HPinv, I, @@ -1537,15 +1838,15 @@ spqr_error_handler (&m_cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - Complex *q_x = static_cast<Complex*> (q->x); + Complex *q_x = reinterpret_cast<Complex *> (q->x); Complex *ret_vec = const_cast<Complex*> (ret.fortran_vec ()); for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nrows; i++) ret_vec[j * nrows + i] = q_x[j * nrows + i]; - CHOLMOD_NAME (free_dense) (&q, &m_cc); - CHOLMOD_NAME (free_dense) (&I, &m_cc); + cholmod_l_free_dense (&q, &m_cc); + cholmod_l_free_dense (&I, &m_cc); return ret; @@ -1964,7 +2265,7 @@ buf[j] = cs_complex_t (0.0, 0.0); BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - CXSPARSE_ZNAME (_pvec) (S->q, reinterpret_cast<cs_complex_t *>(Xx), + CXSPARSE_ZNAME (_pvec) (S->q, reinterpret_cast<cs_complex_t *> (Xx), buf, nr); CXSPARSE_ZNAME (_utsolve) (N->U, buf); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -2034,7 +2335,7 @@ BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; CXSPARSE_ZNAME (_ipvec) (S->pinv, - reinterpret_cast<cs_complex_t *>(Xx), + reinterpret_cast<cs_complex_t *> (Xx), buf, nr); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -2138,7 +2439,7 @@ BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; CXSPARSE_ZNAME (_pvec) (S->q, - reinterpret_cast<cs_complex_t *>(Xx), + reinterpret_cast<cs_complex_t *> (Xx), buf, nr); CXSPARSE_ZNAME (_utsolve) (N->U, buf); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -2374,7 +2675,7 @@ BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; CXSPARSE_ZNAME (_ipvec) (S->pinv, - reinterpret_cast<cs_complex_t *>(Xx), + reinterpret_cast<cs_complex_t *> (Xx), buf, nr); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -2660,24 +2961,27 @@ Matrix x (nc, b_nc); cholmod_common cc; - CHOLMOD_NAME (start) (&cc); - const cholmod_sparse A = ros2rcs (a); - const cholmod_dense B = rod2rcd (b); + cholmod_l_start (&cc); + cholmod_sparse A = ros2rcs (a); + cholmod_dense B = rod2rcd (b); cholmod_dense *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm<double> (order, SPQR_DEFAULT_TOL, - const_cast<cholmod_sparse*> (&A), - const_cast<cholmod_dense*> (&B), &cc); + X = SuiteSparseQR_min2norm<double> (order, SPQR_DEFAULT_TOL, &A, &B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; double *vec = x.fortran_vec (); for (volatile octave_idx_type i = 0; i < nc * b_nc; i++) - vec[i] = static_cast<double*> (X->x)[i]; + vec[i] = reinterpret_cast<double *> (X->x)[i]; info = 0; - CHOLMOD_NAME (finish) (&cc); + if (sizeof (octave_idx_type) != sizeof (SuiteSparse_long)) + { + delete [] reinterpret_cast<SuiteSparse_long *> (A.p); + delete [] reinterpret_cast<SuiteSparse_long *> (A.i); + } + cholmod_l_finish (&cc); return x; @@ -2694,20 +2998,26 @@ SparseMatrix x; cholmod_common cc; - CHOLMOD_NAME (start) (&cc); - const cholmod_sparse A = ros2rcs(a); - cholmod_sparse B = ros2rcs(b); + cholmod_l_start (&cc); + cholmod_sparse A = ros2rcs (a); + cholmod_sparse B = ros2rcs (b); cholmod_sparse *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm<double> (order, SPQR_DEFAULT_TOL, - const_cast<cholmod_sparse*>(&A), &B, - &cc); + X = SuiteSparseQR_min2norm<double> (order, SPQR_DEFAULT_TOL, &A, &B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + if (sizeof (octave_idx_type) != sizeof (SuiteSparse_long)) + { + delete [] reinterpret_cast<SuiteSparse_long *> (A.p); + delete [] reinterpret_cast<SuiteSparse_long *> (A.i); + delete [] reinterpret_cast<SuiteSparse_long *> (B.p); + delete [] reinterpret_cast<SuiteSparse_long *> (B.i); + } + x = rcs2ros (X); - CHOLMOD_NAME (finish) (&cc); + cholmod_l_finish (&cc); info = 0; return x; @@ -2730,25 +3040,23 @@ cholmod_common cc; - CHOLMOD_NAME (start) (&cc); + cholmod_l_start (&cc); cholmod_sparse *A = ros2ccs (a, &cc); - const cholmod_dense B = cod2ccd (b); + cholmod_dense B = cod2ccd (b); cholmod_dense *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, A, - const_cast<cholmod_dense*> (&B), - &cc); + X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, A, &B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; Complex *vec = x.fortran_vec (); for (volatile octave_idx_type i = 0; i < nc * b_nc; i++) - vec[i] = static_cast<Complex*> (X->x)[i]; - - CHOLMOD_NAME (free_sparse) (&A, &cc); - CHOLMOD_NAME (finish) (&cc); + vec[i] = reinterpret_cast<Complex *> (X->x)[i]; + + cholmod_l_free_sparse (&A, &cc); + cholmod_l_finish (&cc); info = 0; @@ -2768,21 +3076,24 @@ cholmod_common cc; - CHOLMOD_NAME (start) (&cc); - - cholmod_sparse * A = ros2ccs (a, &cc); - const cholmod_sparse B = cos2ccs (b); + cholmod_l_start (&cc); + + cholmod_sparse *A = ros2ccs (a, &cc); + cholmod_sparse B = cos2ccs (b); cholmod_sparse *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, A, - const_cast<cholmod_sparse*> (&B), - &cc); + X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, A, &B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - CHOLMOD_NAME (free_sparse) (&A, &cc); - CHOLMOD_NAME (finish) (&cc); + cholmod_l_free_sparse (&A, &cc); + if (sizeof (octave_idx_type) != sizeof (SuiteSparse_long)) + { + delete [] reinterpret_cast<SuiteSparse_long *> (B.p); + delete [] reinterpret_cast<SuiteSparse_long *> (B.i); + } + cholmod_l_finish (&cc); SparseComplexMatrix ret = ccs2cos(X); @@ -2807,25 +3118,27 @@ cholmod_common cc; - CHOLMOD_NAME (start) (&cc); - - const cholmod_sparse A = cos2ccs (a); - const cholmod_dense B = cod2ccd (b); + cholmod_l_start (&cc); + + cholmod_sparse A = cos2ccs (a); + cholmod_dense B = cod2ccd (b); cholmod_dense *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, - const_cast<cholmod_sparse*> (&A), - const_cast<cholmod_dense*> (&B), - &cc); + X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, &A, &B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; Complex *vec = x.fortran_vec (); for (volatile octave_idx_type i = 0; i < nc * b_nc; i++) - vec[i] = static_cast<Complex*> (X->x)[i]; - - CHOLMOD_NAME (finish) (&cc); + vec[i] = reinterpret_cast<Complex *> (X->x)[i]; + + if (sizeof (octave_idx_type) != sizeof (SuiteSparse_long)) + { + delete [] reinterpret_cast<SuiteSparse_long *> (A.p); + delete [] reinterpret_cast<SuiteSparse_long *> (A.i); + } + cholmod_l_finish (&cc); info = 0; @@ -2849,26 +3162,29 @@ cholmod_common cc; - CHOLMOD_NAME (start) (&cc); - - const cholmod_sparse A = cos2ccs (a); + cholmod_l_start (&cc); + + cholmod_sparse A = cos2ccs (a); cholmod_dense *B = rod2ccd (b, &cc); cholmod_dense *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, - const_cast<cholmod_sparse*> (&A), - B, &cc); + X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, &A, B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; Complex *vec = x.fortran_vec (); for (volatile octave_idx_type i = 0; i < nc * b_nc; i++) - vec[i] = static_cast<Complex*> (X->x)[i]; - - CHOLMOD_NAME (free_dense) (&B, &cc); - CHOLMOD_NAME (finish) (&cc); + vec[i] = reinterpret_cast<Complex *> (X->x)[i]; + + if (sizeof (octave_idx_type) != sizeof (SuiteSparse_long)) + { + delete [] reinterpret_cast<SuiteSparse_long *> (A.p); + delete [] reinterpret_cast<SuiteSparse_long *> (A.i); + } + cholmod_l_free_dense (&B, &cc); + cholmod_l_finish (&cc); info = 0; @@ -2888,21 +3204,25 @@ cholmod_common cc; - CHOLMOD_NAME (start) (&cc); - - const cholmod_sparse A = cos2ccs (a); - const cholmod_sparse B = cos2ccs (b); + cholmod_l_start (&cc); + + cholmod_sparse A = cos2ccs (a); + cholmod_sparse B = cos2ccs (b); cholmod_sparse *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, - const_cast<cholmod_sparse*> (&A), - const_cast<cholmod_sparse*> (&B), - &cc); + X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, &A, &B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - CHOLMOD_NAME (finish) (&cc); + if (sizeof (octave_idx_type) != sizeof (SuiteSparse_long)) + { + delete [] reinterpret_cast<SuiteSparse_long *> (A.p); + delete [] reinterpret_cast<SuiteSparse_long *> (A.i); + delete [] reinterpret_cast<SuiteSparse_long *> (B.p); + delete [] reinterpret_cast<SuiteSparse_long *> (B.i); + } + cholmod_l_finish (&cc); info = 0; @@ -2922,25 +3242,26 @@ cholmod_common cc; - CHOLMOD_NAME (start) (&cc); - - const cholmod_sparse A = cos2ccs (a); + cholmod_l_start (&cc); + + cholmod_sparse A = cos2ccs (a); cholmod_sparse *B = ros2ccs (b, &cc); cholmod_sparse *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, - const_cast<cholmod_sparse*> (&A), B, - &cc); + X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, &A, B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - CHOLMOD_NAME (finish) (&cc); - SparseComplexMatrix ret = ccs2cos(X); - CHOLMOD_NAME (free_sparse) (&B, &cc); - CHOLMOD_NAME (finish) (&cc); + if (sizeof (octave_idx_type) != sizeof (SuiteSparse_long)) + { + delete [] reinterpret_cast<SuiteSparse_long *> (A.p); + delete [] reinterpret_cast<SuiteSparse_long *> (A.i); + } + cholmod_l_free_sparse (&B, &cc); + cholmod_l_finish (&cc); info = 0;
--- a/liboctave/util/oct-sparse.cc Wed Jan 06 17:13:54 2021 -0500 +++ b/liboctave/util/oct-sparse.cc Thu Jan 07 00:19:21 2021 +0100 @@ -78,204 +78,6 @@ return reinterpret_cast<const octave_idx_type *> (i); } - -# if defined (HAVE_CHOLMOD) - const cholmod_sparse - ros2rcs (const SparseMatrix &a) - { - cholmod_sparse A; - - A.ncol = a.cols (); - A.nrow = a.rows (); -# if defined (OCTAVE_ENABLE_64) - A.itype = CHOLMOD_LONG; -# else - A.itype = CHOLMOD_INT; -# endif - A.nzmax = a.nnz (); - A.sorted = 0; - A.packed = 1; - A.stype = 0; - A.xtype = CHOLMOD_REAL; - A.dtype = CHOLMOD_DOUBLE; - A.nz = NULL; - A.z = NULL; - A.p = const_cast<suitesparse_integer*> (to_suitesparse_intptr (a.cidx ())); - A.i = const_cast<suitesparse_integer*> (to_suitesparse_intptr (a.ridx ())); - A.x = const_cast<double*> (a.data ()); - - return A; - } - - const cholmod_sparse - cos2ccs (const SparseComplexMatrix &a) - { - cholmod_sparse A; - - A.ncol = a.cols (); - A.nrow = a.rows (); -# if defined (OCTAVE_ENABLE_64) - A.itype = CHOLMOD_LONG; -# else - A.itype = CHOLMOD_INT; -# endif - A.nzmax = a.nnz (); - A.sorted = 0; - A.packed = 1; - A.stype = 0; - A.xtype = CHOLMOD_COMPLEX; - A.dtype = CHOLMOD_DOUBLE; - A.nz = NULL; - A.z = NULL; - A.p = const_cast<suitesparse_integer*> (to_suitesparse_intptr (a.cidx ())); - A.i = const_cast<suitesparse_integer*> (to_suitesparse_intptr (a.ridx ())); - A.x = const_cast<Complex*> - (reinterpret_cast<const Complex*> (a.data ())); - - return A; - } - - cholmod_dense* - rod2ccd (const MArray<double> &a, cholmod_common* cc1) - { - cholmod_dense *A = static_cast<cholmod_dense*> - (CHOLMOD_NAME (allocate_dense) - (a.rows (), a.cols (), a.rows(), CHOLMOD_COMPLEX, - cc1)); - - const double *a_x = a.data (); - - for (octave_idx_type j = 0; j < a.cols() * a.rows() ; j++) - (static_cast<Complex*> (A->x))[j] = Complex (a_x[j], 0.0); - - return A; - } - - const cholmod_dense - rod2rcd (const MArray<double> &a) - { - cholmod_dense A; - - A.ncol = a.cols (); - A.nrow = a.rows (); - A.nzmax = a.cols() * a.rows(); - A.xtype = CHOLMOD_REAL; - A.dtype = CHOLMOD_DOUBLE; - A.z = NULL; - A.d = a.rows(); - A.x = const_cast<double*> (a.data ()); - - return A; - } - - const cholmod_dense - cod2ccd (const ComplexMatrix &a) - { - cholmod_dense A; - - A.ncol = a.cols (); - A.nrow = a.rows (); - A.nzmax = a.cols () * a.rows (); - A.xtype = CHOLMOD_COMPLEX; - A.dtype = CHOLMOD_DOUBLE; - A.z = NULL; - A.d = a.rows(); - A.x = const_cast<Complex*> - (reinterpret_cast<const Complex*> (a.data ())); - - return A; - } - - SparseMatrix - rcs2ros (const cholmod_sparse* y) - { - SparseMatrix ret (static_cast<octave_idx_type> (y->nrow), - static_cast<octave_idx_type> (y->ncol), - static_cast<octave_idx_type> (y->nzmax)); - - octave_idx_type nz = static_cast<octave_idx_type> (y->nzmax); - - for (octave_idx_type j = 0; j < static_cast<octave_idx_type> (y->ncol) + 1; - j++) - ret.xcidx (j) = (static_cast<octave_idx_type*> (y->p))[j]; - - for (octave_idx_type j = 0; j < nz; j++) - { - ret.xridx (j) = (static_cast<octave_idx_type*> (y->i))[j]; - ret.xdata (j) = (static_cast<double*> (y->x))[j]; - } - - return ret; - } - - SparseComplexMatrix - ccs2cos (const cholmod_sparse* a) - { - SparseComplexMatrix ret (static_cast<octave_idx_type> (a->nrow), - static_cast<octave_idx_type> (a->ncol), - static_cast<octave_idx_type> (a->nzmax)); - - octave_idx_type nz = static_cast<octave_idx_type> (a->nzmax); - - for (octave_idx_type j = 0; j < static_cast<octave_idx_type> (a->ncol) + 1; - j++) - ret.xcidx (j) = (static_cast<octave_idx_type*> (a->p))[j]; - - for (octave_idx_type j = 0; j < nz; j++) - { - ret.xridx (j) = (static_cast<octave_idx_type*> (a->i))[j]; - ret.xdata (j) = (static_cast<Complex*> (a->x))[j]; - } - - return ret; - } - - cholmod_sparse* - ros2ccs (const SparseMatrix& a, cholmod_common* cc1) - { - cholmod_sparse *A = static_cast<cholmod_sparse*> - (CHOLMOD_NAME(allocate_sparse) - (a.rows (), a.cols (), a.nnz (), 0, 1, 0, - CHOLMOD_COMPLEX, cc1)); - - for (octave_idx_type j = 0; - j < static_cast<octave_idx_type> (a.cols ()) + 1; j++) - static_cast<octave_idx_type*> (A->p)[j] = a.cidx(j); - - const double *a_x = a.data (); - for (octave_idx_type j = 0; j < a.nnz (); j++) - { - (static_cast<Complex*> (A->x))[j] = Complex (a_x[j], 0.0); - (static_cast<octave_idx_type*> (A->i))[j] = a.ridx(j); - } - return A; - } - - void - spqr_error_handler (const cholmod_common* cc) - { - if (cc->status >= 0) - return; - - switch (cc->status) - { - case CHOLMOD_OUT_OF_MEMORY: - (*current_liboctave_error_handler) - ("sparse_qr: sparse matrix QR factorization failed" - " - out of memory"); - case CHOLMOD_TOO_LARGE: - (*current_liboctave_error_handler) - ("sparse_qr: sparse matrix QR factorization failed" - " - integer overflow occurred"); - default: - (*current_liboctave_error_handler) - ("sparse_qr: sparse matrix QR factorization failed"); - } - - // FIXME: Free memory? - // FIXME: Can cc-status > 0 (CHOLMOD_NOT_POSDEF, CHOLMOD_DSMALL) occur? - } -# endif } #endif
--- a/liboctave/util/oct-sparse.h Wed Jan 06 17:13:54 2021 -0500 +++ b/liboctave/util/oct-sparse.h Thu Jan 07 00:19:21 2021 +0100 @@ -186,61 +186,36 @@ extern OCTAVE_API suitesparse_integer * to_suitesparse_intptr (octave_idx_type *i); - extern OCTAVE_API const suitesparse_integer * + extern const OCTAVE_API suitesparse_integer * to_suitesparse_intptr (const octave_idx_type *i); extern OCTAVE_API octave_idx_type* to_octave_idx_type_ptr (suitesparse_integer *i); - extern OCTAVE_API const octave_idx_type* + extern const OCTAVE_API octave_idx_type* to_octave_idx_type_ptr (const suitesparse_integer *i); -# if defined (HAVE_CHOLMOD) - // Convert real sparse octave matrix to real sparse cholmod matrix. - // Returns a "shallow" copy of a. - extern const OCTAVE_API cholmod_sparse - ros2rcs (const SparseMatrix& a); + inline octave_idx_type + from_suitesparse_long (SuiteSparse_long x) + { + if (x < std::numeric_limits<octave_idx_type>::min () + || x > std::numeric_limits<octave_idx_type>::max ()) + (*current_liboctave_error_handler) + ("integer dimension or index out of range for Octave's indexing type"); - // Convert real sparse cholmod matrix to real sparse octave matrix. - // Returns a "shallow" copy of y. - extern OCTAVE_API SparseMatrix - rcs2ros (const cholmod_sparse *y); - - // Convert real dense octave matrix to real dense cholmod matrix. - // Returns a "shallow" copy of a. - extern const OCTAVE_API cholmod_dense - rod2rcd (const MArray<double>& a); - - // Convert complex dense octave matrix to complex dense cholmod matrix. - // Returns a "shallow" copy of a. - extern const OCTAVE_API cholmod_dense - cod2ccd (const ComplexMatrix &a); + return static_cast<octave_idx_type> (x); + } - // Convert complex sparse octave matrix to complex sparse cholmod matrix. - // Returns a "shallow" copy of a. - extern const OCTAVE_API cholmod_sparse - cos2ccs (const SparseComplexMatrix &a); - - // Convert complex sparse cholmod matrix to complex sparse octave matrix. - // Returns a "deep" copy of a. - extern OCTAVE_API SparseComplexMatrix - ccs2cos (const cholmod_sparse *a); + inline octave_idx_type + from_size_t (size_t x) + { + // size_t is guaranteed to be unsigned + if (x > std::numeric_limits<octave_idx_type>::max ()) + (*current_liboctave_error_handler) + ("integer dimension or index out of range for Octave's index type"); - // Convert real sparse octave matrix to complex sparse cholmod matrix. - // Returns a "deep" copy of a. - // FIXME: const return type not necessary since deep copy is returned. - extern OCTAVE_API cholmod_sparse * - ros2ccs (const SparseMatrix& a, cholmod_common *cc1); - - // Convert real dense octave matrix to complex dense cholmod matrix. - // Returns a "deep" copy of a. - // FIXME: const return type not necessary since deep copy is returned. - extern OCTAVE_API cholmod_dense * - rod2ccd (const MArray<double> &a, cholmod_common *cc1); - - extern OCTAVE_API void - spqr_error_handler (const cholmod_common *cc); -# endif + return static_cast<octave_idx_type> (x); + } } #endif