26#if defined (HAVE_CONFIG_H)
45#if defined (HAVE_CXSPARSE)
46template <
typename SPARSE_T>
67template <
typename SPARSE_T>
72 sparse_qr_rep (
const SPARSE_T& a,
int order);
74 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (sparse_qr_rep)
80#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
81 return (m_H && m_Htau && m_HPinv && m_R && m_E);
82#elif defined (HAVE_CXSPARSE)
97 SPARSE_T
R (
bool econ)
const;
99 typename SPARSE_T::dense_matrix_type
100 C (
const typename SPARSE_T::dense_matrix_type& b,
bool econ =
false);
102 typename SPARSE_T::dense_matrix_type
Q (
bool econ =
false);
107#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
109 template <
typename RHS_T,
typename RET_T>
114#if defined (HAVE_CXSPARSE)
116 typename cxsparse_types<SPARSE_T>::symbolic_type *S;
117 typename cxsparse_types<SPARSE_T>::numeric_type *
N;
121 template <
typename RHS_T,
typename RET_T>
124 template <
typename RHS_T,
typename RET_T>
127#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
134 SuiteSparse_long *m_E;
136 cholmod_dense *m_Htau;
137 SuiteSparse_long *m_HPinv;
142template <
typename SPARSE_T>
146#if defined (HAVE_CXSPARSE)
151 ret.xelem (i) = S->pinv[i];
162template <
typename SPARSE_T>
166#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
176#elif defined (HAVE_CXSPARSE)
181 ret.xelem (S->pinv[i]) = i;
192template <
typename SPARSE_T>
196#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
209#elif defined (HAVE_CXSPARSE)
229#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
243 A.itype = CHOLMOD_LONG;
248 A.xtype = CHOLMOD_REAL;
249 A.dtype = CHOLMOD_DOUBLE;
253# if defined (OCTAVE_SUITESPARSE_LONG_MATCH)
254 A.p =
reinterpret_cast<SuiteSparse_long *
> (a.
cidx ());
255 A.i =
reinterpret_cast<SuiteSparse_long *
> (a.
ridx ());
257 SuiteSparse_long *A_p;
258 A_p =
new SuiteSparse_long[ncols+1];
263 SuiteSparse_long *A_i;
264 A_i =
new SuiteSparse_long[nnz];
270 A.x =
const_cast<double *
> (a.
data ());
287 A.itype = CHOLMOD_LONG;
292 A.xtype = CHOLMOD_COMPLEX;
293 A.dtype = CHOLMOD_DOUBLE;
297# if defined (OCTAVE_SUITESPARSE_LONG_MATCH)
298 A.p =
reinterpret_cast<SuiteSparse_long *
> (a.
cidx ());
299 A.i =
reinterpret_cast<SuiteSparse_long *
> (a.
ridx ());
301 SuiteSparse_long *A_p;
302 A_p =
new SuiteSparse_long[ncols+1];
307 SuiteSparse_long *A_i;
308 A_i =
new SuiteSparse_long[nnz];
322static cholmod_dense *
326 = cholmod_l_allocate_dense (a.
rows (), a.
cols (), a.
rows(),
327 CHOLMOD_COMPLEX, cc1);
329 const double *a_x = a.
data ();
333 A_x[j] =
Complex (a_x[j], 0.0);
348 A.xtype = CHOLMOD_REAL;
349 A.dtype = CHOLMOD_DOUBLE;
352 A.x =
const_cast<double *
> (a.
data ());
367 A.xtype = CHOLMOD_COMPLEX;
368 A.dtype = CHOLMOD_DOUBLE;
379crs2ors (cholmod_sparse *y,
const cholmod_common *cc1)
385 (cholmod_l_nnz (y,
const_cast<cholmod_common *
> (cc1)));
388 SuiteSparse_long *y_p =
reinterpret_cast<SuiteSparse_long *
> (y->p);
392 SuiteSparse_long *y_i =
reinterpret_cast<SuiteSparse_long *
> (y->i);
393 double *y_x =
reinterpret_cast<double *
> (y->x);
397 ret.xdata (j) = y_x[j];
406ccs2ocs (cholmod_sparse *a, cholmod_common *cc1)
413 SuiteSparse_long *a_p =
reinterpret_cast<SuiteSparse_long *
> (a->p);
417 SuiteSparse_long *a_i =
reinterpret_cast<SuiteSparse_long *
> (a->i);
422 ret.xdata(j) = a_x[j];
430static cholmod_sparse *
434 = cholmod_l_allocate_sparse (a.
rows (), a.
cols (), a.
nnz (), 0, 1, 0,
435 CHOLMOD_COMPLEX, cc);
438 SuiteSparse_long *A_p =
reinterpret_cast<SuiteSparse_long *
> (
A->p);
442 const double *a_x = a.
data ();
444 SuiteSparse_long *A_i =
reinterpret_cast<SuiteSparse_long *
> (
A->i);
447 A_x[j] =
Complex (a_x[j], 0.0);
453#if defined (HAVE_CXSPARSE) && ! defined (OCTAVE_SUITESPARSE_INTEGER_MATCH)
455suitesparse_long_to_suitesparse_integer (SuiteSparse_long
x)
457 if (
x < std::numeric_limits<suitesparse_integer>::min ()
458 ||
x > std::numeric_limits<suitesparse_integer>::max ())
459 (*current_liboctave_error_handler)
460 (
"integer dimension or index out of range for SuiteSparse's indexing type");
467spqr_error_handler (
const cholmod_common *cc)
474 case CHOLMOD_OUT_OF_MEMORY:
475 (*current_liboctave_error_handler)
476 (
"sparse_qr: sparse matrix QR factorization failed"
478 case CHOLMOD_TOO_LARGE:
479 (*current_liboctave_error_handler)
480 (
"sparse_qr: sparse matrix QR factorization failed"
481 " - integer overflow occurred");
483 (*current_liboctave_error_handler)
484 (
"sparse_qr: sparse matrix QR factorization failed"
485 " - error %d", cc->status);
513 : nrows (a.rows ()), ncols (a.columns ())
514#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
515 , m_cc (), m_R (nullptr), m_E (nullptr), m_H (nullptr), m_Htau (nullptr),
521 if (nr < 0 || nc < 0)
522 (*current_liboctave_error_handler)
523 (
"matrix dimension with negative size");
525 if (order < 0 || order > 9)
526 (*current_liboctave_error_handler)
527 (
"ordering %d is not supported by SPQR", order);
529 cholmod_l_start (&m_cc);
530 cholmod_sparse
A = ors2crs (a);
532 SuiteSparseQR<double> (order,
static_cast<double> (SPQR_DEFAULT_TOL),
533 static_cast<SuiteSparse_long
> (
A.nrow),
534 &
A, &m_R, &m_E, &m_H, &m_HPinv, &m_Htau, &m_cc);
535 spqr_error_handler (&m_cc);
537# if ! defined (OCTAVE_SUITESPARSE_LONG_MATCH)
538 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
539 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
543#elif defined (HAVE_CXSPARSE)
544 , S (
nullptr),
N (
nullptr)
557 A.
x = const_cast<
double *> (a.data ());
565 ("
sparse_qr: sparse matrix QR factorization filled");
572 octave_unused_parameter (order);
574 (*current_liboctave_error_handler)
575 (
"sparse_qr: support for SPQR or CXSparse was unavailable or disabled when liboctave was built");
583#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
585 cholmod_l_free_sparse (&m_R, &m_cc);
586 cholmod_l_free_sparse (&m_H, &m_cc);
587 cholmod_l_free_dense (&m_Htau, &m_cc);
590 cholmod_l_finish (&m_cc);
592#elif defined (HAVE_CXSPARSE)
604#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
606 return crs2ors (m_H, &m_cc);
608#elif defined (HAVE_CXSPARSE)
624 ret.xcidx (j) =
N->L->p[j];
628 ret.xridx (j) =
N->L->i[j];
629 ret.xdata (j) =
N->L->x[j];
645#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
651 (cholmod_l_nnz (m_R,
const_cast<cholmod_common *
> (&m_cc)));
654 SparseMatrix ret ((econ ? (nc > nr ? nr : nc) : nr), nc, nz);
655 SuiteSparse_long *Rp =
reinterpret_cast<SuiteSparse_long *
> (m_R->p);
656 SuiteSparse_long *Ri =
reinterpret_cast<SuiteSparse_long *
> (m_R->i);
664 ret.
xdata (j) = (
reinterpret_cast<double *
> (m_R->x))[j];
669#elif defined (HAVE_CXSPARSE)
683 SparseMatrix ret ((econ ? (nc > nrows ? nrows : nc) : nrows), nc, nz);
686 ret.
xcidx (j) =
N->U->p[j];
690 ret.
xridx (j) =
N->U->i[j];
691 ret.
xdata (j) =
N->U->x[j];
698 octave_unused_parameter (econ);
709#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
711 ? (ncols > nrows ? nrows : ncols)
718 (*current_liboctave_error_handler)
719 (
"sparse_qr: matrix dimension mismatch");
720 else if (b_nc < 0 || b_nr < 0)
721 (*current_liboctave_error_handler)
722 (
"sparse_qr: matrix dimension with negative size");
725 cholmod_dense
B = ord2crd (b);
727 QTB = SuiteSparseQR_qmult<double> (SPQR_QTX, m_H, m_Htau, m_HPinv, &
B,
729 spqr_error_handler (&m_cc);
732 double *QTB_x =
reinterpret_cast<double *
> (QTB->x);
733 double *ret_vec =
reinterpret_cast<double *
> (ret.rwdata ());
736 ret_vec[j * nr + i] = QTB_x[j * b_nr + i];
738 cholmod_l_free_dense (&QTB, &m_cc);
742#elif defined (HAVE_CXSPARSE)
745 (*current_liboctave_error_handler)
746 (
"sparse-qr: economy mode with CXSparse not supported");
754 const double *bvec = b.
data ();
757 double *vec = ret.rwdata ();
759 if (nr < 0 || nc < 0 || nr != b_nr)
760 (*current_liboctave_error_handler) (
"matrix dimension mismatch");
762 if (nr == 0 || nc == 0 || b_nc == 0)
763 ret =
Matrix (nc, b_nc, 0.0);
797 octave_unused_parameter (b);
798 octave_unused_parameter (econ);
809#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
812 ? (ncols > nrows ? nrows : ncols)
819 = cholmod_l_allocate_dense (nrows, nrows, nrows, CHOLMOD_REAL, &m_cc);
822 (
reinterpret_cast<double *
> (I_mat->x))[i] = 0.0;
825 (
reinterpret_cast<double *
> (I_mat->x))[i * nrows + i] = 1.0;
827 q = SuiteSparseQR_qmult<double> (SPQR_QX, m_H, m_Htau, m_HPinv, I_mat,
829 spqr_error_handler (&m_cc);
831 double *q_x =
reinterpret_cast<double *
> (q->x);
832 double *ret_vec =
const_cast<double *
> (ret.rwdata ());
835 ret_vec[j * nrows + i] = q_x[j * nrows + i];
837 cholmod_l_free_dense (&q, &m_cc);
838 cholmod_l_free_dense (&I_mat, &m_cc);
842#elif defined (HAVE_CXSPARSE)
845 (*current_liboctave_error_handler)
846 (
"sparse-qr: economy mode with CXSparse not supported");
851 double *ret_vec = ret.rwdata ();
853 if (nr < 0 || nc < 0)
854 (*current_liboctave_error_handler) (
"matrix dimension mismatch");
856 if (nr == 0 || nc == 0)
857 ret =
Matrix (nc, nr, 0.0);
887 ret_vec[i+idx] = buf[i];
897 octave_unused_parameter (econ);
912#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD) && defined (HAVE_CXSPARSE))
918 if (nrows < 0 || ncols < 0 || b_nc < 0 || b_nr < 0)
919 (*current_liboctave_error_handler)
920 (
"matrix dimension with negative size");
922 if (nrows < 0 || ncols < 0 || nrows != b_nr)
923 (*current_liboctave_error_handler) (
"matrix dimension mismatch");
926 cholmod_dense
B = ord2crd (b);
930 QTB = SuiteSparseQR_qmult<double> (SPQR_QTX, m_H, m_Htau, m_HPinv, &
B, &m_cc);
932 spqr_error_handler (&m_cc);
938 R2.nzmax = m_R->nzmax;
939 R2.x =
reinterpret_cast<double *
> (m_R->x);
940# if defined (OCTAVE_SUITESPARSE_INTEGER_MATCH)
946 SuiteSparse_long *R_p =
reinterpret_cast<SuiteSparse_long *
> (m_R->p);
948 R2_p[i] = suitesparse_long_to_suitesparse_integer (R_p[i]);
954 SuiteSparse_long *R_i =
reinterpret_cast<SuiteSparse_long *
> (m_R->i);
956 R2_i[i] = suitesparse_long_to_suitesparse_integer (R_i[i]);
960 double *x_vec =
const_cast<double *
> (
x.rwdata ());
962# if defined (OCTAVE_SUITESPARSE_INTEGER_MATCH)
967 E[i] = suitesparse_long_to_suitesparse_integer (m_E[i]);
974 (&R2, &(
reinterpret_cast<double *
> (QTB->x)[j * b_nr]));
977 (E, &(
reinterpret_cast<double *
> (QTB->x)[j * b_nr]),
978 &x_vec[j * ncols], ncols);
981# if ! defined (OCTAVE_SUITESPARSE_INTEGER_MATCH)
986 cholmod_l_free_dense (&QTB, &m_cc);
992#elif defined (HAVE_CXSPARSE)
1000 const double *bvec = b.data ();
1003 double *vec =
x.rwdata ();
1008 i++, idx+=nc, bidx+=b_nr)
1034 octave_unused_parameter (b);
1048#if defined (HAVE_CXSPARSE)
1059 const double *bvec = b.data ();
1062 double *vec =
x.rwdata ();
1069 i++, idx+=nc, bidx+=b_nr)
1094 octave_unused_parameter (b);
1109#if defined (HAVE_CXSPARSE)
1131 Xx[j] = b.
xelem (j, i);
1158 sz = (sz > 10 ? sz : 10) + x_nz;
1159 x.change_capacity (sz);
1177 octave_unused_parameter (b);
1192#if defined (HAVE_CXSPARSE)
1218 Xx[j] = b.
xelem (j, i);
1245 sz = (sz > 10 ? sz : 10) + x_nz;
1246 x.change_capacity (sz);
1260 x.maybe_compress ();
1266 octave_unused_parameter (b);
1281#if defined (HAVE_CXSPARSE)
1338 vec[j+idx] =
Complex (Xx[j], Xz[j]);
1347 octave_unused_parameter (b);
1362#if defined (HAVE_CXSPARSE)
1424 vec[j+idx] =
Complex (Xx[j], Xz[j]);
1433 octave_unused_parameter (b);
1445 : nrows (a.rows ()), ncols (a.columns ())
1446#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
1447 , m_cc (), m_R (nullptr), m_E (nullptr), m_H (nullptr),
1448 m_Htau (nullptr), m_HPinv (nullptr)
1453 if (nr < 0 || nc < 0)
1454 (*current_liboctave_error_handler)
1455 (
"matrix dimension with negative size");
1457 if (order < 0 || order > 9)
1458 (*current_liboctave_error_handler)
1459 (
"ordering %d is not supported by SPQR", order);
1461 cholmod_l_start (&m_cc);
1462 cholmod_sparse
A = ocs2ccs (a);
1464 SuiteSparseQR<Complex> (order,
static_cast<double> (SPQR_DEFAULT_TOL),
1465 static_cast<SuiteSparse_long
> (
A.nrow),
1466 &
A, &m_R, &m_E, &m_H,
1467 &m_HPinv, &m_Htau, &m_cc);
1468 spqr_error_handler (&m_cc);
1470# if ! defined (OCTAVE_SUITESPARSE_LONG_MATCH)
1471 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
1472 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
1476#elif defined (HAVE_CXSPARSE)
1477 , S (
nullptr),
N (
nullptr)
1490 A.
x = const_cast<cs_complex_t *>
1491 (reinterpret_cast<const cs_complex_t *> (a.data ()));
1499 ("
sparse_qr: sparse matrix QR factorization filled");
1506 octave_unused_parameter (order);
1508 (*current_liboctave_error_handler)
1509 (
"sparse_qr: support for CXSparse was unavailable or disabled when liboctave was built");
1517#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
1519 cholmod_l_free_sparse (&m_R, &m_cc);
1520 cholmod_l_free_sparse (&m_H, &m_cc);
1521 cholmod_l_free_dense (&m_Htau, &m_cc);
1524 cholmod_l_finish (&m_cc);
1526#elif defined (HAVE_CXSPARSE)
1538#if defined (HAVE_CXSPARSE)
1553 ret.
xcidx (j) =
N->L->p[j];
1557 ret.
xridx (j) =
N->L->i[j];
1574#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
1580 (cholmod_l_nnz (m_R,
const_cast<cholmod_common *
> (&m_cc)));
1584 SuiteSparse_long *Rp =
reinterpret_cast<SuiteSparse_long *
> (m_R->p);
1585 SuiteSparse_long *Ri =
reinterpret_cast<SuiteSparse_long *
> (m_R->i);
1593 ret.
xdata (j) = (
reinterpret_cast<Complex *
> (m_R->x))[j];
1598#elif defined (HAVE_CXSPARSE)
1616 ret.
xcidx (j) =
N->U->p[j];
1620 ret.
xridx (j) =
N->U->i[j];
1628 octave_unused_parameter (econ);
1640#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
1644 ? (ncols > nrows ? nrows : ncols)
1651 (*current_liboctave_error_handler) (
"matrix dimension mismatch");
1653 if (b_nc < 0 || b_nr < 0)
1654 (*current_liboctave_error_handler)
1655 (
"matrix dimension with negative size");
1658 cholmod_dense
B = ocd2ccd (b);
1660 QTB = SuiteSparseQR_qmult<Complex> (SPQR_QTX, m_H, m_Htau, m_HPinv, &
B,
1662 spqr_error_handler (&m_cc);
1669 ret_vec[j * nr + i] = QTB_x[j * b_nr + i];
1671 cholmod_l_free_dense (&QTB, &m_cc);
1675#elif defined (HAVE_CXSPARSE)
1678 (*current_liboctave_error_handler)
1679 (
"sparse-qr: economy mode with CXSparse not supported");
1685 const cs_complex_t *bvec
1686 =
reinterpret_cast<const cs_complex_t *
> (b.
data ());
1690 if (nr < 0 || nc < 0 || nr != b_nr)
1691 (*current_liboctave_error_handler) (
"matrix dimension mismatch");
1693 if (nr == 0 || nc == 0 || b_nc == 0)
1708 reinterpret_cast<cs_complex_t *
> (buf),
1716 reinterpret_cast<cs_complex_t *
> (buf));
1720 vec[i+idx] = buf[i];
1728 octave_unused_parameter (b);
1729 octave_unused_parameter (econ);
1740#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
1743 ? (ncols > nrows ? nrows : ncols)
1749 cholmod_dense *I_mat
1750 =
reinterpret_cast<cholmod_dense *
>
1751 (cholmod_l_allocate_dense (nrows, nrows, nrows, CHOLMOD_COMPLEX, &m_cc));
1754 (
reinterpret_cast<Complex *
> (I_mat->x))[i] = 0.0;
1757 (
reinterpret_cast<Complex *
> (I_mat->x))[i * nrows + i] = 1.0;
1759 q = SuiteSparseQR_qmult<Complex> (SPQR_QX, m_H, m_Htau, m_HPinv, I_mat,
1761 spqr_error_handler (&m_cc);
1768 ret_vec[j * nrows + i] = q_x[j * nrows + i];
1770 cholmod_l_free_dense (&q, &m_cc);
1771 cholmod_l_free_dense (&I_mat, &m_cc);
1775#elif defined (HAVE_CXSPARSE)
1778 (*current_liboctave_error_handler)
1779 (
"sparse-qr: economy mode with CXSparse not supported");
1786 if (nr < 0 || nc < 0)
1787 (*current_liboctave_error_handler) (
"matrix dimension mismatch");
1789 if (nr == 0 || nc == 0)
1809 reinterpret_cast<cs_complex_t *
> (buf),
1817 reinterpret_cast<cs_complex_t *
> (buf));
1821 vec[i+idx] = buf[i];
1831 octave_unused_parameter (econ);
1847#if defined (HAVE_CXSPARSE)
1916 sz = (sz > 10 ? sz : 10) + x_nz;
1917 x.change_capacity (sz);
1935 octave_unused_parameter (b);
1951#if defined (HAVE_CXSPARSE)
2024 sz = (sz > 10 ? sz : 10) + x_nz;
2025 x.change_capacity (sz);
2039 x.maybe_compress ();
2045 octave_unused_parameter (b);
2061#if defined (HAVE_CXSPARSE)
2070 cs_complex_t *vec =
reinterpret_cast<cs_complex_t *
> (
x.rwdata ());
2080 Xx[j] = b.xelem (j, i);
2086 reinterpret_cast<cs_complex_t *
> (Xx),
2106 octave_unused_parameter (b);
2122#if defined (HAVE_CXSPARSE)
2134 cs_complex_t *vec =
reinterpret_cast<cs_complex_t *
> (
x.rwdata ());
2150 Xx[j] = b.xelem (j, i);
2155 CXSPARSE_ZNAME (_pvec) (S->q,
reinterpret_cast<cs_complex_t *
> (Xx),
2175 octave_unused_parameter (b);
2191#if defined (HAVE_CXSPARSE)
2213 Xx[j] = b.xelem (j, i);
2219 reinterpret_cast<cs_complex_t *
> (Xx),
2231 reinterpret_cast<cs_complex_t *
> (Xx),
2244 sz = (sz > 10 ? sz : 10) + x_nz;
2245 x.change_capacity (sz);
2259 x.maybe_compress ();
2265 octave_unused_parameter (b);
2281#if defined (HAVE_CXSPARSE)
2311 Xx[j] = b.xelem (j, i);
2317 reinterpret_cast<cs_complex_t *
> (Xx),
2329 reinterpret_cast<cs_complex_t *
> (Xx),
2342 sz = (sz > 10 ? sz : 10) + x_nz;
2343 x.change_capacity (sz);
2357 x.maybe_compress ();
2363 octave_unused_parameter (b);
2379#if defined (HAVE_CXSPARSE)
2387 const cs_complex_t *bvec =
reinterpret_cast<const cs_complex_t *
>
2391 cs_complex_t *vec =
reinterpret_cast<cs_complex_t *
>
2397 i++, idx+=nc, bidx+=b_nr)
2423 octave_unused_parameter (b);
2439#if defined (HAVE_CXSPARSE)
2450 const cs_complex_t *bvec =
reinterpret_cast<const cs_complex_t *
>
2454 cs_complex_t *vec =
reinterpret_cast<cs_complex_t *
> (
x.rwdata ());
2465 i++, idx+=nc, bidx+=b_nr)
2491 octave_unused_parameter (b);
2507#if defined (HAVE_CXSPARSE)
2529 Xx[j] = b.xelem (j, i);
2535 reinterpret_cast<cs_complex_t *
> (Xx),
2547 reinterpret_cast<cs_complex_t *
> (Xx),
2560 sz = (sz > 10 ? sz : 10) + x_nz;
2561 x.change_capacity (sz);
2575 x.maybe_compress ();
2581 octave_unused_parameter (b);
2597#if defined (HAVE_CXSPARSE)
2627 Xx[j] = b.xelem (j, i);
2632 CXSPARSE_ZNAME (_pvec) (S->q,
reinterpret_cast<cs_complex_t *
> (Xx),
2644 reinterpret_cast<cs_complex_t *
> (Xx), nc);
2656 sz = (sz > 10 ? sz : 10) + x_nz;
2657 x.change_capacity (sz);
2671 x.maybe_compress ();
2677 octave_unused_parameter (b);
2684template <
typename SPARSE_T>
2686 : m_rep (new sparse_qr_rep (SPARSE_T (), 0))
2689template <
typename SPARSE_T>
2691 : m_rep (new sparse_qr_rep (a, order))
2694template <
typename SPARSE_T>
2698 return m_rep->ok ();
2701template <
typename SPARSE_T>
2708template <
typename SPARSE_T>
2715template <
typename SPARSE_T>
2722template <
typename SPARSE_T>
2730template <
typename SPARSE_T>
2738 ret(perm(i) - 1, i) = 1.0;
2743template <
typename SPARSE_T>
2747 return m_rep->R (econ);
2750template <
typename SPARSE_T>
2751typename SPARSE_T::dense_matrix_type
2755 return m_rep->C (b, econ);
2758template <
typename SPARSE_T>
2759typename SPARSE_T::dense_matrix_type
2762 return m_rep->Q (econ);
2765#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
2780 cholmod_l_start (&cc);
2781 cholmod_sparse
A = ors2crs (a);
2782 cholmod_dense
B = ord2crd (b);
2785 X = SuiteSparseQR_min2norm<double> (order, SPQR_DEFAULT_TOL, &
A, &
B, &cc);
2786 spqr_error_handler (&cc);
2788 double *xdata =
x.rwdata ();
2790 xdata[i] =
reinterpret_cast<double *
> (X->x)[i];
2793# if ! defined (OCTAVE_SUITESPARSE_LONG_MATCH)
2794 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
2795 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
2797 cholmod_l_free_dense (&X, &cc);
2798 cholmod_l_finish (&cc);
2814 cholmod_l_start (&cc);
2815 cholmod_sparse
A = ors2crs (a);
2816 cholmod_sparse
B = ors2crs (b);
2819 X = SuiteSparseQR_min2norm<double> (order, SPQR_DEFAULT_TOL, &
A, &
B, &cc);
2820 spqr_error_handler (&cc);
2822 x = crs2ors (X, &cc);
2825 #if ! defined (OCTAVE_SUITESPARSE_LONG_MATCH)
2826 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
2827 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
2828 delete []
reinterpret_cast<SuiteSparse_long *
> (
B.p);
2829 delete []
reinterpret_cast<SuiteSparse_long *
> (
B.i);
2831 cholmod_l_free_sparse (&X, &cc);
2832 cholmod_l_finish (&cc);
2850 cholmod_l_start (&cc);
2851 cholmod_sparse *
A = ors2ccs (a, &cc);
2852 cholmod_dense
B = ocd2ccd (b);
2855 X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL,
A, &
B, &cc);
2856 spqr_error_handler (&cc);
2860 xdata[i] =
reinterpret_cast<Complex *
> (X->x)[i];
2863 cholmod_l_free_sparse (&
A, &cc);
2864 cholmod_l_free_dense (&X, &cc);
2865 cholmod_l_finish (&cc);
2880 cholmod_l_start (&cc);
2881 cholmod_sparse *
A = ors2ccs (a, &cc);
2882 cholmod_sparse
B = ocs2ccs (b);
2885 X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL,
A, &
B, &cc);
2886 spqr_error_handler (&cc);
2891# if ! defined (OCTAVE_SUITESPARSE_LONG_MATCH)
2892 delete []
reinterpret_cast<SuiteSparse_long *
> (
B.p);
2893 delete []
reinterpret_cast<SuiteSparse_long *
> (
B.i);
2895 cholmod_l_free_sparse (&
A, &cc);
2896 cholmod_l_free_sparse (&X, &cc);
2897 cholmod_l_finish (&cc);
2915 cholmod_l_start (&cc);
2916 cholmod_sparse
A = ocs2ccs (a);
2917 cholmod_dense
B = ocd2ccd (b);
2920 X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, &
A, &
B, &cc);
2921 spqr_error_handler (&cc);
2925 xdata[i] =
reinterpret_cast<Complex *
> (X->x)[i];
2928# if ! defined (OCTAVE_SUITESPARSE_LONG_MATCH)
2929 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
2930 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
2932 cholmod_l_free_dense (&X, &cc);
2933 cholmod_l_finish (&cc);
2955 cholmod_l_start (&cc);
2956 cholmod_sparse
A = ocs2ccs (a);
2957 cholmod_dense *
B = ord2ccd (b, &cc);
2960 X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, &
A,
B, &cc);
2961 spqr_error_handler (&cc);
2965 xdata[i] =
reinterpret_cast<Complex *
> (X->x)[i];
2968# if ! defined (OCTAVE_SUITESPARSE_LONG_MATCH)
2969 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
2970 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
2972 cholmod_l_free_dense (&
B, &cc);
2973 cholmod_l_free_dense (&X, &cc);
2974 cholmod_l_finish (&cc);
2989 cholmod_l_start (&cc);
2990 cholmod_sparse
A = ocs2ccs (a);
2991 cholmod_sparse
B = ocs2ccs (b);
2994 X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, &
A, &
B, &cc);
2995 spqr_error_handler (&cc);
3000# if ! defined (OCTAVE_SUITESPARSE_LONG_MATCH)
3001 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
3002 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
3003 delete []
reinterpret_cast<SuiteSparse_long *
> (
B.p);
3004 delete []
reinterpret_cast<SuiteSparse_long *
> (
B.i);
3006 cholmod_l_free_sparse (&X, &cc);
3007 cholmod_l_finish (&cc);
3026 cholmod_l_start (&cc);
3027 cholmod_sparse
A = ocs2ccs (a);
3028 cholmod_sparse *
B = ors2ccs (b, &cc);
3031 X = SuiteSparseQR_min2norm<Complex> (order, SPQR_DEFAULT_TOL, &
A,
B, &cc);
3032 spqr_error_handler (&cc);
3037# if ! defined (OCTAVE_SUITESPARSE_LONG_MATCH)
3038 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.p);
3039 delete []
reinterpret_cast<SuiteSparse_long *
> (
A.i);
3041 cholmod_l_free_sparse (&
B, &cc);
3042 cholmod_l_free_sparse (&X, &cc);
3043 cholmod_l_finish (&cc);
3054template <
typename SPARSE_T>
3055class cxsparse_defaults
3058 enum { order = -1 };
3065#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
3066 enum { order = SPQR_ORDERING_DEFAULT };
3067#elif defined (HAVE_CXSPARSE)
3076#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
3077 enum { order = SPQR_ORDERING_DEFAULT };
3078#elif defined (HAVE_CXSPARSE)
3083template <
typename SPARSE_T>
3084template <
typename RHS_T,
typename RET_T>
3089#if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD))
3099 int order = cxsparse_defaults<SPARSE_T>::order;
3101 if (nr < 0 || nc < 0 || b_nc < 0 || b_nr < 0)
3102 (*current_liboctave_error_handler)
3103 (
"matrix dimension with negative size");
3106 (*current_liboctave_error_handler)
3107 (
"matrix dimension mismatch in solution of minimum norm problem");
3111 return min2norm_solve<RHS_T, RET_T> (a, b, info, order);
3113#elif defined (HAVE_CXSPARSE)
3123 int order = cxsparse_defaults<SPARSE_T>::order;
3125 if (nr < 0 || nc < 0 || nr != b_nr)
3126 (*current_liboctave_error_handler)
3127 (
"matrix dimension mismatch in solution of minimum norm problem");
3129 if (nr == 0 || nc == 0 || b_nc == 0)
3133 return RET_T (nc, b_nc, 0.0);
3139 return q.
ok () ? q.tall_solve<RHS_T, RET_T> (b, info) : RET_T ();
3145 return q.
ok () ? q.wide_solve<RHS_T, RET_T> (b, info) : RET_T ();
3150 octave_unused_parameter (a);
3151 octave_unused_parameter (b);
3152 octave_unused_parameter (info);
3215template <
typename SPARSE_T>
3216template <
typename RHS_T,
typename RET_T>
3220 return m_rep->template tall_solve<RHS_T, RET_T> (b, info);
3223template <
typename SPARSE_T>
3224template <
typename RHS_T,
typename RET_T>
3228 return m_rep->template wide_solve<RHS_T, RET_T> (b, info);
3333OCTAVE_END_NAMESPACE(math)
3334OCTAVE_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
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
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
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)
F77_RET_T const F77_DBLE * x
Matrix qrsolve(const SparseMatrix &a, const MArray< double > &b, octave_idx_type &info)