57 : rep (new typename
Sparse<T>::
SparseRep (a.rows (), a.cols (), a.rows ())),
89 for (i =
c[_c]; i <
c[_c + 1]; i++)
99 (*current_liboctave_error_handler)
100 (
"Sparse::SparseRep::elem (octave_idx_type, octave_idx_type): sparse matrix filled");
124 (*current_liboctave_error_handler)
125 (
"Sparse::SparseRep::elem (octave_idx_type, octave_idx_type): sparse matrix filled");
151 for (i = i; i < u; i++)
161 change_length (c[ncols]);
173 static const int frac = 5;
174 if (nz > nzmx || nz < nzmx - nzmx/frac)
185 T * new_data =
new T [nz];
232 : rep (0), dimensions (dv)
236 (
"Sparse::Sparse (const dim_vector&): dimension mismatch");
243 : rep (0), dimensions (dv)
247 unsigned long long a_nel =
static_cast<unsigned long long>(a.
rows ()) *
248 static_cast<unsigned long long>(a.
cols ());
249 unsigned long long dv_nel =
static_cast<unsigned long long>(dv (0)) *
250 static_cast<unsigned long long>(dv (1));
253 (*current_liboctave_error_handler)
254 (
"Sparse::Sparse (const Sparse&, const dim_vector&): dimension mismatch");
281 xcidx (k+1) = new_nzmx;
290 : rep (0), dimensions ()
294 else if (r.
extent (nr) > nr)
300 else if (c.
extent (nc) > nc)
302 (
"sparse: column index %d out of bound %d", r.
extent (nc), nc);
307 bool a_scalar = n == 1;
316 if ((rl != 1 && rl != n) || (cl != 1 && cl != n))
317 (*current_liboctave_error_handler) (
"sparse: dimension mismatch");
322 if (rl <= 1 && cl <= 1)
324 if (n == 1 && a(0) != T ())
332 xcidx (j+1) = j >= c(0);
354 new_nz += rd[i-1] != rd[i];
419 sidx[ci[cd[i]+1]++] = rd[0];
421 sidx[ci[cd[i]+1]++] = rd[i];
427 std::sort (sidx + ci[j], sidx + ci[j+1]);
497 new_nz += rd[i-1] != rd[i];
516 if (rd[i] != rd[i-1])
530 if (rd[i] != rd[i-1])
557 typedef std::pair<octave_idx_type, octave_idx_type> idx_pair;
562 idx_pair& p = spairs[ci[cd[i]+1]++];
574 std::sort (spairs + ci[j], spairs + ci[j+1]);
608 rrd[++jj] = a(spairs[i].second);
612 rrd[jj] += a(spairs[i].second);
626 rrd[jj] = a(spairs[i].second);
637 : rep (0), dimensions (a.dims ())
641 (
"Sparse::Sparse (const Array<T>&): dimension mismatch");
661 if (a.
elem (i,j) != T ())
674 if (--rep->count == 0)
684 if (--rep->count == 0)
704 if (n > 0 && n == ra_idx.
length ())
706 retval = ra_idx(--n);
710 retval *= dimensions(n);
716 (
"Sparse<T>::compute_index: invalid ra_idxing operation");
725 (*current_liboctave_error_handler) (
"%s (%d): range error", fcn, n);
733 (*current_liboctave_error_handler) (
"%s (%d): range error", fcn, n);
743 (*current_liboctave_error_handler)
744 (
"%s (%d, %d): range error", fcn, i, j);
752 (*current_liboctave_error_handler)
753 (
"%s (%d, %d): range error", fcn, i, j);
763 std::ostringstream buf;
773 buf <<
", " << ra_idx(i);
775 buf <<
"): range error";
777 std::string buf_str = buf.str ();
779 (*current_liboctave_error_handler) (buf_str.c_str ());
788 std::ostringstream buf;
798 buf <<
", " << ra_idx(i);
800 buf <<
"): range error";
802 std::string buf_str = buf.str ();
804 (*current_liboctave_error_handler) (buf_str.c_str ());
819 (*current_liboctave_warning_handler)
820 (
"reshape: sparse reshape to N-d array smashes dims");
823 dims2(1) *= dims2(i);
828 if (dimensions != dims2)
830 if (dimensions.numel () == dims2.
numel ())
837 retval =
Sparse<T> (new_nr, new_nc, new_nnz);
840 retval.
xcidx (0) = 0;
848 retval.
xcidx (k+1) = j;
850 retval.
xdata (j) = data (j);
851 retval.
xridx (j) = ii;
854 retval.
xcidx (k+1) = new_nnz;
858 std::string dimensions_str = dimensions.str ();
859 std::string new_dims_str = new_dims.
str ();
861 (*current_liboctave_error_handler)
862 (
"reshape: can't reshape %s array to %s array",
863 dimensions_str.c_str (), new_dims_str.c_str ());
881 if (perm_vec.
length () == 2)
883 if (perm_vec(0) == 0 && perm_vec(1) == 1)
885 else if (perm_vec(0) == 1 && perm_vec(1) == 0)
894 (*current_liboctave_error_handler)
895 (
"permutation vector contains an invalid element");
897 return trans ? this->
transpose () : *
this;
909 resize (nr, (n + nr - 1) / nr);
926 (*current_liboctave_error_handler) (
"sparse array must be 2-D");
930 resize (dv(0), dv(1));
939 (*current_liboctave_error_handler)
940 (
"can't resize to negative dimension");
944 if (r == dim1 () && c == dim2 ())
957 for (i = i; i < u; i++)
960 xdata (k) = xdata (i);
961 xridx (k++) = xridx (i);
967 rep->nrows = dimensions(0) = r;
978 rep->c + rep->ncols + 1);
981 rep->ncols = dimensions(1) = c;
983 rep->change_length (rep->nnz ());
995 if (r < 0 || r + a_rows > rows () || c < 0 || c + a_cols > cols ())
997 (*current_liboctave_error_handler) (
"range error for insert");
1004 if (c + a_cols < nc)
1005 nel += cidx (nc) - cidx (c + a_cols);
1009 if (ridx (j) < r || ridx (j) >= r + a_rows)
1018 data (i) = tmp.
data (i);
1019 ridx (i) = tmp.
ridx (i);
1022 cidx (i) = tmp.
cidx (i);
1031 if (tmp.
ridx (j) < r)
1033 data (ii) = tmp.
data (j);
1034 ridx (ii++) = tmp.
ridx (j);
1041 data (ii) = a.
data (j);
1042 ridx (ii++) = r + a.
ridx (j);
1048 if (tmp.
ridx (j) >= r + a_rows)
1050 data (ii) = tmp.
data (j);
1051 ridx (ii++) = tmp.
ridx (j);
1061 data (ii) = tmp.
data (j);
1062 ridx (ii++) = tmp.
ridx (j);
1075 if (ra_idx.
length () != 2)
1077 (*current_liboctave_error_handler) (
"range error for insert");
1081 return insert (a, ra_idx (0), ra_idx (1));
1088 assert (ndims () == 2);
1096 retval.
xcidx (ridx (i) + 1)++;
1102 retval.
xcidx (i) = nz;
1111 retval.
xridx (q) = j;
1112 retval.
xdata (q) = data (k);
1114 assert (nnz () == retval.
xcidx (nr));
1131 for (l = 0; l < nr; l++)
1137 return std::lower_bound (ridx, ridx + nr, ri) - ridx;
1146 assert (ndims () == 2);
1156 if (idx.
extent (nel) > nel)
1173 *
this =
Sparse<T> (nr - (ub - lb), 1, nz_new);
1190 for (; j < sl && sj[j] < r; j++) ;
1191 if (j == sl || sj[j] > r)
1193 data_new[nz_new] = tmp.
data (i);
1194 ridx_new[nz_new++] = r - j;
1214 *
this =
Sparse<T> (1, nc - (ub - lb), new_nz);
1217 fill_or_memset (new_nz, static_cast<octave_idx_type> (0), ridx ());
1225 else if (idx.
length (nel) != 0)
1232 delete_elements (idx);
1242 assert (ndims () == 2);
1252 if (idx_j.
extent (nc) > nc)
1256 if (lb == 0 && ub == nc)
1273 *
this =
Sparse<T> (nr, nc - (ub - lb), new_nz);
1280 tmp.
cidx () + ub + 1, ubi - lbi);
1284 *
this = index (idx_i, idx_j.
complement (nc));
1290 if (idx_i.
extent (nr) > nr)
1294 if (lb == 0 && ub == nr)
1310 tmpl.
nnz () + tmpu.
nnz ());
1316 xdata(k) = tmpl.
data(i);
1317 xridx(k++) = tmpl.
ridx(i);
1322 xdata(k) = tmpu.
data(i);
1323 xridx(k++) = tmpu.
ridx(i) + lb;
1348 bool empty_assignment
1351 if (! empty_assignment)
1352 (*current_liboctave_error_handler)
1353 (
"a null assignment can only have one non-colon index");
1367 (*current_liboctave_error_handler)
1368 (
"invalid dimension in delete_elements");
1379 assert (ndims () == 2);
1389 if (idx_dims.
length () > 2)
1391 (
"cannot index sparse matrix with an N-D Array");
1405 retval.
xdata (j) = data (j);
1406 retval.
xridx (j) = ridx (j) + i * nr;
1410 retval.
xcidx (0) = 0;
1411 retval.
xcidx (1) = nz;
1414 else if (idx.
extent (nel) > nel)
1422 retval = tmp.
index (idx);
1427 else if (nr == 1 && nc == 1)
1434 retval =
Sparse<T> (idx_dims(0), idx_dims(1), nz ? data (0) : T ());
1445 if (i < nz && ridx (i) == idx(0))
1446 retval =
Sparse (1, 1, data (i));
1458 retval =
Sparse<T> (ub - lb, 1, nz_new);
1461 retval.
xcidx (1) = nz_new;
1470 retval.
ridx (j) = nr - ridx (nz - j - 1) - 1;
1473 std::reverse_copy (data (), data () + nz, retval.
data ());
1478 tmp = tmp.
index (idx);
1497 lidx(i) =
lblookup (ridx (), nz, idxa(i));
1507 if (l < nz && ridx (l) == idxa(i, j))
1525 retval.
data (k) = data (l);
1526 retval.
xridx (k++) = i;
1540 retval =
Sparse<T> (1, ub - lb, new_nz);
1550 retval =
Sparse<T> (array_value ().index (idx));
1566 if (idx_dims(0) == 1 && idx_dims(1) != 1)
1577 bool resize_ok)
const
1581 assert (ndims () == 2);
1599 tmp.
resize (ext_i, ext_j);
1600 retval = tmp.
index (idx_i, idx_j);
1602 else if (idx_i.
extent (nr) > nr)
1607 else if (nr == 1 && nc == 1)
1613 retval =
Sparse<T> (array_value ().index (idx_i, idx_j));
1625 retval =
Sparse<T> (nr, ub - lb, new_nz);
1637 retval.
xcidx (j+1) = retval.
xcidx (j) + (cidx (jj+1) - cidx (jj));
1657 retval = index (idx_i);
1677 if (i < nzj && ridx (i+lj) == ii)
1692 if (retval.
xcidx (j+1) > i)
1694 retval.
xridx (i) = 0;
1695 retval.
xdata (i) = data (ij[j]);
1713 li[j] = lij =
lblookup (ridx () + lj, nzj, lb) + lj;
1714 ui[j] = uij =
lblookup (ridx () + lj, nzj, ub) + lj;
1715 retval.
xcidx (j+1) = retval.
xcidx (j) + ui[j] - li[j];
1726 retval.
xdata (k) = data (i);
1727 retval.
xridx (k++) = ridx (i) - lb;
1739 retval.
xcidx (j+1) = retval.
xcidx (j) + (cidx (jj+1) - cidx (jj));
1758 retval.
xdata (li + i) = data (uj - i);
1759 retval.
xridx (li + i) = nr - 1 - ridx (uj - i);
1782 scb[rri[li + i] = iinv[ridx (lj + i)]] = data (lj + i);
1787 std::sort (rri + li, rri + li + nzj);
1791 retval.
xdata (li + i) = scb[rri[li + i]];
1821 assert (ndims () == 2);
1831 if (idx.
length (n) == rhl)
1849 *
this = rhs.
reshape (dimensions);
1851 else if (nc == 1 && rhs.
cols () == 1)
1864 if (new_nz >= nz && new_nz <= capacity ())
1871 std::copy_backward (data () + ui, data () + nz,
1872 data () + nz + rnz);
1873 std::copy_backward (ridx () + ui, ridx () + nz,
1874 ridx () + nz + rnz);
1898 data () + li + rnz);
1900 ridx () + li + rnz);
1914 else if (rhs.
nnz () == 0)
1922 if (li != nz && ri[li] == iidx)
1926 maybe_compress (
true);
1951 *
this = reshape (save_dims);
1957 if (rhs.
nnz () != 0)
1973 assert (ndims () == 2);
1985 bool orig_zero_by_zero = (nr == 0 && nc == 0);
1987 if (orig_zero_by_zero || (idx_i.
length (nr) == n && idx_j.
length (nc) == m))
1992 if (orig_zero_by_zero)
2021 if (nrx != nr || ncx != nc)
2029 if (n == 0 || m == 0)
2045 if (new_nz >= nz && new_nz <= capacity ())
2052 std::copy (data () + ui, data () + nz,
2053 data () + li + rnz);
2054 std::copy (ridx () + ui, ridx () + nz,
2055 ridx () + li + rnz);
2065 assert (nnz () == new_nz);
2087 data () + li + rnz);
2089 ridx () + li + rnz);
2091 tmp.
cidx () + ub + 1, new_nz - nz);
2093 assert (nnz () == new_nz);
2099 assign (idx_i, idx_j.
sorted (),
2114 xcidx (i+1) = tmp.
cidx (i+1) - tmp.
cidx (i);
2120 xcidx (j+1) = rhs.
cidx (i+1) - rhs.
cidx (i);
2125 xcidx (i+1) += xcidx (i);
2127 change_capacity (nnz ());
2154 assign (idx_i, rhs);
2181 else if (m == 1 && n == 1)
2185 if (rhs.
nnz () != 0)
2188 assign (idx_i, idx_j,
Sparse<T> (n, m));
2221 if (m.
length () < 1 || dim > 1)
2252 for (i = 0; i < ns; i++)
2253 if (sparse_ascending_compare<T> (static_cast<T> (0), v[i]))
2258 for (i = 0; i < ns; i++)
2259 if (sparse_descending_compare<T> (static_cast<T> (0), v[i]))
2265 mridx[k] = k - ns + nr;
2287 if (m.
length () < 1 || dim > 1)
2303 indexed_sort.
set_compare (sparse_ascending_compare<T>);
2305 indexed_sort.
set_compare (sparse_descending_compare<T>);
2324 sidx (offset + k) = k;
2331 indexed_sort.
sort (v, vi, ns);
2336 for (i = 0; i < ns; i++)
2337 if (sparse_ascending_compare<T> (static_cast<T> (0), v[i]))
2342 for (i = 0; i < ns; i++)
2343 if (sparse_descending_compare<T> (static_cast<T> (0), v[i]))
2351 if (ii < ns && mridx[ii] == k)
2354 sidx (offset + jj++) = k;
2359 sidx (k + offset) = vi[k];
2365 sidx (k - ns + nr + offset) = vi[k];
2366 mridx[k] = k - ns + nr;
2391 if (nnr == 0 || nnc == 0)
2393 else if (nnr != 1 && nnc != 1)
2400 if (nnr > 0 && nnc > 0)
2409 if (
elem (i, i+k) != 0.)
2415 if (
elem (i-k, i) != 0.)
2421 if (
elem (i, i) != 0.)
2434 T tmp =
elem (i, i+k);
2446 T tmp =
elem (i-k, i);
2458 T tmp =
elem (i, i);
2469 (
"diag: requested diagonal out of range");
2471 else if (nnr != 0 && nnc != 0)
2502 d.
xdata (i) = data (i);
2503 d.
xridx (i) = j + roff;
2505 d.
xcidx (j + coff + 1) = cidx (j+1);
2531 d.
xdata (ii) = data (ii);
2532 d.
xridx (ii++) = ir + roff;
2537 d.
xcidx (i + coff + 1) = ii;
2556 if (dim == -1 || dim == -2)
2562 (*current_liboctave_error_handler)
2563 (
"cat: invalid dimension");
2567 if (dim == 0 || dim == 1)
2570 return sparse_list[0];
2574 if (! (dv.*concat_rule) (sparse_list[i].
dims (), dim))
2575 (*current_liboctave_error_handler)
2576 (
"cat: dimension mismatch");
2577 total_nz += sparse_list[i].
nnz ();
2582 (
"cat: invalid dimension for sparse concatenation");
2615 rcum += spi.
rows ();
2618 retval.
xcidx (j+1) = l;
2631 if (sparse_list[i].is_empty ())
2660 retval(j) = data (i++);
2667 retval(ridx (i), j) = data (i);
2871 os << prefix <<
"rep address: " << rep <<
"\n"
2872 << prefix <<
"rep->nzmx: " << rep->nzmx <<
"\n"
2873 << prefix <<
"rep->nrows: " << rep->nrows <<
"\n"
2874 << prefix <<
"rep->ncols: " << rep->ncols <<
"\n"
2875 << prefix <<
"rep->data: " <<
static_cast<void *
> (rep->d) <<
"\n"
2876 << prefix <<
"rep->ridx: " << static_cast<void *> (rep->r) <<
"\n"
2877 << prefix <<
"rep->cidx: " <<
static_cast<void *
> (rep->c) <<
"\n"
2878 << prefix <<
"rep->count: " << rep->count <<
"\n";
2881 #define INSTANTIATE_SPARSE(T, API) \
2882 template class API Sparse<T>;