44 template <
typename T,
typename Alloc>
54 template <
typename T,
typename Alloc>
56 : m_dimensions (dv), m_rep (a.m_rep),
57 m_slice_data (a.m_slice_data), m_slice_len (a.m_slice_len)
59 bool invalid_size =
false;
72 catch (
const std::bad_alloc&)
77 if (invalid_size || new_numel != a.
numel ())
82 (*current_liboctave_error_handler)
83 (
"reshape: can't reshape %s array to %s array",
84 dimensions_str.c_str (), new_dims_str.c_str ());
93 template <
typename T,
typename Alloc>
97 if (m_rep->m_count > 1)
101 m_slice_data = m_rep->m_data;
104 std::fill_n (m_slice_data, m_slice_len, val);
107 template <
typename T,
typename Alloc>
111 if (--m_rep->m_count == 0)
116 m_slice_data = m_rep->m_data;
117 m_slice_len = m_rep->m_len;
122 template <
typename T,
typename Alloc>
126 if (--m_rep->m_count == 0)
130 m_slice_data = m_rep->m_data;
131 m_slice_len = m_rep->m_len;
137 template <
typename T,
typename Alloc>
145 bool dims_changed =
false;
151 for (
int i = 0; i < ndims (); i++)
153 if (m_dimensions(i) == 1)
156 new_dimensions(k++) = m_dimensions(i);
171 new_dimensions.
resize (2);
173 new_dimensions(0) = tmp;
174 new_dimensions(1) = 1;
179 new_dimensions.
resize (k);
190 template <
typename T,
typename Alloc>
197 template <
typename T,
typename Alloc>
205 template <
typename T,
typename Alloc>
212 template <
typename T,
typename Alloc>
219 if (
n >= m_slice_len)
220 octave::err_index_out_of_range (1, 1,
n+1, m_slice_len, m_dimensions);
225 template <
typename T,
typename Alloc>
232 template <
typename T,
typename Alloc>
239 template <
typename T,
typename Alloc>
246 template <
typename T,
typename Alloc>
253 if (
n >= m_slice_len)
254 octave::err_index_out_of_range (1, 1,
n+1, m_slice_len, m_dimensions);
259 template <
typename T,
typename Alloc>
266 template <
typename T,
typename Alloc>
274 template <
typename T,
typename Alloc>
281 template <
typename T,
typename Alloc>
290 template <
typename T,
typename Alloc>
301 template <
typename T,
typename Alloc>
312 class rec_permute_helper
319 m_stride (m_dim + m_n), m_use_blk (false)
321 assert (m_n == perm.
numel ());
326 for (
int i = 1; i < m_n+1; i++) cdim[i] = cdim[i-1] * dv(i-1);
329 for (
int k = 0; k < m_n; k++)
333 m_stride[k] = cdim[kk];
337 for (
int k = 1; k < m_n; k++)
339 if (m_stride[k] == m_stride[m_top]*m_dim[m_top])
340 m_dim[m_top] *= m_dim[k];
344 m_dim[m_top] = m_dim[k];
345 m_stride[m_top] = m_stride[k];
350 m_use_blk = m_top >= 1 && m_stride[1] == 1 && m_stride[0] == m_dim[1];
354 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (rec_permute_helper)
356 ~rec_permute_helper () {
delete [] m_dim; }
358 template <
typename T>
359 void permute (
const T *src, T *dest)
const { do_permute (src, dest, m_top); }
362 template <
typename T>
373 if (lr ==
m && lc ==
m)
375 const T *ss = src + kc * nr + kr;
378 blk[j*
m+i] = ss[j*nr + i];
379 T *dd = dest + kr * nc + kc;
382 dd[j*nc+i] = blk[i*
m+j];
386 const T *ss = src + kc * nr + kr;
389 blk[j*
m+i] = ss[j*nr + i];
390 T *dd = dest + kr * nc + kc;
393 dd[j*nc+i] = blk[i*
m+j];
403 template <
typename T>
404 T * do_permute (
const T *src, T *dest,
int lev)
const
412 std::copy_n (src,
len, dest);
423 else if (m_use_blk && lev == 1)
424 dest = blk_trans (src, dest, m_dim[1], m_dim[0]);
430 dest = do_permute (src + i * step, dest, lev-1);
448 template <
typename T,
typename Alloc>
458 int perm_vec_len = perm_vec_arg.
numel ();
460 if (perm_vec_len < dv.
ndims ())
461 (*current_liboctave_error_handler)
462 (
"%s: invalid permutation vector", inv ?
"ipermute" :
"permute");
467 dv.
resize (perm_vec_len, 1);
472 bool identity =
true;
475 for (
int i = 0; i < perm_vec_len; i++)
478 if (perm_elt >= perm_vec_len || perm_elt < 0)
479 (*current_liboctave_error_handler)
480 (
"%s: permutation vector contains an invalid element",
481 inv ?
"ipermute" :
"permute");
483 if (checked[perm_elt])
484 (*current_liboctave_error_handler)
485 (
"%s: permutation vector cannot contain identical elements",
486 inv ?
"ipermute" :
"permute");
489 checked[perm_elt] =
true;
490 identity = identity && perm_elt == i;
499 for (
int i = 0; i < perm_vec_len; i++)
500 perm_vec(perm_vec_arg(i)) = i;
503 for (
int i = 0; i < perm_vec_len; i++)
504 dv_new(i) = dv(perm_vec(i));
510 rec_permute_helper rh (dv, perm_vec);
523 class rec_index_helper
540 if (m_idx[m_top].maybe_reduce (m_dim[m_top], ia(i), dv(i)))
543 m_dim[m_top] *= dv(i);
549 m_idx[m_top] = ia(i);
550 m_dim[m_top] = dv(i);
551 m_cdim[m_top] = m_cdim[m_top-1] * m_dim[m_top-1];
556 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (rec_index_helper)
558 ~rec_index_helper () {
delete [] m_idx;
delete [] m_dim; }
560 template <
typename T>
561 void index (
const T *src, T *dest)
const { do_index (src, dest, m_top); }
563 template <
typename T>
564 void assign (
const T *src, T *dest)
const { do_assign (src, dest, m_top); }
566 template <
typename T>
567 void fill (
const T& val, T *dest)
const { do_fill (val, dest, m_top); }
571 return m_top == 0 && m_idx[0].is_cont_range (m_dim[0], l, u);
577 template <
typename T>
581 dest += m_idx[0].index (src, m_dim[0], dest);
587 dest = do_index (src +
d*m_idx[lev].xelem (i), dest, lev-1);
594 template <
typename T>
598 src += m_idx[0].assign (src, m_dim[0], dest);
604 src = do_assign (src, dest +
d*m_idx[lev].xelem (i), lev-1);
611 template <
typename T>
615 m_idx[0].fill (val, m_dim[0], dest);
621 do_fill (val, dest +
d*m_idx[lev].xelem (i), lev-1);
640 class rec_resize_helper
645 : m_cext (nullptr), m_sext (nullptr), m_dext (nullptr), m_n (0)
647 int l = ndv.
ndims ();
648 assert (odv.
ndims () == l);
651 for (; i < l-1 && ndv(i) == odv(i); i++) ld *= ndv(i);
655 m_sext = m_cext + m_n;
656 m_dext = m_sext + m_n;
660 for (
int j = 0; j < m_n; j++)
662 m_cext[j] =
std::min (ndv(i+j), odv(i+j));
663 m_sext[j] = sld *= odv(i+j);
664 m_dext[j] = dld *= ndv(i+j);
669 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (rec_resize_helper)
671 ~rec_resize_helper () {
delete [] m_cext; }
673 template <
typename T>
674 void resize_fill (
const T *src, T *dest,
const T& rfv)
const
675 { do_resize_fill (src, dest, rfv, m_n-1); }
680 template <
typename T>
681 void do_resize_fill (
const T *src, T *dest,
const T& rfv,
int lev)
const
685 std::copy_n (src, m_cext[0], dest);
686 std::fill_n (dest + m_cext[0], m_dext[0] - m_cext[0], rfv);
693 for (k = 0; k < m_cext[lev]; k++)
694 do_resize_fill (src + k * sd, dest + k * dd, rfv, lev - 1);
696 std::fill_n (dest + k * dd, m_dext[lev] - k * dd, rfv);
708 template <
typename T,
typename Alloc>
740 if (i.extent (
n) !=
n)
741 octave::err_index_out_of_range (1, 1, i.extent (
n),
n, m_dimensions);
743 dim_vector result_dims = i.orig_dimensions ();
746 if (
n != 1 && is_nd_vector () && idx_len != 1
758 if (idx_len != 0 && i.is_cont_range (
n, l, u))
775 template <
typename T,
typename Alloc>
785 if (i.is_colon () && j.is_colon ())
792 if (i.extent (
r) !=
r)
793 octave::err_index_out_of_range (2, 1, i.extent (
r),
r, m_dimensions);
794 if (j.extent (c) != c)
795 octave::err_index_out_of_range (2, 2, j.extent (c), c, m_dimensions);
803 if (ii.maybe_reduce (
r, j, c))
806 if (ii.length () > 0 && ii.is_cont_range (
n, l, u))
822 const T *src = data ();
826 dest += i.index (src +
r * j.xelem (k),
r, dest);
833 template <
typename T,
typename Alloc>
837 int ial = ia.
numel ();
842 retval = index (ia(0));
844 retval = index (ia(0), ia(1));
851 bool all_colons =
true;
852 for (
int i = 0; i < ial; i++)
854 if (ia(i).extent (dv(i)) != dv(i))
855 octave::err_index_out_of_range (ial, i+1, ia(i).extent (dv(i)), dv(i),
858 all_colons = all_colons && ia(i).is_colon ();
871 for (
int i = 0; i < ial; i++) rdv(i) = ia(i).length (dv(i));
875 rec_index_helper rh (dv, ia);
878 if (rh.is_cont_range (l, u))
897 template <
typename T,
typename Alloc>
901 static T zero = T ();
908 template <
typename T,
typename Alloc>
912 if (
n < 0 || ndims () != 2)
923 bool invalid =
false;
924 if (rows () == 0 || rows () == 1)
926 else if (columns () == 1)
935 if (
n == nx - 1 &&
n > 0)
938 if (m_rep->m_count == 1)
939 m_slice_data[m_slice_len-1] = T ();
943 else if (
n == nx + 1 && nx > 0)
946 if (m_rep->m_count == 1
947 && m_slice_data + m_slice_len < m_rep->m_data + m_rep->m_len)
949 m_slice_data[m_slice_len++] = rfv;
957 T *dest = tmp.fortran_vec ();
959 std::copy_n (data (), nx, dest);
972 std::copy_n (data (), n0, dest);
973 std::fill_n (dest + n0, n1, rfv);
979 template <
typename T,
typename Alloc>
983 if (
r < 0 || c < 0 || ndims () != 2)
988 if (
r != rx || c != cx)
997 const T *src = data ();
1000 std::copy_n (src,
r * c0, dest);
1007 std::copy_n (src, r0, dest);
1010 std::fill_n (dest, r1, rfv);
1015 std::fill_n (dest,
r * c1, rfv);
1021 template <
typename T,
typename Alloc>
1025 int dvl = dv.
ndims ();
1027 resize2 (dv(0), dv(1), rfv);
1028 else if (m_dimensions != dv)
1030 if (m_dimensions.ndims () > dvl || dv.
any_neg ())
1035 rec_resize_helper rh (dv, m_dimensions.
redim (dvl));
1038 rh.resize_fill (data (), tmp.
fortran_vec (), rfv);
1043 template <
typename T,
typename Alloc>
1060 if (tmp.
numel () != nx)
1064 return tmp.
index (i);
1067 template <
typename T,
typename Alloc>
1070 bool resize_ok,
const T& rfv)
const
1080 if (
r != rx || c != cx)
1082 if (i.is_scalar () && j.is_scalar ())
1092 return tmp.
index (i, j);
1095 template <
typename T,
typename Alloc>
1098 bool resize_ok,
const T& rfv)
const
1103 int ial = ia.
numel ();
1106 for (
int i = 0; i < ial; i++)
1107 dvx(i) = ia(i).extent (dv(i));
1110 bool all_scalars =
true;
1111 for (
int i = 0; i < ial; i++)
1112 all_scalars = all_scalars && ia(i).is_scalar ();
1123 return tmp.
index (ia);
1126 template <
typename T,
typename Alloc>
1133 if (rhl != 1 && i.length (
n) != rhl)
1137 bool colon = i.is_colon_equiv (nx);
1142 if (m_dimensions.zero_by_zero () && colon)
1161 *
this = rhs.
reshape (m_dimensions);
1166 i.fill (rhs(0),
n, fortran_vec ());
1168 i.assign (rhs.
data (),
n, fortran_vec ());
1173 template <
typename T,
typename Alloc>
1178 bool initial_dims_all_zero = m_dimensions.all_zero ();
1192 if (initial_dims_all_zero)
1196 rdv(0) = i.extent (dv(0));
1197 rdv(1) = j.extent (dv(1));
1200 bool isfill = rhs.
numel () == 1;
1204 bool match = (isfill
1205 || (rhdv.
ndims () == 2 && il == rhdv(0) && jl == rhdv(1)));
1206 match = match || (il == 1 && jl == rhdv(0) && rhdv(1) == 1);
1210 bool all_colons = (i.is_colon_equiv (rdv(0))
1211 && j.is_colon_equiv (rdv(1)));
1235 *
this = rhs.
reshape (m_dimensions);
1245 const T *src = rhs.
data ();
1246 T *dest = fortran_vec ();
1249 if (ii.maybe_reduce (
r, j, c))
1252 ii.fill (*src,
n, dest);
1254 ii.assign (src,
n, dest);
1261 i.fill (*src,
r, dest +
r * j.xelem (k));
1266 src += i.assign (src,
r, dest +
r * j.xelem (k));
1272 else if ((il != 0 && jl != 0) || (rhdv(0) != 0 && rhdv(1) != 0))
1277 template <
typename T,
typename Alloc>
1282 int ial = ia.
numel ();
1286 assign (ia(0), rhs, rfv);
1288 assign (ia(0), ia(1), rhs, rfv);
1291 bool initial_dims_all_zero = m_dimensions.all_zero ();
1305 if (initial_dims_all_zero)
1310 for (
int i = 0; i < ial; i++)
1311 rdv(i) = ia(i).extent (dv(i));
1316 bool all_colons =
true;
1317 bool isfill = rhs.
numel () == 1;
1321 int rhdvl = rhdv.
ndims ();
1322 for (
int i = 0; i < ial; i++)
1324 all_colons = all_colons && ia(i).is_colon_equiv (rdv(i));
1326 if (l == 1)
continue;
1327 match = match && j < rhdvl && l == rhdv(j++);
1330 match = match && (j == rhdvl || rhdv(j) == 1);
1331 match = match || isfill;
1359 *
this = rhs.
reshape (m_dimensions);
1366 rec_index_helper rh (dv, ia);
1370 rh.fill (rhs(0), fortran_vec ());
1372 rh.assign (rhs.
data (), fortran_vec ());
1378 bool lhsempty, rhsempty;
1379 lhsempty = rhsempty =
false;
1381 for (
int i = 0; i < ial; i++)
1385 lhsempty = lhsempty || (l == 0);
1386 rhsempty = rhsempty || (rhdv(j++) == 0);
1388 if (! lhsempty || ! rhsempty)
1405 template <
typename T,
typename Alloc>
1414 else if (i.length (
n) != 0)
1416 if (i.extent (
n) !=
n)
1420 bool col_vec = ndims () == 2 && columns () == 1 && rows () != 1;
1421 if (i.is_scalar () && i(0) ==
n-1 && m_dimensions.isvector ())
1426 else if (i.is_cont_range (
n, l, u))
1431 const T *src = data ();
1433 std::copy_n (src, l, dest);
1434 std::copy (src + u, src +
n, dest + l);
1440 *
this = index (i.complement (
n));
1445 template <
typename T,
typename Alloc>
1450 (*current_liboctave_error_handler) (
"invalid dimension in delete_elements");
1454 if (dim >= ndims ())
1455 dimensions.
resize (dim + 1, 1);
1464 else if (i.length (
n) != 0)
1466 if (i.extent (
n) !=
n)
1471 if (i.is_cont_range (
n, l, u))
1479 for (
int k = 0; k < dim; k++) dl *= dimensions(k);
1480 for (
int k = dim + 1; k < ndim; k++) du *= dimensions(k);
1484 const T *src = data ();
1486 l *= dl; u *= dl;
n *= dl;
1489 std::copy_n (src, l, dest);
1491 std::copy (src + u, src +
n, dest);
1502 ia (dim) = i.complement (
n);
1508 template <
typename T,
typename Alloc>
1512 int ial = ia.
numel ();
1515 delete_elements (ia(0));
1519 for (k = 0; k < ial; k++)
1521 if (! ia(k).is_colon ())
1537 delete_elements (dim, ia(dim));
1552 bool empty_assignment =
false;
1554 int num_non_colon_indices = 0;
1558 for (
int i = 0; i < ial; i++)
1562 if (ia(i).length (dim_len) == 0)
1564 empty_assignment =
true;
1568 if (! ia(i).is_colon_equiv (dim_len))
1570 num_non_colon_indices++;
1572 if (num_non_colon_indices == 2)
1577 if (! empty_assignment)
1578 (*current_liboctave_error_handler)
1579 (
"a null assignment can only have one non-colon index");
1585 template <
typename T,
typename Alloc>
1591 if (ndims () == 2 && a.
ndims () == 2)
1598 for (
int k = 2; k < a.
ndims (); k++)
1606 template <
typename T,
typename Alloc>
1621 template <
typename T,
typename Alloc>
1625 assert (ndims () == 2);
1630 if (nr >= 8 && nc >= 8)
1636 rec_permute_helper::blk_trans (data (), result.
fortran_vec (), nr, nc);
1640 else if (nr > 1 && nc > 1)
1646 result.
xelem (j, i) = xelem (i, j);
1657 template <
typename T>
1659 no_op_fcn (
const T&
x)
1664 template <
typename T,
typename Alloc>
1668 assert (ndims () == 2);
1676 if (nr >= 8 && nc >= 8)
1685 for (jj = 0; jj < (nc - 8 + 1); jj += 8)
1688 for (ii = 0; ii < (nr - 8 + 1); ii += 8)
1692 j < jj + 8; j++, idxj += nr)
1694 buf[k++] = xelem (i + idxj);
1701 result.
xelem (j + idxi) = fcn (buf[k]);
1707 result.
xelem (j, i) = fcn (xelem (i, j));
1712 result.
xelem (j, i) = fcn (xelem (i, j));
1722 result.
xelem (j, i) = fcn (xelem (i, j));
1762 template <
typename T,
typename Alloc>
1768 return m_slice_data;
1772 template <
typename T>
1779 template <
typename T,
typename Alloc>
1784 (*current_liboctave_error_handler) (
"sort: invalid dimension");
1793 if (dim >= dv.
ndims ())
1800 for (
int i = 0; i < dim; i++)
1803 T *v =
m.fortran_vec ();
1804 const T *ov = data ();
1828 if (sort_isnan<T> (tmp))
1840 std::reverse (v + ku, v + ns);
1842 std::rotate (v, v + ku, v + ns);
1857 offset += n_strides * stride * (ns - 1);
1864 T tmp = ov[i*stride + offset];
1865 if (sort_isnan<T> (tmp))
1872 lsort.
sort (buf, kl);
1877 std::reverse (buf + ku, buf + ns);
1879 std::rotate (buf, buf + ku, buf + ns);
1884 v[i*stride + offset] = buf[i];
1891 template <
typename T,
typename Alloc>
1896 if (dim < 0 || dim >= ndims ())
1897 (*current_liboctave_error_handler) (
"sort: invalid dimension");
1913 for (
int i = 0; i < dim; i++)
1916 T *v =
m.fortran_vec ();
1917 const T *ov = data ();
1941 if (sort_isnan<T> (tmp))
1956 lsort.
sort (v, vi, kl);
1961 std::reverse (v + ku, v + ns);
1962 std::reverse (vi + ku, vi + ns);
1965 std::rotate (v, v + ku, v + ns);
1966 std::rotate (vi, vi + ku, vi + ns);
1984 offset += n_strides * stride * (ns - 1);
1991 T tmp = ov[i*stride + offset];
1992 if (sort_isnan<T> (tmp))
2007 lsort.
sort (buf, bufi, kl);
2012 std::reverse (buf + ku, buf + ns);
2013 std::reverse (bufi + ku, bufi + ns);
2016 std::rotate (buf, buf + ku, buf + ns);
2017 std::rotate (bufi, bufi + ku, bufi + ns);
2023 v[i*stride + offset] = buf[i];
2025 vi[i*stride + offset] = bufi[i];
2032 template <
typename T,
typename Alloc>
2045 template <
typename T,
typename Alloc>
2059 compare_fcn_type compare
2062 if (compare (elem (
n-1), elem (0)))
2077 template <
typename T,
typename Alloc>
2095 template <
typename T,
typename Alloc>
2104 if (
r <= 1 || c == 0)
2110 compare_fcn_type compare
2114 for (i = 0; i < cols (); i++)
2117 T u = elem (rows () - 1, i);
2128 else if (compare (u, l))
2139 if (mode ==
UNSORTED && i == cols ())
2156 template <
typename T,
typename Alloc>
2174 return lsort.
lookup (data (),
n, value);
2177 template <
typename T,
typename Alloc>
2199 static const double ratio = 1.0;
2207 if ((vmode ==
ASCENDING && sort_isnan<T> (values(nval-1)))
2208 || (vmode ==
DESCENDING && sort_isnan<T> (values(0))))
2221 template <
typename T,
typename Alloc>
2225 const T *src = data ();
2228 const T zero = T ();
2236 template <
typename T,
typename Alloc>
2241 const T *src = data ();
2243 const T zero = T ();
2244 if (n < 0 || n >= nel)
2250 cnt += src[i] != zero;
2252 retval.
clear (cnt, 1);
2255 if (src[i] != zero) *dest++ = i;
2270 for (; l >= 0 && src[l] == zero; l--) ;
2279 std::reverse (rdata, rdata + k);
2288 for (; l != nel && src[l] == zero; l++) ;
2309 || (rows () == 0 && dims ().
numel (1) == 0))
2311 else if (rows () == 1 && ndims () == 2)
2317 template <
typename T,
typename Alloc>
2322 (*current_liboctave_error_handler) (
"nth_element: invalid dimension");
2325 if (dim >= dv.ndims ())
2326 dv.resize (dim+1, 1);
2333 dv.chop_trailing_singletons ();
2344 switch (
n.idx_class ())
2346 case octave::idx_vector::class_scalar:
2350 case octave::idx_vector::class_range:
2365 case octave::idx_vector::class_vector:
2368 if (
n(1) -
n(0) == 1)
2373 else if (
n(1) -
n(0) == -1)
2389 (*current_liboctave_error_handler)
2390 (
"nth_element: n must be a scalar or a contiguous range");
2394 if (lo < 0 || up > ns)
2395 (*current_liboctave_error_handler) (
"nth_element: invalid element index");
2400 for (
int i = 0; i < dim; i++)
2403 T *v =
m.fortran_vec ();
2404 const T *ov = data ();
2422 if (sort_isnan<T> (tmp))
2436 T tmp = ov[offset + i*stride];
2437 if (sort_isnan<T> (tmp))
2443 if (offset == stride-1)
2457 std::rotate (buf, buf + ku, buf + ns);
2471 v[offset + stride * i] = buf[lo + i];
2472 if (offset == stride-1)
2480 #define NO_INSTANTIATE_ARRAY_SORT_API(T, API) \
2481 template <> API Array<T> \
2482 Array<T>::sort (int, sortmode) const \
2486 template <> API Array<T> \
2487 Array<T>::sort (Array<octave_idx_type> &sidx, int, sortmode) const \
2489 sidx = Array<octave_idx_type> (); \
2492 template <> API sortmode \
2493 Array<T>::issorted (sortmode) const \
2497 API Array<T>::compare_fcn_type \
2498 safe_comparator (sortmode, const Array<T>&, bool) \
2502 template <> API Array<octave_idx_type> \
2503 Array<T>::sort_rows_idx (sortmode) const \
2505 return Array<octave_idx_type> (); \
2507 template <> API sortmode \
2508 Array<T>::is_sorted_rows (sortmode) const \
2512 template <> API octave_idx_type \
2513 Array<T>::lookup (T const &, sortmode) const \
2517 template <> API Array<octave_idx_type> \
2518 Array<T>::lookup (const Array<T>&, sortmode) const \
2520 return Array<octave_idx_type> (); \
2522 template <> API octave_idx_type \
2523 Array<T>::nnz () const \
2527 template <> API Array<octave_idx_type> \
2528 Array<T>::find (octave_idx_type, bool) const \
2530 return Array<octave_idx_type> (); \
2532 template <> API Array<T> \
2533 Array<T>::nth_element (const octave::idx_vector&, int) const { \
2534 return Array<T> (); \
2537 #define NO_INSTANTIATE_ARRAY_SORT(T) NO_INSTANTIATE_ARRAY_SORT_API (T,)
2539 template <
typename T,
typename Alloc>
2548 (*current_liboctave_error_handler) (
"Matrix must be 2-dimensional");
2553 if (nnr == 0 && nnc == 0)
2555 else if (nnr != 1 && nnc != 1)
2563 if (nnr > 0 && nnc > 0)
2572 d.xelem (i) = elem (i, i+k);
2577 d.xelem (i) = elem (i-k, i);
2582 d.xelem (i) = elem (i, i);
2610 d.xelem (i+roff, i+coff) = elem (0, i);
2618 d.xelem (i+roff, i+coff) = elem (i, 0);
2625 template <
typename T,
typename Alloc>
2629 if (ndims () != 2 || (rows () != 1 && cols () != 1))
2630 (*current_liboctave_error_handler) (
"cat: invalid dimension");
2636 retval.xelem (i, i) = xelem (i);
2641 template <
typename T,
typename Alloc>
2648 if (dim == -1 || dim == -2)
2654 (*current_liboctave_error_handler) (
"cat: invalid dimension");
2657 return array_list[0];
2684 if (
n > 2 && dim > 1)
2704 if (! (dv.*concat_rule) (array_list[i].
dims (), dim))
2705 (*current_liboctave_error_handler) (
"cat: dimension mismatch");
2709 if (retval.isempty ())
2724 if (array_list[i].isempty ())
2730 if (dim < array_list[i].ndims ())
2731 u = l + array_list[i].
dims ()(dim);
2737 retval.assign (idxa, array_list[i]);
2745 template <
typename T,
typename Alloc>
2749 os << prefix <<
"m_rep address: " << m_rep <<
'\n'
2750 << prefix <<
"m_rep->m_len: " << m_rep->m_len <<
'\n'
2751 << prefix <<
"m_rep->m_data: " <<
static_cast<void *
> (m_rep->m_data) <<
'\n'
2752 << prefix <<
"m_rep->m_count: " << m_rep->m_count <<
'\n'
2753 << prefix <<
"m_slice_data: " <<
static_cast<void *
> (m_slice_data) <<
'\n'
2754 << prefix <<
"m_slice_len: " << m_slice_len <<
'\n';
2762 template <
typename T,
typename Alloc>
2766 bool retval = m_dimensions == dv;
2773 template <
typename T,
typename Alloc>
2782 #define INSTANTIATE_ARRAY(T, API) \
2783 template <> API void \
2784 Array<T>::instantiation_guard () { } \
2786 template class API Array<T>
2790 template <
typename T,
typename Alloc>
2796 int n_dims = a_dims.
ndims ();
2798 os << n_dims <<
"-dimensional array";
2801 os <<
" (" << a_dims.
str () <<
')';
2814 for (
int i = 2; i < n_dims; i++)
2858 for (
int i = 0; i <
m; i++)
2862 for (
int j = 2; j < n_dims - 1; j++)
2863 os <<
ra_idx(j) + 1 <<
',';
2865 os <<
ra_idx(n_dims - 1) + 1 <<
") = \n";
bool sort_isnan(typename ref_param< T >::type)
Array< T, Alloc >::compare_fcn_type safe_comparator(sortmode mode, const Array< T, Alloc > &, bool)
std::ostream & operator<<(std::ostream &os, const Array< T, Alloc > &a)
octave_idx_type compute_index(octave_idx_type n, const dim_vector &dims)
dim_vector zero_dims_inquire(const Array< octave::idx_vector > &ia, const dim_vector &rhdv)
void increment_index(Array< octave_idx_type > &ra_idx, const dim_vector &dimensions, int start_dimension)
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
The real representation of all arrays.
octave::refcount< octave_idx_type > m_count
N Dimensional Array with copy-on-write semantics.
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.
friend class Array
Size of the specified dimension.
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 > nth_element(const octave::idx_vector &n, int dim=0) const
Returns the n-th element in increasing order, using the same ordering as used for sort.
Array< T, Alloc > hermitian(T(*fcn)(const T &)=nullptr) const
Size of the specified dimension.
void resize1(octave_idx_type n, const T &rfv)
Size of the specified dimension.
int ndims() const
Size of the specified dimension.
ref_param< T >::type crefT
Array< T, Alloc > column(octave_idx_type k) const
Extract column: A(:,k+1).
Array< T, Alloc > linear_slice(octave_idx_type lo, octave_idx_type up) const
Extract a slice from this array as a column vector: A(:)(lo+1:up).
bool optimize_dimensions(const dim_vector &dv)
Returns true if this->dims () == dv, and if so, replaces this->m_dimensions by a shallow copy of dv.
octave_idx_type nnz() const
Count nonzero elements.
octave_idx_type rows() const
Array< T, Alloc > page(octave_idx_type k) const
Extract page: A(:,:,k+1).
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
Array< T, Alloc > & insert(const Array< T, Alloc > &a, const Array< octave_idx_type > &idx)
Insert an array into another at a specified position.
Array< T, Alloc > squeeze() const
Chop off leading singleton dimensions.
const T * data() const
Size of the specified dimension.
octave_idx_type dim2() const
octave_idx_type columns() const
void delete_elements(const octave::idx_vector &i)
Deleting elements.
Array< octave_idx_type > sort_rows_idx(sortmode mode=ASCENDING) const
Sort by rows returns only indices.
Array< octave_idx_type > find(octave_idx_type n=-1, bool backward=false) const
Find indices of (at most n) nonzero elements.
octave_idx_type dim1() const
Array< T, Alloc > permute(const Array< octave_idx_type > &vec, bool inv=false) const
Size of the specified dimension.
Array< T, Alloc > sort(int dim=0, sortmode mode=ASCENDING) const
Size of the specified dimension.
bool isempty() const
Size of the specified dimension.
void print_info(std::ostream &os, const std::string &prefix) const
Size of the specified dimension.
sortmode issorted(sortmode mode=UNSORTED) const
Ordering is auto-detected or can be specified.
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
T & xelem(octave_idx_type n)
Size of the specified dimension.
Array< T, Alloc > reshape(octave_idx_type nr, octave_idx_type nc) const
Size of the specified dimension.
T & checkelem(octave_idx_type n)
Size of the specified dimension.
sortmode is_sorted_rows(sortmode mode=UNSORTED) const
Ordering is auto-detected or can be specified.
Array< T, Alloc > diag(octave_idx_type k=0) const
Get the kth super or subdiagonal.
virtual T resize_fill_value() const
Size of the specified dimension.
octave_idx_type compute_index(octave_idx_type i, octave_idx_type j) const
Size of the specified dimension.
octave_idx_type lookup(const T &value, sortmode mode=UNSORTED) const
Do a binary lookup in a sorted array.
Array< T, Alloc >::ArrayRep * m_rep
void resize2(octave_idx_type nr, octave_idx_type nc, const T &rfv)
Resizing (with fill).
static Array< T, Alloc > cat(int dim, octave_idx_type n, const Array< T, Alloc > *array_list)
Concatenation along a specified (0-based) dimension, equivalent to cat().
octave_idx_type numel() const
Number of elements in the array.
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 chop_trailing_singletons()
void resize(int n, int fill_value=0)
static dim_vector alloc(int n)
bool is_nd_vector() const
octave_idx_type ndims() const
Number of dimensions.
void chop_all_singletons()
bool zero_by_zero() const
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 ().
dim_vector make_nd_vector(octave_idx_type n) const
virtual octave_idx_type numel() const
void set_compare(const compare_fcn_type &comp)
void sort_rows(const T *data, octave_idx_type *idx, octave_idx_type rows, octave_idx_type cols)
static bool descending_compare(typename ref_param< T >::type, typename ref_param< T >::type)
bool issorted(const T *data, octave_idx_type nel)
octave_idx_type lookup(const T *data, octave_idx_type nel, const T &value)
void sort(T *data, octave_idx_type nel)
void nth_element(T *data, octave_idx_type nel, octave_idx_type lo, octave_idx_type up=-1)
bool is_sorted_rows(const T *data, octave_idx_type rows, octave_idx_type cols)
void lookup_sorted(const T *data, octave_idx_type nel, const T *values, octave_idx_type nvalues, octave_idx_type *idx, bool rev=false)
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_invalid_index(const std::string &idx, octave_idx_type nd, octave_idx_type dim, const std::string &)
void err_del_index_out_of_range(bool is1d, octave_idx_type idx, octave_idx_type ext)
Complex log2(const Complex &x)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
#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