26#if defined (HAVE_CONFIG_H)
46#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
48static constexpr bool octave_suitesparse_ptr_size_mismatch
51static constexpr bool suitesparse_integer_long_mismatch
55#if defined (HAVE_CXSPARSE)
56template <
typename SPARSE_T>
77template <
typename SPARSE_T>
82 sparse_qr_rep (
const SPARSE_T& a,
int order);
84 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (sparse_qr_rep)
90#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
91 return (m_H && m_Htau && m_HPinv && m_R && m_E);
92#elif defined (HAVE_CXSPARSE)
107 SPARSE_T
R (
bool econ)
const;
109 typename SPARSE_T::dense_matrix_type
110 C (
const typename SPARSE_T::dense_matrix_type& b,
bool econ =
false);
112 typename SPARSE_T::dense_matrix_type
Q (
bool econ =
false);
117#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
119 template <
typename RHS_T,
typename RET_T>
124#if defined (HAVE_CXSPARSE)
126 typename cxsparse_types<SPARSE_T>::symbolic_type *S;
127 typename cxsparse_types<SPARSE_T>::numeric_type *
N;
131 template <
typename RHS_T,
typename RET_T>
134 template <
typename RHS_T,
typename RET_T>
137#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
144 SuiteSparse_long *m_E;
146 cholmod_dense *m_Htau;
147 SuiteSparse_long *m_HPinv;
152template <
typename SPARSE_T>
156#if defined (HAVE_CXSPARSE)
161 ret.xelem (i) = S->pinv[i];
172template <
typename SPARSE_T>
176#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
186#elif defined (HAVE_CXSPARSE)
191 ret.xelem (S->pinv[i]) = i;
202template <
typename SPARSE_T>
206#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
219#elif defined (HAVE_CXSPARSE)
239#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
253 A.itype = CHOLMOD_LONG;
258 A.xtype = CHOLMOD_REAL;
259 A.dtype = CHOLMOD_DOUBLE;
262 if (! octave_suitesparse_ptr_size_mismatch)
264 A.p =
reinterpret_cast<SuiteSparse_long *
> (a.
cidx ());
265 A.i =
reinterpret_cast<SuiteSparse_long *
> (a.
ridx ());
269 SuiteSparse_long *A_p;
270 A_p =
new SuiteSparse_long[ncols+1];
274 SuiteSparse_long *A_i;
275 A_i =
new SuiteSparse_long[nnz];
280 A.x =
const_cast<double *
> (a.
data ());
297 A.itype = CHOLMOD_LONG;
302 A.xtype = CHOLMOD_COMPLEX;
303 A.dtype = CHOLMOD_DOUBLE;
306 if (! octave_suitesparse_ptr_size_mismatch)
308 A.p =
reinterpret_cast<SuiteSparse_long *
> (a.
cidx ());
309 A.i =
reinterpret_cast<SuiteSparse_long *
> (a.
ridx ());
313 SuiteSparse_long *A_p;
314 A_p =
new SuiteSparse_long[ncols+1];
318 SuiteSparse_long *A_i;
319 A_i =
new SuiteSparse_long[nnz];
332static cholmod_dense *
336 = cholmod_l_allocate_dense (a.
rows (), a.
cols (), a.
rows(),
337 CHOLMOD_COMPLEX, cc1);
339 const double *a_x = a.
data ();
343 A_x[j] =
Complex (a_x[j], 0.0);
358 A.xtype = CHOLMOD_REAL;
359 A.dtype = CHOLMOD_DOUBLE;
362 A.x =
const_cast<double *
> (a.
data ());
377 A.xtype = CHOLMOD_COMPLEX;
378 A.dtype = CHOLMOD_DOUBLE;
389crs2ors (cholmod_sparse *y,
const cholmod_common *cc1)
395 (cholmod_l_nnz (y,
const_cast<cholmod_common *
> (cc1)));
398 SuiteSparse_long *y_p =
reinterpret_cast<SuiteSparse_long *
> (y->p);
402 SuiteSparse_long *y_i =
reinterpret_cast<SuiteSparse_long *
> (y->i);
403 double *y_x =
reinterpret_cast<double *
> (y->x);
407 ret.xdata (j) = y_x[j];
416ccs2ocs (cholmod_sparse *a, cholmod_common *cc1)
423 SuiteSparse_long *a_p =
reinterpret_cast<SuiteSparse_long *
> (a->p);
427 SuiteSparse_long *a_i =
reinterpret_cast<SuiteSparse_long *
> (a->i);
432 ret.xdata(j) = a_x[j];
440static cholmod_sparse *
444 = cholmod_l_allocate_sparse (a.
rows (), a.
cols (), a.
nnz (), 0, 1, 0,
445 CHOLMOD_COMPLEX, cc);
448 SuiteSparse_long *A_p =
reinterpret_cast<SuiteSparse_long *
> (
A->p);
452 const double *a_x = a.
data ();
454 SuiteSparse_long *A_i =
reinterpret_cast<SuiteSparse_long *
> (
A->i);
457 A_x[j] =
Complex (a_x[j], 0.0);
465suitesparse_long_to_suitesparse_integer (SuiteSparse_long
x)
467 if (
x < std::numeric_limits<suitesparse_integer>::min ()
468 ||
x > std::numeric_limits<suitesparse_integer>::max ())
469 (*current_liboctave_error_handler)
470 (
"integer dimension or index out of range for SuiteSparse's indexing type");
477spqr_error_handler (
const cholmod_common *cc)
484 case CHOLMOD_OUT_OF_MEMORY:
485 (*current_liboctave_error_handler)
486 (
"sparse_qr: sparse matrix QR factorization failed"
488 case CHOLMOD_TOO_LARGE:
489 (*current_liboctave_error_handler)
490 (
"sparse_qr: sparse matrix QR factorization failed"
491 " - integer overflow occurred");
493 (*current_liboctave_error_handler)
494 (
"sparse_qr: sparse matrix QR factorization failed"
495 " - error %d", cc->status);
523 : nrows (a.rows ()), ncols (a.columns ())
524#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
525 , m_cc (), m_R (nullptr), m_E (nullptr), m_H (nullptr), m_Htau (nullptr),
531 if (nr < 0 || nc < 0)
532 (*current_liboctave_error_handler)
533 (
"matrix dimension with negative size");
535 if (order < 0 || order > 9)
536 (*current_liboctave_error_handler)
537 (
"ordering %d is not supported by SPQR", order);
539 cholmod_l_start (&m_cc);
540 cholmod_sparse
A = ors2crs (a);
542 SuiteSparseQR<double> (order,
static_cast<double> (SPQR_DEFAULT_TOL),
543 static_cast<SuiteSparse_long
> (
A.nrow),
544 &
A, &m_R, &m_E, &m_H, &m_HPinv, &m_Htau, &m_cc);
545 spqr_error_handler (&m_cc);
547 if (octave_suitesparse_ptr_size_mismatch)
549 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
550 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
554#elif defined (HAVE_CXSPARSE)
555 , S (
nullptr),
N (
nullptr)
568 A.
x = const_cast<
double *> (a.data ());
576 ("
sparse_qr: sparse matrix QR factorization filled");
583 octave_unused_parameter (order);
585 (*current_liboctave_error_handler)
586 (
"sparse_qr: support for SPQR or CXSparse was unavailable or disabled when liboctave was built");
594#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
596 cholmod_l_free_sparse (&m_R, &m_cc);
597 cholmod_l_free_sparse (&m_H, &m_cc);
598 cholmod_l_free_dense (&m_Htau, &m_cc);
601 cholmod_l_finish (&m_cc);
603#elif defined (HAVE_CXSPARSE)
615#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
617 return crs2ors (m_H, &m_cc);
619#elif defined (HAVE_CXSPARSE)
635 ret.xcidx (j) =
N->L->p[j];
639 ret.xridx (j) =
N->L->i[j];
640 ret.xdata (j) =
N->L->x[j];
656#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
662 (cholmod_l_nnz (m_R,
const_cast<cholmod_common *
> (&m_cc)));
665 SparseMatrix ret ((econ ? (nc > nr ? nr : nc) : nr), nc, nz);
666 SuiteSparse_long *Rp =
reinterpret_cast<SuiteSparse_long *
> (m_R->p);
667 SuiteSparse_long *Ri =
reinterpret_cast<SuiteSparse_long *
> (m_R->i);
675 ret.
xdata (j) = (
reinterpret_cast<double *
> (m_R->x))[j];
680#elif defined (HAVE_CXSPARSE)
694 SparseMatrix ret ((econ ? (nc > nrows ? nrows : nc) : nrows), nc, nz);
697 ret.
xcidx (j) =
N->U->p[j];
701 ret.
xridx (j) =
N->U->i[j];
702 ret.
xdata (j) =
N->U->x[j];
709 octave_unused_parameter (econ);
720#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
722 ? (ncols > nrows ? nrows : ncols)
729 (*current_liboctave_error_handler)
730 (
"sparse_qr: matrix dimension mismatch");
731 else if (b_nc < 0 || b_nr < 0)
732 (*current_liboctave_error_handler)
733 (
"sparse_qr: matrix dimension with negative size");
736 cholmod_dense
B = ord2crd (b);
738 QTB = SuiteSparseQR_qmult<double> (SPQR_QTX, m_H, m_Htau, m_HPinv, &
B,
740 spqr_error_handler (&m_cc);
743 double *QTB_x =
reinterpret_cast<double *
> (QTB->x);
744 double *ret_vec =
reinterpret_cast<double *
> (ret.rwdata ());
747 ret_vec[j * nr + i] = QTB_x[j * b_nr + i];
749 cholmod_l_free_dense (&QTB, &m_cc);
753#elif defined (HAVE_CXSPARSE)
756 (*current_liboctave_error_handler)
757 (
"sparse-qr: economy mode with CXSparse not supported");
765 const double *bvec = b.
data ();
768 double *vec = ret.rwdata ();
770 if (nr < 0 || nc < 0 || nr != b_nr)
771 (*current_liboctave_error_handler) (
"matrix dimension mismatch");
773 if (nr == 0 || nc == 0 || b_nc == 0)
774 ret =
Matrix (nc, b_nc, 0.0);
808 octave_unused_parameter (b);
809 octave_unused_parameter (econ);
820#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
823 ? (ncols > nrows ? nrows : ncols)
830 = cholmod_l_allocate_dense (nrows, nrows, nrows, CHOLMOD_REAL, &m_cc);
833 (
reinterpret_cast<double *
> (I_mat->x))[i] = 0.0;
836 (
reinterpret_cast<double *
> (I_mat->x))[i * nrows + i] = 1.0;
838 q = SuiteSparseQR_qmult<double> (SPQR_QX, m_H, m_Htau, m_HPinv, I_mat,
840 spqr_error_handler (&m_cc);
842 double *q_x =
reinterpret_cast<double *
> (q->x);
843 double *ret_vec =
const_cast<double *
> (ret.rwdata ());
846 ret_vec[j * nrows + i] = q_x[j * nrows + i];
848 cholmod_l_free_dense (&q, &m_cc);
849 cholmod_l_free_dense (&I_mat, &m_cc);
853#elif defined (HAVE_CXSPARSE)
856 (*current_liboctave_error_handler)
857 (
"sparse-qr: economy mode with CXSparse not supported");
862 double *ret_vec = ret.rwdata ();
864 if (nr < 0 || nc < 0)
865 (*current_liboctave_error_handler) (
"matrix dimension mismatch");
867 if (nr == 0 || nc == 0)
868 ret =
Matrix (nc, nr, 0.0);
898 ret_vec[i+idx] = buf[i];
908 octave_unused_parameter (econ);
923#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD) && defined (HAVE_CXSPARSE))
929 if (nrows < 0 || ncols < 0 || b_nc < 0 || b_nr < 0)
930 (*current_liboctave_error_handler)
931 (
"matrix dimension with negative size");
933 if (nrows < 0 || ncols < 0 || nrows != b_nr)
934 (*current_liboctave_error_handler) (
"matrix dimension mismatch");
937 cholmod_dense
B = ord2crd (b);
941 QTB = SuiteSparseQR_qmult<double> (SPQR_QTX, m_H, m_Htau, m_HPinv, &
B, &m_cc);
943 spqr_error_handler (&m_cc);
949 R2.nzmax = m_R->nzmax;
950 R2.x =
reinterpret_cast<double *
> (m_R->x);
953 if (! suitesparse_integer_long_mismatch)
961 SuiteSparse_long *R_p =
reinterpret_cast<SuiteSparse_long *
> (m_R->p);
963 R2_p[i] = suitesparse_long_to_suitesparse_integer (R_p[i]);
967 SuiteSparse_long *R_i =
reinterpret_cast<SuiteSparse_long *
> (m_R->i);
969 R2_i[i] = suitesparse_long_to_suitesparse_integer (R_i[i]);
973 double *x_vec =
const_cast<double *
> (
x.rwdata ());
975 if (suitesparse_integer_long_mismatch)
979 E[i] = suitesparse_long_to_suitesparse_integer (m_E[i]);
988 (&R2, &(
reinterpret_cast<double *
> (QTB->x)[j * b_nr]));
991 (E, &(
reinterpret_cast<double *
> (QTB->x)[j * b_nr]),
992 &x_vec[j * ncols], ncols);
995 if (suitesparse_integer_long_mismatch)
1001 cholmod_l_free_dense (&QTB, &m_cc);
1007#elif defined (HAVE_CXSPARSE)
1015 const double *bvec = b.data ();
1018 double *vec =
x.rwdata ();
1023 i++, idx+=nc, bidx+=b_nr)
1049 octave_unused_parameter (b);
1063#if defined (HAVE_CXSPARSE)
1074 const double *bvec = b.data ();
1077 double *vec =
x.rwdata ();
1084 i++, idx+=nc, bidx+=b_nr)
1109 octave_unused_parameter (b);
1124#if defined (HAVE_CXSPARSE)
1146 Xx[j] = b.
xelem (j, i);
1173 sz = (sz > 10 ? sz : 10) + x_nz;
1174 x.change_capacity (sz);
1192 octave_unused_parameter (b);
1207#if defined (HAVE_CXSPARSE)
1233 Xx[j] = b.
xelem (j, i);
1260 sz = (sz > 10 ? sz : 10) + x_nz;
1261 x.change_capacity (sz);
1275 x.maybe_compress ();
1281 octave_unused_parameter (b);
1296#if defined (HAVE_CXSPARSE)
1353 vec[j+idx] =
Complex (Xx[j], Xz[j]);
1362 octave_unused_parameter (b);
1377#if defined (HAVE_CXSPARSE)
1439 vec[j+idx] =
Complex (Xx[j], Xz[j]);
1448 octave_unused_parameter (b);
1460 : nrows (a.rows ()), ncols (a.columns ())
1461#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
1462 , m_cc (), m_R (nullptr), m_E (nullptr), m_H (nullptr),
1463 m_Htau (nullptr), m_HPinv (nullptr)
1468 if (nr < 0 || nc < 0)
1469 (*current_liboctave_error_handler)
1470 (
"matrix dimension with negative size");
1472 if (order < 0 || order > 9)
1473 (*current_liboctave_error_handler)
1474 (
"ordering %d is not supported by SPQR", order);
1476 cholmod_l_start (&m_cc);
1477 cholmod_sparse
A = ocs2ccs (a);
1479 SuiteSparseQR<Complex> (order,
static_cast<double> (SPQR_DEFAULT_TOL),
1480 static_cast<SuiteSparse_long
> (
A.nrow),
1481 &
A, &m_R, &m_E, &m_H,
1482 &m_HPinv, &m_Htau, &m_cc);
1483 spqr_error_handler (&m_cc);
1485 if (octave_suitesparse_ptr_size_mismatch)
1487 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
1488 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
1492#elif defined (HAVE_CXSPARSE)
1493 , S (
nullptr),
N (
nullptr)
1506 A.
x = const_cast<cs_complex_t *>
1507 (reinterpret_cast<const cs_complex_t *> (a.data ()));
1515 ("
sparse_qr: sparse matrix QR factorization filled");
1522 octave_unused_parameter (order);
1524 (*current_liboctave_error_handler)
1525 (
"sparse_qr: support for CXSparse was unavailable or disabled when liboctave was built");
1533#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
1535 cholmod_l_free_sparse (&m_R, &m_cc);
1536 cholmod_l_free_sparse (&m_H, &m_cc);
1537 cholmod_l_free_dense (&m_Htau, &m_cc);
1540 cholmod_l_finish (&m_cc);
1542#elif defined (HAVE_CXSPARSE)
1554#if defined (HAVE_CXSPARSE)
1569 ret.
xcidx (j) =
N->L->p[j];
1573 ret.
xridx (j) =
N->L->i[j];
1590#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
1596 (cholmod_l_nnz (m_R,
const_cast<cholmod_common *
> (&m_cc)));
1600 SuiteSparse_long *Rp =
reinterpret_cast<SuiteSparse_long *
> (m_R->p);
1601 SuiteSparse_long *Ri =
reinterpret_cast<SuiteSparse_long *
> (m_R->i);
1609 ret.
xdata (j) = (
reinterpret_cast<Complex *
> (m_R->x))[j];
1614#elif defined (HAVE_CXSPARSE)
1632 ret.
xcidx (j) =
N->U->p[j];
1636 ret.
xridx (j) =
N->U->i[j];
1644 octave_unused_parameter (econ);
1656#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
1660 ? (ncols > nrows ? nrows : ncols)
1667 (*current_liboctave_error_handler) (
"matrix dimension mismatch");
1669 if (b_nc < 0 || b_nr < 0)
1670 (*current_liboctave_error_handler)
1671 (
"matrix dimension with negative size");
1674 cholmod_dense
B = ocd2ccd (b);
1676 QTB = SuiteSparseQR_qmult<Complex> (SPQR_QTX, m_H, m_Htau, m_HPinv, &
B,
1678 spqr_error_handler (&m_cc);
1685 ret_vec[j * nr + i] = QTB_x[j * b_nr + i];
1687 cholmod_l_free_dense (&QTB, &m_cc);
1691#elif defined (HAVE_CXSPARSE)
1694 (*current_liboctave_error_handler)
1695 (
"sparse-qr: economy mode with CXSparse not supported");
1701 const cs_complex_t *bvec
1702 =
reinterpret_cast<const cs_complex_t *
> (b.
data ());
1706 if (nr < 0 || nc < 0 || nr != b_nr)
1707 (*current_liboctave_error_handler) (
"matrix dimension mismatch");
1709 if (nr == 0 || nc == 0 || b_nc == 0)
1724 reinterpret_cast<cs_complex_t *
> (buf),
1732 reinterpret_cast<cs_complex_t *
> (buf));
1736 vec[i+idx] = buf[i];
1744 octave_unused_parameter (b);
1745 octave_unused_parameter (econ);
1756#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
1759 ? (ncols > nrows ? nrows : ncols)
1765 cholmod_dense *I_mat
1766 =
reinterpret_cast<cholmod_dense *
>
1767 (cholmod_l_allocate_dense (nrows, nrows, nrows, CHOLMOD_COMPLEX, &m_cc));
1770 (
reinterpret_cast<Complex *
> (I_mat->x))[i] = 0.0;
1773 (
reinterpret_cast<Complex *
> (I_mat->x))[i * nrows + i] = 1.0;
1775 q = SuiteSparseQR_qmult<Complex> (SPQR_QX, m_H, m_Htau, m_HPinv, I_mat,
1777 spqr_error_handler (&m_cc);
1784 ret_vec[j * nrows + i] = q_x[j * nrows + i];
1786 cholmod_l_free_dense (&q, &m_cc);
1787 cholmod_l_free_dense (&I_mat, &m_cc);
1791#elif defined (HAVE_CXSPARSE)
1794 (*current_liboctave_error_handler)
1795 (
"sparse-qr: economy mode with CXSparse not supported");
1802 if (nr < 0 || nc < 0)
1803 (*current_liboctave_error_handler) (
"matrix dimension mismatch");
1805 if (nr == 0 || nc == 0)
1825 reinterpret_cast<cs_complex_t *
> (buf),
1833 reinterpret_cast<cs_complex_t *
> (buf));
1837 vec[i+idx] = buf[i];
1847 octave_unused_parameter (econ);
1863#if defined (HAVE_CXSPARSE)
1932 sz = (sz > 10 ? sz : 10) + x_nz;
1933 x.change_capacity (sz);
1951 octave_unused_parameter (b);
1967#if defined (HAVE_CXSPARSE)
2040 sz = (sz > 10 ? sz : 10) + x_nz;
2041 x.change_capacity (sz);
2055 x.maybe_compress ();
2061 octave_unused_parameter (b);
2077#if defined (HAVE_CXSPARSE)
2086 cs_complex_t *vec =
reinterpret_cast<cs_complex_t *
> (
x.rwdata ());
2096 Xx[j] = b.xelem (j, i);
2102 reinterpret_cast<cs_complex_t *
> (Xx),
2122 octave_unused_parameter (b);
2138#if defined (HAVE_CXSPARSE)
2150 cs_complex_t *vec =
reinterpret_cast<cs_complex_t *
> (
x.rwdata ());
2166 Xx[j] = b.xelem (j, i);
2171 CXSPARSE_ZNAME (_pvec) (S->q,
reinterpret_cast<cs_complex_t *
> (Xx),
2191 octave_unused_parameter (b);
2207#if defined (HAVE_CXSPARSE)
2229 Xx[j] = b.xelem (j, i);
2235 reinterpret_cast<cs_complex_t *
> (Xx),
2247 reinterpret_cast<cs_complex_t *
> (Xx),
2260 sz = (sz > 10 ? sz : 10) + x_nz;
2261 x.change_capacity (sz);
2275 x.maybe_compress ();
2281 octave_unused_parameter (b);
2297#if defined (HAVE_CXSPARSE)
2327 Xx[j] = b.xelem (j, i);
2333 reinterpret_cast<cs_complex_t *
> (Xx),
2345 reinterpret_cast<cs_complex_t *
> (Xx),
2358 sz = (sz > 10 ? sz : 10) + x_nz;
2359 x.change_capacity (sz);
2373 x.maybe_compress ();
2379 octave_unused_parameter (b);
2395#if defined (HAVE_CXSPARSE)
2403 const cs_complex_t *bvec =
reinterpret_cast<const cs_complex_t *
>
2407 cs_complex_t *vec =
reinterpret_cast<cs_complex_t *
>
2413 i++, idx+=nc, bidx+=b_nr)
2439 octave_unused_parameter (b);
2455#if defined (HAVE_CXSPARSE)
2466 const cs_complex_t *bvec =
reinterpret_cast<const cs_complex_t *
>
2470 cs_complex_t *vec =
reinterpret_cast<cs_complex_t *
> (
x.rwdata ());
2481 i++, idx+=nc, bidx+=b_nr)
2507 octave_unused_parameter (b);
2523#if defined (HAVE_CXSPARSE)
2545 Xx[j] = b.xelem (j, i);
2551 reinterpret_cast<cs_complex_t *
> (Xx),
2563 reinterpret_cast<cs_complex_t *
> (Xx),
2576 sz = (sz > 10 ? sz : 10) + x_nz;
2577 x.change_capacity (sz);
2591 x.maybe_compress ();
2597 octave_unused_parameter (b);
2613#if defined (HAVE_CXSPARSE)
2643 Xx[j] = b.xelem (j, i);
2648 CXSPARSE_ZNAME (_pvec) (S->q,
reinterpret_cast<cs_complex_t *
> (Xx),
2660 reinterpret_cast<cs_complex_t *
> (Xx), nc);
2672 sz = (sz > 10 ? sz : 10) + x_nz;
2673 x.change_capacity (sz);
2687 x.maybe_compress ();
2693 octave_unused_parameter (b);
2700template <
typename SPARSE_T>
2702 : m_rep (new sparse_qr_rep (SPARSE_T (), 0))
2705template <
typename SPARSE_T>
2707 : m_rep (new sparse_qr_rep (a, order))
2710template <
typename SPARSE_T>
2714 return m_rep->ok ();
2717template <
typename SPARSE_T>
2724template <
typename SPARSE_T>
2731template <
typename SPARSE_T>
2738template <
typename SPARSE_T>
2746template <
typename SPARSE_T>
2754 ret(perm(i) - 1, i) = 1.0;
2759template <
typename SPARSE_T>
2763 return m_rep->R (econ);
2766template <
typename SPARSE_T>
2767typename SPARSE_T::dense_matrix_type
2771 return m_rep->C (b, econ);
2774template <
typename SPARSE_T>
2775typename SPARSE_T::dense_matrix_type
2778 return m_rep->Q (econ);
2781#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
2796 cholmod_l_start (&cc);
2797 cholmod_sparse
A = ors2crs (a);
2798 cholmod_dense
B = ord2crd (b);
2801 X = SuiteSparseQR_min2norm<double> (order, SPQR_DEFAULT_TOL, &
A, &
B, &cc);
2802 spqr_error_handler (&cc);
2804 double *xdata =
x.rwdata ();
2806 xdata[i] =
reinterpret_cast<double *
> (X->x)[i];
2809 if (octave_suitesparse_ptr_size_mismatch)
2811 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
2812 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
2814 cholmod_l_free_dense (&X, &cc);
2815 cholmod_l_finish (&cc);
2831 cholmod_l_start (&cc);
2832 cholmod_sparse
A = ors2crs (a);
2833 cholmod_sparse
B = ors2crs (b);
2836 X = SuiteSparseQR_min2norm<double> (order, SPQR_DEFAULT_TOL, &
A, &
B, &cc);
2837 spqr_error_handler (&cc);
2839 x = crs2ors (X, &cc);
2842 if (octave_suitesparse_ptr_size_mismatch)
2844 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
2845 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
2846 delete []
reinterpret_cast<SuiteSparse_long *
> (
B.p);
2847 delete []
reinterpret_cast<SuiteSparse_long *
> (
B.i);
2849 cholmod_l_free_sparse (&X, &cc);
2850 cholmod_l_finish (&cc);
2868 cholmod_l_start (&cc);
2869 cholmod_sparse *
A = ors2ccs (a, &cc);
2870 cholmod_dense
B = ocd2ccd (b);
2873 X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL,
A, &
B, &cc);
2874 spqr_error_handler (&cc);
2878 xdata[i] =
reinterpret_cast<Complex *
> (X->x)[i];
2881 cholmod_l_free_sparse (&
A, &cc);
2882 cholmod_l_free_dense (&X, &cc);
2883 cholmod_l_finish (&cc);
2898 cholmod_l_start (&cc);
2899 cholmod_sparse *
A = ors2ccs (a, &cc);
2900 cholmod_sparse
B = ocs2ccs (b);
2903 X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL,
A, &
B, &cc);
2904 spqr_error_handler (&cc);
2909 if (octave_suitesparse_ptr_size_mismatch)
2911 delete []
reinterpret_cast<SuiteSparse_long *
> (
B.p);
2912 delete []
reinterpret_cast<SuiteSparse_long *
> (
B.i);
2914 cholmod_l_free_sparse (&
A, &cc);
2915 cholmod_l_free_sparse (&X, &cc);
2916 cholmod_l_finish (&cc);
2934 cholmod_l_start (&cc);
2935 cholmod_sparse
A = ocs2ccs (a);
2936 cholmod_dense
B = ocd2ccd (b);
2939 X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, &
A, &
B, &cc);
2940 spqr_error_handler (&cc);
2944 xdata[i] =
reinterpret_cast<Complex *
> (X->x)[i];
2947 if (octave_suitesparse_ptr_size_mismatch)
2949 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
2950 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
2952 cholmod_l_free_dense (&X, &cc);
2953 cholmod_l_finish (&cc);
2975 cholmod_l_start (&cc);
2976 cholmod_sparse
A = ocs2ccs (a);
2977 cholmod_dense *
B = ord2ccd (b, &cc);
2980 X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, &
A,
B, &cc);
2981 spqr_error_handler (&cc);
2985 xdata[i] =
reinterpret_cast<Complex *
> (X->x)[i];
2988 if (octave_suitesparse_ptr_size_mismatch)
2990 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
2991 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
2993 cholmod_l_free_dense (&
B, &cc);
2994 cholmod_l_free_dense (&X, &cc);
2995 cholmod_l_finish (&cc);
3010 cholmod_l_start (&cc);
3011 cholmod_sparse
A = ocs2ccs (a);
3012 cholmod_sparse
B = ocs2ccs (b);
3015 X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, &
A, &
B, &cc);
3016 spqr_error_handler (&cc);
3021 if (octave_suitesparse_ptr_size_mismatch)
3023 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
3024 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
3025 delete []
reinterpret_cast<SuiteSparse_long *
> (
B.p);
3026 delete []
reinterpret_cast<SuiteSparse_long *
> (
B.i);
3028 cholmod_l_free_sparse (&X, &cc);
3029 cholmod_l_finish (&cc);
3048 cholmod_l_start (&cc);
3049 cholmod_sparse
A = ocs2ccs (a);
3050 cholmod_sparse *
B = ors2ccs (b, &cc);
3053 X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, &
A,
B, &cc);
3054 spqr_error_handler (&cc);
3059 if (octave_suitesparse_ptr_size_mismatch)
3061 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
3062 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
3064 cholmod_l_free_sparse (&
B, &cc);
3065 cholmod_l_free_sparse (&X, &cc);
3066 cholmod_l_finish (&cc);
3077template <
typename SPARSE_T>
3078class cxsparse_defaults
3081 enum { order = -1 };
3088#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
3089 enum { order = SPQR_ORDERING_DEFAULT };
3090#elif defined (HAVE_CXSPARSE)
3099#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
3100 enum { order = SPQR_ORDERING_DEFAULT };
3101#elif defined (HAVE_CXSPARSE)
3106template <
typename SPARSE_T>
3107template <
typename RHS_T,
typename RET_T>
3112#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
3122 int order = cxsparse_defaults<SPARSE_T>::order;
3124 if (nr < 0 || nc < 0 || b_nc < 0 || b_nr < 0)
3125 (*current_liboctave_error_handler)
3126 (
"matrix dimension with negative size");
3129 (*current_liboctave_error_handler)
3130 (
"matrix dimension mismatch in solution of minimum norm problem");
3134 return min2norm_solve<RHS_T, RET_T> (a, b, info, order);
3136#elif defined (HAVE_CXSPARSE)
3146 int order = cxsparse_defaults<SPARSE_T>::order;
3148 if (nr < 0 || nc < 0 || nr != b_nr)
3149 (*current_liboctave_error_handler)
3150 (
"matrix dimension mismatch in solution of minimum norm problem");
3152 if (nr == 0 || nc == 0 || b_nc == 0)
3156 return RET_T (nc, b_nc, 0.0);
3162 return q.
ok () ? q.tall_solve<RHS_T, RET_T> (b, info) : RET_T ();
3168 return q.
ok () ? q.wide_solve<RHS_T, RET_T> (b, info) : RET_T ();
3173 octave_unused_parameter (a);
3174 octave_unused_parameter (b);
3175 octave_unused_parameter (info);
3238template <
typename SPARSE_T>
3239template <
typename RHS_T,
typename RET_T>
3243 return m_rep->template tall_solve<RHS_T, RET_T> (b, info);
3246template <
typename SPARSE_T>
3247template <
typename RHS_T,
typename RET_T>
3251 return m_rep->template wide_solve<RHS_T, RET_T> (b, info);
3356OCTAVE_END_NAMESPACE(math)
3357OCTAVE_END_NAMESPACE(octave)
octave_idx_type rows() const
octave_idx_type cols() const
const T * data() const
Size of the specified dimension.
Template for N-dimensional array classes with like-type math operators.
SparseComplexMatrix hermitian() const
SparseMatrix transpose() const
octave_idx_type cols() const
octave_idx_type nnz() const
Actual number of nonzero terms.
octave_idx_type rows() const
T & xelem(octave_idx_type n)
octave_idx_type * xcidx()
octave_idx_type * xridx()
SPARSE_T R(bool econ=false) const
SparseMatrix E_MAT() const
SPARSE_T::dense_matrix_type Q(bool econ=false) const
SPARSE_T::dense_matrix_type C(const typename SPARSE_T::dense_matrix_type &b, bool econ=false) const
static RET_T solve(const SPARSE_T &a, const RHS_T &b, octave_idx_type &info)
ColumnVector Pinv() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
F77_RET_T const F77_INT F77_CMPLX const F77_INT F77_CMPLX * B
F77_RET_T const F77_INT const F77_INT const F77_INT F77_DBLE const F77_INT F77_DBLE const F77_INT F77_DBLE * Q
F77_RET_T const F77_INT F77_CMPLX * A
F77_RET_T const F77_INT & N
F77_RET_T const F77_DBLE * x
std::complex< double > Complex
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
suitesparse_integer * to_suitesparse_intptr(octave_idx_type *i)
#define CXSPARSE_DNAME(name)
#define CXSPARSE_ZNAME(name)
octave_idx_type from_suitesparse_long(SuiteSparse_long x)
octave_idx_type from_size_t(std::size_t x)
Matrix qrsolve(const SparseMatrix &a, const MArray< double > &b, octave_idx_type &info)