GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Array.h
Go to the documentation of this file.
1 // Template array classes
2 /*
3 
4 Copyright (C) 1993-2017 John W. Eaton
5 Copyright (C) 2008-2009 Jaroslav Hajek
6 Copyright (C) 2010 VZLU Prague
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 the
12 Free Software Foundation; either version 3 of the License, or (at your
13 option) any later version.
14 
15 Octave is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 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 <http://www.gnu.org/licenses/>.
23 
24 */
25 
26 #if ! defined (octave_Array_h)
27 #define octave_Array_h 1
28 
29 #include "octave-config.h"
30 
31 #include <cassert>
32 #include <cstddef>
33 
34 #include <algorithm>
35 #include <iosfwd>
36 
37 #include "dim-vector.h"
38 #include "idx-vector.h"
39 #include "lo-error.h"
40 #include "lo-traits.h"
41 #include "lo-utils.h"
42 #include "oct-sort.h"
43 #include "quit.h"
44 #include "oct-refcount.h"
45 
46 //! N Dimensional Array with copy-on-write semantics.
47 /*!
48  The Array class is at the root of Octave. It provides a container
49  with an arbitrary number of dimensions. The operator () provides
50  access to individual elements via subscript and linear indexing.
51  Indexing starts at 0. Arrays are column-major order as in Fortran.
52 
53  @code{.cc}
54  // 3 D Array with 10 rows, 20 columns, and 5 pages, filled with 7.0
55  Array<double> A Array<double (dim_vector (10, 20, 5), 7.0);
56 
57  // set value for row 0, column 10, and page 3
58  A(0, 10, 3) = 2.5;
59 
60  // get value for row 1, column 2, and page 0
61  double v = A(1, 2, 0);
62 
63  // get value for 25th element (row 4, column 3, page 1)
64  double v = A(24);
65  @endcode
66 
67  ## Notes on STL compatibility
68 
69  ### size() and length()
70 
71  To access the total number of elements in an Array, use numel()
72  which is short for number of elements and is equivalent to the
73  Octave function with same name.
74 
75  @code{.cc}
76  Array<int> A (dim_vector (10, 20, 4), 1);
77 
78  octave_idx_type n = A.numel (); // returns 800 (10x20x4)
79 
80  octave_idx_type nr = A.size (0); // returns 10 (number of rows/dimension 0)
81  octave_idx_type nc = A.size (1); // returns 20 (number of columns)
82  octave_idx_type nc = A.size (2); // returns 4 (size of dimension 3)
83  octave_idx_type l6 = A.size (6); // returns 1 (implicit singleton dimension)
84 
85  // Alternatively, get a dim_vector which represents the dimensions.
86  dim_vector dims = A.dims ();
87  @endcode
88 
89  The methods size() and length() as they exist in the STL cause
90  confusion in the context of a N dimensional array.
91 
92  The size() of an array is the length of all dimensions. In Octave,
93  the size() function returns a row vector with the length of each
94  dimension, or the size of a specific dimension. Only the latter is
95  present in liboctave.
96 
97  Since there is more than 1 dimension, length() would not make sense
98  without expliciting which dimension. If the function existed, which
99  length should it return? Octave length() function returns the length
100  of the longest dimension which is an odd definition, only useful for
101  vectors and square matrices. The alternatives numel(), rows(),
102  columns(), and size(d) are more explict and recommended.
103 
104  ### size_type
105 
106  Array::size_type is `octave_idx_type` which is a typedef for `int`
107  or `long int`, depending whether Octave was configured for 64-bit
108  indexing.
109 
110  This is a signed integer which may cause problems when mixed with
111  STL containers. The reason is that Octave interacts with Fortran
112  routines, providing an interface many Fortran numeric libraries.
113 
114  ## Subclasses
115 
116  The following subclasses specializations, will be of most use:
117  - Matrix: Array<double> with only 2 dimensions
118  - ComplexMatrix: Array<std::complex<double>> with only 2 dimensions
119  - boolNDArray: N dimensional Array<bool>
120  - ColumnVector: Array<double> with 1 column
121  - string_vector: Array<std::string> with 1 column
122  - Cell: Array<octave_value>, equivalent to an Octave cell.
123 
124 */
125 template <typename T>
126 class
127 Array
128 {
129 protected:
130 
131  //! The real representation of all arrays.
132  class ArrayRep
133  {
134  public:
135 
136  T *data;
139 
141  : data (new T [l]), len (l), count (1)
142  {
143  std::copy (d, d+l, data);
144  }
145 
146  template <typename U>
148  : data (new T [l]), len (l), count (1)
149  {
150  std::copy (d, d+l, data);
151  }
152 
153  ArrayRep (void) : data (0), len (0), count (1) { }
154 
156  : data (new T [n]), len (n), count (1) { }
157 
158  explicit ArrayRep (octave_idx_type n, const T& val)
159  : data (new T [n]), len (n), count (1)
160  {
161  std::fill_n (data, n, val);
162  }
163 
164  ArrayRep (const ArrayRep& a)
165  : data (new T [a.len]), len (a.len), count (1)
166  {
167  std::copy (a.data, a.data + a.len, data);
168  }
169 
170  ~ArrayRep (void) { delete [] data; }
171 
172  octave_idx_type numel (void) const { return len; }
173 
174  private:
175 
176  // No assignment!
177 
178  ArrayRep& operator = (const ArrayRep& a);
179  };
180 
181  //--------------------------------------------------------------------
182 
183 public:
184 
185  void make_unique (void)
186  {
187  if (rep->count > 1)
188  {
189  ArrayRep *r = new ArrayRep (slice_data, slice_len);
190 
191  if (--rep->count == 0)
192  delete rep;
193 
194  rep = r;
195  slice_data = rep->data;
196  }
197  }
198 
199  typedef T element_type;
200 
201  typedef T value_type;
202 
203  //! Used for operator(), and returned by numel() and size()
204  //! (beware: signed integer)
206 
207  typedef typename ref_param<T>::type crefT;
208 
209  typedef bool (*compare_fcn_type) (typename ref_param<T>::type,
210  typename ref_param<T>::type);
211 
212 protected:
213 
215 
217 
218  // Rationale:
219  // slice_data is a pointer to rep->data, denoting together with slice_len the
220  // actual portion of the data referenced by this Array<T> object. This
221  // allows to make shallow copies not only of a whole array, but also of
222  // contiguous subranges. Every time rep is directly manipulated, slice_data
223  // and slice_len need to be properly updated.
224 
227 
228  //! slice constructor
229  Array (const Array<T>& a, const dim_vector& dv,
231  : dimensions (dv), rep(a.rep), slice_data (a.slice_data+l), slice_len (u-l)
232  {
233  rep->count++;
234  dimensions.chop_trailing_singletons ();
235  }
236 
237 private:
238 
239  static typename Array<T>::ArrayRep *nil_rep (void);
240 
241 protected:
242 
243  //! For jit support
244  Array (T *sdata, octave_idx_type slen, octave_idx_type *adims, void *arep)
245  : dimensions (adims),
246  rep (reinterpret_cast<typename Array<T>::ArrayRep *> (arep)),
247  slice_data (sdata), slice_len (slen) { }
248 
249 public:
250 
251  //! Empty ctor (0 by 0).
252  Array (void)
253  : dimensions (), rep (nil_rep ()), slice_data (rep->data),
254  slice_len (rep->len)
255  {
256  rep->count++;
257  }
258 
259  //! nD uninitialized ctor.
260  explicit Array (const dim_vector& dv)
261  : dimensions (dv),
262  rep (new typename Array<T>::ArrayRep (dv.safe_numel ())),
263  slice_data (rep->data), slice_len (rep->len)
264  {
265  dimensions.chop_trailing_singletons ();
266  }
267 
268  //! nD initialized ctor.
269  explicit Array (const dim_vector& dv, const T& val)
270  : dimensions (dv),
271  rep (new typename Array<T>::ArrayRep (dv.safe_numel ())),
272  slice_data (rep->data), slice_len (rep->len)
273  {
274  fill (val);
275  dimensions.chop_trailing_singletons ();
276  }
277 
278  //! Reshape constructor.
279  Array (const Array<T>& a, const dim_vector& dv);
280 
281  //! Constructor from standard library sequence containers.
282  template<template <typename...> class Container>
283  Array (const Container<T>& a, const dim_vector& dv);
284 
285  //! Type conversion case.
286  template <typename U>
287  Array (const Array<U>& a)
288  : dimensions (a.dims ()),
289  rep (new typename Array<T>::ArrayRep (a.data (), a.numel ())),
290  slice_data (rep->data), slice_len (rep->len)
291  { }
292 
293  //! No type conversion case.
294  Array (const Array<T>& a)
295  : dimensions (a.dimensions), rep (a.rep), slice_data (a.slice_data),
296  slice_len (a.slice_len)
297  {
298  rep->count++;
299  }
300 
301 public:
302 
303  virtual ~Array (void)
304  {
305  if (--rep->count == 0)
306  delete rep;
307  }
308 
309  Array<T>& operator = (const Array<T>& a)
310  {
311  if (this != &a)
312  {
313  if (--rep->count == 0)
314  delete rep;
315 
316  rep = a.rep;
317  rep->count++;
318 
319  dimensions = a.dimensions;
320  slice_data = a.slice_data;
321  slice_len = a.slice_len;
322  }
323 
324  return *this;
325  }
326 
327  void fill (const T& val);
328 
329  void clear (void);
330  void clear (const dim_vector& dv);
331 
333  { clear (dim_vector (r, c)); }
334 
335  // Number of elements in the array. These are all synonyms.
336  //@{
337  //! Number of elements in the array.
338  //! Synonymous with numel().
339  //! @note This method is deprecated in favour of numel().
340  OCTAVE_DEPRECATED ("use 'numel' instead")
341  octave_idx_type capacity (void) const { return numel (); }
342 
343  //! Number of elements in the array.
344  /*! Synonymous with numel().
345  @note This method is deprecated in favour of numel().
346 
347  @note
348  This is @em not the same as @c %length() at the Octave interpreter.
349  At the Octave interpreter, the function @c %length() returns the
350  length of the greatest dimension. This method returns the total
351  number of elements.
352  */
353  OCTAVE_DEPRECATED ("use 'numel' instead")
354  octave_idx_type length (void) const { return numel (); }
355 
356  //! Number of elements in the array.
357  //! Synonymous with numel().
358  //! @note This method is deprecated in favour of numel().
359  OCTAVE_DEPRECATED ("use 'numel' instead")
360  octave_idx_type nelem (void) const { return numel (); }
361 
362  //! Number of elements in the array.
363  octave_idx_type numel (void) const { return slice_len; }
364  //@}
365 
366  //! Return the array as a column vector.
367  Array<T> as_column (void) const
368  {
369  Array<T> retval (*this);
370  if (dimensions.ndims () != 2 || dimensions(1) != 1)
371  retval.dimensions = dim_vector (numel (), 1);
372 
373  return retval;
374  }
375 
376  //! Return the array as a row vector.
377  Array<T> as_row (void) const
378  {
379  Array<T> retval (*this);
380  if (dimensions.ndims () != 2 || dimensions(0) != 1)
381  retval.dimensions = dim_vector (1, numel ());
382 
383  return retval;
384  }
385 
386  //! Return the array as a matrix.
387  Array<T> as_matrix (void) const
388  {
389  Array<T> retval (*this);
390  if (dimensions.ndims () != 2)
391  retval.dimensions = dimensions.redim (2);
392 
393  return retval;
394  }
395 
396  //! @name First dimension
397  //!
398  //! Get the first dimension of the array (number of rows)
399  //@{
400  octave_idx_type dim1 (void) const { return dimensions(0); }
401  octave_idx_type rows (void) const { return dim1 (); }
402  //@}
403 
404  //! @name Second dimension
405  //!
406  //! Get the second dimension of the array (number of columns)
407  //@{
408  octave_idx_type dim2 (void) const { return dimensions(1); }
409  octave_idx_type cols (void) const { return dim2 (); }
410  octave_idx_type columns (void) const { return dim2 (); }
411  //@}
412 
413  //! @name Third dimension
414  //!
415  //! Get the third dimension of the array (number of pages)
416  //@{
417  octave_idx_type dim3 (void) const { return dimensions(2); }
418  octave_idx_type pages (void) const { return dim3 (); }
419  //@}
420 
421  //! Size of the specified dimension.
422  /*!
423  Dimensions beyond the Array number of dimensions return 1 as
424  those are implicit singleton dimensions.
425 
426  Equivalent to Octave's `size (A, DIM)`
427  */
428  size_type size (const size_type d) const
429  {
430  // Should we throw for negative values?
431  // Should >= ndims () be handled by dim_vector operator() instead ?
432  return d >= ndims () ? 1 : dimensions(d);
433  }
434 
435  size_t byte_size (void) const
436  { return static_cast<size_t> (numel ()) * sizeof (T); }
437 
438  //! Return a const-reference so that dims ()(i) works efficiently.
439  const dim_vector& dims (void) const { return dimensions; }
440 
441  //! Chop off leading singleton dimensions
442  Array<T> squeeze (void) const;
443 
446  octave_idx_type k) const;
448 
450  const
451  { return dimensions.compute_index (ra_idx.data (), ra_idx.numel ()); }
452 
453  // No checking, even for multiple references, ever.
454 
455  T& xelem (octave_idx_type n) { return slice_data[n]; }
456  crefT xelem (octave_idx_type n) const { return slice_data[n]; }
457 
459  { return xelem (dim1 ()*j+i); }
461  { return xelem (dim1 ()*j+i); }
462 
464  { return xelem (i, dim2 ()*k+j); }
466  { return xelem (i, dim2 ()*k+j); }
467 
469  { return xelem (compute_index_unchecked (ra_idx)); }
470 
471  crefT xelem (const Array<octave_idx_type>& ra_idx) const
472  { return xelem (compute_index_unchecked (ra_idx)); }
473 
474  // FIXME: would be nice to fix this so that we don't unnecessarily force
475  // a copy, but that is not so easy, and I see no clean way to do it.
476 
477  T& checkelem (octave_idx_type n);
478  T& checkelem (octave_idx_type i, octave_idx_type j);
480  T& checkelem (const Array<octave_idx_type>& ra_idx);
481 
483  {
484  make_unique ();
485  return xelem (n);
486  }
487 
488  T& elem (octave_idx_type i, octave_idx_type j) { return elem (dim1 ()*j+i); }
489 
491  { return elem (i, dim2 ()*k+j); }
492 
494  { return Array<T>::elem (compute_index_unchecked (ra_idx)); }
495 
496 #if defined (OCTAVE_ENABLE_BOUNDS_CHECK)
497  T& operator () (octave_idx_type n) { return checkelem (n); }
498  T& operator () (octave_idx_type i, octave_idx_type j)
499  { return checkelem (i, j); }
500  T& operator () (octave_idx_type i, octave_idx_type j, octave_idx_type k)
501  { return checkelem (i, j, k); }
502  T& operator () (const Array<octave_idx_type>& ra_idx)
503  { return checkelem (ra_idx); }
504 #else
505  T& operator () (octave_idx_type n) { return elem (n); }
506  T& operator () (octave_idx_type i, octave_idx_type j) { return elem (i, j); }
508  { return elem (i, j, k); }
509  T& operator () (const Array<octave_idx_type>& ra_idx)
510  { return elem (ra_idx); }
511 #endif
512 
513  crefT checkelem (octave_idx_type n) const;
514  crefT checkelem (octave_idx_type i, octave_idx_type j) const;
515  crefT checkelem (octave_idx_type i, octave_idx_type j,
516  octave_idx_type k) const;
517  crefT checkelem (const Array<octave_idx_type>& ra_idx) const;
518 
519  crefT elem (octave_idx_type n) const { return xelem (n); }
520 
522  { return xelem (i, j); }
523 
525  { return xelem (i, j, k); }
526 
527  crefT elem (const Array<octave_idx_type>& ra_idx) const
528  { return Array<T>::xelem (compute_index_unchecked (ra_idx)); }
529 
530 #if defined (OCTAVE_ENABLE_BOUNDS_CHECK)
531  crefT operator () (octave_idx_type n) const { return checkelem (n); }
532  crefT operator () (octave_idx_type i, octave_idx_type j) const
533  { return checkelem (i, j); }
534  crefT operator () (octave_idx_type i, octave_idx_type j,
535  octave_idx_type k) const
536  { return checkelem (i, j, k); }
537  crefT operator () (const Array<octave_idx_type>& ra_idx) const
538  { return checkelem (ra_idx); }
539 #else
540  crefT operator () (octave_idx_type n) const { return elem (n); }
541  crefT operator () (octave_idx_type i, octave_idx_type j) const
542  { return elem (i, j); }
543  crefT operator () (octave_idx_type i, octave_idx_type j,
544  octave_idx_type k) const
545  { return elem (i, j, k); }
546  crefT operator () (const Array<octave_idx_type>& ra_idx) const
547  { return elem (ra_idx); }
548 #endif
549 
550  // Fast extractors. All of these produce shallow copies.
551  // Warning: none of these do check bounds, unless
552  // OCTAVE_ENABLE_BOUNDS_CHECK is defined!
553 
554  //! Extract column: A(:,k+1).
556  //! Extract page: A(:,:,k+1).
557  Array<T> page (octave_idx_type k) const;
558 
559  //! Extract a slice from this array as a column vector: A(:)(lo+1:up).
560  //! Must be 0 <= lo && up <= numel. May be up < lo.
561  Array<T> linear_slice (octave_idx_type lo, octave_idx_type up) const;
562 
564  { return Array<T> (*this, dim_vector (nr, nc)); }
565 
566  Array<T> reshape (const dim_vector& new_dims) const
567  { return Array<T> (*this, new_dims); }
568 
569  Array<T> permute (const Array<octave_idx_type>& vec, bool inv = false) const;
571  { return permute (vec, true); }
572 
573  bool is_square (void) const { return (dim1 () == dim2 ()); }
574 
575  bool is_empty (void) const { return numel () == 0; }
576 
577  bool is_vector (void) const { return dimensions.is_vector (); }
578 
579  Array<T> transpose (void) const;
580  Array<T> hermitian (T (*fcn) (const T&) = 0) const;
581 
582  const T *data (void) const { return slice_data; }
583 
584  const T *fortran_vec (void) const { return data (); }
585 
586  T *fortran_vec (void);
587 
588  bool is_shared (void) { return rep->count > 1; }
589 
590  int ndims (void) const { return dimensions.ndims (); }
591 
592  //@{
593  //! Indexing without resizing.
594  Array<T> index (const idx_vector& i) const;
595 
596  Array<T> index (const idx_vector& i, const idx_vector& j) const;
597 
598  Array<T> index (const Array<idx_vector>& ia) const;
599  //@}
600 
601  virtual T resize_fill_value (void) const;
602 
603  //@{
604  //! Resizing (with fill).
605  void resize2 (octave_idx_type nr, octave_idx_type nc, const T& rfv);
607  {
608  resize2 (nr, nc, resize_fill_value ());
609  }
610 
611  void resize1 (octave_idx_type n, const T& rfv);
612  void resize1 (octave_idx_type n) { resize1 (n, resize_fill_value ()); }
613 
614  void resize (const dim_vector& dv, const T& rfv);
615  void resize (const dim_vector& dv) { resize (dv, resize_fill_value ()); }
616  //@}
617 
618  //@{
619  //! Indexing with possible resizing and fill
620 
621  // FIXME: this is really a corner case, that should better be
622  // handled directly in liboctinterp.
623 
624  Array<T> index (const idx_vector& i, bool resize_ok, const T& rfv) const;
625  Array<T> index (const idx_vector& i, bool resize_ok) const
626  {
627  return index (i, resize_ok, resize_fill_value ());
628  }
629 
630  Array<T> index (const idx_vector& i, const idx_vector& j, bool resize_ok,
631  const T& rfv) const;
632  Array<T> index (const idx_vector& i, const idx_vector& j,
633  bool resize_ok) const
634  {
635  return index (i, j, resize_ok, resize_fill_value ());
636  }
637 
638  Array<T> index (const Array<idx_vector>& ia, bool resize_ok,
639  const T& rfv) const;
640  Array<T> index (const Array<idx_vector>& ia, bool resize_ok) const
641  {
642  return index (ia, resize_ok, resize_fill_value ());
643  }
644  //@}
645 
646  //@{
647  //! Indexed assignment (always with resize & fill).
648  void assign (const idx_vector& i, const Array<T>& rhs, const T& rfv);
649  void assign (const idx_vector& i, const Array<T>& rhs)
650  {
651  assign (i, rhs, resize_fill_value ());
652  }
653 
654  void assign (const idx_vector& i, const idx_vector& j, const Array<T>& rhs,
655  const T& rfv);
656  void assign (const idx_vector& i, const idx_vector& j, const Array<T>& rhs)
657  {
658  assign (i, j, rhs, resize_fill_value ());
659  }
660 
661  void assign (const Array<idx_vector>& ia, const Array<T>& rhs, const T& rfv);
662  void assign (const Array<idx_vector>& ia, const Array<T>& rhs)
663  {
664  assign (ia, rhs, resize_fill_value ());
665  }
666  //@}
667 
668  //@{
669  //! Deleting elements.
670 
671  //! A(I) = [] (with a single subscript)
672  void delete_elements (const idx_vector& i);
673 
674  //! A(:,...,I,...,:) = [] (>= 2 subscripts, one of them is non-colon)
675  void delete_elements (int dim, const idx_vector& i);
676 
677  //! Dispatcher to the above two.
678  void delete_elements (const Array<idx_vector>& ia);
679  //@}
680 
681  //! Insert an array into another at a specified position. If
682  //! size (a) is [d1 d2 ... dN] and idx is [i1 i2 ... iN], this
683  //! method is equivalent to x(i1:i1+d1-1, i2:i2+d2-1, ... ,
684  //! iN:iN+dN-1) = a.
685  Array<T>& insert (const Array<T>& a, const Array<octave_idx_type>& idx);
686 
687  //! This is just a special case for idx = [r c 0 ...]
688  Array<T>& insert (const Array<T>& a, octave_idx_type r, octave_idx_type c);
689 
690  void maybe_economize (void)
691  {
692  if (rep->count == 1 && slice_len != rep->len)
693  {
694  ArrayRep *new_rep = new ArrayRep (slice_data, slice_len);
695  delete rep;
696  rep = new_rep;
697  slice_data = rep->data;
698  }
699  }
700 
701  void print_info (std::ostream& os, const std::string& prefix) const;
702 
703  //! Give a pointer to the data in mex format. Unsafe. This function
704  //! exists to support the MEX interface. You should not use it
705  //! anywhere else.
706  void *mex_get_data (void) const { return const_cast<T *> (data ()); }
707 
708  Array<T> sort (int dim = 0, sortmode mode = ASCENDING) const;
709  Array<T> sort (Array<octave_idx_type> &sidx, int dim = 0,
710  sortmode mode = ASCENDING) const;
711 
712  //! Ordering is auto-detected or can be specified.
713  sortmode is_sorted (sortmode mode = UNSORTED) const;
714 
715  //! Sort by rows returns only indices.
716  Array<octave_idx_type> sort_rows_idx (sortmode mode = ASCENDING) const;
717 
718  //! Ordering is auto-detected or can be specified.
719  sortmode is_sorted_rows (sortmode mode = UNSORTED) const;
720 
721  //! @brief Do a binary lookup in a sorted array. Must not contain NaNs.
722  //! Mode can be specified or is auto-detected by comparing 1st and last element.
723  octave_idx_type lookup (const T& value, sortmode mode = UNSORTED) const;
724 
725  //! Ditto, but for an array of values, specializing on the case when values
726  //! are sorted. NaNs get the value N.
728  sortmode mode = UNSORTED) const;
729 
730  //! Count nonzero elements.
731  octave_idx_type nnz (void) const;
732 
733  //! Find indices of (at most n) nonzero elements. If n is specified,
734  //! backward specifies search from backward.
736  bool backward = false) const;
737 
738  //! Returns the n-th element in increasing order, using the same
739  //! ordering as used for sort. n can either be a scalar index or a
740  //! contiguous range.
741  Array<T> nth_element (const idx_vector& n, int dim = 0) const;
742 
743  //! Get the kth super or subdiagonal. The zeroth diagonal is the
744  //! ordinary diagonal.
745  Array<T> diag (octave_idx_type k = 0) const;
746 
747  Array<T> diag (octave_idx_type m, octave_idx_type n) const;
748 
749  //! Concatenation along a specified (0-based) dimension, equivalent
750  //! to cat(). dim = -1 corresponds to dim = 0 and dim = -2
751  //! corresponds to dim = 1, but apply the looser matching rules of
752  //! vertcat/horzcat.
753  static Array<T>
754  cat (int dim, octave_idx_type n, const Array<T> *array_list);
755 
756  //! Apply function fcn to each element of the Array<T>. This function
757  //! is optimized with a manually unrolled loop.
758  template <typename U, typename F>
759  Array<U>
760  map (F fcn) const
761  {
762  octave_idx_type len = numel ();
763 
764  const T *m = data ();
765 
766  Array<U> result (dims ());
767  U *p = result.fortran_vec ();
768 
770  for (i = 0; i < len - 3; i += 4)
771  {
772  octave_quit ();
773 
774  p[i] = fcn (m[i]);
775  p[i+1] = fcn (m[i+1]);
776  p[i+2] = fcn (m[i+2]);
777  p[i+3] = fcn (m[i+3]);
778  }
779 
780  octave_quit ();
781 
782  for (; i < len; i++)
783  p[i] = fcn (m[i]);
784 
785  return result;
786  }
787 
788  //@{
789  //! Overloads for function references.
790  template <typename U>
791  Array<U>
792  map (U (&fcn) (T)) const
793  { return map<U, U (&) (T)> (fcn); }
794 
795  template <typename U>
796  Array<U>
797  map (U (&fcn) (const T&)) const
798  { return map<U, U (&) (const T&)> (fcn); }
799  //@}
800 
801  //! Generic any/all test functionality with arbitrary predicate.
802  template <typename F, bool zero>
803  bool test (F fcn) const
804  {
805  return any_all_test<F, T, zero> (fcn, data (), numel ());
806  }
807 
808  //@{
809  //! Simpler calls.
810  template <typename F>
811  bool test_any (F fcn) const
812  { return test<F, false> (fcn); }
813 
814  template <typename F>
815  bool test_all (F fcn) const
816  { return test<F, true> (fcn); }
817  //@}
818 
819  //@{
820  //! Overloads for function references.
821  bool test_any (bool (&fcn) (T)) const
822  { return test<bool (&) (T), false> (fcn); }
823 
824  bool test_any (bool (&fcn) (const T&)) const
825  { return test<bool (&) (const T&), false> (fcn); }
826 
827  bool test_all (bool (&fcn) (T)) const
828  { return test<bool (&) (T), true> (fcn); }
829 
830  bool test_all (bool (&fcn) (const T&)) const
831  { return test<bool (&) (const T&), true> (fcn); }
832  //@}
833 
834  template <typename U> friend class Array;
835 
836  //! Returns true if this->dims () == dv, and if so, replaces this->dimensions
837  //! by a shallow copy of dv. This is useful for maintaining several arrays
838  //! with supposedly equal dimensions (e.g. structs in the interpreter).
839  bool optimize_dimensions (const dim_vector& dv);
840 
841  //@{
842  //! WARNING: Only call these functions from jit
843 
844  int *jit_ref_count (void) { return rep->count.get (); }
845 
846  T *jit_slice_data (void) const { return slice_data; }
847 
848  octave_idx_type *jit_dimensions (void) const { return dimensions.to_jit (); }
849 
850  void *jit_array_rep (void) const { return rep; }
851  //@}
852 
853 private:
854  static void instantiation_guard ();
855 };
856 
857 // We use a variadic template for template template parameter so that
858 // we don't have to specify all the template parameters and limit this
859 // to Container<T>. http://stackoverflow.com/a/20499809/1609556
860 template<typename T>
861 template<template <typename...> class Container>
862 Array<T>::Array (const Container<T>& a, const dim_vector& dv)
863  : dimensions (dv), rep (new typename Array<T>::ArrayRep (dv.safe_numel ())),
864  slice_data (rep->data), slice_len (rep->len)
865 {
866  if (dimensions.safe_numel () != octave_idx_type (a.size ()))
867  {
868  std::string new_dims_str = dimensions.str ();
869 
870  (*current_liboctave_error_handler)
871  ("reshape: can't reshape %i elements into %s array",
872  a.size (), new_dims_str.c_str ());
873  }
874 
875  octave_idx_type i = 0;
876  for (const T& x : a)
877  slice_data[i++] = x;
878 
879  dimensions.chop_trailing_singletons ();
880 }
881 
882 //! This is a simple wrapper template that will subclass an Array<T>
883 //! type or any later type derived from it and override the default
884 //! non-const operator() to not check for the array's uniqueness. It
885 //! is, however, the user's responsibility to ensure the array is
886 //! actually unaliased whenever elements are accessed.
887 template <typename ArrayClass>
888 class NoAlias : public ArrayClass
889 {
890  typedef typename ArrayClass::element_type T;
891 public:
892  NoAlias () : ArrayClass () { }
893 
894  // FIXME: this would be simpler once C++0x is available
895  template <typename X>
896  explicit NoAlias (X x) : ArrayClass (x) { }
897 
898  template <typename X, typename Y>
899  explicit NoAlias (X x, Y y) : ArrayClass (x, y) { }
900 
901  template <typename X, typename Y, typename Z>
902  explicit NoAlias (X x, Y y, Z z) : ArrayClass (x, y, z) { }
903 
905  { return ArrayClass::xelem (n); }
907  { return ArrayClass::xelem (i, j); }
909  { return ArrayClass::xelem (i, j, k); }
911  { return ArrayClass::xelem (ra_idx); }
912 };
913 
914 template <typename T>
915 std::ostream&
916 operator << (std::ostream& os, const Array<T>& a);
917 
918 #endif
dim_vector dimensions
Definition: Array.h:214
Array< T > as_matrix(void) const
Return the array as a matrix.
Definition: Array.h:387
octave_idx_type compute_index(octave_idx_type n, const dim_vector &dims)
Definition: Array-util.cc:176
T & elem(octave_idx_type i, octave_idx_type j, octave_idx_type k)
Definition: Array.h:490
octave_idx_type compute_index_unchecked(const Array< octave_idx_type > &ra_idx) const
Definition: Array.h:449
bool is_empty(void) const
Definition: Array.h:575
Array(T *sdata, octave_idx_type slen, octave_idx_type *adims, void *arep)
For jit support.
Definition: Array.h:244
OCTAVE_EXPORT octave_value_list column
Definition: sparse.cc:123
std::string str(char sep= 'x') const
Definition: dim-vector.cc:73
crefT elem(const Array< octave_idx_type > &ra_idx) const
Definition: Array.h:527
Array< T > reshape(const dim_vector &new_dims) const
Definition: Array.h:566
Array(void)
Empty ctor (0 by 0).
Definition: Array.h:252
ref_param< T >::type crefT
Definition: Array.h:207
const octave_base_value const Array< octave_idx_type > & ra_idx
void resize(const dim_vector &dv)
Definition: Array.h:615
NoAlias(X x, Y y, Z z)
Definition: Array.h:902
octave_idx_type len
Definition: Array.h:137
bool is_vector(void) const
Definition: dim-vector.h:458
NoAlias()
Definition: Array.h:892
void assign(const Array< idx_vector > &ia, const Array< T > &rhs)
Definition: Array.h:662
int ndims(void) const
Definition: Array.h:590
sortmode
Definition: oct-sort.h:105
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:5068
ArrayRep(octave_idx_type n, const T &val)
Definition: Array.h:158
Return the CPU time used by your Octave session The first output is the total time spent executing your process and is equal to the sum of second and third which are the number of CPU seconds spent executing in user mode and the number of CPU seconds spent executing in system mode
Definition: data.cc:6386
crefT xelem(octave_idx_type i, octave_idx_type j) const
Definition: Array.h:460
Array< U > map(U(&fcn)(T)) const
Overloads for function references.
Definition: Array.h:792
T & operator()(octave_idx_type n)
Definition: Array.h:904
octave_idx_type dim2(void) const
Definition: Array.h:408
ArrayRep(U *d, octave_idx_type l)
Definition: Array.h:147
for large enough k
Definition: lu.cc:606
OCTAVE_EXPORT octave_value_list page
Definition: sub2ind.cc:107
void * mex_get_data(void) const
Give a pointer to the data in mex format.
Definition: Array.h:706
Array(const Array< T > &a, const dim_vector &dv, octave_idx_type l, octave_idx_type u)
slice constructor
Definition: Array.h:229
octave_idx_type * jit_dimensions(void) const
Definition: Array.h:848
static void transpose(octave_idx_type N, const octave_idx_type *ridx, const octave_idx_type *cidx, octave_idx_type *ridx2, octave_idx_type *cidx2)
Definition: symrcm.cc:382
virtual ~Array(void)
Definition: Array.h:303
Array(const Array< T > &a)
No type conversion case.
Definition: Array.h:294
cat(2, A, B) esult
Definition: data.cc:2417
octave_idx_type numel(void) const
Definition: Array.h:172
T * jit_slice_data(void) const
Definition: Array.h:846
size_type size(const size_type d) const
Size of the specified dimension.
Definition: Array.h:428
Array(const dim_vector &dv, const T &val)
nD initialized ctor.
Definition: Array.h:269
T & elem(octave_idx_type n)
Definition: Array.h:482
octave_idx_type lookup(const T *x, octave_idx_type n, T y)
crefT xelem(const Array< octave_idx_type > &ra_idx) const
Definition: Array.h:471
u
Definition: lu.cc:138
bool test_all(bool(&fcn)(T)) const
Definition: Array.h:827
T & xelem(octave_idx_type i, octave_idx_type j, octave_idx_type k)
Definition: Array.h:463
Array< T > as_row(void) const
Return the array as a row vector.
Definition: Array.h:377
crefT xelem(octave_idx_type i, octave_idx_type j, octave_idx_type k) const
Definition: Array.h:465
The real representation of all arrays.
Definition: Array.h:132
octave_idx_type dim1(void) const
Definition: Array.h:400
Array(const dim_vector &dv)
nD uninitialized ctor.
Definition: Array.h:260
ArrayRep(const ArrayRep &a)
Definition: Array.h:164
octave_idx_type rows(void) const
Definition: Array.h:401
octave_function * fcn
Definition: ov-class.cc:1743
void clear(octave_idx_type r, octave_idx_type c)
Definition: Array.h:332
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
OCTAVE_EXPORT octave_value_list return the value of the option it must match the dimension of the state and the relative tolerance must also be a vector of the same length tem it must match the dimension of the state and the absolute tolerance must also be a vector of the same length The local error test applied at each integration step is xample roup calculate Y_a and Y _d item Given Y
Definition: DASPK-opts.cc:739
cell array If invoked with two or more scalar integer or a vector of integer values
Definition: ov-cell.cc:1205
bool optimize_dimensions(const dim_vector &dv)
Returns true if this->dims () == dv, and if so, replaces this->dimensions by a shallow copy of dv...
Definition: Array.cc:2750
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:398
octave_idx_type * to_jit(void) const
Definition: dim-vector.h:248
Array< T > as_column(void) const
Return the array as a column vector.
Definition: Array.h:367
static void instantiation_guard()
Definition: Array.cc:2760
octave_idx_type dim3(void) const
Definition: Array.h:417
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:439
size_t byte_size(void) const
Definition: Array.h:435
void resize1(octave_idx_type n)
Definition: Array.h:612
octave_idx_type safe_numel(void) const
Definition: dim-vector.cc:103
int * jit_ref_count(void)
WARNING: Only call these functions from jit.
Definition: Array.h:844
bool test_any(F fcn) const
Simpler calls.
Definition: Array.h:811
void assign(const idx_vector &i, const Array< T > &rhs)
Definition: Array.h:649
void make_unique(void)
Definition: Array.h:185
Array< U > map(F fcn) const
Apply function fcn to each element of the Array.
Definition: Array.h:760
T & xelem(const Array< octave_idx_type > &ra_idx)
Definition: Array.h:468
nd deftypefn *octave_map m
Definition: ov-struct.cc:2058
bool is_vector(void) const
Definition: Array.h:577
T & xelem(octave_idx_type i, octave_idx_type j)
Definition: Array.h:458
const T * data(void) const
Definition: Array.h:582
ArrayClass::element_type T
Definition: Array.h:890
ArrayRep(T *d, octave_idx_type l)
Definition: Array.h:140
static int elem
Definition: __contourc__.cc:50
ArrayRep(void)
Definition: Array.h:153
Array< T > index(const Array< idx_vector > &ia, bool resize_ok) const
Definition: Array.h:640
T value_type
Definition: Array.h:201
octave_value retval
Definition: data.cc:6294
bool is_square(void) const
Definition: Array.h:573
dim_vector redim(int n) const
Definition: dim-vector.cc:275
F77_RET_T const F77_INT const F77_INT const F77_INT F77_DBLE const F77_INT F77_DBLE const F77_INT F77_DBLE const F77_INT F77_DBLE * Z
bool test_any(bool(&fcn)(const T &)) const
Definition: Array.h:824
octave_idx_type slice_len
Definition: Array.h:226
the sparsity preserving column transformation such that that defines the pivoting threshold can be given in which case it defines the c
Definition: lu.cc:138
the exceeded dimensions are set to if fewer subscripts than dimensions are the exceeding dimensions are merged into the final requested dimension For consider the following dims
Definition: sub2ind.cc:255
NoAlias(X x, Y y)
Definition: Array.h:899
crefT xelem(octave_idx_type n) const
Definition: Array.h:456
With real return the complex result
Definition: data.cc:3375
if_then_else< is_class_type< T >::no, T, T const & >::result type
Definition: lo-traits.h:118
T & elem(octave_idx_type i, octave_idx_type j)
Definition: Array.h:488
static octave_idx_type find(octave_idx_type i, octave_idx_type *pp)
Definition: colamd.cc:112
bool test_any(bool(&fcn)(T)) const
Overloads for function references.
Definition: Array.h:821
T & xelem(octave_idx_type n)
Definition: Array.h:455
count_type * get(void)
Definition: oct-refcount.h:107
bool test_all(F fcn) const
Definition: Array.h:815
N Dimensional Array with copy-on-write semantics.
Definition: Array.h:126
bool test(F fcn) const
Generic any/all test functionality with arbitrary predicate.
Definition: Array.h:803
T * slice_data
Definition: Array.h:225
T::size_type numel(const T &str)
Definition: oct-string.cc:61
This is a simple wrapper template that will subclass an Array type or any later type derived from ...
Definition: Array.h:888
octave_idx_type compute_index(const octave_idx_type *idx) const
Linear index from an index tuple.
Definition: dim-vector.h:475
crefT elem(octave_idx_type i, octave_idx_type j) const
Definition: Array.h:521
bool test_all(bool(&fcn)(const T &)) const
Definition: Array.h:830
crefT elem(octave_idx_type i, octave_idx_type j, octave_idx_type k) const
Definition: Array.h:524
octave_refcount< int > count
Definition: Array.h:138
bool is_shared(void)
Definition: Array.h:588
T element_type
Definition: Array.h:199
Array< T > index(const idx_vector &i, const idx_vector &j, bool resize_ok) const
Definition: Array.h:632
Array< T > index(const idx_vector &i, bool resize_ok) const
Definition: Array.h:625
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
octave_idx_type size_type
Used for operator(), and returned by numel() and size() (beware: signed integer)
Definition: Array.h:205
p
Definition: lu.cc:138
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the IEEE symbol zero divided by nd tex zero divided by nd ifnottex and any operation involving another NaN value(5+NaN).Note that NaN always compares not equal to NaN(NaN!
~ArrayRep(void)
Definition: Array.h:170
Array(const Array< U > &a)
Type conversion case.
Definition: Array.h:287
octave_idx_type ndims(void) const
Number of dimensions.
Definition: dim-vector.h:301
the element is set to zero In other the statement xample y
Definition: data.cc:5342
void assign(const idx_vector &i, const idx_vector &j, const Array< T > &rhs)
Definition: Array.h:656
Array< T > reshape(octave_idx_type nr, octave_idx_type nc) const
Definition: Array.h:563
octave_idx_type pages(void) const
Definition: Array.h:418
T & elem(const Array< octave_idx_type > &ra_idx)
Definition: Array.h:493
void resize2(octave_idx_type nr, octave_idx_type nc)
Definition: Array.h:606
void maybe_economize(void)
Definition: Array.h:690
Array< T > ipermute(const Array< octave_idx_type > &vec) const
Definition: Array.h:570
const T * fortran_vec(void) const
Definition: Array.h:584
octave_idx_type cols(void) const
Definition: Array.h:409
ArrayRep(octave_idx_type n)
Definition: Array.h:155
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
void chop_trailing_singletons(void)
Definition: dim-vector.h:232
static void clear(octave::dynamic_library &oct_file)
Definition: dynamic-ld.cc:230
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:854
dim_vector dv
Definition: sub2ind.cc:263
octave_idx_type columns(void) const
Definition: Array.h:410
crefT elem(octave_idx_type n) const
Definition: Array.h:519
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE * x
NoAlias(X x)
Definition: Array.h:896
void * jit_array_rep(void) const
Definition: Array.h:850
Array< T >::ArrayRep * rep
Definition: Array.h:216
void F(const TSRC *v, TRES *r, octave_idx_type m, octave_idx_type n)
Definition: mx-inlines.cc:719
Array< U > map(U(&fcn)(const T &)) const
Definition: Array.h:797