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>
228 template <
typename T,
typename Alloc>
232 m_dimensions (
dim_vector (a.rows (), a.cols ()))
247 template <
typename T,
typename Alloc>
250 : m_rep (nullptr), m_dimensions (dv)
252 if (dv.
ndims () != 2)
253 (*current_liboctave_error_handler)
254 (
"Sparse::Sparse (const dim_vector&): dimension mismatch");
259 template <
typename T,
typename Alloc>
262 : m_rep (nullptr), m_dimensions (dv)
266 unsigned long long a_nel =
static_cast<unsigned long long>(a.
rows ()) *
267 static_cast<unsigned long long>(a.
cols ());
268 unsigned long long dv_nel =
static_cast<unsigned long long>(dv(0)) *
269 static_cast<unsigned long long>(dv(1));
272 (*current_liboctave_error_handler)
273 (
"Sparse::Sparse (const Sparse&, const dim_vector&): dimension mismatch");
302 template <
typename T,
typename Alloc>
309 : m_rep (nullptr), m_dimensions ()
313 else if (
r.extent (nr) > nr)
314 (*current_liboctave_error_handler)
315 (
"sparse: row index %" OCTAVE_IDX_TYPE_FORMAT
"out of bound "
316 "%" OCTAVE_IDX_TYPE_FORMAT,
r.extent (nr), nr);
320 else if (c.extent (nc) > nc)
322 (
"sparse: column index %" OCTAVE_IDX_TYPE_FORMAT
" out of bound "
323 "%" OCTAVE_IDX_TYPE_FORMAT,
r.extent (nc), nc);
330 bool a_scalar =
n == 1;
339 if ((rl != 1 && rl !=
n) || (cl != 1 && cl !=
n))
340 (*current_liboctave_error_handler) (
"sparse: dimension mismatch");
345 if (rl <= 1 && cl <= 1)
347 if (
n == 1 && a(0) != T ())
352 std::fill_n (
xcidx () + c(0) + 1, nc - c(0), 1);
374 new_nz += rd[i-1] != rd[i];
378 std::fill_n (
xcidx () + c(0) + 1, nc - c(0), new_nz);
443 sidx[ci[cd[i]+1]++] = rd[0];
445 sidx[ci[cd[i]+1]++] = rd[i];
451 std::sort (sidx + ci[j], sidx + ci[j+1]);
523 new_nz += rd[i-1] != rd[i];
527 std::fill_n (
xcidx () + c(0) + 1, nc - c(0), new_nz);
543 if (rd[i] != rd[i-1])
557 if (rd[i] != rd[i-1])
586 typedef std::pair<octave_idx_type, octave_idx_type> idx_pair;
591 idx_pair& p = spairs[ci[cd[i]+1]++];
603 std::sort (spairs + ci[j], spairs + ci[j+1]);
638 rrd[++jj] = a(spairs[i].second);
642 rrd[jj] += a(spairs[i].second);
656 rrd[jj] = a(spairs[i].second);
671 template <
typename T,
typename Alloc>
674 : m_rep (nullptr), m_dimensions (a.dims ())
677 (*current_liboctave_error_handler)
678 (
"Sparse::Sparse (const Array<T>&): dimension mismatch");
697 if (a.
elem (i, j) != T ())
706 template <
typename T,
typename Alloc>
710 if (--m_rep->m_count == 0)
714 template <
typename T,
typename Alloc>
720 if (--m_rep->m_count == 0)
732 template <
typename T,
typename Alloc>
740 (*current_liboctave_error_handler)
741 (
"Sparse<T, Alloc>::compute_index: invalid ra_idxing operation");
749 retval *= m_dimensions(
n);
756 template <
typename T,
typename Alloc>
761 (*current_liboctave_error_handler) (
"%s (%" OCTAVE_IDX_TYPE_FORMAT
"): "
762 "range error", fcn,
n);
765 template <
typename T,
typename Alloc>
770 (*current_liboctave_error_handler) (
"%s (%" OCTAVE_IDX_TYPE_FORMAT
"): "
771 "range error", fcn,
n);
774 template <
typename T,
typename Alloc>
780 (*current_liboctave_error_handler)
781 (
"%s (%" OCTAVE_IDX_TYPE_FORMAT
", %" OCTAVE_IDX_TYPE_FORMAT
"): "
782 "range error", fcn, i, j);
785 template <
typename T,
typename Alloc>
791 (*current_liboctave_error_handler)
792 (
"%s (%" OCTAVE_IDX_TYPE_FORMAT
", %" OCTAVE_IDX_TYPE_FORMAT
"): "
793 "range error", fcn, i, j);
796 template <
typename T,
typename Alloc>
802 std::ostringstream buf;
814 buf <<
"): range error";
816 std::string buf_str = buf.str ();
818 (*current_liboctave_error_handler) (
"%s", buf_str.c_str ());
821 template <
typename T,
typename Alloc>
827 std::ostringstream buf;
839 buf <<
"): range error";
841 std::string buf_str = buf.str ();
843 (*current_liboctave_error_handler) (
"%s", buf_str.c_str ());
846 template <
typename T,
typename Alloc>
854 if (dims2.
ndims () > 2)
856 (*current_liboctave_warning_with_id_handler)
857 (
"Octave:reshape-smashes-dims",
858 "reshape: sparse reshape to N-D array smashes dims");
861 dims2(1) *= dims2(i);
866 if (m_dimensions != dims2)
868 if (m_dimensions.numel () == dims2.
numel ())
878 retval.
xcidx (0) = 0;
886 if (i_old_rm >= new_nr)
888 i_old_qu += i_old_rm / new_nr;
889 i_old_rm = i_old_rm % new_nr;
894 ii = (i_old_rm + ridx (j)) % new_nr;
895 jj = i_old_qu + (i_old_rm + ridx (j)) / new_nr;
901 retval.
xcidx (k+1) = j;
903 retval.
xdata (j) = data (j);
904 retval.
xridx (j) = ii;
908 retval.
xcidx (k+1) = new_nnz;
912 std::string dimensions_str = m_dimensions.str ();
913 std::string new_dims_str = new_dims.
str ();
915 (*current_liboctave_error_handler)
916 (
"reshape: can't reshape %s array to %s array",
917 dimensions_str.c_str (), new_dims_str.c_str ());
926 template <
typename T,
typename Alloc>
936 if (perm_vec.
numel () == 2)
938 if (perm_vec(0) == 0 && perm_vec(1) == 1)
940 else if (perm_vec(0) == 1 && perm_vec(1) == 0)
949 (*current_liboctave_error_handler)
950 (
"permutation vector contains an invalid element");
952 return trans ? this->
transpose () : *
this;
955 template <
typename T,
typename Alloc>
966 resize (nr, (
n + nr - 1) / nr);
975 template <
typename T,
typename Alloc>
983 (*current_liboctave_error_handler) (
"sparse array must be 2-D");
985 resize (dv(0), dv(1));
988 template <
typename T,
typename Alloc>
994 (*current_liboctave_error_handler) (
"can't resize to negative dimension");
996 if (
r == dim1 () && c == dim2 ())
1013 xdata (k) = xdata (i);
1014 xridx (k++) = xridx (i);
1020 m_rep->m_nrows = m_dimensions(0) =
r;
1022 if (c != m_rep->m_ncols)
1025 std::copy_n (m_rep->m_cidx,
std::min (c, m_rep->m_ncols) + 1, new_cidx);
1026 m_rep->idx_type_deallocate (m_rep->m_cidx, m_rep->m_ncols + 1);
1027 m_rep->m_cidx = new_cidx;
1029 if (c > m_rep->m_ncols)
1030 std::fill_n (m_rep->m_cidx + m_rep->m_ncols + 1, c - m_rep->m_ncols,
1031 m_rep->m_cidx[m_rep->m_ncols]);
1034 m_rep->m_ncols = m_dimensions(1) = c;
1036 m_rep->change_length (m_rep->nnz ());
1039 template <
typename T,
typename Alloc>
1050 if (r < 0 || r + a_rows > rows () || c < 0 || c + a_cols > cols ())
1051 (*current_liboctave_error_handler) (
"range error for insert");
1056 if (c + a_cols < nc)
1057 nel += cidx (nc) - cidx (c + a_cols);
1061 if (ridx (j) <
r || ridx (j) >=
r + a_rows)
1070 data (i) = tmp.
data (i);
1071 ridx (i) = tmp.
ridx (i);
1074 cidx (i) = tmp.
cidx (i);
1083 if (tmp.
ridx (j) <
r)
1085 data (ii) = tmp.
data (j);
1086 ridx (ii++) = tmp.
ridx (j);
1093 data (ii) = a.
data (j);
1094 ridx (ii++) =
r + a.
ridx (j);
1100 if (tmp.
ridx (j) >=
r + a_rows)
1102 data (ii) = tmp.
data (j);
1103 ridx (ii++) = tmp.
ridx (j);
1113 data (ii) = tmp.
data (j);
1114 ridx (ii++) = tmp.
ridx (j);
1122 template <
typename T,
typename Alloc>
1130 (*current_liboctave_error_handler) (
"range error for insert");
1135 template <
typename T,
typename Alloc>
1140 assert (ndims () == 2);
1148 retval.
xcidx (ridx (i) + 1)++;
1154 retval.
xcidx (i) = nz;
1163 retval.
xridx (q) = j;
1164 retval.
xdata (q) = data (k);
1166 assert (nnz () == retval.
xcidx (nr));
1184 for (l = 0; l < nr; l++)
1190 return std::lower_bound (ridx, ridx + nr, ri) - ridx;
1193 template <
typename T,
typename Alloc>
1200 assert (ndims () == 2);
1208 const dim_vector idx_dims = idx.orig_dimensions ();
1210 if (idx.extent (nel) > nel)
1220 if (idx.is_cont_range (nel, lb, ub))
1229 std::copy_n (tmp.
data (), li, data ());
1230 std::copy_n (tmp.
ridx (), li, xridx ());
1231 std::copy (tmp.
data () + ui, tmp.
data () + nz, xdata () + li);
1247 for (; j < sl && sj[j] <
r; j++) ;
1248 if (j == sl || sj[j] >
r)
1250 data_new[nz_new] = tmp.
data (i);
1251 ridx_new[nz_new++] =
r - j;
1256 std::copy_n (ridx_new, nz_new, ridx ());
1257 std::copy_n (data_new, nz_new, xdata ());
1265 if (idx.is_cont_range (nc, lb, ub))
1272 std::copy_n (tmp.
data (), lbi, data ());
1273 std::copy (tmp.
data () + ubi, tmp.
data () + nz, xdata () + lbi);
1275 std::copy_n (tmp.
cidx () + 1, lb, cidx () + 1);
1280 *
this = index (idx.complement (nc));
1282 else if (idx.length (nel) != 0)
1284 if (idx.is_colon_equiv (nel))
1288 *
this = index (octave::idx_vector::colon);
1289 delete_elements (idx);
1295 template <
typename T,
typename Alloc>
1301 assert (ndims () == 2);
1307 if (idx_i.is_colon ())
1311 if (idx_j.extent (nc) > nc)
1313 else if (idx_j.is_cont_range (nc, lb, ub))
1315 if (lb == 0 && ub == nc)
1333 std::copy_n (tmp.
data (), lbi, data ());
1334 std::copy_n (tmp.
ridx (), lbi, ridx ());
1335 std::copy (tmp.
data () + ubi, tmp.
data () + nz, xdata () + lbi);
1336 std::copy (tmp.
ridx () + ubi, tmp.
ridx () + nz, xridx () + lbi);
1337 std::copy_n (tmp.
cidx () + 1, lb, cidx () + 1);
1339 tmp.
cidx () + ub + 1, ubi - lbi);
1343 *
this = index (idx_i, idx_j.complement (nc));
1345 else if (idx_j.is_colon ())
1349 if (idx_i.extent (nr) > nr)
1351 else if (idx_i.is_cont_range (nr, lb, ub))
1353 if (lb == 0 && ub == nr)
1369 tmpl.
nnz () + tmpu.
nnz ());
1375 xdata (k) = tmpl.
data (i);
1376 xridx (k++) = tmpl.
ridx (i);
1381 xdata (k) = tmpu.
data (i);
1382 xridx (k++) = tmpu.
ridx (i) + lb;
1407 bool empty_assignment
1408 = (idx_i.length (nr) == 0 || idx_j.length (nc) == 0);
1410 if (! empty_assignment)
1411 (*current_liboctave_error_handler)
1412 (
"a null assignment can only have one non-colon index");
1416 template <
typename T,
typename Alloc>
1422 delete_elements (idx, octave::idx_vector::colon);
1424 delete_elements (octave::idx_vector::colon, idx);
1429 template <
typename T,
typename Alloc>
1436 assert (ndims () == 2);
1446 if (idx.is_colon ())
1459 retval.
xdata (j) = data (j);
1460 retval.
xridx (j) = ridx (j) + i * nr;
1464 retval.
xcidx (0) = 0;
1465 retval.
xcidx (1) = nz;
1468 else if (idx.extent (nel) > nel)
1477 retval = tmp.
index (idx);
1479 else if (nr == 1 && nc == 1)
1485 retval = (
Sparse<T, Alloc> (idx_dims(0), idx_dims(1), nz ? data (0) : T ()));
1492 if (idx.is_scalar ())
1496 if (i < nz && ridx (i) == idx(0))
1497 retval =
Sparse (1, 1, data (i));
1501 else if (idx.is_cont_range (nel, lb, ub))
1510 std::copy_n (data () + li, nz_new, retval.
data ());
1512 retval.
xcidx (1) = nz_new;
1514 else if (idx.is_permutation (nel) && idx.isvector ())
1516 if (idx.is_range () && idx.increment () == -1)
1521 retval.
ridx (j) = nr - ridx (nz - j - 1) - 1;
1523 std::copy_n (cidx (), 2, retval.
cidx ());
1524 std::reverse_copy (data (), data () + nz, retval.
data ());
1529 tmp = tmp.
index (idx);
1562 if (l < nz && ridx (l) == idxa(i, j))
1565 lidx.
xelem (i, j) = nz;
1580 retval.
data (k) = data (l);
1581 retval.
xridx (k++) = i;
1589 if (idx.is_scalar ())
1591 else if (idx.is_cont_range (nel, lb, ub))
1598 std::copy_n (data () + lbi, new_nz, retval.
data ());
1611 if (nr != 0 && idx.is_scalar ())
1619 retval = index (octave::idx_vector::colon).
index (idx);
1622 if (idx_dims(0) == 1 && idx_dims(1) != 1)
1630 template <
typename T,
typename Alloc>
1635 bool resize_ok)
const
1639 assert (ndims () == 2);
1649 if (idx_i.extent (nr) > nr || idx_j.extent (nc) > nc)
1657 tmp.
resize (ext_i, ext_j);
1658 retval = tmp.
index (idx_i, idx_j);
1660 else if (idx_i.extent (nr) > nr)
1665 else if (nr == 1 && nc == 1)
1673 else if (idx_i.is_colon ())
1677 if (idx_j.is_colon ())
1679 else if (idx_j.is_cont_range (nc, lb, ub))
1686 std::copy_n (data () + lbi, new_nz, retval.
data ());
1687 std::copy_n (ridx () + lbi, new_nz, retval.
ridx ());
1697 retval.
xcidx (j+1) = retval.
xcidx (j) + (cidx (jj+1) - cidx (jj));
1709 std::copy_n (data () + ljj, nzj, retval.
data () + lj);
1710 std::copy_n (ridx () + ljj, nzj, retval.
ridx () + lj);
1714 else if (nc == 1 && idx_j.is_colon_equiv (nc) && idx_i.isvector ())
1717 retval = index (idx_i);
1723 else if (idx_i.is_scalar ())
1737 if (i < nzj && ridx (i+lj) == ii)
1752 if (retval.
xcidx (j+1) > i)
1754 retval.
xridx (i) = 0;
1755 retval.
xdata (i) = data (ij[j]);
1759 else if (idx_i.is_cont_range (nr, lb, ub))
1773 li[j] = lij =
lblookup (ridx () + lj, nzj, lb) + lj;
1774 ui[j] = uij =
lblookup (ridx () + lj, nzj, ub) + lj;
1775 retval.
xcidx (j+1) = retval.
xcidx (j) + ui[j] - li[j];
1786 retval.
xdata (k) = data (i);
1787 retval.
xridx (k++) = ridx (i) - lb;
1791 else if (idx_i.is_permutation (nr))
1799 retval.
xcidx (j+1) = retval.
xcidx (j) + (cidx (jj+1) - cidx (jj));
1806 if (idx_i.is_range () && idx_i.increment () == -1)
1819 retval.
xdata (li + i) = data (uj - i);
1820 retval.
xridx (li + i) = nr - 1 - ridx (uj - i);
1843 scb[rri[li + i] = iinv[ridx (lj + i)]] = data (lj + i);
1848 std::sort (rri + li, rri + li + nzj);
1852 retval.
xdata (li + i) = scb[rri[li + i]];
1857 else if (idx_j.is_colon ())
1863 retval = retval.
index (octave::idx_vector::colon, idx_i);
1869 retval = index (octave::idx_vector::colon, idx_j);
1870 retval = retval.
index (idx_i, octave::idx_vector::colon);
1876 template <
typename T,
typename Alloc>
1884 assert (ndims () == 2);
1894 if (idx.length (
n) == rhl)
1910 if (idx.is_colon ())
1912 *
this = rhs.
reshape (m_dimensions);
1914 else if (nc == 1 && rhs.
cols () == 1)
1919 if (idx.is_cont_range (nr, lb, ub))
1928 if (new_nz >= nz && new_nz <= nzmax ())
1935 std::copy_backward (data () + ui, data () + nz,
1936 data () + nz + rnz);
1937 std::copy_backward (ridx () + ui, ridx () + nz,
1938 ridx () + nz + rnz);
1942 std::copy_n (rhs.
data (), rnz, data () + li);
1953 std::copy_n (tmp.
data (), li, data ());
1954 std::copy_n (tmp.
ridx (), li, ridx ());
1957 std::copy_n (rhs.
data (), rnz, data () + li);
1961 std::copy (tmp.
data () + ui, tmp.
data () + nz,
1962 data () + li + rnz);
1963 std::copy (tmp.
ridx () + ui, tmp.
ridx () + nz,
1964 ridx () + li + rnz);
1969 else if (idx.is_range () && idx.increment () == -1)
1974 else if (idx.is_permutation (
n))
1976 *
this = rhs.
index (idx.inverse_permutation (
n));
1978 else if (rhs.
nnz () == 0)
1986 if (li != nz && ri[li] == iidx)
1990 maybe_compress (
true);
2011 *
this = index (octave::idx_vector::colon);
2012 assign (idx, rhs.
index (octave::idx_vector::colon));
2013 *
this = reshape (save_dims);
2018 rhl = idx.length (
n);
2019 if (rhs.
nnz () != 0)
2028 template <
typename T,
typename Alloc>
2041 template <
typename T,
typename Alloc>
2050 assert (ndims () == 2);
2062 bool orig_zero_by_zero = (nr == 0 && nc == 0);
2064 if (orig_zero_by_zero || (idx_i.length (nr) ==
n && idx_j.length (nc) ==
m))
2069 if (orig_zero_by_zero)
2071 if (idx_i.is_colon ())
2075 if (idx_j.is_colon ())
2078 ncx = idx_j.extent (nc);
2080 else if (idx_j.is_colon ())
2082 nrx = idx_i.extent (nr);
2087 nrx = idx_i.extent (nr);
2088 ncx = idx_j.extent (nc);
2093 nrx = idx_i.extent (nr);
2094 ncx = idx_j.extent (nc);
2098 if (nrx != nr || ncx != nc)
2106 if (
n == 0 ||
m == 0)
2109 if (idx_i.is_colon ())
2114 if (idx_j.is_colon ())
2116 else if (idx_j.is_cont_range (nc, lb, ub))
2124 if (new_nz >= nz && new_nz <= nzmax ())
2131 std::copy_backward (data () + ui, data () + nz,
2133 std::copy_backward (ridx () + ui, ridx () + nz,
2139 std::copy_n (rhs.
data (), rnz, data () + li);
2140 std::copy_n (rhs.
ridx (), rnz, ridx () + li);
2144 assert (nnz () == new_nz);
2154 std::copy_n (tmp.
data (), li, data ());
2155 std::copy_n (tmp.
ridx (), li, ridx ());
2156 std::copy_n (tmp.
cidx () + 1, lb, cidx () + 1);
2159 std::copy_n (rhs.
data (), rnz, data () + li);
2160 std::copy_n (rhs.
ridx (), rnz, ridx () + li);
2165 std::copy (tmp.
data () + ui, tmp.
data () + nz,
2166 data () + li + rnz);
2167 std::copy (tmp.
ridx () + ui, tmp.
ridx () + nz,
2168 ridx () + li + rnz);
2170 tmp.
cidx () + ub + 1, new_nz - nz);
2172 assert (nnz () == new_nz);
2175 else if (idx_j.is_range () && idx_j.increment () == -1)
2178 assign (idx_i, idx_j.sorted (),
2181 else if (idx_j.is_permutation (nc))
2183 *
this = rhs.
index (idx_i, idx_j.inverse_permutation (nc));
2193 xcidx (i+1) = tmp.
cidx (i+1) - tmp.
cidx (i);
2199 xcidx (j+1) = rhs.
cidx (i+1) - rhs.
cidx (i);
2204 xcidx (i+1) += xcidx (i);
2206 change_capacity (nnz ());
2218 std::copy_n (rhs.
data () + k, u - l, xdata () + l);
2219 std::copy_n (rhs.
ridx () + k, u - l, xridx () + l);
2225 std::copy_n (tmp.
data () + k, u - l, xdata () + l);
2226 std::copy_n (tmp.
ridx () + k, u - l, xridx () + l);
2232 else if (nc == 1 && idx_j.is_colon_equiv (nc) && idx_i.isvector ())
2235 assign (idx_i, rhs);
2237 else if (idx_j.is_colon ())
2239 if (idx_i.is_permutation (nr))
2241 *
this = rhs.
index (idx_i.inverse_permutation (nr), idx_j);
2250 assign (octave::idx_vector::colon, idx_i, rhs.
transpose ());
2258 tmp.
assign (idx_i, octave::idx_vector::colon, rhs);
2259 assign (octave::idx_vector::colon, idx_j, tmp);
2262 else if (
m == 1 &&
n == 1)
2264 n = idx_i.length (nr);
2265 m = idx_j.length (nc);
2266 if (rhs.
nnz () != 0)
2271 else if (idx_i.length (nr) ==
m && idx_j.length (nc) ==
n
2272 && (
n == 1 ||
m == 1))
2274 assign (idx_i, idx_j, rhs.
transpose ());
2280 template <
typename T,
typename Alloc>
2296 template <
typename T>
2305 template <
typename T>
2314 template <
typename T,
typename Alloc>
2324 if (
m.numel () < 1 || dim > 1)
2327 bool sort_by_column = (dim > 0);
2342 (
"Sparse<T, Alloc>::sort: invalid MODE");
2356 for (i = 0; i < ns; i++)
2357 if (sparse_ascending_compare<T> (
static_cast<T
> (0), v[i]))
2362 for (i = 0; i < ns; i++)
2363 if (sparse_descending_compare<T> (
static_cast<T
> (0), v[i]))
2369 mridx[k] = k - ns + nr;
2381 template <
typename T,
typename Alloc>
2392 if (
m.numel () < 1 || dim > 1)
2398 bool sort_by_column = (dim > 0);
2408 indexed_sort.
set_compare (sparse_ascending_compare<T>);
2410 indexed_sort.
set_compare (sparse_descending_compare<T>);
2413 (
"Sparse<T, Alloc>::sort: invalid MODE");
2430 sidx(offset + k) = k;
2437 indexed_sort.
sort (v, vi, ns);
2442 for (i = 0; i < ns; i++)
2443 if (sparse_ascending_compare<T> (
static_cast<T
> (0), v[i]))
2448 for (i = 0; i < ns; i++)
2449 if (sparse_descending_compare<T> (
static_cast<T
> (0), v[i]))
2457 if (ii < ns && mridx[ii] == k)
2460 sidx(offset + jj++) = k;
2465 sidx(k + offset) = vi[k];
2471 sidx(k - ns + nr + offset) = vi[k];
2472 mridx[k] = k - ns + nr;
2489 template <
typename T,
typename Alloc>
2498 if (nnr == 0 || nnc == 0)
2500 else if (nnr != 1 && nnc != 1)
2507 if (nnr > 0 && nnc > 0)
2516 if (
elem (i, i+k) != 0.)
2522 if (
elem (i-k, i) != 0.)
2528 if (
elem (i, i) != 0.)
2541 T tmp =
elem (i, i+k);
2553 T tmp =
elem (i-k, i);
2565 T tmp =
elem (i, i);
2616 d.xdata (i) = data (i);
2617 d.xridx (i) = j + roff;
2619 d.xcidx (j + coff + 1) = cidx (j+1);
2645 d.xdata (ii) = data (ii);
2646 d.xridx (ii++) = ir + roff;
2651 d.xcidx (i + coff + 1) = ii;
2663 template <
typename T,
typename Alloc>
2672 if (dim == -1 || dim == -2)
2678 (*current_liboctave_error_handler) (
"cat: invalid dimension");
2682 if (dim != 0 && dim != 1)
2683 (*current_liboctave_error_handler)
2684 (
"cat: invalid dimension for sparse concatenation");
2687 return sparse_list[0];
2691 if (! (dv.*concat_rule) (sparse_list[i].
dims (), dim))
2692 (*current_liboctave_error_handler) (
"cat: dimension mismatch");
2694 total_nz += sparse_list[i].
nnz ();
2729 rcum += spi.
rows ();
2732 retval.
xcidx (j+1) = l;
2745 if (sparse_list[i].isempty ())
2763 template <
typename T,
typename Alloc>
2775 retval.
xelem (j) = data (i++);
2782 retval.
xelem (ridx (i), j) = data (i);
2788 template <
typename T>
2792 T (*read_fcn) (std::istream&))
2798 if (nr > 0 && nc > 0)
2820 std::string err_field;
2822 (*current_liboctave_error_handler)
2823 (
"invalid sparse matrix: element %" OCTAVE_IDX_TYPE_FORMAT
": "
2824 "Symbols '%s' is not an integer format",
2825 i+1, err_field.c_str ());
2828 if (itmp < 0 || itmp >= nr)
2830 is.setstate (std::ios::failbit);
2832 (*current_liboctave_error_handler)
2833 (
"invalid sparse matrix: element %" OCTAVE_IDX_TYPE_FORMAT
": "
2834 "row index = %" OCTAVE_IDX_TYPE_FORMAT
" out of range",
2838 if (jtmp < 0 || jtmp >= nc)
2840 is.setstate (std::ios::failbit);
2842 (*current_liboctave_error_handler)
2843 (
"invalid sparse matrix: element %" OCTAVE_IDX_TYPE_FORMAT
": "
2844 "column index = %" OCTAVE_IDX_TYPE_FORMAT
" out of range",
2850 is.setstate (std::ios::failbit);
2852 (*current_liboctave_error_handler)
2853 (
"invalid sparse matrix: element %" OCTAVE_IDX_TYPE_FORMAT
":"
2854 "column indices must appear in ascending order "
2855 "(%" OCTAVE_IDX_TYPE_FORMAT
" < %" OCTAVE_IDX_TYPE_FORMAT
")",
2858 else if (jtmp > jold)
2863 else if (itmp < iold)
2865 is.setstate (std::ios::failbit);
2867 (*current_liboctave_error_handler)
2868 (
"invalid sparse matrix: element %" OCTAVE_IDX_TYPE_FORMAT
": "
2869 "row indices must appear in ascending order in each column "
2870 "(%" OCTAVE_IDX_TYPE_FORMAT
" < %" OCTAVE_IDX_TYPE_FORMAT
")",
2877 tmp = read_fcn (is);
2883 a.
ridx (ii++) = itmp;
3091 template <
typename T,
typename Alloc>
3096 os << prefix <<
"m_rep address: " << m_rep <<
"\n"
3097 << prefix <<
"m_rep->m_nzmax: " << m_rep->m_nzmax <<
"\n"
3098 << prefix <<
"m_rep->m_nrows: " << m_rep->m_nrows <<
"\n"
3099 << prefix <<
"m_rep->m_ncols: " << m_rep->m_ncols <<
"\n"
3100 << prefix <<
"m_rep->m_data: " << m_rep->m_data <<
"\n"
3101 << prefix <<
"m_rep->m_ridx: " << m_rep->m_ridx <<
"\n"
3102 << prefix <<
"m_rep->m_cidx: " << m_rep->m_cidx <<
"\n"
3103 << prefix <<
"m_rep->m_count: " << m_rep->m_count <<
"\n";
3106 #if defined (__clang__)
3107 # define INSTANTIATE_SPARSE(T) \
3108 template class OCTAVE_API Sparse<T>; \
3109 template OCTAVE_API std::istream& \
3110 read_sparse_matrix<T> (std::istream& is, Sparse<T>& a, \
3111 T (*read_fcn) (std::istream&));
3113 # define INSTANTIATE_SPARSE(T) \
3114 template class Sparse<T>; \
3115 template OCTAVE_API std::istream& \
3116 read_sparse_matrix<T> (std::istream& is, Sparse<T>& a, \
3117 T (*read_fcn) (std::istream&));
class OCTAVE_TEMPLATE_API Sparse
OCTAVE_API bool sparse_descending_compare(typename ref_param< T >::type a, typename ref_param< T >::type b)
static octave_idx_type lblookup(const octave_idx_type *ridx, octave_idx_type nr, octave_idx_type ri)
OCTAVE_API bool sparse_ascending_compare(typename ref_param< T >::type a, typename ref_param< T >::type b)
OCTAVE_API std::istream & read_sparse_matrix(std::istream &is, Sparse< T > &a, T(*read_fcn)(std::istream &))
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
OCTARRAY_API Array< T, Alloc > transpose(void) const
Size of the specified dimension.
OCTARRAY_API Array< T, Alloc > index(const octave::idx_vector &i) const
Indexing without resizing.
OCTARRAY_OVERRIDABLE_FUNC_API const T * data(void) const
Size of the specified dimension.
OCTARRAY_API void assign(const octave::idx_vector &i, const Array< T, Alloc > &rhs, const T &rfv)
Indexed assignment (always with resize & fill).
OCTARRAY_OVERRIDABLE_FUNC_API Array< T, Alloc > as_matrix(void) const
Return the array as a matrix.
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type numel(void) const
Number of elements in the array.
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type rows(void) const
OCTARRAY_API T * fortran_vec(void)
Size of the specified dimension.
OCTARRAY_OVERRIDABLE_FUNC_API T & elem(octave_idx_type n)
Size of the specified dimension.
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type cols(void) const
OCTARRAY_OVERRIDABLE_FUNC_API T & xelem(octave_idx_type n)
Size of the specified dimension.
const Array< octave_idx_type > & col_perm_vec(void) const
octave_idx_type rows(void) const
OCTAVE_API T celem(octave_idx_type r, octave_idx_type c) const
OCTAVE_API void change_length(octave_idx_type nz)
octave::refcount< octave_idx_type > m_count
OCTAVE_API bool any_element_is_nan(void) const
OCTAVE_API bool indices_ok(void) const
OCTAVE_API T & elem(octave_idx_type r, octave_idx_type c)
OCTAVE_API void maybe_compress(bool remove_zeros)
octave_idx_type rows(void) const
octave_idx_type * cidx(void)
octave_idx_type columns(void) const
OCTAVE_API Sparse< T, Alloc > & insert(const Sparse< T, Alloc > &a, octave_idx_type r, octave_idx_type c)
octave_idx_type * ridx(void)
static OCTAVE_API Sparse< T, Alloc >::SparseRep * nil_rep(void)
OCTAVE_API void print_info(std::ostream &os, const std::string &prefix) const
OCTAVE_API Sparse< T, Alloc > transpose(void) const
OCTAVE_API Sparse< T, Alloc > permute(const Array< octave_idx_type > &vec, bool inv=false) const
OCTAVE_API void resize(octave_idx_type r, octave_idx_type c)
OCTAVE_API void assign(const octave::idx_vector &i, const Sparse< T, Alloc > &rhs)
octave_idx_type nnz(void) const
Actual number of nonzero terms.
OCTAVE_API Array< T > array_value(void) const
dim_vector dims(void) const
Sparse< T, Alloc >::SparseRep * m_rep
OCTAVE_API Sparse< T, Alloc > index(const octave::idx_vector &i, bool resize_ok=false) const
OCTAVE_API Sparse< T, Alloc > reshape(const dim_vector &new_dims) const
OCTAVE_API Sparse< T, Alloc > sort(octave_idx_type dim=0, sortmode mode=ASCENDING) const
OCTAVE_API Sparse< T, Alloc > diag(octave_idx_type k=0) const
Sparse< T, Alloc > maybe_compress(bool remove_zeros=false)
OCTAVE_API octave_idx_type compute_index(const Array< octave_idx_type > &ra_idx) const
octave_idx_type nzmax(void) const
Amount of storage for nonzero elements.
OCTAVE_API Sparse< T, Alloc > & operator=(const Sparse< T, Alloc > &a)
OCTAVE_API void delete_elements(const octave::idx_vector &i)
OCTAVE_API void resize1(octave_idx_type n)
octave_idx_type cols(void) const
void change_capacity(octave_idx_type nz)
OCTAVE_NORETURN OCTAVE_API T range_error(const char *fcn, octave_idx_type n) const
static OCTAVE_API Sparse< T, Alloc > cat(int dim, octave_idx_type n, const Sparse< T, Alloc > *sparse_list)
octave_idx_type numel(void) const
octave_idx_type * xcidx(void)
octave_idx_type * xridx(void)
Vector representing the dimensions (size) of an Array.
OCTAVE_API bool concat(const dim_vector &dvb, int dim)
This corresponds to cat().
OCTAVE_API 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_API bool hvcat(const dim_vector &dvb, int dim)
This corresponds to [,] (horzcat, dim = 0) and [;] (vertcat, dim = 1).
octave_idx_type ndims(void) const
Number of dimensions.
OCTAVE_API dim_vector redim(int n) const
Force certain dimensionality, preserving numel ().
OCTAVE_API octave_idx_type safe_numel(void) const
The following function will throw a std::bad_alloc () exception if the requested size is larger than ...
virtual octave_idx_type numel(void) 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
static OCTAVE_NORETURN void err_index_out_of_range(void)
octave::idx_vector idx_vector
void err_invalid_resize(void)
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)
static void transpose(octave_idx_type N, const octave_idx_type *ridx, const octave_idx_type *cidx, octave_idx_type *ridx2, octave_idx_type *cidx2)