55 template <
typename T,
typename Alloc>
63 template <
typename T,
typename Alloc>
71 (*current_liboctave_error_handler)
72 (
"Sparse::SparseRep::elem (octave_idx_type, octave_idx_type): sparse matrix filled");
83 (*current_liboctave_error_handler)
84 (
"Sparse::SparseRep::elem (octave_idx_type, octave_idx_type): sparse matrix filled");
105 template <
typename T,
typename Alloc>
117 template <
typename T,
typename Alloc>
130 if (m_data[i] != T ())
132 m_data[k] = m_data[i];
133 m_ridx[k++] = m_ridx[i];
139 change_length (m_cidx[m_ncols]);
142 template <
typename T,
typename Alloc>
151 nz = (nz > 0 ? nz : 1);
154 static const int frac = 5;
155 if (nz > m_nzmax || nz < m_nzmax - m_nzmax/frac)
161 std::copy_n (m_ridx, min_nzmax, new_ridx);
163 idx_type_deallocate (m_ridx, m_nzmax);
166 T *new_data = T_allocate (nz);
167 std::copy_n (m_data, min_nzmax, new_data);
169 T_deallocate (m_data, m_nzmax);
176 template <
typename T,
typename Alloc>
184 template <
typename T,
typename Alloc>
198 template <
typename T,
typename Alloc>
227 template <
typename T,
typename Alloc>
231 m_dimensions (
dim_vector (a.rows (), a.cols ()))
246 template <
typename T,
typename Alloc>
249 : m_rep (nullptr), m_dimensions (dv)
251 if (dv.
ndims () != 2)
252 (*current_liboctave_error_handler)
253 (
"Sparse::Sparse (const dim_vector&): dimension mismatch");
258 template <
typename T,
typename Alloc>
261 : m_rep (nullptr), m_dimensions (dv)
265 unsigned long long a_nel =
static_cast<unsigned long long> (a.
rows ()) *
266 static_cast<unsigned long long> (a.
cols ());
267 unsigned long long dv_nel =
static_cast<unsigned long long> (dv(0)) *
268 static_cast<unsigned long long> (dv(1));
271 (*current_liboctave_error_handler)
272 (
"Sparse::Sparse (const Sparse&, const dim_vector&): dimension mismatch");
298 xcidx (k+1) = new_nzmax;
301 template <
typename T,
typename Alloc>
308 : m_rep (nullptr), m_dimensions ()
312 else if (
r.extent (nr) > nr)
313 (*current_liboctave_error_handler)
314 (
"sparse: row index %" OCTAVE_IDX_TYPE_FORMAT
"out of bound "
315 "%" OCTAVE_IDX_TYPE_FORMAT,
r.extent (nr), nr);
319 else if (c.extent (nc) > nc)
321 (
"sparse: column index %" OCTAVE_IDX_TYPE_FORMAT
" out of bound "
322 "%" OCTAVE_IDX_TYPE_FORMAT,
r.extent (nc), nc);
329 bool a_scalar =
n == 1;
338 if ((rl != 1 && rl !=
n) || (cl != 1 && cl !=
n))
339 (*current_liboctave_error_handler) (
"sparse: dimension mismatch");
344 if (rl <= 1 && cl <= 1)
346 if (
n == 1 && a(0) != T ())
351 std::fill_n (
xcidx () + c(0) + 1, nc - c(0), 1);
373 new_nz += rd[i-1] != rd[i];
377 std::fill_n (
xcidx () + c(0) + 1, nc - c(0), new_nz);
442 sidx[ci[cd[i]+1]++] = rd[0];
444 sidx[ci[cd[i]+1]++] = rd[i];
450 std::sort (sidx + ci[j], sidx + ci[j+1]);
522 new_nz += rd[i-1] != rd[i];
526 std::fill_n (
xcidx () + c(0) + 1, nc - c(0), new_nz);
542 if (rd[i] != rd[i-1])
556 if (rd[i] != rd[i-1])
585 typedef std::pair<octave_idx_type, octave_idx_type> idx_pair;
590 idx_pair& p = spairs[ci[cd[i]+1]++];
602 std::sort (spairs + ci[j], spairs + ci[j+1]);
637 rrd[++jj] = a(spairs[i].second);
641 rrd[jj] += a(spairs[i].second);
655 rrd[jj] = a(spairs[i].second);
670 template <
typename T,
typename Alloc>
673 : m_rep (nullptr), m_dimensions (a.dims ())
676 (*current_liboctave_error_handler)
677 (
"Sparse::Sparse (const Array<T>&): dimension mismatch");
696 if (a.
elem (i, j) != T ())
705 template <
typename T,
typename Alloc>
709 if (--m_rep->m_count == 0)
713 template <
typename T,
typename Alloc>
719 if (--m_rep->m_count == 0)
731 template <
typename T,
typename Alloc>
739 (*current_liboctave_error_handler)
740 (
"Sparse<T, Alloc>::compute_index: invalid ra_idxing operation");
748 retval *= m_dimensions(
n);
755 template <
typename T,
typename Alloc>
760 (*current_liboctave_error_handler) (
"%s (%" OCTAVE_IDX_TYPE_FORMAT
"): "
761 "range error", fcn,
n);
764 template <
typename T,
typename Alloc>
769 (*current_liboctave_error_handler) (
"%s (%" OCTAVE_IDX_TYPE_FORMAT
"): "
770 "range error", fcn,
n);
773 template <
typename T,
typename Alloc>
779 (*current_liboctave_error_handler)
780 (
"%s (%" OCTAVE_IDX_TYPE_FORMAT
", %" OCTAVE_IDX_TYPE_FORMAT
"): "
781 "range error", fcn, i, j);
784 template <
typename T,
typename Alloc>
790 (*current_liboctave_error_handler)
791 (
"%s (%" OCTAVE_IDX_TYPE_FORMAT
", %" OCTAVE_IDX_TYPE_FORMAT
"): "
792 "range error", fcn, i, j);
795 template <
typename T,
typename Alloc>
801 std::ostringstream buf;
813 buf <<
"): range error";
815 std::string buf_str = buf.str ();
817 (*current_liboctave_error_handler) (
"%s", buf_str.c_str ());
820 template <
typename T,
typename Alloc>
826 std::ostringstream buf;
838 buf <<
"): range error";
840 std::string buf_str = buf.str ();
842 (*current_liboctave_error_handler) (
"%s", buf_str.c_str ());
845 template <
typename T,
typename Alloc>
853 if (dims2.
ndims () > 2)
855 (*current_liboctave_warning_with_id_handler)
856 (
"Octave:reshape-smashes-dims",
857 "reshape: sparse reshape to N-D array smashes dims");
860 dims2(1) *= dims2(i);
865 if (m_dimensions != dims2)
867 if (m_dimensions.numel () == dims2.
numel ())
876 if (new_nr == 0 || new_nc == 0)
880 retval.
xcidx (0) = 0;
888 if (i_old_rm >= new_nr)
890 i_old_qu += i_old_rm / new_nr;
891 i_old_rm = i_old_rm % new_nr;
896 ii = (i_old_rm + ridx (j)) % new_nr;
897 jj = i_old_qu + (i_old_rm + ridx (j)) / new_nr;
903 retval.
xcidx (k+1) = j;
905 retval.
xdata (j) = data (j);
906 retval.
xridx (j) = ii;
910 retval.
xcidx (k+1) = new_nnz;
914 std::string dimensions_str = m_dimensions.str ();
915 std::string new_dims_str = new_dims.
str ();
917 (*current_liboctave_error_handler)
918 (
"reshape: can't reshape %s array to %s array",
919 dimensions_str.c_str (), new_dims_str.c_str ());
928 template <
typename T,
typename Alloc>
938 if (perm_vec.
numel () == 2)
940 if (perm_vec(0) == 0 && perm_vec(1) == 1)
942 else if (perm_vec(0) == 1 && perm_vec(1) == 0)
951 (*current_liboctave_error_handler)
952 (
"permutation vector contains an invalid element");
954 return trans ? this->transpose () : *
this;
957 template <
typename T,
typename Alloc>
968 resize (nr, (
n + nr - 1) / nr);
977 template <
typename T,
typename Alloc>
985 (*current_liboctave_error_handler) (
"sparse array must be 2-D");
987 resize (dv(0), dv(1));
990 template <
typename T,
typename Alloc>
996 (*current_liboctave_error_handler) (
"can't resize to negative dimension");
998 if (
r == dim1 () && c == dim2 ())
1015 xdata (k) = xdata (i);
1016 xridx (k++) = xridx (i);
1022 m_rep->m_nrows = m_dimensions(0) =
r;
1024 if (c != m_rep->m_ncols)
1027 std::copy_n (m_rep->m_cidx,
std::min (c, m_rep->m_ncols) + 1, new_cidx);
1028 m_rep->idx_type_deallocate (m_rep->m_cidx, m_rep->m_ncols + 1);
1029 m_rep->m_cidx = new_cidx;
1031 if (c > m_rep->m_ncols)
1032 std::fill_n (m_rep->m_cidx + m_rep->m_ncols + 1, c - m_rep->m_ncols,
1033 m_rep->m_cidx[m_rep->m_ncols]);
1036 m_rep->m_ncols = m_dimensions(1) = c;
1038 m_rep->change_length (m_rep->nnz ());
1041 template <
typename T,
typename Alloc>
1052 if (r < 0 || r + a_rows > rows () || c < 0 || c + a_cols > cols ())
1053 (*current_liboctave_error_handler) (
"range error for insert");
1058 if (c + a_cols < nc)
1059 nel += cidx (nc) - cidx (c + a_cols);
1063 if (ridx (j) <
r || ridx (j) >=
r + a_rows)
1072 data (i) = tmp.
data (i);
1073 ridx (i) = tmp.
ridx (i);
1076 cidx (i) = tmp.
cidx (i);
1085 if (tmp.
ridx (j) <
r)
1087 data (ii) = tmp.
data (j);
1088 ridx (ii++) = tmp.
ridx (j);
1095 data (ii) = a.
data (j);
1096 ridx (ii++) =
r + a.
ridx (j);
1102 if (tmp.
ridx (j) >=
r + a_rows)
1104 data (ii) = tmp.
data (j);
1105 ridx (ii++) = tmp.
ridx (j);
1115 data (ii) = tmp.
data (j);
1116 ridx (ii++) = tmp.
ridx (j);
1124 template <
typename T,
typename Alloc>
1132 (*current_liboctave_error_handler) (
"range error for insert");
1137 template <
typename T,
typename Alloc>
1142 assert (ndims () == 2);
1150 retval.
xcidx (ridx (i) + 1)++;
1156 retval.
xcidx (i) = nz;
1165 retval.
xridx (q) = j;
1166 retval.
xdata (q) = data (k);
1168 assert (nnz () == retval.
xcidx (nr));
1186 for (l = 0; l < nr; l++)
1192 return std::lower_bound (ridx, ridx + nr, ri) - ridx;
1195 template <
typename T,
typename Alloc>
1202 assert (ndims () == 2);
1210 const dim_vector idx_dims = idx.orig_dimensions ();
1212 if (idx.extent (nel) > nel)
1222 if (idx.is_cont_range (nel, lb, ub))
1231 std::copy_n (tmp.
data (), li, data ());
1232 std::copy_n (tmp.
ridx (), li, xridx ());
1233 std::copy (tmp.
data () + ui, tmp.
data () + nz, xdata () + li);
1249 for (; j < sl && sj[j] <
r; j++) ;
1250 if (j == sl || sj[j] >
r)
1252 data_new[nz_new] = tmp.
data (i);
1253 ridx_new[nz_new++] =
r - j;
1258 std::copy_n (ridx_new, nz_new, ridx ());
1259 std::copy_n (data_new, nz_new, xdata ());
1267 if (idx.is_cont_range (nc, lb, ub))
1274 std::copy_n (tmp.
data (), lbi, data ());
1275 std::copy (tmp.
data () + ubi, tmp.
data () + nz, xdata () + lbi);
1277 std::copy_n (tmp.
cidx () + 1, lb, cidx () + 1);
1282 *
this = index (idx.complement (nc));
1284 else if (idx.length (nel) != 0)
1286 if (idx.is_colon_equiv (nel))
1290 *
this = index (octave::idx_vector::colon);
1291 delete_elements (idx);
1292 *
this = transpose ();
1297 template <
typename T,
typename Alloc>
1303 assert (ndims () == 2);
1309 if (idx_i.is_colon ())
1313 if (idx_j.extent (nc) > nc)
1315 else if (idx_j.is_cont_range (nc, lb, ub))
1317 if (lb == 0 && ub == nc)
1335 std::copy_n (tmp.
data (), lbi, data ());
1336 std::copy_n (tmp.
ridx (), lbi, ridx ());
1337 std::copy (tmp.
data () + ubi, tmp.
data () + nz, xdata () + lbi);
1338 std::copy (tmp.
ridx () + ubi, tmp.
ridx () + nz, xridx () + lbi);
1339 std::copy_n (tmp.
cidx () + 1, lb, cidx () + 1);
1341 tmp.
cidx () + ub + 1, ubi - lbi);
1345 *
this = index (idx_i, idx_j.complement (nc));
1347 else if (idx_j.is_colon ())
1351 if (idx_i.extent (nr) > nr)
1353 else if (idx_i.is_cont_range (nr, lb, ub))
1355 if (lb == 0 && ub == nr)
1371 tmpl.
nnz () + tmpu.
nnz ());
1377 xdata (k) = tmpl.
data (i);
1378 xridx (k++) = tmpl.
ridx (i);
1383 xdata (k) = tmpu.
data (i);
1384 xridx (k++) = tmpu.
ridx (i) + lb;
1409 bool empty_assignment
1410 = (idx_i.length (nr) == 0 || idx_j.length (nc) == 0);
1412 if (! empty_assignment)
1413 (*current_liboctave_error_handler)
1414 (
"a null assignment can only have one non-colon index");
1418 template <
typename T,
typename Alloc>
1424 delete_elements (idx, octave::idx_vector::colon);
1426 delete_elements (octave::idx_vector::colon, idx);
1431 template <
typename T,
typename Alloc>
1438 assert (ndims () == 2);
1448 if (idx.is_colon ())
1461 retval.
xdata (j) = data (j);
1462 retval.
xridx (j) = ridx (j) + i * nr;
1466 retval.
xcidx (0) = 0;
1467 retval.
xcidx (1) = nz;
1470 else if (idx.extent (nel) > nel)
1473 octave::err_index_out_of_range (1, 1, idx.extent (nel), nel, dims ());
1479 retval = tmp.
index (idx);
1481 else if (nr == 1 && nc == 1)
1487 retval = (
Sparse<T, Alloc> (idx_dims(0), idx_dims(1), nz ? data (0) : T ()));
1494 if (idx.is_scalar ())
1498 if (i < nz && ridx (i) == idx(0))
1499 retval =
Sparse (1, 1, data (i));
1503 else if (idx.is_cont_range (nel, lb, ub))
1512 std::copy_n (data () + li, nz_new, retval.
data ());
1514 retval.
xcidx (1) = nz_new;
1516 else if (idx.is_permutation (nel) && idx.isvector ())
1518 if (idx.is_range () && idx.increment () == -1)
1523 retval.
ridx (j) = nr - ridx (nz - j - 1) - 1;
1525 std::copy_n (cidx (), 2, retval.
cidx ());
1526 std::reverse_copy (data (), data () + nz, retval.
data ());
1531 tmp = tmp.
index (idx);
1554 lidx.
xelem (i) = lblookup (ridx (), nz, idxa(i));
1564 if (l < nz && ridx (l) == idxa(i, j))
1567 lidx.
xelem (i, j) = nz;
1582 retval.
data (k) = data (l);
1583 retval.
xridx (k++) = i;
1591 if (idx.is_scalar ())
1593 else if (idx.is_cont_range (nel, lb, ub))
1600 std::copy_n (data () + lbi, new_nz, retval.
data ());
1613 if (nr != 0 && idx.is_scalar ())
1621 retval = index (octave::idx_vector::colon).
index (idx);
1624 if (idx_dims(0) == 1 && idx_dims(1) != 1)
1632 template <
typename T,
typename Alloc>
1637 bool resize_ok)
const
1641 assert (ndims () == 2);
1651 if (idx_i.extent (nr) > nr || idx_j.extent (nc) > nc)
1659 tmp.
resize (ext_i, ext_j);
1660 retval = tmp.
index (idx_i, idx_j);
1662 else if (idx_i.extent (nr) > nr)
1663 octave::err_index_out_of_range (2, 1, idx_i.extent (nr), nr, dims ());
1665 octave::err_index_out_of_range (2, 2, idx_j.extent (nc), nc, dims ());
1667 else if (nr == 1 && nc == 1)
1675 else if (idx_i.is_colon ())
1679 if (idx_j.is_colon ())
1681 else if (idx_j.is_cont_range (nc, lb, ub))
1688 std::copy_n (data () + lbi, new_nz, retval.
data ());
1689 std::copy_n (ridx () + lbi, new_nz, retval.
ridx ());
1699 retval.
xcidx (j+1) = retval.
xcidx (j) + (cidx (jj+1) - cidx (jj));
1711 std::copy_n (data () + ljj, nzj, retval.
data () + lj);
1712 std::copy_n (ridx () + ljj, nzj, retval.
ridx () + lj);
1716 else if (nc == 1 && idx_j.is_colon_equiv (nc) && idx_i.isvector ())
1719 retval = index (idx_i);
1725 else if (idx_i.is_scalar ())
1739 if (i < nzj && ridx (i+lj) == ii)
1754 if (retval.
xcidx (j+1) > i)
1756 retval.
xridx (i) = 0;
1757 retval.
xdata (i) = data (ij[j]);
1761 else if (idx_i.is_cont_range (nr, lb, ub))
1775 li[j] = lij = lblookup (ridx () + lj, nzj, lb) + lj;
1776 ui[j] = uij = lblookup (ridx () + lj, nzj, ub) + lj;
1777 retval.
xcidx (j+1) = retval.
xcidx (j) + ui[j] - li[j];
1788 retval.
xdata (k) = data (i);
1789 retval.
xridx (k++) = ridx (i) - lb;
1793 else if (idx_i.is_permutation (nr))
1801 retval.
xcidx (j+1) = retval.
xcidx (j) + (cidx (jj+1) - cidx (jj));
1808 if (idx_i.is_range () && idx_i.increment () == -1)
1821 retval.
xdata (li + i) = data (uj - i);
1822 retval.
xridx (li + i) = nr - 1 - ridx (uj - i);
1845 scb[rri[li + i] = iinv[ridx (lj + i)]] = data (lj + i);
1850 std::sort (rri + li, rri + li + nzj);
1854 retval.
xdata (li + i) = scb[rri[li + i]];
1859 else if (idx_j.is_colon ())
1864 retval = transpose ();
1865 retval = retval.
index (octave::idx_vector::colon, idx_i);
1871 retval = index (octave::idx_vector::colon, idx_j);
1872 retval = retval.
index (idx_i, octave::idx_vector::colon);
1878 template <
typename T,
typename Alloc>
1886 assert (ndims () == 2);
1896 if (idx.length (
n) == rhl)
1912 if (idx.is_colon ())
1914 *
this = rhs.
reshape (m_dimensions);
1916 else if (nc == 1 && rhs.
cols () == 1)
1921 if (idx.is_cont_range (nr, lb, ub))
1930 if (new_nz >= nz && new_nz <= nzmax ())
1937 std::copy_backward (data () + ui, data () + nz,
1938 data () + nz + rnz);
1939 std::copy_backward (ridx () + ui, ridx () + nz,
1940 ridx () + nz + rnz);
1944 std::copy_n (rhs.
data (), rnz, data () + li);
1955 std::copy_n (tmp.
data (), li, data ());
1956 std::copy_n (tmp.
ridx (), li, ridx ());
1959 std::copy_n (rhs.
data (), rnz, data () + li);
1963 std::copy (tmp.
data () + ui, tmp.
data () + nz,
1964 data () + li + rnz);
1965 std::copy (tmp.
ridx () + ui, tmp.
ridx () + nz,
1966 ridx () + li + rnz);
1971 else if (idx.is_range () && idx.increment () == -1)
1976 else if (idx.is_permutation (
n))
1978 *
this = rhs.
index (idx.inverse_permutation (
n));
1980 else if (rhs.
nnz () == 0)
1988 if (li != nz && ri[li] == iidx)
1992 maybe_compress (
true);
2013 *
this = index (octave::idx_vector::colon);
2014 assign (idx, rhs.
index (octave::idx_vector::colon));
2015 *
this = reshape (save_dims);
2020 rhl = idx.length (
n);
2021 if (rhs.
nnz () != 0)
2030 template <
typename T,
typename Alloc>
2042 template <
typename T,
typename Alloc>
2051 assert (ndims () == 2);
2063 bool orig_zero_by_zero = (nr == 0 && nc == 0);
2065 if (orig_zero_by_zero || (idx_i.length (nr) ==
n && idx_j.length (nc) ==
m))
2070 if (orig_zero_by_zero)
2072 if (idx_i.is_colon ())
2076 if (idx_j.is_colon ())
2079 ncx = idx_j.extent (nc);
2081 else if (idx_j.is_colon ())
2083 nrx = idx_i.extent (nr);
2088 nrx = idx_i.extent (nr);
2089 ncx = idx_j.extent (nc);
2094 nrx = idx_i.extent (nr);
2095 ncx = idx_j.extent (nc);
2099 if (nrx != nr || ncx != nc)
2107 if (
n == 0 ||
m == 0)
2110 if (idx_i.is_colon ())
2115 if (idx_j.is_colon ())
2117 else if (idx_j.is_cont_range (nc, lb, ub))
2125 if (new_nz >= nz && new_nz <= nzmax ())
2132 std::copy_backward (data () + ui, data () + nz,
2134 std::copy_backward (ridx () + ui, ridx () + nz,
2140 std::copy_n (rhs.
data (), rnz, data () + li);
2141 std::copy_n (rhs.
ridx (), rnz, ridx () + li);
2145 assert (nnz () == new_nz);
2155 std::copy_n (tmp.
data (), li, data ());
2156 std::copy_n (tmp.
ridx (), li, ridx ());
2157 std::copy_n (tmp.
cidx () + 1, lb, cidx () + 1);
2160 std::copy_n (rhs.
data (), rnz, data () + li);
2161 std::copy_n (rhs.
ridx (), rnz, ridx () + li);
2166 std::copy (tmp.
data () + ui, tmp.
data () + nz,
2167 data () + li + rnz);
2168 std::copy (tmp.
ridx () + ui, tmp.
ridx () + nz,
2169 ridx () + li + rnz);
2171 tmp.
cidx () + ub + 1, new_nz - nz);
2173 assert (nnz () == new_nz);
2176 else if (idx_j.is_range () && idx_j.increment () == -1)
2179 assign (idx_i, idx_j.sorted (),
2182 else if (idx_j.is_permutation (nc))
2184 *
this = rhs.
index (idx_i, idx_j.inverse_permutation (nc));
2194 xcidx (i+1) = tmp.
cidx (i+1) - tmp.
cidx (i);
2200 xcidx (j+1) = rhs.
cidx (i+1) - rhs.
cidx (i);
2205 xcidx (i+1) += xcidx (i);
2207 change_capacity (nnz ());
2219 std::copy_n (rhs.
data () + k, u - l, xdata () + l);
2220 std::copy_n (rhs.
ridx () + k, u - l, xridx () + l);
2226 std::copy_n (tmp.
data () + k, u - l, xdata () + l);
2227 std::copy_n (tmp.
ridx () + k, u - l, xridx () + l);
2233 else if (nc == 1 && idx_j.is_colon_equiv (nc) && idx_i.isvector ())
2236 assign (idx_i, rhs);
2238 else if (idx_j.is_colon ())
2240 if (idx_i.is_permutation (nr))
2242 *
this = rhs.
index (idx_i.inverse_permutation (nr), idx_j);
2250 *
this = transpose ();
2251 assign (octave::idx_vector::colon, idx_i, rhs.
transpose ());
2252 *
this = transpose ();
2259 tmp.
assign (idx_i, octave::idx_vector::colon, rhs);
2260 assign (octave::idx_vector::colon, idx_j, tmp);
2263 else if (
m == 1 &&
n == 1)
2265 n = idx_i.length (nr);
2266 m = idx_j.length (nc);
2267 if (rhs.
nnz () != 0)
2272 else if (idx_i.length (nr) ==
m && idx_j.length (nc) ==
n
2273 && (
n == 1 ||
m == 1))
2275 assign (idx_i, idx_j, rhs.
transpose ());
2281 template <
typename T,
typename Alloc>
2297 template <
typename T>
2306 template <
typename T>
2315 template <
typename T,
typename Alloc>
2325 if (
m.numel () < 1 || dim > 1)
2328 bool sort_by_column = (dim > 0);
2343 (
"Sparse<T, Alloc>::sort: invalid MODE");
2357 for (i = 0; i < ns; i++)
2358 if (sparse_ascending_compare<T> (
static_cast<T
> (0), v[i]))
2363 for (i = 0; i < ns; i++)
2364 if (sparse_descending_compare<T> (
static_cast<T
> (0), v[i]))
2370 mridx[k] = k - ns + nr;
2382 template <
typename T,
typename Alloc>
2393 if (
m.numel () < 1 || dim > 1)
2399 bool sort_by_column = (dim > 0);
2409 indexed_sort.
set_compare (sparse_ascending_compare<T>);
2411 indexed_sort.
set_compare (sparse_descending_compare<T>);
2414 (
"Sparse<T, Alloc>::sort: invalid MODE");
2431 sidx(offset + k) = k;
2438 indexed_sort.
sort (v, vi, ns);
2443 for (i = 0; i < ns; i++)
2444 if (sparse_ascending_compare<T> (
static_cast<T
> (0), v[i]))
2449 for (i = 0; i < ns; i++)
2450 if (sparse_descending_compare<T> (
static_cast<T
> (0), v[i]))
2458 if (ii < ns && mridx[ii] == k)
2461 sidx(offset + jj++) = k;
2466 sidx(k + offset) = vi[k];
2472 sidx(k - ns + nr + offset) = vi[k];
2473 mridx[k] = k - ns + nr;
2490 template <
typename T,
typename Alloc>
2499 if (nnr == 0 || nnc == 0)
2501 else if (nnr != 1 && nnc != 1)
2508 if (nnr > 0 && nnc > 0)
2517 if (elem (i, i+k) != 0.)
2523 if (elem (i-k, i) != 0.)
2529 if (elem (i, i) != 0.)
2542 T tmp = elem (i, i+k);
2554 T tmp = elem (i-k, i);
2566 T tmp = elem (i, i);
2617 d.xdata (i) = data (i);
2618 d.xridx (i) = j + roff;
2620 d.xcidx (j + coff + 1) = cidx (j+1);
2646 d.xdata (ii) = data (ii);
2647 d.xridx (ii++) = ir + roff;
2652 d.xcidx (i + coff + 1) = ii;
2664 template <
typename T,
typename Alloc>
2673 if (dim == -1 || dim == -2)
2679 (*current_liboctave_error_handler) (
"cat: invalid dimension");
2683 if (dim != 0 && dim != 1)
2684 (*current_liboctave_error_handler)
2685 (
"cat: invalid dimension for sparse concatenation");
2688 return sparse_list[0];
2692 if (! (dv.*concat_rule) (sparse_list[i].
dims (), dim))
2693 (*current_liboctave_error_handler) (
"cat: dimension mismatch");
2695 total_nz += sparse_list[i].
nnz ();
2730 rcum += spi.
rows ();
2733 retval.
xcidx (j+1) = l;
2746 if (sparse_list[i].isempty ())
2764 template <
typename T,
typename Alloc>
2776 retval.
xelem (j) = data (i++);
2783 retval.
xelem (ridx (i), j) = data (i);
2789 template <
typename T>
2793 T (*read_fcn) (std::istream&))
2799 if (nr > 0 && nc > 0)
2821 std::string err_field;
2823 (*current_liboctave_error_handler)
2824 (
"invalid sparse matrix: element %" OCTAVE_IDX_TYPE_FORMAT
": "
2825 "Symbols '%s' is not an integer format",
2826 i+1, err_field.c_str ());
2829 if (itmp < 0 || itmp >= nr)
2831 is.setstate (std::ios::failbit);
2833 (*current_liboctave_error_handler)
2834 (
"invalid sparse matrix: element %" OCTAVE_IDX_TYPE_FORMAT
": "
2835 "row index = %" OCTAVE_IDX_TYPE_FORMAT
" out of range",
2839 if (jtmp < 0 || jtmp >= nc)
2841 is.setstate (std::ios::failbit);
2843 (*current_liboctave_error_handler)
2844 (
"invalid sparse matrix: element %" OCTAVE_IDX_TYPE_FORMAT
": "
2845 "column index = %" OCTAVE_IDX_TYPE_FORMAT
" out of range",
2851 is.setstate (std::ios::failbit);
2853 (*current_liboctave_error_handler)
2854 (
"invalid sparse matrix: element %" OCTAVE_IDX_TYPE_FORMAT
":"
2855 "column indices must appear in ascending order "
2856 "(%" OCTAVE_IDX_TYPE_FORMAT
" < %" OCTAVE_IDX_TYPE_FORMAT
")",
2859 else if (jtmp > jold)
2864 else if (itmp < iold)
2866 is.setstate (std::ios::failbit);
2868 (*current_liboctave_error_handler)
2869 (
"invalid sparse matrix: element %" OCTAVE_IDX_TYPE_FORMAT
": "
2870 "row indices must appear in ascending order in each column "
2871 "(%" OCTAVE_IDX_TYPE_FORMAT
" < %" OCTAVE_IDX_TYPE_FORMAT
")",
2878 tmp = read_fcn (is);
2884 a.
ridx (ii++) = itmp;
3092 template <
typename T,
typename Alloc>
3097 os << prefix <<
"m_rep address: " << m_rep <<
"\n"
3098 << prefix <<
"m_rep->m_nzmax: " << m_rep->m_nzmax <<
"\n"
3099 << prefix <<
"m_rep->m_nrows: " << m_rep->m_nrows <<
"\n"
3100 << prefix <<
"m_rep->m_ncols: " << m_rep->m_ncols <<
"\n"
3101 << prefix <<
"m_rep->m_data: " << m_rep->m_data <<
"\n"
3102 << prefix <<
"m_rep->m_ridx: " << m_rep->m_ridx <<
"\n"
3103 << prefix <<
"m_rep->m_cidx: " << m_rep->m_cidx <<
"\n"
3104 << prefix <<
"m_rep->m_count: " << m_rep->m_count <<
"\n";
3107 #if defined (__clang__)
3108 # define INSTANTIATE_SPARSE(T) \
3109 template class OCTAVE_API Sparse<T>; \
3110 template OCTAVE_API std::istream& \
3111 read_sparse_matrix<T> (std::istream& is, Sparse<T>& a, \
3112 T (*read_fcn) (std::istream&));
3114 # define INSTANTIATE_SPARSE(T) \
3115 template class Sparse<T>; \
3116 template OCTAVE_API std::istream& \
3117 read_sparse_matrix<T> (std::istream& is, Sparse<T>& a, \
3118 T (*read_fcn) (std::istream&));
bool sparse_descending_compare(typename ref_param< T >::type a, typename ref_param< T >::type b)
std::istream & read_sparse_matrix(std::istream &is, Sparse< T > &a, T(*read_fcn)(std::istream &))
bool sparse_ascending_compare(typename ref_param< T >::type a, typename ref_param< T >::type b)
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
T & elem(octave_idx_type n)
Size of the specified dimension.
T * fortran_vec()
Size of the specified dimension.
Array< T, Alloc > index(const octave::idx_vector &i) const
Indexing without resizing.
void assign(const octave::idx_vector &i, const Array< T, Alloc > &rhs, const T &rfv)
Indexed assignment (always with resize & fill).
Array< T, Alloc > transpose() const
Size of the specified dimension.
Array< T, Alloc > as_matrix() const
Return the array as a matrix.
octave_idx_type rows() const
const T * data() const
Size of the specified dimension.
octave_idx_type cols() const
T & xelem(octave_idx_type n)
Size of the specified dimension.
octave_idx_type numel() const
Number of elements in the array.
octave_idx_type rows() const
const Array< octave_idx_type > & col_perm_vec() const
bool any_element_is_nan() const
void change_length(octave_idx_type nz)
octave::refcount< octave_idx_type > m_count
void maybe_compress(bool remove_zeros)
T & elem(octave_idx_type r, octave_idx_type c)
T celem(octave_idx_type r, octave_idx_type c) const
octave_idx_type cols() const
Sparse< T, Alloc > diag(octave_idx_type k=0) const
Sparse< T, Alloc > permute(const Array< octave_idx_type > &vec, bool inv=false) const
octave_idx_type * xcidx()
octave_idx_type nzmax() const
Amount of storage for nonzero elements.
Array< T > array_value() const
void delete_elements(const octave::idx_vector &i)
Sparse< T, Alloc > index(const octave::idx_vector &i, bool resize_ok=false) const
void print_info(std::ostream &os, const std::string &prefix) const
octave_idx_type columns() const
void assign(const octave::idx_vector &i, const Sparse< T, Alloc > &rhs)
void resize(octave_idx_type r, octave_idx_type c)
Sparse< T, Alloc >::SparseRep * m_rep
Sparse< T, Alloc > sort(octave_idx_type dim=0, sortmode mode=ASCENDING) const
Sparse< T, Alloc > & insert(const Sparse< T, Alloc > &a, octave_idx_type r, octave_idx_type c)
void resize1(octave_idx_type n)
Sparse< T, Alloc > maybe_compress(bool remove_zeros=false)
OCTAVE_NORETURN T range_error(const char *fcn, octave_idx_type n) const
octave_idx_type numel() const
static Sparse< T, Alloc > cat(int dim, octave_idx_type n, const Sparse< T, Alloc > *sparse_list)
Sparse< T, Alloc > & operator=(const Sparse< T, Alloc > &a)
octave_idx_type nnz() const
Actual number of nonzero terms.
octave_idx_type rows() const
void change_capacity(octave_idx_type nz)
Sparse< T, Alloc > transpose() const
octave_idx_type compute_index(const Array< octave_idx_type > &ra_idx) const
Sparse< T, Alloc > reshape(const dim_vector &new_dims) const
octave_idx_type * xridx()
Vector representing the dimensions (size) of an Array.
bool concat(const dim_vector &dvb, int dim)
This corresponds to cat().
octave_idx_type safe_numel() const
The following function will throw a std::bad_alloc () exception if the requested size is larger than ...
std::string str(char sep='x') const
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
void resize(int n, int fill_value=0)
octave_idx_type ndims() const
Number of dimensions.
bool hvcat(const dim_vector &dvb, int dim)
This corresponds to [,] (horzcat, dim = 0) and [;] (vertcat, dim = 1).
dim_vector redim(int n) const
Force certain dimensionality, preserving numel ().
virtual octave_idx_type numel() const
void set_compare(const compare_fcn_type &comp)
void sort(T *data, octave_idx_type nel)
if_then_else< is_class_type< T >::no, T, T const & >::result type
octave::idx_vector idx_vector
void err_invalid_resize()
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
void err_del_index_out_of_range(bool is1d, octave_idx_type idx, octave_idx_type ext)
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
void mx_inline_add2(std::size_t n, R *r, const X *x)
void mx_inline_sub(std::size_t n, R *r, const X *x, const Y *y)
void mx_inline_add(std::size_t n, R *r, const X *x, const Y *y)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
#define OCTAVE_LOCAL_BUFFER_INIT(T, buf, size, value)
T::size_type numel(const T &str)
const octave_base_value const Array< octave_idx_type > & ra_idx
bool sparse_indices_ok(octave_idx_type *r, octave_idx_type *c, octave_idx_type nrows, octave_idx_type ncols, octave_idx_type nnz)