GNU Octave 11.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
Array-base.h
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1993-2026 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if ! defined (octave_Array_base_h)
27#define octave_Array_base_h 1
28
29#include "octave-config.h"
30
31#include <cstddef>
32
33#include <algorithm>
34#include <iosfwd>
35#include <string>
36
37#include "Array-fwd.h"
38#include "dim-vector.h"
39#include "idx-vector.h"
40#include "oct-error.h"
41#include "oct-traits.h"
42#include "lo-utils.h"
43#include "oct-refcount.h"
44#include "oct-sort.h"
45#include "quit.h"
46
47//! N Dimensional Array with copy-on-write semantics.
48//!
49//! The Array class is at the root of Octave. It provides a container
50//! with an arbitrary number of dimensions. The operator () provides
51//! access to individual elements via subscript and linear indexing.
52//! Indexing starts at 0. Arrays are column-major order as in Fortran.
53//!
54//! @code{.cc}
55//! // 3 D Array with 10 rows, 20 columns, and 5 pages, filled with 7.0
56//! Array<double> A (dim_vector (10, 20, 5), 7.0);
57//!
58//! // set value for row 0, column 10, and page 3
59//! A(0, 10, 3) = 2.5;
60//!
61//! // get value for row 1, column 2, and page 0
62//! double v = A(1, 2, 0);
63//!
64//! // get value for 25th element (row 4, column 3, page 1)
65//! double v = A(24);
66//! @endcode
67//!
68//! ## Notes on STL compatibility
69//!
70//! ### size() and length()
71//!
72//! To access the total number of elements in an Array, use numel()
73//! which is short for number of elements and is equivalent to the
74//! Octave function with same name.
75//!
76//! @code{.cc}
77//! Array<int> A (dim_vector (10, 20, 4), 1);
78//!
79//! octave_idx_type n = A.numel (); // returns 800 (10x20x4)
80//!
81//! octave_idx_type nr = A.size (0); // returns 10 (number of rows/dimension 0)
82//! octave_idx_type nc = A.size (1); // returns 20 (number of columns)
83//! octave_idx_type nc = A.size (2); // returns 4 (size of dimension 3)
84//! octave_idx_type l6 = A.size (6); // returns 1 (implicit singleton dimension)
85//!
86//! // Alternatively, get a dim_vector which represents the dimensions.
87//! dim_vector dims = A.dims ();
88//! @endcode
89//!
90//! The methods size() and length() as they exist in the STL cause
91//! confusion in the context of a N dimensional array.
92//!
93//! The size() of an array is the length of all dimensions. In Octave,
94//! the size() function returns a row vector with the length of each
95//! dimension, or the size of a specific dimension. Only the latter is
96//! present in liboctave.
97//!
98//! Since there is more than 1 dimension, length() would not make sense
99//! without expliciting which dimension. If the function existed, which
100//! length should it return? Octave length() function returns the length
101//! of the longest dimension which is an odd definition, only useful for
102//! vectors and square matrices. The alternatives numel(), rows(),
103//! columns(), and size(d) are more explicit and recommended.
104//!
105//! ### size_type
106//!
107//! Array::size_type is 'octave_idx_type' which is a typedef for 'int'
108//! or 'long int', depending whether Octave was configured for 64-bit
109//! indexing.
110//!
111//! This is a signed integer which may cause problems when mixed with
112//! STL containers. The reason is that Octave interacts with Fortran
113//! routines, providing an interface many Fortran numeric libraries.
114//!
115//! ## Subclasses
116//!
117//! The following subclasses specializations, will be of most use:
118//! - Matrix: Array<double> with only 2 dimensions
119//! - ComplexMatrix: Array<std::complex<double>> with only 2 dimensions
120//! - boolNDArray: N dimensional Array<bool>
121//! - ColumnVector: Array<double> with 1 column
122//! - string_vector: Array<std::string> with 1 column
123//! - Cell: Array<octave_value>, equivalent to an Octave cell.
124
125// forward declare template with visibility attributes
126template <typename T, typename Alloc> class OCTARRAY_API Array;
127
128template <typename T, typename Alloc>
129class OCTARRAY_TEMPLATE_API Array
130{
131protected:
132
133 //! The real representation of all arrays.
134 class OCTARRAY_TEMPLATE_API ArrayRep : public Alloc
135 {
136 public:
137
138 typedef std::allocator_traits<Alloc> Alloc_traits;
139
140 typedef typename Alloc_traits::template rebind_traits<T> T_Alloc_traits;
141 typedef typename T_Alloc_traits::pointer pointer;
142
145 octave::refcount<octave_idx_type> m_count;
146
147 OCTARRAY_OVERRIDABLE_FUNC_API
149 : Alloc (), m_data (allocate (len)), m_len (len), m_count (1)
150 {
151 std::copy_n (d, len, m_data);
152 }
153
154 template <typename U>
155 OCTARRAY_OVERRIDABLE_FUNC_API
157 : Alloc (), m_data (allocate (len)), m_len (len), m_count (1)
158 {
159 if constexpr (std::is_same_v<T, bool>)
160 {
161 // Required specialization because std::copy_n can sometimes choose
162 // to copy bool as bit, rather than as 8-bit byte. See bug #63515.
163 for (octave_idx_type i = 0; i < len; i++)
164 m_data[i] = static_cast<bool> (d[i]);
165 }
166 else
167 std::copy_n (d, len, m_data);
168 }
169
170 // Use new instead of setting data to 0 so that rwdata() and data()
171 // always return valid addresses, even for zero-size arrays.
172
173 OCTARRAY_OVERRIDABLE_FUNC_API ArrayRep ()
174 : Alloc (), m_data (allocate (0)), m_len (0), m_count (1) { }
175
176 explicit OCTARRAY_OVERRIDABLE_FUNC_API ArrayRep (octave_idx_type len)
177 : Alloc (), m_data (allocate (len)), m_len (len), m_count (1) { }
178
179 explicit OCTARRAY_OVERRIDABLE_FUNC_API
181 : Alloc (), m_data (allocate (len)), m_len (len), m_count (1)
182 {
183 std::fill_n (m_data, len, val);
184 }
185
186 explicit OCTARRAY_OVERRIDABLE_FUNC_API
187 ArrayRep (pointer ptr, const dim_vector& dv,
188 const Alloc& xallocator = Alloc ())
189 : Alloc (xallocator), m_data (ptr), m_len (dv.safe_numel ()), m_count (1)
190 { }
191
192 // FIXME: Should the allocator be copied or created with the default?
193 OCTARRAY_OVERRIDABLE_FUNC_API ArrayRep (const ArrayRep& a)
194 : Alloc (), m_data (allocate (a.m_len)), m_len (a.m_len),
195 m_count (1)
196 {
197 std::copy_n (a.m_data, a.m_len, m_data);
198 }
199
200 OCTARRAY_OVERRIDABLE_FUNC_API ~ArrayRep () { deallocate (m_data, m_len); }
201
202 OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type numel () const
203 {
204 return m_len;
205 }
206
207 // No assignment!
208
209 OCTARRAY_OVERRIDABLE_FUNC_API ArrayRep&
210 operator = (const ArrayRep&) = delete;
211
212 OCTARRAY_OVERRIDABLE_FUNC_API pointer allocate (size_t len)
213 {
214 pointer data = Alloc_traits::allocate (*this, len);
215 for (size_t i = 0; i < len; i++)
216 T_Alloc_traits::construct (*this, data+i);
217 return data;
218 }
219
220 OCTARRAY_OVERRIDABLE_FUNC_API void deallocate (pointer data, size_t len)
221 {
222 for (size_t i = 0; i < len; i++)
223 T_Alloc_traits::destroy (*this, data+i);
224 Alloc_traits::deallocate (*this, data, len);
225 }
226 };
227
228 //--------------------------------------------------------------------
229
230public:
231
232 OCTARRAY_OVERRIDABLE_FUNC_API void make_unique ()
233 {
234 if (m_rep->m_count > 1)
235 {
236 ArrayRep *r = new ArrayRep (m_slice_data, m_slice_len);
237
238 if (--m_rep->m_count == 0)
239 delete m_rep;
240
241 m_rep = r;
242 m_slice_data = m_rep->m_data;
243 }
244 }
245
246 typedef T element_type;
247
248 typedef T value_type;
249
250 //! Used for operator(), and returned by numel() and size()
251 //! (beware: signed integer)
253
254 typedef typename ref_param<T>::type crefT;
255
256 typedef bool (*compare_fcn_type) (typename ref_param<T>::type,
257 typename ref_param<T>::type);
258
259protected:
260
262
264
265 // Rationale:
266 // m_slice_data is a pointer to m_rep->m_data, denoting together with m_slice_len the
267 // actual portion of the data referenced by this Array<T> object. This
268 // allows to make shallow copies not only of a whole array, but also of
269 // contiguous subranges. Every time m_rep is directly manipulated, m_slice_data
270 // and m_slice_len need to be properly updated.
271
274
275 //! slice constructor
276 OCTARRAY_OVERRIDABLE_FUNC_API
277 Array (const Array<T, Alloc>& a, const dim_vector& dv,
279 : m_dimensions (dv), m_rep(a.m_rep), m_slice_data (a.m_slice_data+l), m_slice_len (u-l)
280 {
281 m_rep->m_count++;
282 m_dimensions.chop_trailing_singletons ();
283 }
284
285private:
286
287 static OCTARRAY_API typename Array<T, Alloc>::ArrayRep * nil_rep ();
288
289public:
290
291 //! Empty ctor (0 by 0).
292 OCTARRAY_OVERRIDABLE_FUNC_API Array ()
293 : m_dimensions (), m_rep (nil_rep ()), m_slice_data (m_rep->m_data),
294 m_slice_len (m_rep->m_len)
295 {
296 m_rep->m_count++;
297 }
298
299 //! nD uninitialized ctor.
300 OCTARRAY_OVERRIDABLE_FUNC_API
301 explicit Array (const dim_vector& dv)
302 : m_dimensions (dv),
303 m_rep (new typename Array<T, Alloc>::ArrayRep (dv.safe_numel ())),
304 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
305 {
306 m_dimensions.chop_trailing_singletons ();
307 }
308
309 //! nD initialized ctor.
310 OCTARRAY_OVERRIDABLE_FUNC_API
311 explicit Array (const dim_vector& dv, const T& val)
312 : m_dimensions (dv),
313 m_rep (new typename Array<T, Alloc>::ArrayRep (dv.safe_numel ())),
314 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
315 {
316 fill (val);
317 m_dimensions.chop_trailing_singletons ();
318 }
319
320 // Construct an Array from a pointer to an externally allocated array
321 // of values. PTR must be allocated with operator new. The Array
322 // object takes ownership of PTR and will delete it when the Array
323 // object is deleted. The dimension vector DV must be consistent with
324 // the size of the allocated PTR array.
325
326 OCTARRAY_OVERRIDABLE_FUNC_API
327 explicit Array (T *ptr, const dim_vector& dv,
328 const Alloc& xallocator = Alloc ())
329 : m_dimensions (dv),
330 m_rep (new typename Array<T, Alloc>::ArrayRep (ptr, dv, xallocator)),
331 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
332 {
333 m_dimensions.chop_trailing_singletons ();
334 }
335
336 //! Reshape constructor.
337 OCTARRAY_API Array (const Array<T, Alloc>& a, const dim_vector& dv);
338
339 //! Constructor from standard library sequence containers.
340 template<template <typename...> class Container>
341 OCTARRAY_OVERRIDABLE_FUNC_API
342 Array (const Container<T>& a, const dim_vector& dv);
343
344 //! Type conversion case.
345 template <typename U, typename A = Alloc>
346 OCTARRAY_OVERRIDABLE_FUNC_API
348 : m_dimensions (a.dims ()),
349 m_rep (new typename Array<T, Alloc>::ArrayRep (a.data (), a.numel ())),
350 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
351 { }
352
353 //! No type conversion case.
354 OCTARRAY_OVERRIDABLE_FUNC_API
356 : m_dimensions (a.m_dimensions), m_rep (a.m_rep), m_slice_data (a.m_slice_data),
357 m_slice_len (a.m_slice_len)
358 {
359 m_rep->m_count++;
360 }
361
362 OCTARRAY_OVERRIDABLE_FUNC_API
364 : m_dimensions (std::move (a.m_dimensions)), m_rep (a.m_rep),
365 m_slice_data (a.m_slice_data), m_slice_len (a.m_slice_len)
366 {
367 a.m_rep = nullptr;
368 a.m_slice_data = nullptr;
369 a.m_slice_len = 0;
370 }
371
372public:
373
374 virtual OCTARRAY_OVERRIDABLE_FUNC_API ~Array ()
375 {
376 // Because we define a move constructor and a move assignment
377 // operator, m_rep may be a nullptr here. We should only need to
378 // protect the move assignment operator in a similar way.
379
380 if (m_rep && --m_rep->m_count == 0)
381 delete m_rep;
382 }
383
384 OCTARRAY_OVERRIDABLE_FUNC_API Array<T, Alloc>&
385 operator = (const Array<T, Alloc>& a)
386 {
387 if (this != &a)
388 {
389 if (--m_rep->m_count == 0)
390 delete m_rep;
391
392 m_rep = a.m_rep;
393 m_rep->m_count++;
394
395 m_dimensions = a.m_dimensions;
396 m_slice_data = a.m_slice_data;
397 m_slice_len = a.m_slice_len;
398 }
399
400 return *this;
401 }
402
403 OCTARRAY_OVERRIDABLE_FUNC_API Array<T, Alloc>&
404 operator = (Array<T, Alloc>&& a)
405 {
406 if (this != &a)
407 {
408 m_dimensions = std::move (a.m_dimensions);
409
410 // Because we define a move constructor and a move assignment
411 // operator, m_rep may be a nullptr here. We should only need to
412 // protect the destructor in a similar way.
413
414 if (m_rep && --m_rep->m_count == 0)
415 delete m_rep;
416
417 m_rep = a.m_rep;
418 m_slice_data = a.m_slice_data;
419 m_slice_len = a.m_slice_len;
420
421 a.m_rep = nullptr;
422 a.m_slice_data = nullptr;
423 a.m_slice_len = 0;
424 }
425
426 return *this;
427 }
428
429 OCTARRAY_API void fill (const T& val);
430
431 OCTARRAY_API void clear ();
432 OCTARRAY_API void clear (const dim_vector& dv);
433
434 OCTARRAY_OVERRIDABLE_FUNC_API void
436 { clear (dim_vector (r, c)); }
437
438 //! Number of elements in the array.
439 OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type
440 numel () const
441 { return m_slice_len; }
442 //@}
443
444 //! Return the array as a column vector.
445 OCTARRAY_OVERRIDABLE_FUNC_API Array<T, Alloc>
446 as_column () const
447 {
448 Array<T, Alloc> retval (*this);
449 if (m_dimensions.ndims () != 2 || m_dimensions(1) != 1)
450 retval.m_dimensions = dim_vector (numel (), 1);
451
452 return retval;
453 }
454
455 //! Return the array as a row vector.
456 OCTARRAY_OVERRIDABLE_FUNC_API Array<T, Alloc>
457 as_row () const
458 {
459 Array<T, Alloc> retval (*this);
460 if (m_dimensions.ndims () != 2 || m_dimensions(0) != 1)
461 retval.m_dimensions = dim_vector (1, numel ());
462
463 return retval;
464 }
465
466 //! Return the array as a matrix.
467 OCTARRAY_OVERRIDABLE_FUNC_API Array<T, Alloc>
468 as_matrix () const
469 {
470 Array<T, Alloc> retval (*this);
471 if (m_dimensions.ndims () != 2)
472 retval.m_dimensions = m_dimensions.redim (2);
473
474 return retval;
475 }
476
477 //! @name First dimension
478 //!
479 //! Get the first dimension of the array (number of rows)
480 //@{
481 OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type
482 dim1 () const
483 { return m_dimensions(0); }
484 OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type
485 rows () const
486 { return dim1 (); }
487 //@}
488
489 //! @name Second dimension
490 //!
491 //! Get the second dimension of the array (number of columns)
492 //@{
493 OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type dim2 () const
494 { return m_dimensions(1); }
495 OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type cols () const
496 { return dim2 (); }
497 OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type columns () const
498 { return dim2 (); }
499 //@}
500
501 //! @name Third dimension
502 //!
503 //! Get the third dimension of the array (number of pages)
504 //@{
505 OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type dim3 () const
506 { return m_dimensions.ndims () >= 3 ? m_dimensions(2) : 1; }
507 OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type pages () const
508 { return dim3 (); }
509 //@}
510
511 //! Size of the specified dimension.
512 //!
513 //! Dimensions beyond the Array number of dimensions return 1 as
514 //! those are implicit singleton dimensions.
515 //!
516 //! Equivalent to Octave's 'size (A, DIM)'
517
518 OCTARRAY_OVERRIDABLE_FUNC_API size_type size (const size_type d) const
519 {
520 // Should we throw for negative values?
521 // Should >= ndims () be handled by dim_vector operator() instead ?
522 return d >= ndims () ? 1 : m_dimensions(d);
523 }
524
525 OCTARRAY_OVERRIDABLE_FUNC_API std::size_t byte_size () const
526 { return static_cast<std::size_t> (numel ()) * sizeof (T); }
527
528 //! Return a const-reference so that dims ()(i) works efficiently.
529 OCTARRAY_OVERRIDABLE_FUNC_API const dim_vector& dims () const
530 { return m_dimensions; }
531
532 //! Chop off leading singleton dimensions
533 OCTARRAY_API Array<T, Alloc> squeeze () const;
534
535 OCTARRAY_API octave_idx_type
537 OCTARRAY_API octave_idx_type
539 OCTARRAY_API octave_idx_type
541
542 OCTARRAY_API octave_idx_type
543 compute_index_unchecked (const Array<octave_idx_type>& ra_idx) const;
544
545 // No checking, even for multiple references, ever.
546
547 OCTARRAY_OVERRIDABLE_FUNC_API T& xelem (octave_idx_type n)
548 { return m_slice_data[n]; }
549 OCTARRAY_OVERRIDABLE_FUNC_API crefT xelem (octave_idx_type n) const
550 { return m_slice_data[n]; }
551
552 OCTARRAY_OVERRIDABLE_FUNC_API T&
554 { return xelem (dim1 ()*j+i); }
555 OCTARRAY_OVERRIDABLE_FUNC_API crefT
557 { return xelem (dim1 ()*j+i); }
558
559 OCTARRAY_OVERRIDABLE_FUNC_API T&
561 { return xelem (i, dim2 ()*k+j); }
562 OCTARRAY_OVERRIDABLE_FUNC_API crefT
564 { return xelem (i, dim2 ()*k+j); }
565
566 OCTARRAY_OVERRIDABLE_FUNC_API T&
568 { return xelem (compute_index_unchecked (ra_idx)); }
569
570 OCTARRAY_OVERRIDABLE_FUNC_API crefT
572 { return xelem (compute_index_unchecked (ra_idx)); }
573
574 // FIXME: would be nice to fix this so that we don't unnecessarily force
575 // a copy, but that is not so easy, and I see no clean way to do it.
576
577 OCTARRAY_API T& checkelem (octave_idx_type n);
578
579 OCTARRAY_API T& checkelem (octave_idx_type i, octave_idx_type j);
580
581 OCTARRAY_API T& checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k);
582
583 OCTARRAY_API T& checkelem (const Array<octave_idx_type>& ra_idx);
584
585 OCTARRAY_OVERRIDABLE_FUNC_API T& elem (octave_idx_type n)
586 {
587 make_unique ();
588 return xelem (n);
589 }
590
591 OCTARRAY_OVERRIDABLE_FUNC_API T& elem (octave_idx_type i, octave_idx_type j)
592 { return elem (dim1 ()*j+i); }
593
594 OCTARRAY_OVERRIDABLE_FUNC_API T& elem (octave_idx_type i, octave_idx_type j, octave_idx_type k)
595 { return elem (i, dim2 ()*k+j); }
596
597 OCTARRAY_OVERRIDABLE_FUNC_API T& elem (const Array<octave_idx_type>& ra_idx)
598 { return Array<T, Alloc>::elem (compute_index_unchecked (ra_idx)); }
599
600 OCTARRAY_OVERRIDABLE_FUNC_API T& operator () (octave_idx_type n)
601 { return elem (n); }
602 OCTARRAY_OVERRIDABLE_FUNC_API T& operator () (octave_idx_type i, octave_idx_type j)
603 { return elem (i, j); }
604 OCTARRAY_OVERRIDABLE_FUNC_API T& operator () (octave_idx_type i, octave_idx_type j, octave_idx_type k)
605 { return elem (i, j, k); }
606 OCTARRAY_OVERRIDABLE_FUNC_API T& operator () (const Array<octave_idx_type>& ra_idx)
607 { return elem (ra_idx); }
608
609 OCTARRAY_API crefT checkelem (octave_idx_type n) const;
610
611 OCTARRAY_API crefT checkelem (octave_idx_type i, octave_idx_type j) const;
612
613 OCTARRAY_API crefT checkelem (octave_idx_type i, octave_idx_type j,
614 octave_idx_type k) const;
615
616 OCTARRAY_API crefT checkelem (const Array<octave_idx_type>& ra_idx) const;
617
618 OCTARRAY_OVERRIDABLE_FUNC_API crefT elem (octave_idx_type n) const
619 { return xelem (n); }
620
621 OCTARRAY_OVERRIDABLE_FUNC_API crefT
623 { return xelem (i, j); }
624
625 OCTARRAY_OVERRIDABLE_FUNC_API crefT
627 { return xelem (i, j, k); }
628
629 OCTARRAY_OVERRIDABLE_FUNC_API crefT
631 { return Array<T, Alloc>::xelem (compute_index_unchecked (ra_idx)); }
632
633 OCTARRAY_OVERRIDABLE_FUNC_API crefT
634 operator () (octave_idx_type n) const { return elem (n); }
635 OCTARRAY_OVERRIDABLE_FUNC_API crefT
636 operator () (octave_idx_type i, octave_idx_type j) const
637 { return elem (i, j); }
638 OCTARRAY_OVERRIDABLE_FUNC_API crefT
640 { return elem (i, j, k); }
641 OCTARRAY_OVERRIDABLE_FUNC_API crefT
642 operator () (const Array<octave_idx_type>& ra_idx) const
643 { return elem (ra_idx); }
644
645 // Fast extractors. All of these produce shallow copies.
646
647 //! Extract column: A(:,k+1).
648 OCTARRAY_API Array<T, Alloc> column (octave_idx_type k) const;
649 //! Extract page: A(:,:,k+1).
650 OCTARRAY_API Array<T, Alloc> page (octave_idx_type k) const;
651
652 //! Extract a slice from this array as a column vector: A(:)(lo+1:up).
653 //! Must be 0 <= lo && up <= numel. May be up < lo.
654 OCTARRAY_API Array<T, Alloc>
655 linear_slice (octave_idx_type lo, octave_idx_type up) const;
656
657 OCTARRAY_OVERRIDABLE_FUNC_API Array<T, Alloc>
659 { return Array<T, Alloc> (*this, dim_vector (nr, nc)); }
660
661 OCTARRAY_OVERRIDABLE_FUNC_API Array<T, Alloc>
662 reshape (const dim_vector& new_dims) const
663 { return Array<T, Alloc> (*this, new_dims); }
664
665 OCTARRAY_API Array<T, Alloc>
666 permute (const Array<octave_idx_type>& vec, bool inv = false) const;
667 OCTARRAY_OVERRIDABLE_FUNC_API Array<T, Alloc>
669 { return permute (vec, true); }
670
671 OCTARRAY_OVERRIDABLE_FUNC_API bool issquare () const
672 { return (dim1 () == dim2 ()); }
673
674 OCTARRAY_OVERRIDABLE_FUNC_API bool isempty () const
675 { return numel () == 0; }
676
677 OCTARRAY_OVERRIDABLE_FUNC_API bool isvector () const
678 { return m_dimensions.isvector (); }
679
680 OCTARRAY_OVERRIDABLE_FUNC_API bool is_nd_vector () const
681 { return m_dimensions.is_nd_vector (); }
682
683 OCTARRAY_API Array<T, Alloc> transpose () const;
684 OCTARRAY_API Array<T, Alloc> hermitian (T (*fcn) (const T&) = nullptr) const;
685
686 // Use for direct read-only access to Array data.
687 OCTARRAY_OVERRIDABLE_FUNC_API const T * data () const
688 { return m_slice_data; }
689
690 // Use for direct read-write access to Array data.
691 OCTARRAY_API T * rwdata ();
692
693 // Alias for direct read-write access to Array data.
694 // FIXME: It is recommended to use rwdata() in future code for clarity.
695 inline OCTARRAY_OVERRIDABLE_FUNC_API T * fortran_vec ()
696 { return rwdata (); }
697
698 OCTARRAY_OVERRIDABLE_FUNC_API bool is_shared () const
699 { return m_rep->m_count > 1; }
700
701 OCTARRAY_OVERRIDABLE_FUNC_API int ndims () const
702 { return m_dimensions.ndims (); }
703
704 //@{
705 //! Indexing without resizing.
706 OCTARRAY_API Array<T, Alloc> index (const octave::idx_vector& i) const;
707
708 OCTARRAY_API Array<T, Alloc> index (const octave::idx_vector& i, const octave::idx_vector& j) const;
709
710 OCTARRAY_API Array<T, Alloc> index (const Array<octave::idx_vector>& ia) const;
711 //@}
712
713 virtual OCTARRAY_API T resize_fill_value () const;
714
715 //@{
716 //! Resizing (with fill).
717 OCTARRAY_API void resize2 (octave_idx_type nr, octave_idx_type nc, const T& rfv);
718 OCTARRAY_OVERRIDABLE_FUNC_API void resize2 (octave_idx_type nr, octave_idx_type nc)
719 {
720 resize2 (nr, nc, resize_fill_value ());
721 }
722
723 OCTARRAY_API void resize1 (octave_idx_type n, const T& rfv);
724 OCTARRAY_OVERRIDABLE_FUNC_API void resize1 (octave_idx_type n)
725 { resize1 (n, resize_fill_value ()); }
726
727 OCTARRAY_API void resize (const dim_vector& dv, const T& rfv);
728 OCTARRAY_OVERRIDABLE_FUNC_API void resize (const dim_vector& dv)
729 { resize (dv, resize_fill_value ()); }
730 //@}
731
732 //@{
733 //! Indexing with possible resizing and fill
734
735 // FIXME: this is really a corner case, that should better be
736 // handled directly in liboctinterp.
737
738 OCTARRAY_API Array<T, Alloc>
739 index (const octave::idx_vector& i, bool resize_ok, const T& rfv) const;
740 OCTARRAY_OVERRIDABLE_FUNC_API Array<T, Alloc>
741 index (const octave::idx_vector& i, bool resize_ok) const
742 {
743 return index (i, resize_ok, resize_fill_value ());
744 }
745
746 OCTARRAY_API Array<T, Alloc>
747 index (const octave::idx_vector& i, const octave::idx_vector& j,
748 bool resize_ok, const T& rfv) const;
749 OCTARRAY_OVERRIDABLE_FUNC_API Array<T, Alloc>
750 index (const octave::idx_vector& i, const octave::idx_vector& j,
751 bool resize_ok) const
752 {
753 return index (i, j, resize_ok, resize_fill_value ());
754 }
755
756 OCTARRAY_API Array<T, Alloc>
757 index (const Array<octave::idx_vector>& ia, bool resize_ok,
758 const T& rfv) const;
759 OCTARRAY_API Array<T, Alloc>
760 index (const Array<octave::idx_vector>& ia, bool resize_ok) const;
761 //@}
762
763 //@{
764 //! Indexed assignment (always with resize & fill).
765 OCTARRAY_API void
766 assign (const octave::idx_vector& i, const Array<T, Alloc>& rhs, const T& rfv);
767 OCTARRAY_OVERRIDABLE_FUNC_API void
768 assign (const octave::idx_vector& i, const Array<T, Alloc>& rhs)
769 {
770 assign (i, rhs, resize_fill_value ());
771 }
772
773 OCTARRAY_API void
774 assign (const octave::idx_vector& i, const octave::idx_vector& j,
775 const Array<T, Alloc>& rhs, const T& rfv);
776 OCTARRAY_OVERRIDABLE_FUNC_API void
777 assign (const octave::idx_vector& i, const octave::idx_vector& j,
778 const Array<T, Alloc>& rhs)
779 {
780 assign (i, j, rhs, resize_fill_value ());
781 }
782
783 OCTARRAY_API void
784 assign (const Array<octave::idx_vector>& ia, const Array<T, Alloc>& rhs, const T& rfv);
785 OCTARRAY_API void
786 assign (const Array<octave::idx_vector>& ia, const Array<T, Alloc>& rhs);
787 //@}
788
789 //@{
790 //! Deleting elements.
791
792 //! A(I) = [] (with a single subscript)
793 OCTARRAY_API void delete_elements (const octave::idx_vector& i);
794
795 //! A(:,...,I,...,:) = [] (>= 2 subscripts, one of them is non-colon)
796 OCTARRAY_API void delete_elements (int dim, const octave::idx_vector& i);
797
798 //! Dispatcher to the above two.
799 OCTARRAY_API void delete_elements (const Array<octave::idx_vector>& ia);
800 //@}
801
802 //! Insert an array into another at a specified position. If
803 //! size (a) is [d1 d2 ... dN] and idx is [i1 i2 ... iN], this
804 //! method is equivalent to x(i1:i1+d1-1, i2:i2+d2-1, ... ,
805 //! iN:iN+dN-1) = a.
806 OCTARRAY_API Array<T, Alloc>&
807 insert (const Array<T, Alloc>& a, const Array<octave_idx_type>& idx);
808
809 //! This is just a special case for idx = [r c 0 ...]
810 OCTARRAY_API Array<T, Alloc>&
811 insert (const Array<T, Alloc>& a, octave_idx_type r, octave_idx_type c);
812
813 OCTARRAY_OVERRIDABLE_FUNC_API void maybe_economize ()
814 {
815 if (m_rep->m_count == 1 && m_slice_len != m_rep->m_len)
816 {
817 ArrayRep *new_rep = new ArrayRep (m_slice_data, m_slice_len);
818 delete m_rep;
819 m_rep = new_rep;
820 m_slice_data = m_rep->m_data;
821 }
822 }
823
824 OCTARRAY_API void print_info (std::ostream& os, const std::string& prefix) const;
825
826 OCTARRAY_API Array<T, Alloc> sort (int dim = 0, sortmode mode = ASCENDING) const;
827 OCTARRAY_API Array<T, Alloc> sort (Array<octave_idx_type>& sidx, int dim = 0,
828 sortmode mode = ASCENDING) const;
829
830 //! Ordering is auto-detected or can be specified.
831 OCTARRAY_API sortmode issorted (sortmode mode = UNSORTED) const;
832
833 //! Sort by rows returns only indices.
834 OCTARRAY_API Array<octave_idx_type> sort_rows_idx (sortmode mode = ASCENDING) const;
835
836 //! Ordering is auto-detected or can be specified.
837 OCTARRAY_API sortmode is_sorted_rows (sortmode mode = UNSORTED) const;
838
839 //! Do a binary lookup in a sorted array. Must not contain NaNs.
840 //! Mode can be specified or is auto-detected by comparing 1st and last element.
841 OCTARRAY_API octave_idx_type lookup (const T& value, sortmode mode = UNSORTED) const;
842
843 //! Ditto, but for an array of values, specializing on the case when values
844 //! are sorted. NaNs get the value N.
845 OCTARRAY_API Array<octave_idx_type> lookup (const Array<T, Alloc>& values,
846 sortmode mode = UNSORTED) const;
847
848 //! Count nonzero elements.
849 OCTARRAY_API octave_idx_type nnz () const;
850
851 //! Find indices of (at most n) nonzero elements. If n is specified,
852 //! backward specifies search from backward.
853 OCTARRAY_API Array<octave_idx_type> find (octave_idx_type n = -1,
854 bool backward = false) const;
855
856 //! Returns the n-th element in increasing order, using the same
857 //! ordering as used for sort. n can either be a scalar index or a
858 //! contiguous range.
859 OCTARRAY_API Array<T, Alloc> nth_element (const octave::idx_vector& n, int dim = 0) const;
860
861 //! Get the kth super or subdiagonal. The zeroth diagonal is the
862 //! ordinary diagonal.
863 OCTARRAY_API Array<T, Alloc> diag (octave_idx_type k = 0) const;
864
865 OCTARRAY_API Array<T, Alloc> diag (octave_idx_type m, octave_idx_type n) const;
866
867 //! Concatenation along a specified (0-based) dimension, equivalent
868 //! to cat(). dim = -1 corresponds to dim = 0 and dim = -2
869 //! corresponds to dim = 1, but apply the looser matching rules of
870 //! vertcat/horzcat.
871 static OCTARRAY_API Array<T, Alloc>
872 cat (int dim, octave_idx_type n, const Array<T, Alloc> *array_list);
873
874 //! Apply function fcn to each element of the Array<T, Alloc>. This function
875 //! is optimized with a manually unrolled loop.
876#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
877 template <typename U, typename F,
878 typename A = std::pmr::polymorphic_allocator<U>>
879#else
880 template <typename U, typename F, typename A = std::allocator<U>>
881#endif
882 OCTARRAY_OVERRIDABLE_FUNC_API
884 map (F fcn) const
885 {
887
888 const T *m = data ();
889
890 Array<U, A> result (dims ());
891 U *p = result.rwdata ();
892
894 for (i = 0; i < len - 3; i += 4)
895 {
896 octave_quit ();
897
898 p[i] = fcn (m[i]);
899 p[i+1] = fcn (m[i+1]);
900 p[i+2] = fcn (m[i+2]);
901 p[i+3] = fcn (m[i+3]);
902 }
903
904 octave_quit ();
905
906 for (; i < len; i++)
907 p[i] = fcn (m[i]);
908
909 return result;
910 }
911
912 //@{
913 //! Overloads for function references.
914#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
915 template <typename U, typename A = std::pmr::polymorphic_allocator<U>>
916#else
917 template <typename U, typename A = std::allocator<U>>
918#endif
919 OCTARRAY_OVERRIDABLE_FUNC_API
921 map (U (&fcn) (T)) const
922 { return map<U, U (&) (T), A> (fcn); }
923
924#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
925 template <typename U, typename A = std::pmr::polymorphic_allocator<U>>
926#else
927 template <typename U, typename A = std::allocator<U>>
928#endif
929 OCTARRAY_OVERRIDABLE_FUNC_API
931 map (U (&fcn) (const T&)) const
932 { return map<U, U (&) (const T&), A> (fcn); }
933 //@}
934
935 //! Generic any/all test functionality with arbitrary predicate.
936 template <typename F, bool zero>
937 OCTARRAY_OVERRIDABLE_FUNC_API
938 bool test (F fcn) const
939 {
940 return octave::any_all_test<F, T, zero> (fcn, data (), numel ());
941 }
942
943 //@{
944 //! Simpler calls.
945 template <typename F>
946 OCTARRAY_OVERRIDABLE_FUNC_API
947 bool test_any (F fcn) const
948 { return test<F, false> (fcn); }
949
950 template <typename F>
951 OCTARRAY_OVERRIDABLE_FUNC_API
952 bool test_all (F fcn) const
953 { return test<F, true> (fcn); }
954 //@}
955
956 //@{
957 //! Overloads for function references.
958 OCTARRAY_OVERRIDABLE_FUNC_API bool test_any (bool (&fcn) (T)) const
959 { return test<bool (&) (T), false> (fcn); }
960
961 OCTARRAY_OVERRIDABLE_FUNC_API bool test_any (bool (&fcn) (const T&)) const
962 { return test<bool (&) (const T&), false> (fcn); }
963
964 OCTARRAY_OVERRIDABLE_FUNC_API bool test_all (bool (&fcn) (T)) const
965 { return test<bool (&) (T), true> (fcn); }
966
967 OCTARRAY_OVERRIDABLE_FUNC_API bool test_all (bool (&fcn) (const T&)) const
968 { return test<bool (&) (const T&), true> (fcn); }
969 //@}
970
971 template <typename U, typename A> friend class Array;
972
973 //! Returns true if this->dims () == dv, and if so, replaces this->m_dimensions
974 //! by a shallow copy of dv. This is useful for maintaining several arrays
975 //! with supposedly equal dimensions (e.g. structs in the interpreter).
976 OCTARRAY_API bool optimize_dimensions (const dim_vector& dv);
977
978private:
979 OCTARRAY_API static void instantiation_guard ();
980};
981
982// We use a variadic template for template template parameter so that
983// we don't have to specify all the template parameters and limit this
984// to Container<T>. http://stackoverflow.com/a/20499809/1609556
985template<typename T, typename Alloc>
986template<template <typename...> class Container>
987OCTARRAY_OVERRIDABLE_FUNC_API
988Array<T, Alloc>::Array (const Container<T>& a, const dim_vector& dv)
989 : m_dimensions (dv), m_rep (new typename Array<T, Alloc>::ArrayRep (dv.safe_numel ())),
990 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
991{
992 if (m_dimensions.safe_numel () != octave_idx_type (a.size ()))
993 {
994 std::string new_dims_str = m_dimensions.str ();
995
996 (*current_liboctave_error_handler)
997 ("reshape: can't reshape %zi elements into %s array",
998 a.size (), new_dims_str.c_str ());
999 }
1000
1001 octave_idx_type i = 0;
1002 for (const T& x : a)
1003 m_slice_data[i++] = x;
1004
1006}
1007
1008template <typename T, typename Alloc>
1009OCTARRAY_API std::ostream&
1010operator << (std::ostream& os, const Array<T, Alloc>& a);
1011
1012#endif
std::ostream & operator<<(std::ostream &os, const Array< T, Alloc > &a)
octave_idx_type compute_index(octave_idx_type n, const dim_vector &dims)
octave_idx_type lookup(const T *x, octave_idx_type n, T y)
The real representation of all arrays.
Definition Array-base.h:135
T_Alloc_traits::pointer pointer
Definition Array-base.h:141
pointer allocate(size_t len)
Definition Array-base.h:212
ArrayRep(U *d, octave_idx_type len)
Definition Array-base.h:156
ArrayRep(pointer d, octave_idx_type len)
Definition Array-base.h:148
octave_idx_type m_len
Definition Array-base.h:144
octave::refcount< octave_idx_type > m_count
Definition Array-base.h:145
ArrayRep(octave_idx_type len)
Definition Array-base.h:176
octave_idx_type numel() const
Definition Array-base.h:202
ArrayRep(octave_idx_type len, const T &val)
Definition Array-base.h:180
ArrayRep(pointer ptr, const dim_vector &dv, const Alloc &xallocator=Alloc())
Definition Array-base.h:187
std::allocator_traits< Alloc > Alloc_traits
Definition Array-base.h:138
ArrayRep(const ArrayRep &a)
Definition Array-base.h:193
void deallocate(pointer data, size_t len)
Definition Array-base.h:220
Alloc_traits::template rebind_traits< T > T_Alloc_traits
Definition Array-base.h:140
N Dimensional Array with copy-on-write semantics.
Definition Array-base.h:130
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
Definition Array-base.h:529
Array< T, Alloc >::ArrayRep * m_rep
Definition Array-base.h:263
bool test_all(bool(&fcn)(const T &)) const
Size of the specified dimension.
Definition Array-base.h:967
T & xelem(octave_idx_type n)
Size of the specified dimension.
Definition Array-base.h:547
T * fortran_vec()
Size of the specified dimension.
Definition Array-base.h:695
void resize2(octave_idx_type nr, octave_idx_type nc)
Size of the specified dimension.
Definition Array-base.h:718
crefT xelem(octave_idx_type n) const
Size of the specified dimension.
Definition Array-base.h:549
size_type size(const size_type d) const
Size of the specified dimension.
Definition Array-base.h:518
T & xelem(octave_idx_type i, octave_idx_type j)
Size of the specified dimension.
Definition Array-base.h:553
friend class Array
Size of the specified dimension.
Definition Array-base.h:971
crefT xelem(octave_idx_type i, octave_idx_type j) const
Size of the specified dimension.
Definition Array-base.h:556
octave_idx_type size_type
Used for operator(), and returned by numel() and size() (beware: signed integer)
Definition Array-base.h:252
Array< T, Alloc > ipermute(const Array< octave_idx_type > &vec) const
Size of the specified dimension.
Definition Array-base.h:668
std::size_t byte_size() const
Size of the specified dimension.
Definition Array-base.h:525
void resize(const dim_vector &dv)
Size of the specified dimension.
Definition Array-base.h:728
crefT elem(octave_idx_type n) const
Size of the specified dimension.
Definition Array-base.h:618
bool test_all(bool(&fcn)(T)) const
Size of the specified dimension.
Definition Array-base.h:964
void maybe_economize()
Size of the specified dimension.
Definition Array-base.h:813
T & elem(octave_idx_type i, octave_idx_type j)
Size of the specified dimension.
Definition Array-base.h:591
Array(T *ptr, const dim_vector &dv, const Alloc &xallocator=Alloc())
Definition Array-base.h:327
octave_idx_type pages() const
Size of the specified dimension.
Definition Array-base.h:507
bool test_all(F fcn) const
Size of the specified dimension.
Definition Array-base.h:952
octave_idx_type dim3() const
Size of the specified dimension.
Definition Array-base.h:505
bool issquare() const
Size of the specified dimension.
Definition Array-base.h:671
Array(const Array< U, A > &a)
Type conversion case.
Definition Array-base.h:347
void resize1(octave_idx_type n)
Size of the specified dimension.
Definition Array-base.h:724
T & elem(octave_idx_type n)
Size of the specified dimension.
Definition Array-base.h:585
bool isvector() const
Size of the specified dimension.
Definition Array-base.h:677
int ndims() const
Size of the specified dimension.
Definition Array-base.h:701
octave_idx_type m_slice_len
Definition Array-base.h:273
ref_param< T >::type crefT
Definition Array-base.h:254
crefT elem(octave_idx_type i, octave_idx_type j) const
Size of the specified dimension.
Definition Array-base.h:622
T & xelem(const Array< octave_idx_type > &ra_idx)
Size of the specified dimension.
Definition Array-base.h:567
crefT xelem(octave_idx_type i, octave_idx_type j, octave_idx_type k) const
Size of the specified dimension.
Definition Array-base.h:563
Array< U, A > map(U(&fcn)(const T &)) const
Size of the specified dimension.
Definition Array-base.h:931
Array< U, A > map(F fcn) const
Apply function fcn to each element of the Array<T, Alloc>.
Definition Array-base.h:884
void clear(octave_idx_type r, octave_idx_type c)
Definition Array-base.h:435
Array(const dim_vector &dv, const T &val)
nD initialized ctor.
Definition Array-base.h:311
octave_idx_type rows() const
Definition Array-base.h:485
Array(const dim_vector &dv)
nD uninitialized ctor.
Definition Array-base.h:301
T * m_slice_data
Definition Array-base.h:272
bool test_any(F fcn) const
Simpler calls.
Definition Array-base.h:947
Array< T, Alloc > as_row() const
Return the array as a row vector.
Definition Array-base.h:457
Array< T, Alloc > index(const octave::idx_vector &i, bool resize_ok) const
Size of the specified dimension.
Definition Array-base.h:741
Array< U, A > map(U(&fcn)(T)) const
Overloads for function references.
Definition Array-base.h:921
void assign(const octave::idx_vector &i, const Array< T, Alloc > &rhs)
Size of the specified dimension.
Definition Array-base.h:768
Array< T, Alloc > reshape(const dim_vector &new_dims) const
Size of the specified dimension.
Definition Array-base.h:662
octave_idx_type dim2() const
Definition Array-base.h:493
Array< T, Alloc > as_column() const
Return the array as a column vector.
Definition Array-base.h:446
void assign(const octave::idx_vector &i, const octave::idx_vector &j, const Array< T, Alloc > &rhs)
Size of the specified dimension.
Definition Array-base.h:777
bool is_nd_vector() const
Size of the specified dimension.
Definition Array-base.h:680
octave_idx_type columns() const
Definition Array-base.h:497
Array(Array< T, Alloc > &&a)
Definition Array-base.h:363
octave_idx_type dim1() const
Definition Array-base.h:482
octave_idx_type cols() const
Definition Array-base.h:495
void make_unique()
Definition Array-base.h:232
dim_vector m_dimensions
Definition Array-base.h:261
Array(const Array< T, Alloc > &a, const dim_vector &dv, octave_idx_type l, octave_idx_type u)
slice constructor
Definition Array-base.h:277
Array< T, Alloc > as_matrix() const
Return the array as a matrix.
Definition Array-base.h:468
Array< T, Alloc > reshape(octave_idx_type nr, octave_idx_type nc) const
Size of the specified dimension.
Definition Array-base.h:658
bool test_any(bool(&fcn)(const T &)) const
Size of the specified dimension.
Definition Array-base.h:961
bool isempty() const
Size of the specified dimension.
Definition Array-base.h:674
const T * data() const
Size of the specified dimension.
Definition Array-base.h:687
T element_type
Definition Array-base.h:246
bool is_shared() const
Size of the specified dimension.
Definition Array-base.h:698
T * rwdata()
Size of the specified dimension.
bool test(F fcn) const
Generic any/all test functionality with arbitrary predicate.
Definition Array-base.h:938
Array(const Container< T > &a, const dim_vector &dv)
Constructor from standard library sequence containers.
Definition Array-base.h:988
T & xelem(octave_idx_type i, octave_idx_type j, octave_idx_type k)
Size of the specified dimension.
Definition Array-base.h:560
crefT elem(octave_idx_type i, octave_idx_type j, octave_idx_type k) const
Size of the specified dimension.
Definition Array-base.h:626
T value_type
Definition Array-base.h:248
crefT elem(const Array< octave_idx_type > &ra_idx) const
Size of the specified dimension.
Definition Array-base.h:630
T & elem(octave_idx_type i, octave_idx_type j, octave_idx_type k)
Size of the specified dimension.
Definition Array-base.h:594
T & elem(const Array< octave_idx_type > &ra_idx)
Size of the specified dimension.
Definition Array-base.h:597
bool test_any(bool(&fcn)(T)) const
Overloads for function references.
Definition Array-base.h:958
Array< T, Alloc > index(const octave::idx_vector &i, const octave::idx_vector &j, bool resize_ok) const
Size of the specified dimension.
Definition Array-base.h:750
crefT xelem(const Array< octave_idx_type > &ra_idx) const
Size of the specified dimension.
Definition Array-base.h:571
virtual ~Array()
Definition Array-base.h:374
Array(const Array< T, Alloc > &a)
No type conversion case.
Definition Array-base.h:355
octave_idx_type numel() const
Number of elements in the array.
Definition Array-base.h:440
Array()
Empty ctor (0 by 0).
Definition Array-base.h:292
Vector representing the dimensions (size) of an Array.
Definition dim-vector.h:92
octave_idx_type safe_numel() const
The following function will throw a std::bad_alloc () exception if the requested size is larger than ...
Definition dim-vector.h:364
std::string str(char sep='x') const
Definition dim-vector.cc:58
void chop_trailing_singletons()
Definition dim-vector.h:162
bool is_nd_vector() const
Definition dim-vector.h:437
octave_idx_type ndims() const
Number of dimensions.
Definition dim-vector.h:263
bool isvector() const
Definition dim-vector.h:432
dim_vector redim(int n) const
Force certain dimensionality, preserving numel ().
if_then_else< is_class_type< T >::no, T, Tconst & >::result type
Definition oct-traits.h:121
F77_RET_T const F77_INT F77_CMPLX * A
sortmode
Definition oct-sort.h:97
@ UNSORTED
Definition oct-sort.h:97
@ ASCENDING
Definition oct-sort.h:97
T::size_type numel(const T &str)
Definition oct-string.cc:81
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
F77_RET_T len
Definition xerbla.cc:61