45template <
typename T,
typename Alloc>
55template <
typename T,
typename Alloc>
57 : m_dimensions (dv), m_rep (a.m_rep),
58 m_slice_data (a.m_slice_data), m_slice_len (a.m_slice_len)
60 bool invalid_size =
false;
73 catch (
const std::bad_alloc&)
78 if (invalid_size || new_numel != a.
numel ())
83 (*current_liboctave_error_handler)
84 (
"reshape: can't reshape %s array to %s array",
85 dimensions_str.c_str (), new_dims_str.c_str ());
94template <
typename T,
typename Alloc>
98 if (m_rep->m_count > 1)
102 m_slice_data = m_rep->m_data;
105 std::fill_n (m_slice_data, m_slice_len, val);
108template <
typename T,
typename Alloc>
112 if (--m_rep->m_count == 0)
117 m_slice_data = m_rep->m_data;
118 m_slice_len = m_rep->m_len;
123template <
typename T,
typename Alloc>
127 if (--m_rep->m_count == 0)
131 m_slice_data = m_rep->m_data;
132 m_slice_len = m_rep->m_len;
138template <
typename T,
typename Alloc>
146 bool dims_changed =
false;
152 for (
int i = 0; i < ndims (); i++)
154 if (m_dimensions(i) == 1)
157 new_dimensions(k++) = m_dimensions(i);
172 new_dimensions.
resize (2);
174 new_dimensions(0) = tmp;
175 new_dimensions(1) = 1;
180 new_dimensions.
resize (k);
191template <
typename T,
typename Alloc>
195 return ::compute_index (i, j, m_dimensions);
198template <
typename T,
typename Alloc>
203 return ::compute_index (i, j, k, m_dimensions);
206template <
typename T,
typename Alloc>
210 return ::compute_index (
ra_idx, m_dimensions);
213template <
typename T,
typename Alloc>
220template <
typename T,
typename Alloc>
226 octave::err_invalid_index (n);
227 if (n >= m_slice_len)
228 octave::err_index_out_of_range (1, 1, n+1, m_slice_len, m_dimensions);
233template <
typename T,
typename Alloc>
240template <
typename T,
typename Alloc>
247template <
typename T,
typename Alloc>
254template <
typename T,
typename Alloc>
260 octave::err_invalid_index (n);
261 if (n >= m_slice_len)
262 octave::err_index_out_of_range (1, 1, n+1, m_slice_len, m_dimensions);
267template <
typename T,
typename Alloc>
274template <
typename T,
typename Alloc>
282template <
typename T,
typename Alloc>
289template <
typename T,
typename Alloc>
298template <
typename T,
typename Alloc>
309template <
typename T,
typename Alloc>
320class rec_permute_helper
327 m_stride (m_dim + m_n), m_use_blk (false)
334 for (
int i = 1; i < m_n+1; i++) cdim[i] = cdim[i-1] * dv(i-1);
337 for (
int k = 0; k < m_n; k++)
341 m_stride[k] = cdim[kk];
345 for (
int k = 1; k < m_n; k++)
347 if (m_stride[k] == m_stride[m_top]*m_dim[m_top])
348 m_dim[m_top] *= m_dim[k];
352 m_dim[m_top] = m_dim[k];
353 m_stride[m_top] = m_stride[k];
358 m_use_blk = m_top >= 1 && m_stride[1] == 1 && m_stride[0] == m_dim[1];
362 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (rec_permute_helper)
364 ~rec_permute_helper () {
delete [] m_dim; }
366 template <
typename T>
367 void permute (
const T *src, T *dest)
const { do_permute (src, dest, m_top); }
370 template <
typename T>
381 if (lr == m && lc == m)
383 const T *ss = src + kc * nr + kr;
386 blk[j*m+i] = ss[j*nr + i];
387 T *dd = dest + kr * nc + kc;
390 dd[j*nc+i] = blk[i*m+j];
394 const T *ss = src + kc * nr + kr;
397 blk[j*m+i] = ss[j*nr + i];
398 T *dd = dest + kr * nc + kc;
401 dd[j*nc+i] = blk[i*m+j];
411 template <
typename T>
412 T * do_permute (
const T *src, T *dest,
int lev)
const
420 std::copy_n (src,
len, dest);
431 else if (m_use_blk && lev == 1)
432 dest = blk_trans (src, dest, m_dim[1], m_dim[0]);
438 dest = do_permute (src + i * step, dest, lev-1);
456template <
typename T,
typename Alloc>
466 int perm_vec_len = perm_vec_arg.
numel ();
468 if (perm_vec_len < dv.
ndims ())
469 (*current_liboctave_error_handler)
470 (
"%s: invalid permutation vector", inv ?
"ipermute" :
"permute");
475 dv.
resize (perm_vec_len, 1);
480 bool identity =
true;
483 for (
int i = 0; i < perm_vec_len; i++)
486 if (perm_elt >= perm_vec_len || perm_elt < 0)
487 (*current_liboctave_error_handler)
488 (
"%s: permutation vector contains an invalid element",
489 inv ?
"ipermute" :
"permute");
491 if (checked[perm_elt])
492 (*current_liboctave_error_handler)
493 (
"%s: permutation vector cannot contain identical elements",
494 inv ?
"ipermute" :
"permute");
497 checked[perm_elt] =
true;
498 identity = identity && perm_elt == i;
507 for (
int i = 0; i < perm_vec_len; i++)
508 perm_vec(perm_vec_arg(i)) = i;
511 for (
int i = 0; i < perm_vec_len; i++)
512 dv_new(i) = dv(perm_vec(i));
518 rec_permute_helper rh (dv, perm_vec);
519 rh.permute (data (), retval.
rwdata ());
531class rec_index_helper
537 m_cdim (m_dim + m_n), m_idx (new octave::
idx_vector [m_n])
548 if (m_idx[m_top].maybe_reduce (m_dim[m_top], ia(i), dv(i)))
551 m_dim[m_top] *= dv(i);
557 m_idx[m_top] = ia(i);
558 m_dim[m_top] = dv(i);
559 m_cdim[m_top] = m_cdim[m_top-1] * m_dim[m_top-1];
564 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (rec_index_helper)
566 ~rec_index_helper () {
delete [] m_idx;
delete [] m_dim; }
568 template <
typename T>
569 void index (
const T *src, T *dest)
const { do_index (src, dest, m_top); }
571 template <
typename T>
572 void assign (
const T *src, T *dest)
const { do_assign (src, dest, m_top); }
574 template <
typename T>
575 void fill (
const T& val, T *dest)
const { do_fill (val, dest, m_top); }
579 return m_top == 0 && m_idx[0].is_cont_range (m_dim[0], l, u);
585 template <
typename T>
589 dest += m_idx[0].index (src, m_dim[0], dest);
595 dest = do_index (src +
d*m_idx[lev].xelem (i), dest, lev-1);
602 template <
typename T>
606 src += m_idx[0].assign (src, m_dim[0], dest);
612 src = do_assign (src, dest +
d*m_idx[lev].xelem (i), lev-1);
619 template <
typename T>
623 m_idx[0].fill (val, m_dim[0], dest);
629 do_fill (val, dest +
d*m_idx[lev].xelem (i), lev-1);
642 octave::idx_vector *m_idx;
648class rec_resize_helper
653 : m_cext (nullptr), m_sext (nullptr), m_dext (nullptr), m_n (0)
659 for (; i < l-1 && ndv(i) == odv(i); i++) ld *= ndv(i);
663 m_sext = m_cext + m_n;
664 m_dext = m_sext + m_n;
668 for (
int j = 0; j < m_n; j++)
670 m_cext[j] = std::min (ndv(i+j), odv(i+j));
671 m_sext[j] = sld *= odv(i+j);
672 m_dext[j] = dld *= ndv(i+j);
677 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (rec_resize_helper)
679 ~rec_resize_helper () {
delete [] m_cext; }
681 template <
typename T>
682 void resize_fill (
const T *src, T *dest,
const T& rfv)
const
683 { do_resize_fill (src, dest, rfv, m_n-1); }
688 template <
typename T>
689 void do_resize_fill (
const T *src, T *dest,
const T& rfv,
int lev)
const
693 std::copy_n (src, m_cext[0], dest);
694 std::fill_n (dest + m_cext[0], m_dext[0] - m_cext[0], rfv);
701 for (k = 0; k < m_cext[lev]; k++)
702 do_resize_fill (src + k * sd, dest + k * dd, rfv, lev - 1);
704 std::fill_n (dest + k * dd, m_dext[lev] - k * dd, rfv);
716template <
typename T,
typename Alloc>
748 if (i.extent (n) != n)
749 octave::err_index_out_of_range (1, 1, i.extent (n), n, m_dimensions);
751 dim_vector result_dims = i.orig_dimensions ();
754 if (n != 1 && is_nd_vector () && idx_len != 1
766 if (idx_len != 0 && i.is_cont_range (n, l, u))
776 i.index (data (), n, retval.
rwdata ());
783template <
typename T,
typename Alloc>
793 if (i.is_colon () && j.is_colon ())
800 if (i.extent (r) != r)
801 octave::err_index_out_of_range (2, 1, i.extent (r), r, m_dimensions);
802 if (j.extent (c) != c)
803 octave::err_index_out_of_range (2, 2, j.extent (c), c, m_dimensions);
809 octave::idx_vector ii (i);
811 if (ii.maybe_reduce (r, j, c))
814 if (ii.length () > 0 && ii.is_cont_range (n, l, u))
822 ii.index (data (), n, retval.
rwdata ());
830 const T *src = data ();
834 dest += i.index (src + r * j.xelem (k), r, dest);
841template <
typename T,
typename Alloc>
850 retval = index (ia(0));
852 retval = index (ia(0), ia(1));
859 bool all_colons =
true;
860 for (
int i = 0; i < ial; i++)
862 if (ia(i).extent (dv(i)) != dv(i))
863 octave::err_index_out_of_range (ial, i+1, ia(i).extent (dv(i)), dv(i),
866 all_colons = all_colons && ia(i).is_colon ();
879 for (
int i = 0; i < ial; i++) rdv(i) = ia(i).length (dv(i));
883 rec_index_helper rh (dv, ia);
886 if (rh.is_cont_range (l, u))
895 rh.index (data (), retval.
rwdata ());
905template <
typename T,
typename Alloc>
909 static T zero = T ();
916template <
typename T,
typename Alloc>
920 if (n < 0 || ndims () != 2)
921 octave::err_invalid_resize ();
931 bool invalid =
false;
932 if (rows () == 0 || rows () == 1)
934 else if (columns () == 1)
940 octave::err_invalid_resize ();
943 if (n == nx - 1 && n > 0)
946 if (m_rep->m_count == 1)
947 m_slice_data[m_slice_len-1] = T ();
951 else if (n == nx + 1 && nx > 0)
954 if (m_rep->m_count == 1
955 && m_slice_data + m_slice_len < m_rep->m_data + m_rep->m_len)
957 m_slice_data[m_slice_len++] = rfv;
967 std::copy_n (data (), nx, dest);
980 std::copy_n (data (), n0, dest);
981 std::fill_n (dest + n0, n1, rfv);
987template <
typename T,
typename Alloc>
991 if (r < 0 || c < 0 || ndims () != 2)
992 octave::err_invalid_resize ();
996 if (r != rx || c != cx)
1005 const T *src = data ();
1008 std::copy_n (src, r * c0, dest);
1015 std::copy_n (src, r0, dest);
1018 std::fill_n (dest, r1, rfv);
1023 std::fill_n (dest, r * c1, rfv);
1029template <
typename T,
typename Alloc>
1033 int dvl = dv.
ndims ();
1035 resize2 (dv(0), dv(1), rfv);
1036 else if (m_dimensions != dv)
1038 if (m_dimensions.ndims () > dvl || dv.
any_neg ())
1039 octave::err_invalid_resize ();
1043 rec_resize_helper rh (dv, m_dimensions.
redim (dvl));
1046 rh.resize_fill (data (), tmp.
rwdata (), rfv);
1051template <
typename T,
typename Alloc>
1068 if (tmp.
numel () != nx)
1072 return tmp.
index (i);
1075template <
typename T,
typename Alloc>
1078 bool resize_ok,
const T& rfv)
const
1088 if (r != rx || c != cx)
1090 if (i.is_scalar () && j.is_scalar ())
1100 return tmp.
index (i, j);
1103template <
typename T,
typename Alloc>
1106 bool resize_ok,
const T& rfv)
const
1111 int ial = ia.
numel ();
1117 for (
int i = 0; i < ial; i++)
1118 dvx(i) = ia(i).extent (dv(i));
1121 bool all_scalars =
true;
1122 for (
int i = 0; i < ial; i++)
1123 all_scalars = all_scalars && ia(i).is_scalar ();
1134 return tmp.
index (ia);
1137template <
typename T,
typename Alloc>
1141 return index (ia, resize_ok, resize_fill_value ());
1144template <
typename T,
typename Alloc>
1151 if (rhl != 1 && i.length (n) != rhl)
1152 octave::err_nonconformant (
"=",
dim_vector(i.length(n), 1), rhs.
dims());
1155 bool colon = i.is_colon_equiv (nx);
1160 if (m_dimensions.zero_by_zero () && colon)
1179 *
this = rhs.
reshape (m_dimensions);
1184 i.fill (rhs(0), n, rwdata ());
1186 i.assign (rhs.
data (), n, rwdata ());
1191template <
typename T,
typename Alloc>
1196 bool initial_dims_all_zero = m_dimensions.all_zero ();
1210 if (initial_dims_all_zero)
1214 rdv(0) = i.extent (dv(0));
1215 rdv(1) = j.extent (dv(1));
1218 bool isfill = rhs.
numel () == 1;
1222 bool match = (isfill
1223 || (rhdv.
ndims () == 2 && il == rhdv(0) && jl == rhdv(1)));
1224 match = match || (il == 1 && jl == rhdv(0) && rhdv(1) == 1);
1228 bool all_colons = (i.is_colon_equiv (rdv(0))
1229 && j.is_colon_equiv (rdv(1)));
1253 *
this = rhs.
reshape (m_dimensions);
1261 octave::idx_vector ii (i);
1263 const T *src = rhs.
data ();
1264 T *dest = rwdata ();
1267 if (ii.maybe_reduce (r, j, c))
1270 ii.fill (*src, n, dest);
1272 ii.assign (src, n, dest);
1279 i.fill (*src, r, dest + r * j.xelem (k));
1284 src += i.assign (src, r, dest + r * j.xelem (k));
1290 else if ((il != 0 && jl != 0) || (rhdv(0) != 0 && rhdv(1) != 0))
1291 octave::err_nonconformant (
"=", il, jl, rhs.
dim1 (), rhs.
dim2 ());
1295template <
typename T,
typename Alloc>
1300 int ial = ia.
numel ();
1304 assign (ia(0), rhs, rfv);
1306 assign (ia(0), ia(1), rhs, rfv);
1309 bool initial_dims_all_zero = m_dimensions.all_zero ();
1323 if (initial_dims_all_zero)
1328 for (
int i = 0; i < ial; i++)
1329 rdv(i) = ia(i).extent (dv(i));
1334 bool all_colons =
true;
1335 bool isfill = rhs.
numel () == 1;
1339 int rhdvl = rhdv.
ndims ();
1340 for (
int i = 0; i < ial; i++)
1342 all_colons = all_colons && ia(i).is_colon_equiv (rdv(i));
1344 if (l == 1)
continue;
1345 match = match && j < rhdvl && l == rhdv(j++);
1348 match = match && (j == rhdvl || rhdv(j) == 1);
1349 match = match || isfill;
1377 *
this = rhs.
reshape (m_dimensions);
1384 rec_index_helper rh (dv, ia);
1388 rh.fill (rhs(0), rwdata ());
1390 rh.assign (rhs.
data (), rwdata ());
1396 bool lhsempty, rhsempty;
1397 lhsempty = rhsempty =
false;
1399 for (
int i = 0; i < ial; i++)
1403 lhsempty = lhsempty || (l == 0);
1404 rhsempty = rhsempty || (rhdv(j++) == 0);
1406 if (! lhsempty || ! rhsempty)
1409 octave::err_nonconformant (
"=", lhs_dv, rhdv);
1415template <
typename T,
typename Alloc>
1420 assign (ia, rhs, resize_fill_value ());
1431template <
typename T,
typename Alloc>
1440 else if (i.length (n) != 0)
1442 if (i.extent (n) != n)
1443 octave::err_del_index_out_of_range (
true, i.extent (n), n);
1446 bool col_vec = ndims () == 2 && columns () == 1 && rows () != 1;
1447 if (i.is_scalar () && i(0) == n-1 && m_dimensions.isvector ())
1452 else if (i.is_cont_range (n, l, u))
1457 const T *src = data ();
1459 std::copy_n (src, l, dest);
1460 std::copy (src + u, src + n, dest + l);
1466 *
this = index (i.complement (n));
1471template <
typename T,
typename Alloc>
1476 (*current_liboctave_error_handler) (
"invalid dimension in delete_elements");
1480 if (dim >= ndims ())
1481 dimensions.
resize (dim + 1, 1);
1490 else if (i.length (n) != 0)
1492 if (i.extent (n) != n)
1493 octave::err_del_index_out_of_range (
false, i.extent (n), n);
1497 if (i.is_cont_range (n, l, u))
1505 for (
int k = 0; k < dim; k++) dl *= dimensions(k);
1506 for (
int k = dim + 1; k < ndim; k++) du *= dimensions(k);
1510 const T *src = data ();
1512 l *= dl; u *= dl; n *= dl;
1515 std::copy_n (src, l, dest);
1517 std::copy (src + u, src + n, dest);
1528 ia (dim) = i.complement (n);
1534template <
typename T,
typename Alloc>
1538 int ial = ia.
numel ();
1541 delete_elements (ia(0));
1545 for (k = 0; k < ial; k++)
1547 if (! ia(k).is_colon ())
1563 delete_elements (dim, ia(dim));
1578 bool empty_assignment =
false;
1580 int num_non_colon_indices = 0;
1584 for (
int i = 0; i < ial; i++)
1588 if (ia(i).length (dim_len) == 0)
1590 empty_assignment =
true;
1594 if (! ia(i).is_colon_equiv (dim_len))
1596 num_non_colon_indices++;
1598 if (num_non_colon_indices == 2)
1603 if (! empty_assignment)
1604 (*current_liboctave_error_handler)
1605 (
"a null assignment can only have one non-colon index");
1611template <
typename T,
typename Alloc>
1615 octave::idx_vector i (r, r + a.
rows ());
1616 octave::idx_vector j (c, c + a.
columns ());
1617 if (ndims () == 2 && a.
ndims () == 2)
1624 for (
int k = 2; k < a.
ndims (); k++)
1632template <
typename T,
typename Alloc>
1640 idx(k) = octave::idx_vector (
ra_idx(k),
ra_idx(k) + dva(k));
1647template <
typename T,
typename Alloc>
1656 if (nr >= 8 && nc >= 8)
1662 rec_permute_helper::blk_trans (data (), result.
rwdata (), nr, nc);
1666 else if (nr > 1 && nc > 1)
1672 result.
xelem (j, i) = xelem (i, j);
1683template <
typename T>
1685no_op_fcn (
const T&
x)
1690template <
typename T,
typename Alloc>
1702 if (nr >= 8 && nc >= 8)
1711 for (jj = 0; jj < (nc - 8 + 1); jj += 8)
1714 for (ii = 0; ii < (nr - 8 + 1); ii += 8)
1718 j < jj + 8; j++, idxj += nr)
1720 buf[k++] = xelem (i + idxj);
1727 result.
xelem (j + idxi) = fcn (buf[k]);
1733 result.
xelem (j, i) = fcn (xelem (i, j));
1738 result.
xelem (j, i) = fcn (xelem (i, j));
1748 result.
xelem (j, i) = fcn (xelem (i, j));
1788template <
typename T,
typename Alloc>
1794 return m_slice_data;
1798template <
typename T>
1805template <
typename T,
typename Alloc>
1810 (*current_liboctave_error_handler) (
"sort: invalid dimension");
1815 if (dim >= ndims ())
1832 for (
int i = 0; i < dim; i++)
1836 const T *ov = data ();
1860 if (sort_isnan<T> (tmp))
1872 std::reverse (v + ku, v + ns);
1874 std::rotate (v, v + ku, v + ns);
1889 offset += n_strides * stride * (ns - 1);
1896 T tmp = ov[i*stride + offset];
1897 if (sort_isnan<T> (tmp))
1904 lsort.
sort (buf, kl);
1909 std::reverse (buf + ku, buf + ns);
1911 std::rotate (buf, buf + ku, buf + ns);
1916 v[i*stride + offset] = buf[i];
1923template <
typename T,
typename Alloc>
1929 (*current_liboctave_error_handler) (
"sort: invalid dimension");
1935 if (
numel () < 1 || dim >= ndims ())
1944 for (
int i = 0; i < dim; i++)
1948 const T *ov = data ();
1971 if (sort_isnan<T> (tmp))
1986 lsort.
sort (v, vi, kl);
1991 std::reverse (v + ku, v + ns);
1992 std::reverse (vi + ku, vi + ns);
1995 std::rotate (v, v + ku, v + ns);
1996 std::rotate (vi, vi + ku, vi + ns);
2014 offset += n_strides * stride * (ns - 1);
2021 T tmp = ov[i*stride + offset];
2022 if (sort_isnan<T> (tmp))
2037 lsort.
sort (buf, bufi, kl);
2042 std::reverse (buf + ku, buf + ns);
2043 std::reverse (bufi + ku, bufi + ns);
2046 std::rotate (buf, buf + ku, buf + ns);
2047 std::rotate (bufi, bufi + ku, bufi + ns);
2053 v[i*stride + offset] = buf[i];
2055 vi[i*stride + offset] = bufi[i];
2062template <
typename T,
typename Alloc>
2075template <
typename T,
typename Alloc>
2089 compare_fcn_type compare
2092 if (compare (elem (n-1), elem (0)))
2107template <
typename T,
typename Alloc>
2125template <
typename T,
typename Alloc>
2134 if (r <= 1 || c == 0)
2140 compare_fcn_type compare
2144 for (i = 0; i < cols (); i++)
2147 T u = elem (rows () - 1, i);
2158 else if (compare (u, l))
2169 if (mode ==
UNSORTED && i == cols ())
2186template <
typename T,
typename Alloc>
2204 return lsort.
lookup (data (), n, value);
2207template <
typename T,
typename Alloc>
2229 static const double RATIO = 1.0;
2233 if (nval > RATIO * n / octave::math::log2 (n + 1.0))
2237 if ((vmode ==
ASCENDING && sort_isnan<T> (values(nval-1)))
2238 || (vmode ==
DESCENDING && sort_isnan<T> (values(0))))
2244 idx.
rwdata (), vmode != mode);
2251template <
typename T,
typename Alloc>
2255 const T *src = data ();
2258 const T zero = T ();
2266template <
typename T,
typename Alloc>
2271 const T *src = data ();
2273 const T zero = T ();
2274 if (n < 0 || n >= nel)
2280 cnt += src[i] != zero;
2282 retval.
clear (cnt, 1);
2285 if (src[i] != zero) *dest++ = i;
2292 retval.
clear (n, 1);
2300 for (; l >= 0 && src[l] == zero; l--) ;
2309 std::reverse (rdata, rdata + k);
2318 for (; l != nel && src[l] == zero; l++) ;
2339 || (rows () == 0 && dims ().
numel (1) == 0))
2341 else if (rows () == 1 && ndims () == 2)
2347template <
typename T,
typename Alloc>
2352 (*current_liboctave_error_handler) (
"nth_element: invalid dimension");
2355 if (dim >= dv.ndims ())
2356 dv.resize (dim+1, 1);
2362 dv(dim) = std::min (nn, ns);
2363 dv.chop_trailing_singletons ();
2374 switch (n.idx_class ())
2376 case octave::idx_vector::class_scalar:
2380 case octave::idx_vector::class_range:
2395 case octave::idx_vector::class_vector:
2398 if (n(1) - n(0) == 1)
2403 else if (n(1) - n(0) == -1)
2410 if ((mode ==
ASCENDING && n(i) - n(i-1) != 1)
2411 || (mode ==
DESCENDING && n(i) - n(i-1) != -1))
2419 (*current_liboctave_error_handler)
2420 (
"nth_element: n must be a scalar or a contiguous range");
2424 if (lo < 0 || up > ns)
2425 (*current_liboctave_error_handler) (
"nth_element: invalid element index");
2430 for (
int i = 0; i < dim; i++)
2434 const T *ov = data ();
2452 if (sort_isnan<T> (tmp))
2466 T tmp = ov[offset + i*stride];
2467 if (sort_isnan<T> (tmp))
2473 if (offset == stride-1)
2480 lsort.
nth_element (buf, ku, lo, std::min (ku, up));
2485 lsort.
nth_element (buf, ku, std::max (lo - nnan, zero),
2486 std::max (up - nnan, zero));
2487 std::rotate (buf, buf + ku, buf + ns);
2501 v[offset + stride * i] = buf[lo + i];
2502 if (offset == stride-1)
2510#define NO_INSTANTIATE_ARRAY_SORT_API(T, API) \
2511 template <> API Array<T> \
2512 Array<T>::sort (int, sortmode) const \
2516 template <> API Array<T> \
2517 Array<T>::sort (Array<octave_idx_type> &sidx, int, sortmode) const \
2519 sidx = Array<octave_idx_type> (); \
2522 template <> API sortmode \
2523 Array<T>::issorted (sortmode) const \
2527 API Array<T>::compare_fcn_type \
2528 safe_comparator (sortmode, const Array<T>&, bool) \
2532 template <> API Array<octave_idx_type> \
2533 Array<T>::sort_rows_idx (sortmode) const \
2535 return Array<octave_idx_type> (); \
2537 template <> API sortmode \
2538 Array<T>::is_sorted_rows (sortmode) const \
2542 template <> API octave_idx_type \
2543 Array<T>::lookup (T const &, sortmode) const \
2547 template <> API Array<octave_idx_type> \
2548 Array<T>::lookup (const Array<T>&, sortmode) const \
2550 return Array<octave_idx_type> (); \
2552 template <> API octave_idx_type \
2553 Array<T>::nnz () const \
2557 template <> API Array<octave_idx_type> \
2558 Array<T>::find (octave_idx_type, bool) const \
2560 return Array<octave_idx_type> (); \
2562 template <> API Array<T> \
2563 Array<T>::nth_element (const octave::idx_vector&, int) const { \
2564 return Array<T> (); \
2567#define NO_INSTANTIATE_ARRAY_SORT(T) NO_INSTANTIATE_ARRAY_SORT_API (T,)
2569template <
typename T,
typename Alloc>
2578 (*current_liboctave_error_handler) (
"Matrix must be 2-dimensional");
2583 if (nnr == 0 && nnc == 0)
2585 else if (nnr != 1 && nnc != 1)
2593 if (nnr > 0 && nnc > 0)
2602 d.xelem (i) = elem (i, i+k);
2607 d.xelem (i) = elem (i-k, i);
2612 d.xelem (i) = elem (i, i);
2640 d.xelem (i+roff, i+coff) = elem (0, i);
2648 d.xelem (i+roff, i+coff) = elem (i, 0);
2655template <
typename T,
typename Alloc>
2659 if (ndims () != 2 || (rows () != 1 && cols () != 1))
2660 (*current_liboctave_error_handler) (
"cat: invalid dimension");
2666 retval.xelem (i, i) = xelem (i);
2671template <
typename T,
typename Alloc>
2678 if (dim == -1 || dim == -2)
2684 (*current_liboctave_error_handler) (
"cat: invalid dimension");
2687 return array_list[0];
2714 if (n > 2 && dim > 1)
2734 if (! (dv.*concat_rule) (array_list[i].
dims (), dim))
2735 (*current_liboctave_error_handler) (
"cat: dimension mismatch");
2739 if (retval.isempty ())
2754 if (array_list[i].isempty ())
2760 if (dim < array_list[i].ndims ())
2761 u = l + array_list[i].
dims ()(dim);
2765 idxa(dim) = octave::idx_vector (l, u);
2767 retval.assign (idxa, array_list[i]);
2775template <
typename T,
typename Alloc>
2779 os << prefix <<
"m_rep address: " << m_rep <<
'\n'
2780 << prefix <<
"m_rep->m_len: " << m_rep->m_len <<
'\n'
2781 << prefix <<
"m_rep->m_data: " <<
static_cast<void *
> (m_rep->m_data) <<
'\n'
2782 << prefix <<
"m_rep->m_count: " << m_rep->m_count <<
'\n'
2783 << prefix <<
"m_slice_data: " <<
static_cast<void *
> (m_slice_data) <<
'\n'
2784 << prefix <<
"m_slice_len: " << m_slice_len <<
'\n';
2792template <
typename T,
typename Alloc>
2796 bool retval = m_dimensions == dv;
2803template <
typename T,
typename Alloc>
2812#define INSTANTIATE_ARRAY(T, API) \
2813 template <> API void \
2814 Array<T>::instantiation_guard () { } \
2816 template class API Array<T>
2820template <
typename T,
typename Alloc>
2826 int n_dims = a_dims.
ndims ();
2828 os << n_dims <<
"-dimensional array";
2831 os <<
" (" << a_dims.
str () <<
')';
2844 for (
int i = 2; i < n_dims; i++)
2888 for (
int i = 0; i < m; i++)
2892 for (
int j = 2; j < n_dims - 1; j++)
2893 os <<
ra_idx(j) + 1 <<
',';
2895 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)
The real representation of all arrays.
octave::refcount< octave_idx_type > m_count
N Dimensional Array with copy-on-write semantics.
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
Array< T, Alloc >::ArrayRep * m_rep
T & xelem(octave_idx_type n)
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.
octave_idx_type compute_index_unchecked(const Array< octave_idx_type > &ra_idx) const
Size of the specified dimension.
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.
T & elem(octave_idx_type n)
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.
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.
Array< T, Alloc > reshape(octave_idx_type nr, octave_idx_type nc) const
Size of the specified dimension.
bool isempty() const
Size of the specified dimension.
const T * data() 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.
T * rwdata()
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.
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, Tconst & >::result type
#define liboctave_panic_unless(cond)
#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
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x