26 #if defined (HAVE_CONFIG_H)
47 OCTAVE_NORETURN
static void err_invalid_range ()
49 (*current_liboctave_error_handler) (
"invalid range used as index");
52 OCTAVE_NORETURN
static void
53 err_index_out_of_range ()
55 (*current_liboctave_error_handler)
56 (
"internal error: idx_vector index out of range");
59 idx_vector::idx_vector_rep *
60 idx_vector::nil_rep ()
62 static idx_vector_rep ivr;
67 idx_vector::idx_base_rep::as_array ()
69 (*current_liboctave_error_handler)
70 (
"internal error: as_array not allowed for this index class");
76 idx_vector::idx_colon_rep::idx_colon_rep (
char c)
80 (*current_liboctave_error_handler)
81 (
"internal error: invalid character converted to idx_vector; must be ':'");
88 err_index_out_of_range ();
93 idx_vector::idx_base_rep *
96 (*current_liboctave_error_handler)
97 (
"internal error: idx_colon_rep::sort_idx");
101 idx_vector::idx_colon_rep::print (std::ostream& os)
const
109 : idx_base_rep (), m_start(start),
112 ? std::
max ((limit - start + step - (step > 0 ? 1 : -1)) / step,
118 err_invalid_range ();
121 if (m_step < 0 && m_start + (m_len-1)*m_step < 0)
126 : idx_base_rep (), m_start (0), m_len (
r.
numel ()), m_step (1)
129 err_invalid_range ();
133 if (
r.all_elements_are_ints ())
139 if (m_step < 0 && m_start + (m_len - 1)*m_step < 0)
145 double b =
r.base ();
146 double inc =
r.increment ();
155 if (i < 0 || i >= m_len)
156 err_index_out_of_range ();
158 return m_start + i*m_step;
161 idx_vector::idx_base_rep *
162 idx_vector::idx_range_rep::sort_uniq_clone (
bool)
165 return new idx_range_rep (m_start + (m_len - 1)*m_step, m_len, -m_step, DIRECT);
173 idx_vector::idx_base_rep *
176 if (m_step < 0 && m_len > 0)
178 idx.
clear (1, m_len);
180 idx.
xelem (i) = m_len - 1 - i;
181 return new idx_range_rep (m_start + (m_len - 1)*m_step, m_len, -m_step, DIRECT);
185 idx.
clear (1, m_len);
194 idx_vector::idx_range_rep::print (std::ostream& os)
const
196 os << m_start <<
':' << m_step <<
':' << m_start + m_len *m_step;
201 idx_vector::idx_range_rep::unconvert ()
const
204 (
static_cast<double> (m_start+1),
static_cast<double> (m_step), m_len);
208 idx_vector::idx_range_rep::as_array ()
212 retval.xelem (i) = m_start + i*m_step;
234 if (
static_cast<double> (i) !=
x)
246 template <
typename T>
255 template <
typename T>
256 idx_vector::idx_scalar_rep::idx_scalar_rep (T
x)
257 : idx_base_rep (), m_data (0)
265 : idx_base_rep (), m_data (i)
275 err_index_out_of_range ();
280 idx_vector::idx_base_rep *
290 idx_vector::idx_scalar_rep::print (std::ostream& os)
const
296 idx_vector::idx_scalar_rep::unconvert ()
const
302 idx_vector::idx_scalar_rep::as_array ()
307 template <
typename T>
308 idx_vector::idx_vector_rep::idx_vector_rep (
const Array<T>& nda)
309 : idx_base_rep (), m_data (nullptr), m_len (nda.
numel ()), m_ext (0),
310 m_aowner (nullptr), m_orig_dims (nda.dims ())
319 m_data =
d.release ();
326 : idx_base_rep (), m_data (inda.data ()), m_len (inda.
numel ()), m_ext (0),
347 : idx_base_rep (), m_data (inda.data ()), m_len (inda.
numel ()),
349 m_orig_dims (inda.dims ())
363 idx_vector::idx_vector_rep::idx_vector_rep (
bool b)
364 : idx_base_rep (), m_data (nullptr), m_len (b ? 1 : 0), m_ext (0),
365 m_aowner (nullptr), m_orig_dims (m_len, m_len)
376 idx_vector::idx_vector_rep::idx_vector_rep (
const Array<bool>& bnda,
378 : idx_base_rep (), m_data (nullptr), m_len (nnz), m_ext (0),
379 m_aowner (nullptr), m_orig_dims ()
405 idx_vector::idx_vector_rep::idx_vector_rep (
const Sparse<bool>& bnda)
406 : idx_base_rep (), m_data (nullptr), m_len (bnda.nnz ()), m_ext (0),
407 m_aowner (nullptr), m_orig_dims ()
424 d[k++] = j * nr + bnda.
ridx (i);
432 idx_vector::idx_vector_rep::~idx_vector_rep ()
443 if (n < 0 || n >= m_len)
449 idx_vector::idx_base_rep *
450 idx_vector::idx_vector_rep::sort_uniq_clone (
bool uniq)
459 std::unique_ptr<idx_vector_rep> new_rep
460 (
new idx_vector_rep (
nullptr, m_len, m_ext, m_orig_dims, DIRECT));
466 new_rep->m_data = new_data;
468 std::copy_n (m_data, m_len, new_data);
471 lsort.
sort (new_data, m_len);
477 new_rep->m_len = new_len;
478 if (new_rep->m_orig_dims.ndims () == 2 && new_rep->m_orig_dims(0) == 1)
479 new_rep->m_orig_dims =
dim_vector (1, new_len);
481 new_rep->m_orig_dims =
dim_vector (new_len, 1);
489 has[m_data[i]] =
true;
495 new_rep->m_len = new_len;
496 if (new_rep->m_orig_dims.ndims () == 2 && new_rep->m_orig_dims(0) == 1)
497 new_rep->m_orig_dims =
dim_vector (1, new_len);
499 new_rep->m_orig_dims =
dim_vector (new_len, 1);
502 new_rep->m_data = new_data;
516 new_rep->m_data = new_data;
525 return new_rep.release ();
528 idx_vector::idx_base_rep *
532 std::unique_ptr<idx_vector_rep> new_rep
533 (
new idx_vector_rep (
nullptr, m_len, m_ext, m_orig_dims, DIRECT));
538 idx.
clear (m_orig_dims);
544 new_rep->m_data = new_data;
545 std::copy_n (m_data, m_len, new_data);
549 lsort.
sort (new_data, idx_data, m_len);
559 idx.
clear (m_orig_dims);
563 new_rep->m_data = new_data;
581 return new_rep.release ();
585 idx_vector::idx_vector_rep::print (std::ostream& os)
const
590 os << m_data[i] <<
',' <<
' ';
593 os << m_data[m_len-1];
601 idx_vector::idx_vector_rep::unconvert ()
const
605 retval.xelem (i) = m_data[i] + 1;
610 idx_vector::idx_vector_rep::as_array ()
620 std::memcpy (retval.fortran_vec (), m_data, m_len* sizeof (
octave_idx_type));
625 m_data = retval.fortran_vec ();
632 idx_vector::idx_mask_rep::idx_mask_rep (
bool b)
633 : idx_base_rep (), m_data (nullptr), m_len (b ? 1 : 0), m_ext (0),
634 m_lsti (-1), m_lste (-1), m_aowner (nullptr), m_orig_dims (m_len, m_len)
638 bool *
d =
new bool [1];
645 idx_vector::idx_mask_rep::idx_mask_rep (
const Array<bool>& bnda,
647 : idx_base_rep (), m_data (nullptr), m_len (nnz), m_ext (bnda.
numel ()),
648 m_lsti (-1), m_lste (-1), m_aowner (nullptr), m_orig_dims ()
655 while (m_ext > 0 && ! bnda(m_ext-1))
663 m_data = bnda.
data ();
666 idx_vector::idx_mask_rep::~idx_mask_rep ()
680 while (! m_data[++m_lste]) ;
687 if (m_data[++m_lste]) --
n;
695 if (n < 0 || n >= m_len)
702 idx_vector::idx_mask_rep::print (std::ostream& os)
const
707 os << m_data[i] <<
',' <<
' ';
710 os << m_data[m_ext-1];
718 idx_vector::idx_mask_rep::unconvert ()
const
726 retval.xelem (i) = m_data[i];
732 idx_vector::idx_mask_rep::as_array ()
741 retval.xelem (j++) = i;
747 idx_vector::idx_base_rep *
750 idx.
clear (m_len, 1);
766 if (nnz <= bnda.
numel () / factor)
767 m_rep =
new idx_vector_rep (bnda, nnz);
769 m_rep =
new idx_mask_rep (bnda, nnz);
776 bool reduced =
false;
779 if (m_rep->length (
n) == 0)
786 if (
n == 1 && m_rep->is_colon_equiv (
n))
798 switch (m_rep->idx_class ())
808 idx_scalar_rep *
r =
dynamic_cast<idx_scalar_rep *
> (m_rep);
810 *
this =
new idx_range_rep (k, nj,
n, DIRECT);
818 idx_range_rep *
r =
dynamic_cast<idx_range_rep *
> (m_rep);
824 *
this =
new idx_range_rep (s, l * nj, t, DIRECT);
836 switch (m_rep->idx_class ())
841 idx_range_rep *rj =
dynamic_cast<idx_range_rep *
> (j.m_rep);
842 if (rj->get_step () == 1)
846 *
this =
new idx_range_rep (sj *
n, lj *
n, 1, DIRECT);
855 idx_scalar_rep *
r =
dynamic_cast<idx_scalar_rep *
> (m_rep);
856 idx_range_rep *rj =
dynamic_cast<idx_range_rep *
> (j.m_rep);
861 *
this =
new idx_range_rep (
n * sj + k, lj,
n * tj, DIRECT);
870 idx_range_rep *
r =
dynamic_cast<idx_range_rep *
> (m_rep);
874 idx_range_rep *rj =
dynamic_cast<idx_range_rep *
> (j.m_rep);
878 if ((l*t ==
n && tj == 1) || (t == 0 && tj == 0))
880 *
this =
new idx_range_rep (s +
n * sj, l * lj, t, DIRECT);
892 switch (m_rep->idx_class ())
897 idx_scalar_rep *
r =
dynamic_cast<idx_scalar_rep *
> (m_rep);
898 idx_scalar_rep *rj =
dynamic_cast<idx_scalar_rep *
> (j.m_rep);
900 *
this =
new idx_scalar_rep (k, DIRECT);
908 idx_range_rep *
r =
dynamic_cast<idx_range_rep *
> (m_rep);
909 idx_scalar_rep *rj =
dynamic_cast<idx_scalar_rep *
> (j.m_rep);
914 *
this =
new idx_range_rep (
n * k + s, l, t, DIRECT);
922 idx_scalar_rep *rj =
dynamic_cast<idx_scalar_rep *
> (j.m_rep);
924 *
this =
new idx_range_rep (
n * k,
n, 1, DIRECT);
947 switch (m_rep->idx_class ())
956 idx_range_rep *
r =
dynamic_cast<idx_range_rep *
> (m_rep);
957 if (
r->get_step () == 1)
960 u = l +
r->length (
n);
968 idx_scalar_rep *
r =
dynamic_cast<idx_scalar_rep *
> (m_rep);
977 idx_mask_rep *
r =
dynamic_cast<idx_mask_rep *
> (m_rep);
1000 switch (m_rep->idx_class ())
1007 retval =
dynamic_cast<idx_range_rep *
> (m_rep) -> get_step ();
1031 idx_vector_rep *
r =
dynamic_cast<idx_vector_rep *
> (m_rep);
1033 assert (
r !=
nullptr);
1035 return r->get_data ();
1043 switch (m_rep->idx_class ())
1046 (*current_liboctave_error_handler) (
"colon not allowed");
1051 idx_range_rep *
r =
dynamic_cast<idx_range_rep *
> (m_rep);
1056 for (i = m_start, j = m_start + m_len; i < j; i++) *m_data++ = i;
1057 else if (m_step == -1)
1058 for (i = m_start, j = m_start - m_len; i > j; i--) *m_data++ = i;
1060 for (i = 0, j = m_start; i < m_len; i++, j += m_step) *m_data++ = j;
1066 idx_scalar_rep *
r =
dynamic_cast<idx_scalar_rep *
> (m_rep);
1067 *m_data =
r->get_data ();
1073 idx_vector_rep *
r =
dynamic_cast<idx_vector_rep *
> (m_rep);
1075 std::copy_n (rdata, m_len, m_data);
1081 idx_mask_rep *
r =
dynamic_cast<idx_mask_rep *
> (m_rep);
1082 const bool *mask =
r->get_data ();
1101 (*current_liboctave_error_handler)
1102 (
"internal error: out of range complement index requested");
1106 idx_mask_rep *
r =
dynamic_cast<idx_mask_rep *
> (m_rep);
1110 const bool *m_data =
r->get_data ();
1113 ndata[i] = ! m_data[i];
1114 std::fill_n (ndata + m_ext,
n - m_ext,
true);
1115 retval =
new idx_mask_rep (mask,
n - nz);
1130 bool retval =
false;
1175 idx_vector_rep *
r =
dynamic_cast<idx_vector_rep *
> (m_rep);
1179 idx.
xelem (ri[i]) = i;
1180 retval =
new idx_vector_rep (idx,
r->extent (0), DIRECT);
1196 idx_mask_rep *
r =
dynamic_cast<idx_mask_rep *
> (m_rep);
1197 const bool *m_data =
r->get_data ();
1206 m_ext = (m_len > 0 ? idata[m_len - 1] + 1 : 0);
1208 return new idx_vector_rep (idata, m_len, m_ext,
r->orig_dimensions (),
1228 idx_range_rep *
r =
dynamic_cast<idx_range_rep *
> (m_rep);
1235 idx_scalar_rep *
r =
dynamic_cast<idx_scalar_rep *
> (m_rep);
1236 scalar =
r->unconvert ();
1242 idx_vector_rep *
r =
dynamic_cast<idx_vector_rep *
> (m_rep);
1243 array =
r->unconvert ();
1249 idx_mask_rep *
r =
dynamic_cast<idx_mask_rep *
> (m_rep);
1250 mask =
r->unconvert ();
1263 return m_rep->as_array ();
1275 if (! resize_ok &&
extent (z_len) > z_len)
1276 (*current_liboctave_error_handler)
1277 (
"invalid matrix index = %" OCTAVE_IDX_TYPE_FORMAT,
extent (z_len));
1300 #define INSTANTIATE_SCALAR_VECTOR_REP_CONST(T) \
1301 template OCTAVE_API idx_vector::idx_scalar_rep::idx_scalar_rep (T); \
1302 template OCTAVE_API idx_vector::idx_vector_rep::idx_vector_rep (const Array<T>&);
1315 OCTAVE_END_NAMESPACE(
octave)
charNDArray max(char d, const charNDArray &m)
T * fortran_vec()
Size of the specified dimension.
octave_idx_type nnz() const
Count nonzero elements.
const T * data() const
Size of the specified dimension.
Array< octave_idx_type > find(octave_idx_type n=-1, bool backward=false) const
Find indices of (at most n) nonzero elements.
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.
octave_idx_type numel() const
Number of elements in the array.
octave_idx_type cols() const
octave_idx_type rows() const
Vector representing the dimensions (size) of an Array.
dim_vector make_nd_vector(octave_idx_type n) const
idx_vector unmask() const
octave_idx_type xelem(octave_idx_type n) const
idx_class_type idx_class() const
octave_idx_type ones_count() const
idx_vector sorted(bool uniq=false) const
octave_idx_type fill(const T &val, octave_idx_type n, T *dest) const
static const idx_vector colon
dim_vector orig_dimensions() const
bool maybe_reduce(octave_idx_type n, const idx_vector &j, octave_idx_type nj)
void copy_data(octave_idx_type *data) const
void unconvert(idx_class_type &iclass, double &scalar, range< double > &range, Array< double > &array, Array< bool > &mask) const
octave_idx_type length(octave_idx_type n=0) const
octave_idx_type elem(octave_idx_type n) const
octave_idx_type freeze(octave_idx_type z_len, const char *tag, bool resize_ok=false)
bool is_cont_range(octave_idx_type n, octave_idx_type &l, octave_idx_type &u) const
idx_vector complement(octave_idx_type n) const
Array< octave_idx_type > as_array() const
bool is_permutation(octave_idx_type n) const
idx_vector inverse_permutation(octave_idx_type n) const
octave_idx_type increment() const
octave_idx_type extent(octave_idx_type n) const
const octave_idx_type * raw()
bool is_colon_equiv(octave_idx_type n) const
void set_compare(const compare_fcn_type &comp)
void sort(T *data, octave_idx_type nel)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define INSTANTIATE_SCALAR_VECTOR_REP_CONST(T)
octave_idx_type convert_index(octave_idx_type i, octave_idx_type &ext)
void err_invalid_index(const std::string &idx, octave_idx_type nd, octave_idx_type dim, const std::string &)
Complex log2(const Complex &x)
std::complex< T > trunc(const std::complex< T > &x)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
#define OCTAVE_LOCAL_BUFFER_INIT(T, buf, size, value)
T::size_type numel(const T &str)