49 : dimensions (dv), rep (a.rep),
50 slice_data (a.slice_data), slice_len (a.slice_len)
57 (*current_liboctave_error_handler)
58 (
"reshape: can't reshape %s array to %s array",
59 dimensions_str.c_str (), new_dims_str.c_str ());
76 slice_data = rep->data;
86 if (--rep->count == 0)
91 slice_data = rep->data;
101 if (--rep->count == 0)
105 slice_data = rep->
data;
106 slice_len = rep->len;
120 bool dims_changed =
false;
126 for (
int i = 0; i < ndims (); i++)
128 if (dimensions(i) == 1)
131 new_dimensions(k++) = dimensions(i);
146 new_dimensions.
resize (2);
148 new_dimensions(0) = tmp;
149 new_dimensions(1) = 1;
154 new_dimensions.
resize (k);
159 retval =
Array<T> (*
this, new_dimensions);
261 #ifdef BOUNDS_CHECKING
262 if (k < 0 || k > dimensions.numel (1))
274 #ifdef BOUNDS_CHECKING
275 if (k < 0 || k > dimensions.numel (2))
286 #ifdef BOUNDS_CHECKING
292 if (up < lo) up = lo;
319 for (
int i = 1; i <
n+1; i++) cdim[i] = cdim[i-1] * dv(i-1);
322 for (
int k = 0; k <
n; k++)
330 for (
int k = 1; k <
n; k++)
361 if (lr == m && lc == m)
363 const T *ss = src + kc * nr + kr;
366 blk[j*m+i] = ss[j*nr + i];
367 T *dd = dest + kr * nc + kc;
370 dd[j*nc+i] = blk[i*m+j];
374 const T *ss = src + kc * nr + kr;
377 blk[j*m+i] = ss[j*nr + i];
378 T *dd = dest + kr * nc + kc;
381 dd[j*nc+i] = blk[i*m+j];
416 dest =
do_permute (src + i * step, dest, lev-1);
445 int perm_vec_len = perm_vec_arg.
length ();
447 if (perm_vec_len < dv.
length ())
449 (
"%s: invalid permutation vector", inv ?
"ipermute" :
"permute");
454 dv.
resize (perm_vec_len, 1);
459 bool identity =
true;
462 for (
int i = 0; i < perm_vec_len; i++)
465 if (perm_elt >= perm_vec_len || perm_elt < 0)
467 (*current_liboctave_error_handler)
468 (
"%s: permutation vector contains an invalid element",
469 inv ?
"ipermute" :
"permute");
474 if (checked[perm_elt])
476 (*current_liboctave_error_handler)
477 (
"%s: permutation vector cannot contain identical elements",
478 inv ?
"ipermute" :
"permute");
484 checked[perm_elt] =
true;
485 identity = identity && perm_elt == i;
494 for (
int i = 0; i < perm_vec_len; i++)
495 perm_vec(perm_vec_arg(i)) = i;
498 for (
int i = 0; i < perm_vec_len; i++)
499 dv_new(i) = dv(perm_vec(i));
540 for (
int i = 1; i <
n; i++)
573 dest =
do_index (src +
d*
idx[lev].xelem (i), dest, lev-1);
581 const T *
do_assign (
const T *src, T *dest,
int lev)
const
597 void do_fill (
const T& val, T *dest,
int lev)
const
648 assert (odv.
length () == l);
651 for (; i < l-1 && ndv(i) == odv(i); i++) ld *= ndv(i);
659 for (
int j = 0; j <
n; j++)
662 sext[j] = sld *= odv(i+j);
663 dext[j] = dld *= ndv(i+j);
684 for (k = 0; k <
cext[lev]; k++)
742 if (ndims () == 2 && n != 1 && rd.
is_vector ())
746 else if (rows () == 1)
753 retval =
Array<T> (*
this, rd, l, u);
812 const T* src = data ();
816 dest += i.
index (src + r * j.
xelem (k), r, dest);
832 retval = index (ia(0));
834 retval = index (ia(0), ia(1));
841 bool all_colons =
true;
842 for (
int i = 0; i < ial; i++)
844 if (ia(i).extent (dv(i)) != dv(i))
847 all_colons = all_colons && ia(i).is_colon ();
861 for (
int i = 0; i < ial; i++) rdv(i) = ia(i).
length (dv(i));
870 retval =
Array<T> (*
this, rdv, l, u);
891 static T zero = T ();
902 if (n >= 0 && ndims () == 2)
912 bool invalid =
false;
913 if (rows () == 0 || rows () == 1)
915 else if (columns () == 1)
925 if (n == nx - 1 && n > 0)
929 slice_data[slice_len-1] = T ();
933 else if (n == nx + 1 && nx > 0)
937 && slice_data + slice_len < rep->data + rep->len)
939 slice_data[slice_len++] = rfv;
976 if (r >= 0 && c >= 0 && ndims () == 2)
979 if (r != rx || c != cx)
986 const T *src = data ();
1020 resize2 (dv(0), dv(1), rfv);
1021 else if (dimensions != dv)
1023 if (dimensions.length () <= dvl && ! dv.
any_neg ())
1054 if (tmp.
numel () != nx)
1058 return tmp.
index (i);
1064 bool resize_ok,
const T& rfv)
const
1072 if (r != rx || c != cx)
1084 return tmp.
index (i, j);
1090 bool resize_ok,
const T& rfv)
const
1098 for (
int i = 0; i < ial; i++) dvx(i) = ia(i).extent (dv (i));
1101 bool all_scalars =
true;
1102 for (
int i = 0; i < ial; i++)
1103 all_scalars = all_scalars && ia(i).is_scalar ();
1114 return tmp.
index (ia);
1124 if (rhl == 1 || i.
length (n) == rhl)
1132 if (dimensions.zero_by_zero () && colon)
1151 *
this = rhs.
reshape (dimensions);
1156 i.
fill (rhs(0), n, fortran_vec ());
1170 bool initial_dims_all_zero = dimensions.all_zero ();
1184 if (initial_dims_all_zero)
1188 rdv(0) = i.
extent (dv(0));
1189 rdv(1) = j.
extent (dv(1));
1192 bool isfill = rhs.
numel () == 1;
1195 bool match = (isfill
1196 || (rhdv.
length () == 2 && il == rhdv(0) && jl == rhdv(1)));
1197 match = match || (il == 1 && jl == rhdv(0) && rhdv(1) == 1);
1226 *
this = rhs.
reshape (dimensions);
1234 const T* src = rhs.
data ();
1235 T *dest = fortran_vec ();
1241 ii.
fill (*src, n, dest);
1243 ii.
assign (src, n, dest);
1250 i.
fill (*src, r, dest + r * j.
xelem (k));
1273 assign (ia(0), rhs, rfv);
1275 assign (ia(0), ia(1), rhs, rfv);
1278 bool initial_dims_all_zero = dimensions.all_zero ();
1292 if (initial_dims_all_zero)
1297 for (
int i = 0; i < ial; i++)
1298 rdv(i) = ia(i).extent (dv(i));
1302 bool match =
true, all_colons =
true, isfill = rhs.
numel () == 1;
1305 int j = 0, rhdvl = rhdv.
length ();
1306 for (
int i = 0; i < ial; i++)
1308 all_colons = all_colons && ia(i).is_colon_equiv (rdv(i));
1310 if (l == 1)
continue;
1311 match = match && j < rhdvl && l == rhdv(j++);
1314 match = match && (j == rhdvl || rhdv(j) == 1);
1315 match = match || isfill;
1343 *
this = rhs.
reshape (dimensions);
1354 rh.
fill (rhs(0), fortran_vec ());
1373 else if (i.
length (n) != 0)
1379 bool col_vec = ndims () == 2 && columns () == 1 && rows () != 1;
1380 if (i.
is_scalar () && i(0) == n-1 && dimensions.is_vector ())
1390 const T *src = data ();
1408 if (dim < 0 || dim >= ndims ())
1410 (*current_liboctave_error_handler)
1411 (
"invalid dimension in delete_elements");
1420 else if (i.
length (n) != 0)
1433 for (
int k = 0; k < dim; k++) dl *= dimensions(k);
1434 for (
int k = dim + 1; k < ndims (); k++) du *= dimensions(k);
1438 const T *src = data ();
1440 l *= dl; u *= dl; n *= dl;
1469 delete_elements (ia(0));
1473 for (k = 0; k < ial; k++)
1475 if (! ia(k).is_colon ())
1491 delete_elements (dim, ia(dim));
1506 bool empty_assignment =
false;
1508 int num_non_colon_indices = 0;
1512 for (
int i = 0; i < ial; i++)
1516 if (ia(i).
length (dim_len) == 0)
1518 empty_assignment =
true;
1522 if (! ia(i).is_colon_equiv (dim_len))
1524 num_non_colon_indices++;
1526 if (num_non_colon_indices == 2)
1531 if (! empty_assignment)
1532 (*current_liboctave_error_handler)
1533 (
"a null assignment can only have one non-colon index");
1545 if (ndims () == 2 && a.
ndims () == 2)
1552 for (
int k = 2; k < a.
ndims (); k++)
1568 idx(k) =
idx_vector (ra_idx (k), ra_idx (k) + dva(k));
1580 assert (ndims () == 2);
1585 if (nr >= 8 && nc >= 8)
1595 else if (nr > 1 && nc > 1)
1601 result.
xelem (j, i) = xelem (i, j);
1623 assert (ndims () == 2);
1631 if (nr >= 8 && nc >= 8)
1642 for (jj = 0; jj < (nc - 8 + 1); jj += 8)
1644 for (ii = 0; ii < (nr - 8 + 1); ii += 8)
1648 j < jj + 8; j++, idxj += nr)
1650 buf[k++] = xelem (i + idxj);
1657 result.
xelem (j + idxi) = fcn (buf[k]);
1663 result.
xelem (j, i) = fcn (xelem (i, j));
1668 result.
xelem (j, i) = fcn (xelem (i, j));
1678 result.
xelem (j, i) = fcn (xelem (i, j));
1741 (*current_liboctave_error_handler)
1742 (
"sort: invalid dimension");
1760 for (
int i = 0; i < dim; i++)
1764 const T *ov = data ();
1783 if (sort_isnan<T> (tmp))
1795 std::reverse (v + ku, v + ns);
1797 std::rotate (v, v + ku, v + ns);
1813 while (offset >= stride)
1819 offset += offset2 * stride * ns;
1826 T tmp = ov[i*stride + offset];
1827 if (sort_isnan<T> (tmp))
1834 lsort.
sort (buf, kl);
1839 std::reverse (buf + ku, buf + ns);
1841 std::rotate (buf, buf + ku, buf + ns);
1846 v[i*stride + offset] = buf[i];
1858 if (dim < 0 || dim >= ndims ())
1860 (*current_liboctave_error_handler)
1861 (
"sort: invalid dimension");
1879 for (
int i = 0; i < dim; i++)
1883 const T *ov = data ();
1905 if (sort_isnan<T> (tmp))
1920 lsort.
sort (v, vi, kl);
1925 std::reverse (v + ku, v + ns);
1926 std::reverse (vi + ku, vi + ns);
1929 std::rotate (v, v + ku, v + ns);
1930 std::rotate (vi, vi + ku, vi + ns);
1949 while (offset >= stride)
1955 offset += offset2 * stride * ns;
1962 T tmp = ov[i*stride + offset];
1963 if (sort_isnan<T> (tmp))
1978 lsort.
sort (buf, bufi, kl);
1983 std::reverse (buf + ku, buf + ns);
1984 std::reverse (bufi + ku, bufi + ns);
1987 std::rotate (buf, buf + ku, buf + ns);
1988 std::rotate (bufi, bufi + ku, bufi + ns);
1994 v[i*stride + offset] = buf[i];
1996 vi[i*stride + offset] = bufi[i];
2030 compare_fcn_type compare
2033 if (compare (
elem (n-1),
elem (0)))
2077 if (r <= 1 || c == 0)
2083 compare_fcn_type compare
2087 for (i = 0; i < cols (); i++)
2089 T l =
elem (0, i), u =
elem (rows () - 1, i);
2100 else if (compare (u, l))
2111 if (mode ==
UNSORTED && i == cols ())
2146 return lsort.
lookup (data (), n, value);
2170 static const double ratio = 1.0;
2174 if (nval > ratio * n /
xlog2 (n + 1.0))
2178 if ((vmode ==
ASCENDING && sort_isnan<T> (values(nval-1)))
2179 || (vmode ==
DESCENDING && sort_isnan<T> (values(0))))
2185 idx.fortran_vec (), vmode != mode);
2187 lsort.
lookup (data (), n, values.
data (), nval, idx.fortran_vec ());
2196 const T *src = data ();
2198 const T zero = T ();
2211 const T *src = data ();
2213 const T zero = T ();
2214 if (n < 0 || n >= nel)
2220 cnt += src[i] != zero;
2222 retval.
clear (cnt, 1);
2225 if (src[i] != zero) *dest++ = i;
2232 retval.
clear (n, 1);
2239 for (; l >= 0 && src[l] == zero; l--) ;
2248 std::reverse (rdata, rdata + k);
2256 for (; l != nel && src[l] == zero; l++) ;
2276 if ((numel () == 1 && retval.
is_empty ())
2277 || (rows () == 0 && dims ().numel (1) == 0))
2279 else if (rows () == 1 && ndims () == 2)
2291 (*current_liboctave_error_handler)
2292 (
"nth_element: invalid dimension");
2310 if (m.numel () == 0)
2342 (*current_liboctave_error_handler)
2343 (
"nth_element: n must be a scalar or a contiguous range");
2349 if (lo < 0 || up > ns)
2351 (*current_liboctave_error_handler)
2352 (
"nth_element: invalid element index");
2359 for (
int i = 0; i < dim; i++)
2362 T *v = m.fortran_vec ();
2363 const T *ov = data ();
2381 if (sort_isnan<T> (tmp))
2396 T tmp = ov[offset + i*stride];
2397 if (sort_isnan<T> (tmp))
2403 if (offset == stride-1)
2417 std::rotate (buf, buf + ku, buf + ns);
2431 v[offset + stride * i] = buf[lo + i];
2432 if (offset == stride-1)
2441 #define INSTANTIATE_ARRAY_SORT(T) template class OCTAVE_API octave_sort<T>;
2443 #define NO_INSTANTIATE_ARRAY_SORT(T) \
2445 template <> Array<T> \
2446 Array<T>::sort (int, sortmode) const { return *this; } \
2448 template <> Array<T> \
2449 Array<T>::sort (Array<octave_idx_type> &sidx, int, sortmode) const \
2450 { sidx = Array<octave_idx_type> (); return *this; } \
2452 template <> sortmode \
2453 Array<T>::is_sorted (sortmode) const \
2454 { return UNSORTED; } \
2456 Array<T>::compare_fcn_type \
2457 safe_comparator (sortmode, const Array<T>&, bool) \
2460 template <> Array<octave_idx_type> \
2461 Array<T>::sort_rows_idx (sortmode) const \
2462 { return Array<octave_idx_type> (); } \
2464 template <> sortmode \
2465 Array<T>::is_sorted_rows (sortmode) const \
2466 { return UNSORTED; } \
2468 template <> octave_idx_type \
2469 Array<T>::lookup (T const &, sortmode) const \
2471 template <> Array<octave_idx_type> \
2472 Array<T>::lookup (const Array<T>&, sortmode) const \
2473 { return Array<octave_idx_type> (); } \
2475 template <> octave_idx_type \
2476 Array<T>::nnz (void) const\
2478 template <> Array<octave_idx_type> \
2479 Array<T>::find (octave_idx_type, bool) const\
2480 { return Array<octave_idx_type> (); } \
2482 template <> Array<T> \
2483 Array<T>::nth_element (const idx_vector&, int) const { return Array<T> (); } \
2495 (*current_liboctave_error_handler) (
"Matrix must be 2-dimensional");
2501 if (nnr == 0 && nnc == 0)
2503 else if (nnr != 1 && nnc != 1)
2511 if (nnr > 0 && nnc > 0)
2535 (
"diag: requested diagonal out of range");
2581 if (ndims () == 2 && (rows () == 1 || cols () == 1))
2586 retval.
xelem (i, i) = xelem (i);
2590 (
"cat: invalid dimension");
2602 if (dim == -1 || dim == -2)
2608 (*current_liboctave_error_handler)
2609 (
"cat: invalid dimension");
2612 return array_list[0];
2639 if (n > 2 && dim > 1)
2659 if (! (dv.*concat_rule) (array_list[i].
dims (), dim))
2660 (*current_liboctave_error_handler)
2661 (
"cat: dimension mismatch");
2665 if (retval.is_empty ())
2680 if (array_list[i].is_empty ())
2686 if (dim < array_list[i].ndims ())
2687 u = l + array_list[i].
dims ()(dim);
2693 retval.assign (idxa, array_list[i]);
2705 os << prefix <<
"rep address: " << rep <<
'\n'
2706 << prefix <<
"rep->len: " << rep->len <<
'\n'
2707 << prefix <<
"rep->data: " <<
static_cast<void *
> (rep->data) <<
'\n'
2708 << prefix <<
"rep->count: " << rep->count <<
'\n'
2709 << prefix <<
"slice_data: " << static_cast<void *> (slice_data) <<
'\n'
2710 << prefix <<
"slice_len: " << slice_len <<
'\n';
2721 bool retval = dimensions == dv;
2736 #define INSTANTIATE_ARRAY(T, API) \
2737 template <> void Array<T>::instantiation_guard () { } \
2738 template class API Array<T>
2744 operator << (std::ostream& os, const Array<T>& a)
2748 int n_dims = a_dims.
length ();
2750 os << n_dims <<
"-dimensional array";
2753 os <<
" (" << a_dims.
str () <<
")";
2766 for (
int i = 2; i < n_dims; i++)
2786 os <<
" " << a.
elem (ra_idx);
2798 os <<
" " << a.
elem (ra_idx);
2810 for (
int i = 0; i < m; i++)
2814 for (
int j = 2; j < n_dims - 1; j++)
2815 os << ra_idx(j) + 1 <<
",";
2817 os << ra_idx(n_dims - 1) + 1 <<
") = \n";
2826 os <<
" " << a.
elem (ra_idx);