casa  5.7.0-16
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Array.h
Go to the documentation of this file.
1 //# Array.h: A templated N-D Array class with zero origin
2 //# Copyright (C) 1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2015
3 //# Associated Universities, Inc. Washington DC, USA,
4 //# National Astronomical Observatory of Japan
5 //# 2-21-1, Osawa, Mitaka, Tokyo, 181-8588, Japan.
6 //#
7 //# This library is free software; you can redistribute it and/or modify it
8 //# under the terms of the GNU Library General Public License as published by
9 //# the Free Software Foundation; either version 2 of the License, or (at your
10 //# option) any later version.
11 //#
12 //# This library is distributed in the hope that it will be useful, but WITHOUT
13 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15 //# License for more details.
16 //#
17 //# You should have received a copy of the GNU Library General Public License
18 //# along with this library; if not, write to the Free Software Foundation,
19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
20 //#
21 //# Correspondence concerning AIPS++ should be addressed as follows:
22 //# Internet email: aips2-request@nrao.edu.
23 //# Postal address: AIPS++ Project Office
24 //# National Radio Astronomy Observatory
25 //# 520 Edgemont Road
26 //# Charlottesville, VA 22903-2475 USA
27 //#
28 //# $Id: Array.h 21545 2015-01-22 19:36:35Z gervandiepen $
29 
30 #ifndef CASA_ARRAY_H
31 #define CASA_ARRAY_H
32 
33 //# Includes
34 #include <casacore/casa/aips.h>
40 #include <casacore/casa/ostream.h>
41 #include <iterator>
43 
44 
45 namespace casacore { //#Begin casa namespace
46 //# Forward Declarations
47 class AipsIO;
48 class Slice;
49 class Slicer;
50 template<class T> class Matrix;
51 template<class T> class ArrayIterator;
52 template<class T> class MaskedArray;
53 template<class Domain, class Range> class Functional;
54 //template <class T, class U> class vector;
55 
56 
57 // <summary> A templated N-D Array class with zero origin </summary>
58 
59 // Array<T> is a templated, N-dimensional, Array class. The origin is zero,
60 // but by default indices are zero-based. This Array class is the
61 // base class for specialized Vector<T>, Matrix<T>, and Cube<T> classes.
62 //
63 // Indexing into the array, and positions in general, are given with IPosition
64 // (essentially a vector of integers) objects. That is, an N-dimensional
65 // array requires a length-N IPosition to define a position within the array.
66 // Unlike C, indexing is done with (), not []. Also, the storage order
67 // is the same as in FORTRAN, i.e. memory varies most rapidly with the first
68 // index.
69 // <srcblock>
70 // // axisLengths = [1,2,3,4,5]
71 // IPosition axisLengths(5, 1, 2, 3, 4, 5);
72 // Array<Int> ai(axisLengths); // ai is a 5 dimensional array of
73 // // integers; indices are 0-based
74 // // => ai.nelements() == 120
75 // Array<Int> ai2(axisLengths); // The first element is at index 0
76 // IPosition zero(5); zero = 0; // [0,0,0,0,0]
77 // //...
78 // </srcblock>
79 // Indexing into an N-dimensional array is relatively expensive. Normally
80 // you will index into a Vector, Matrix, or Cube. These may be obtained from
81 // an N-dimensional array by creating a reference, or by using an
82 // ArrayIterator. The "shape" of the array is an IPosition which gives the
83 // length of each axis.
84 //
85 // An Array may be standalone, or it may refer to another array, or to
86 // part of another array (by refer we mean that if you change a pixel in
87 // the current array, a pixel in the referred to array also changes, i.e.
88 // they share underlying storage).
89 // <note role=warning>
90 // One way one array can reference another is through the copy
91 // constructor. While this might be what you want, you should
92 // probably use the reference() member function to make it explicit.
93 // The copy constructor is used when arguments are passed by value;
94 // normally functions should not pass Arrays by value, rather they
95 // should pass a reference or a const reference. On the positive
96 // side, returning an array from a function is efficient since no
97 // copying need be done.
98 // </note>
99 //
100 // Aside from the explicit reference() member function, a user will
101 // most commonly encounter an array which references another array
102 // when he takes an array slice (or section). A slice is a sub-region of
103 // an array (which might also have a stride: every nth row, every mth column,
104 // ...).
105 // <srcblock>
106 // IPosition lengths(3,10,20,30);
107 // Array<Int> ai(lengths); // A 10x20x30 cube
108 // Cube<Int> ci;
109 // //...
110 // ci.reference(ai1); // ci and ai now reference the same
111 // // storage
112 // ci(0,0,0) = 123; // Can use Cube indexing
113 // ci.xyPlane(2) = 0; // and other member functions
114 // IPosition zero(3,0,0,0);
115 // assert(ai(zero) == 123); // True because ai, ci are references
116 // //...
117 // Array<Int> subArray;
118 // IPosition blc(3,0,0,0), trc(3,5,5,5);
119 // subArray.reference(ai(blc, trc));
120 // subArray = 10; // All of subArray, which is the
121 // // subcube from 0,0,0 to 5,5,5 in
122 // // ai, has the value 10.
123 // </srcblock>
124 // While the last example has an array slice referenced explicitly by another
125 // array variable, normally the user will often only use the slice as
126 // a temporary in an expresion, for example:
127 // <srcblock>
128 // Array<Complex> array;
129 // IPosition blc, trc, offset;
130 // //...
131 // // Copy from one region of the array into another
132 // array(blc, trc) = array(blc+offset, trc+offset);
133 // </srcblock>
134 //
135 // The Array classes are intended to operate on relatively large
136 // amounts of data. While they haven't been extensively tuned yet,
137 // they are relatively efficient in terms of speed. Presently they
138 // are not space efficient -- the overhead is about 15 words. While
139 // this will be improved (probably to about 1/2 that), these array
140 // classes are not appropriate for very large numbers of very small
141 // arrays. The Block<T> class may be what you want in this circumstance.
142 //
143 // Element by element mathematical and logical operations are available
144 // for arrays (defined in aips/ArrayMath.h and aips/ArrayLogical.h).
145 // Because arithmetic and logical functions are split out, it is possible
146 // to create an Array<T> (and hence Vector<T> etc) for any type T that has
147 // a default constructor, assignment operator, and copy constructor. In
148 // particular, Array<String> works.
149 //
150 // If compiled with the preprocessor symbol AIPS_DEBUG symbol, array
151 // consistency ("invariants") will be checked in most member
152 // functions, and indexing will be range-checked. This should not be
153 // defined for production runs.
154 //
155 // <note role=tip>
156 // Most of the data members and functions which are "protected" should
157 // likely become "private".
158 // </note>
159 //
160 // <todo asof="1999/12/30">
161 // <li> Integrate into the Lattice hierarchy
162 // <li> Factor out the common functions (shape etc) into a type-independent
163 // base class.
164 // </todo>
165 
166 template<class T> class Array : public ArrayBase
167 {
168 public:
169 
170  // Result has dimensionality of zero, and nelements is zero.
171  // Storage will be allocated by <src>DefaultAllocator<T></src>.
172  Array();
173 
174  // Create an array of the given shape, i.e. after construction
175  // array.ndim() == shape.nelements() and array.shape() == shape.
176  // The origin of the Array is zero.
177  // Storage is allocated by <src>DefaultAllocator<T></src>.
178  // Without initPolicy parameter, the initialization of elements depends on type <src>T</src>.
179  // When <src>T</src> is a fundamental type like <src>int</src>, elements are NOT initialized.
180  // When <src>T</src> is a class type like <src>casacore::Complex</src> or <src>std::string</src>, elements are initialized.
181  // This inconsistent behavior confuses programmers and make it hard to write efficient and generic code using template.
182  // Especially when <src>T</src> is of type <src>Complex</src> or <src>DComplex</src> and it is unnecessary to initialize,
183  // provide initPolicy with value <src>NO_INIT</src> to skip the initialization.
184  // Therefore, it is strongly recommended to explicitly provide initPolicy parameter,
185  explicit Array(const IPosition &shape);
186 
187  // Create an array of the given shape, i.e. after construction
188  // array.ndim() == shape.nelements() and array.shape() == shape.
189  // The origin of the Array is zero.
190  // Storage is allocated by <src>DefaultAllocator<T></src>.
191  // When initPolicy parameter is <src>INIT</src>, elements are initialized with the default value of <src>T()</src>.
192  // When initPolicy parameter is <src>NO_INIT</src>, elements are NOT initialized and programmers are responsible to
193  // initialize elements before they are referred, especially when <src>T</src> is such type like <src>std::string</src>.
194  // <srcblock>
195  // IPosition shape(1, 10);
196  // Array<Int> ai(shape, ArrayInitPolicies::NO_INIT);
197  // size_t nread = fread(ai.data(), sizeof(Int), ai.nelements(), fp);
198  // </srcblock>
199  Array(const IPosition &shape, ArrayInitPolicy initPolicy);
200 
201  // Create an array of the given shape and initialize it with the
202  // initial value.
203  // Storage is allocated by <src>DefaultAllocator<T></src>.
204  Array(const IPosition &shape, const T &initialValue);
205 
206  // After construction, this and other reference the same storage.
207  Array(const Array<T> &other);
208 
209  // Create an Array of a given shape from a pointer.
210  // If <src>policy</src> is <src>COPY</src>, storage of a new copy is allocated by <src>DefaultAllocator<T></src>.
211  // If <src>policy</src> is <src>TAKE_OVER</src>, <src>storage</src> will be destructed and released by <src>NewDelAllocator<T></src>.
212  // It is strongly recommended to supply an appropriate <src>allocator</src> argument explicitly
213  // whenever <src>policy</src> == <src>TAKE_OVER</src>
214  // to let <src>Array</src> to know how to release the <src>storage</src>.
215  Array(const IPosition &shape, T *storage, StorageInitPolicy policy = COPY);
216 
217  // Create an Array of a given shape from a pointer.
218  // If <src>policy</src> is <src>COPY</src>, storage of a new copy is allocated by the specified allocator.
219  // If <src>policy</src> is <src>TAKE_OVER</src>, <src>storage</src> will be destructed and released by the specified allocator.
220  // Otherwise, <src>allocator</src> is ignored.
221  // It is strongly recommended to allocate and initialize <src>storage</src> with <src>DefaultAllocator<T></src>
222  // rather than new[] or <src>NewDelAllocator<T></src> because new[] can't decouple allocation and initialization.
223  // <src>DefaultAllocator<T></src> is a subclass of std::allocator. You can allocate <src>storage</src> via
224  // the allocator as below.
225  // <srcblock>
226  // FILE *fp = ...;
227  // typedef DefaultAllocator<Int> Alloc;
228  // Alloc::type alloc;
229  // IPosition shape(1, 10);
230  // Int *ptr = alloc.allocate(shape.product());
231  // size_t nread = fread(ptr, sizeof(Int), shape.product(), fp);
232  // Array<Int> ai(shape, ptr, TAKE_OVER, Alloc::value);
233  // </srcblock>
234  Array(const IPosition &shape, T *storage, StorageInitPolicy policy, AbstractAllocator<T> const &allocator);
235 
236  // Create an Array of a given shape from a pointer. Because the pointer
237  // is const, a copy is always made.
238  // The copy is allocated by <src>DefaultAllocator<T></src>.
239  Array(const IPosition &shape, const T *storage);
240 
241  // Frees up storage only if this array was the last reference to it.
242  virtual ~Array();
243 
244  // Make an empty array of the same template type.
245  virtual CountedPtr<ArrayBase> makeArray() const;
246 
247  // Assign the other array to this array.
248  // If the shapes mismatch, this array is resized.
249  // <group>
250  virtual void assign (const Array<T>& other);
251  virtual void assignBase (const ArrayBase& other, Bool checkType=True);
252  // </group>
253 
254  // Set every element of the array to "value." Also could use the
255  // assignment operator which assigns an array from a scalar.
256  void set(const T &value);
257 
258  // Apply the function to every element of the array. This modifies
259  // the array in place.
260  // <group>
261  // This version takes a function which takes a T and returns a T.
262  void apply(T (*function)(T));
263  // This version takes a function which takes a const T reference and
264  // returns a T.
265  void apply(T (*function)(const T &));
266  // This version applies a functional.
267  void apply(const Functional<T,T> &function);
268  // </group>
269 
270  // After invocation, this array and other reference the same storage. That
271  // is, modifying an element through one will show up in the other. The
272  // arrays appear to be identical; they have the same shape.
273  // <br>Please note that this function makes it possible to reference a
274  // const Array, thus effectively it makes a const Array non-const.
275  // Although this may seem undesirable at first sight, it is necessary to
276  // be able to make references to temporary Array objects, in particular to
277  // Array slices. Otherwise one first needs to use the copy constructor.
278  //# The const has been introduced on 2005-Mar-31 because of the hassle
279  //# involved in calling the copy ctor before reference.
280  virtual void reference(const Array<T> &other);
281 
282  // Copy the values in other to this. If the array on the left hand
283  // side has no elements, then it is resized to be the same size as
284  // as the array on the right hand side. Otherwise, the arrays must
285  // conform (same shapes).
286  // <srcblock>
287  // IPosition shape(2,10,10); // some shape
288  // Array<Double> ad(shape);
289  // //...
290  // Array<Double> ad2; // N.B. ad2.nelements() == 0
291  // ad2 = ad; // ad2 resizes, then elements
292  // // are copied.
293  // shape = 20;
294  // Array<Double> ad3(shape);
295  // ad3 = ad; // Error: arrays do not conform
296  // </srcblock>
297  // Note that the assign function can be used to assign a
298  // non-conforming array.
299  virtual Array<T> &operator=(const Array<T> &other);
300 
301  // Set every element of this array to "value". In other words, a scalar
302  // behaves as if it were a constant conformant array.
303  Array<T> &operator=(const T &value);
304 
305  // Copy to this those values in marray whose corresponding elements
306  // in marray's mask are True.
307  //
308  // <thrown>
309  // <li> ArrayConformanceError
310  // </thrown>
311  //
313 
314  // This makes a copy of the array and returns it. This can be
315  // useful for, e.g. making working copies of function arguments
316  // that you can write into.
317  // <srcblock>
318  // void someFunction(const Array<Int> &arg)
319  // {
320  // Array<Int> tmp(arg.copy());
321  // // ...
322  // }
323  // </srcblock>
324  // Note that since the copy constructor makes a reference, if we just
325  // created used to copy constructor, modifying "tmp" would also
326  // modify "arg". Clearly another alternative would simply be:
327  // <srcblock>
328  // void someFunction(const Array<Int> &arg)
329  // {
330  // Array<Int> tmp;
331  // tmp = arg;
332  // // ...
333  // }
334  // </srcblock>
335  // which likely would be simpler to understand. (Should copy()
336  // be deprecated and removed?)
337  //
338  Array<T> copy(ArrayInitPolicy policy = ArrayInitPolicies::NO_INIT) const; // Make a copy of this
339 
340  // This function copies the matching part of from array to this array.
341  // The matching part is the part with the minimum size for each axis.
342  // E.g. if this array has shape [4,5,6] and from array has shape [7,3],
343  // the matching part has shape [4,3].
344  // <br>Note it is used by the resize function if
345  // <src>copyValues==True</src>.
346  void copyMatchingPart (const Array<T> &from);
347 
348  // This ensures that this array does not reference any other storage.
349  // <note role=tip>
350  // When a section is taken of an array with non-unity strides,
351  // storage can be wasted if the array, which originally contained
352  // all the data, goes away. unique() also reclaims storage. This
353  // is an optimization users don't normally need to understand.
354  //
355  // <srcblock>
356  // IPosition shape(...), blc(...), trc(...), inc(...);
357  // Array<Float> af(shape);
358  // inc = 2; // or anything > 1
359  // Array<Float> aSection.reference(af(blc, trc, inc));
360  // af.reference(anotherArray);
361  // // aSection now references storage that has a stride
362  // // in it, but nothing else is. Storage is wasted.
363  // aSection.unique();
364  // </srcblock>
365  // </note>
366  void unique();
367 
368  // Create an STL vector from an Array. The created vector is a linear
369  // representation of the Array memory. See
370  // <linkto class=Vector>Vector</linkto> for
371  // details of the operation and its reverse (i.e. creating a
372  // <src>Vector</src> from a <src>vector</src>), and for details of
373  // definition and instantiation.
374  // <group>
375  template <class U>
376  void tovector(vector<T, U> &out) const;
377 
378  vector<T> tovector() const;
379  // </group>
380 
381  // It is occasionally useful to have an array which access the same
382  // storage appear to have a different shape. For example,
383  // turning an N-dimensional array into a Vector.
384  // <br>When the array data are contiguous, the array can be reshaped
385  // to any form as long as the number of elements stays the same.
386  // When not contiguous, it is only possible to remove or add axes
387  // with length 1.
388  // <srcblock>
389  // IPosition squareShape(2,5,5);
390  // Array<Float> square(squareShape);
391  // IPosition lineShape(1,25);
392  // Vector<Float> line(square.reform(lineShape));
393  // // "square"'s storage may now be accessed through Vector "line"
394  // </srcblock>
395  Array<T> reform(const IPosition &shape) const;
396 
397  // Having an array that can be reused without requiring reallocation can
398  // be useful for large arrays. The method reformOrResize permits this
399  // usage.
400  //
401  // The reformOrResize method first attempts to reform the matrix so that
402  // it reuses the existing storage for an array with a new shape. If the
403  // existing storage will not hold the new shape, then the method will
404  // resize the array when resizeIfNeeded is true; if a resize is needed and
405  // resizeIfNeeded is false, then an ArrayConformanceError is thrown. The
406  // copyDataIfNeeded parameter is passed to resize if resizing is performed.
407  // resizePercentage is the percent of additional storage to be addeed when
408  // a resize is performed; this allows the allocations to be amortized when
409  // the caller expects to be calling this method again in the future. The
410  // parameter is used to define an allocation shape which is larger than
411  // the newShape by increasing the last dimension by resizePercentage percent
412  // (i.e., lastDim = (lastDim * (100 + resizePercentage)) / 100). If
413  // resizePercentage <= 0 then resizing uses newShape as-is. Returns true
414  // if resizing (allocation) was performed.
415  //
416  // To truncate the array so that it no longer holds additional storage,
417  // use the resize method.
418  //
419  // Array may not be shared with another Array object during this call.
420  // Exception thrown if it is shared.
421 
422  bool reformOrResize (const IPosition & newShape,
423  uInt resizePercentage = 0,
424  Bool resizeIfNeeded = True);
425 
426  // Use this method to extend or reduce the last dimension of an array. If
427  // sufficient excess capacity exists then the bookkeeping is adjusted to
428  // support the new shape. If insufficient storage exists then a new array
429  // is allocated (unless resizeIfNeeded is false; then an exception is thrown).
430  // If resizing is not required then the data remains untouched; if resizing
431  // is required then the data is copied into the new storage. The resizePercentage
432  // works the same as for reformOrResize (see above). This method never releases
433  // extra storage; use "resize" to do this. Array may not be sharing storage
434  // with another array at call time; an exception will be thrown if the array is shared.
435  // Returns true if the array was extension required a Array<T>::resize operation.
436 
437  bool adjustLastAxis (const IPosition & newShape,
438  uInt resizePercentage = 0,
439  bool resizeIfNeeded = True);
440 
441  // Returns the number of elements allocated. This value is >= to the value returned
442  // by size().
443 
444  size_t capacity () const;
445 
446  // These member functions remove degenerate (ie. length==1) axes from
447  // Arrays. Only axes greater than startingAxis are considered (normally
448  // one wants to remove trailing axes). The first two of these functions
449  // return an Array reference with axes removed. The latter two functions
450  // let this Array object reference the 'other' array with degenerated axes
451  // removed.
452  // <br>
453  // Unless throwIfError is False, an exception will be thrown if
454  // startingAxis exceeds the array's dimensionality.
455  // <br>
456  // The functions with argument <src>ignoreAxes</src> do
457  // not consider the axes given in that argument. In this way it can be
458  // achieved that degenerate axes are kept.
459  // <note role=caution> When the two functions returning <src>void</src>
460  // are invoked on a derived object (e.g. Matrix), an exception is
461  // thrown if removing the degenerate axes from other does not result
462  // in a correct number of axes.
463  // </note>
464  // <group>
465  Array<T> nonDegenerate(uInt startingAxis=0, Bool throwIfError=True) const;
466  Array<T> nonDegenerate(const IPosition& ignoreAxes) const;
467  void nonDegenerate(const Array<T> &other, uInt startingAxis=0,
469  void nonDegenerate(const Array<T> &other, const IPosition &ignoreAxes)
470  { doNonDegenerate (other, ignoreAxes); }
471  // </group>
472 
473  // Remove degenerate axes from this Array object.
474  // Note it does not make sense to use these functions on a derived object
475  // like Matrix, because it is not possible to remove axes from them.
476  // <group>
477  void removeDegenerate(uInt startingAxis=0,
479  void removeDegenerate(const IPosition &ignoreAxes);
480  // </group>
481 
482  // This member function returns an Array reference with the specified
483  // number of extra axes, all of length one, appended to the end of the
484  // Array. Note that the <src>reform</src> function can also be
485  // used to add extra axes.
486  // <group>
487  const Array<T> addDegenerate(uInt numAxes) const;
488  Array<T> addDegenerate(uInt numAxes);
489  // </group>
490 
491  // Make this array a different shape. If <src>copyValues==True</src>
492  // the old values are copied over to the new array.
493  // Copying is done on a per axis basis, thus a subsection with the
494  // minimum of the old and new shape is copied.
495  // <br>Resize without argument is equal to resize(IPosition()).
496  // <br>It is important to note that if multiple Array objects
497  // reference the same data storage, this Array object still references
498  // the same data storage as the other Array objects if the shape does
499  // not change. Otherwise this Array object references newly allocated
500  // storage, while the other Array objects still reference the existing
501  // data storage.
502  // <br>If you want to be sure that the data storage of this Array object
503  // is not referenced by other Array objects, the function unique should
504  // be called first.
505  // <group>
506  virtual void resize();
507  virtual void resize(const IPosition &newShape, Bool copyValues=False);
508  virtual void resize(const IPosition &newShape, Bool copyValues, ArrayInitPolicy policy);
509  // </group>
510 
511  // Access a single element of the array. This is relatively
512  // expensive. Extensive indexing should be done through one
513  // of the Array specializations (Vector, Matrix, Cube). If
514  // AIPS_DEBUG is defined, index checking will be performed.
515  // <group>
516  T &operator()(const IPosition &);
517  const T &operator()(const IPosition &) const;
518  // </group>
519 
520  // Get a reference to an array section extending
521  // from start to end (inclusive).
522  // <group>
523  Array<T> operator()(const IPosition &start,
524  const IPosition &end);
525  const Array<T> operator()(const IPosition &start,
526  const IPosition &end) const;
527  // Along the ith axis, every inc[i]'th element is chosen.
528  Array<T> operator()(const IPosition &start,
529  const IPosition &end,
530  const IPosition &inc);
531  const Array<T> operator()(const IPosition &start,
532  const IPosition &end,
533  const IPosition &inc) const;
534  // </group>
535 
536  // Get a reference to an array section using a Slicer.
537  // <group>
538  Array<T> operator()(const Slicer&);
539  const Array<T> operator()(const Slicer&) const;
540  // </group>
541 
542  // Get a reference to a section of an array.
543  // This is the same as operator(), but can be used in a type-agnostic way.
544  virtual CountedPtr<ArrayBase> getSection (const Slicer&) const;
545 
546  // Get the subset given by the i-th value of the last axis. So for a cube
547  // it returns the i-th xy plane. For a Matrix it returns the i-th row.
548  // The returned array references the original array data; its dimensionality
549  // is one less. For a 1-dim array it still returns a 1-dim array.
550  // <note>This function should not be used in tight loops as it is (much)
551  // slower than iterating using begin() and end(), ArrayIter, or
552  // ArrayAccessor.</note>
553  Array<T> operator[] (size_t i) const;
554 
555  // Get the diagonal of each matrix part in the full array.
556  // The matrices are taken using axes firstAxes and firstAxis+1.
557  // diag==0 is main diagonal; diag>0 above the main diagonal; diag<0 below.
558  Array<T> diagonals (uInt firstAxis=0, Int64 diag=0) const;
559 
560  // The array is masked by the input LogicalArray.
561  // This mask must conform to the array.
562  // <group>
563  const MaskedArray<T> operator() (const LogicalArray &mask) const;
564  MaskedArray<T> operator() (const LogicalArray &mask);
565  // </group>
566 
567  // The array is masked by the input MaskedLogicalArray.
568  // The mask is effectively the AND of the internal LogicalArray
569  // and the internal mask of the MaskedLogicalArray.
570  // The MaskedLogicalArray must conform to the array.
571  // <group>
572  const MaskedArray<T> operator() (const MaskedLogicalArray &mask) const;
573  MaskedArray<T> operator() (const MaskedLogicalArray &mask);
574  // </group>
575 
576  // The number of references the underlying storage has assigned to it.
577  // It is 1 unless there are outstanding references to the storage (e.g.,
578  // through a slice). Normally you have no need to do this since the
579  // arrays handle all of the references for you.
580  uInt nrefs() const;
581 
582  // Check to see if the Array is consistent. This is about the same thing
583  // as checking for invariants. If AIPS_DEBUG is defined, this is invoked
584  // after construction and on entry to most member functions.
585  virtual Bool ok() const;
586 
587  // Are the shapes identical?
588  // <group>
589  Bool conform (const Array<T> &other) const
590  { return conform2(other); }
591  Bool conform (const MaskedArray<T> &other) const;
592  // </group>
593 
594  // Get a pointer to the beginning of the array.
595  // Note that the array may not be contiguous.
596  // <group>
597  T* data()
598  { return begin_p; }
599  const T* data() const
600  { return begin_p; }
601  // </group>
602 
603  // Generally use of this should be shunned, except to use a FORTRAN routine
604  // or something similar. Because you can't know the state of the underlying
605  // data layout (in particular, if there are increments) sometimes the
606  // pointer returned will be to a copy, but often this won't be necessary.
607  // A boolean is returned which tells you if this is a copy (and hence the
608  // storage must be deleted). Note that if you don't do anything unusual,
609  // getStorage followed by freeStorage or putStorage will do the deletion
610  // for you (if required). e.g.:
611  // <srcblock>
612  // Array<Int> a(shape); ...
613  // Bool deleteIt; Int *storage = a.getStorage(deleteIt);
614  // foo(storage, a.nelements()); a.puStorage(storage, deleteIt);
615  // // or a.freeStorage(storage, deleteIt) if a is const.
616  // </srcblock>
617  // NB: However, if you only use getStorage, you will have to delete the
618  // pointer yourself using freeStorage().
619  //
620  // It would probably be useful to have corresponding "copyin" "copyout"
621  // functions that used a user supplied buffer.
622  // Note that deleteIt is set in this function.
623  // <group>
624  T *getStorage(Bool &deleteIt);
625  const T *getStorage(Bool &deleteIt) const
626  {
627  // The cast is OK because the return pointer will be cast to const
628  return const_cast<Array<T>*>(this)->getStorage(deleteIt);
629  }
630  virtual void *getVStorage(Bool &deleteIt);
631  virtual const void *getVStorage(Bool &deleteIt) const;
632  // </group>
633 
634  // putStorage() is normally called after a call to getStorage() (cf).
635  // The "storage" pointer is set to zero.
636  void putStorage(T *&storage, Bool deleteAndCopy);
637  virtual void putVStorage(void *&storage, Bool deleteAndCopy);
638 
639  // If deleteIt is set, delete "storage". Normally freeStorage calls
640  // will follow calls to getStorage. The reason the pointer is "const"
641  // is because only const pointers are released from const arrays.
642  // The "storage" pointer is set to zero.
643  void freeStorage(const T *&storage, Bool deleteIt) const;
644  void freeVStorage(const void *&storage, Bool deleteIt) const;
645 
646  // Replace the data values with those in the pointer <src>storage</src>.
647  // The results are undefined if storage does not point at nelements() or
648  // more data elements. After takeStorage() is called, <src>nrefs()</src>
649  // is 1.
650  // <group>
651  // If <src>policy</src> is <src>COPY</src>, storage of a new copy is allocated by <src>DefaultAllocator<T></src>.
652  // If <src>policy</src> is <src>TAKE_OVER</src>, <src>storage</src> will be destructed and released by <src>NewDelAllocator<T></src>.
653  // It is strongly recommended to supply an appropriate <src>allocator</src> argument explicitly
654  // whenever <src>policy</src> == <src>TAKE_OVER</src>
655  // to let <src>Array</src> to know how to release the <src>storage</src>.
656  virtual void takeStorage(const IPosition &shape, T *storage,
657  StorageInitPolicy policy = COPY);
658 
659  // If <src>policy</src> is <src>COPY</src>, storage of a new copy is allocated by <src>allocator</src>.
660  // If <src>policy</src> is <src>TAKE_OVER</src>, <src>storage</src> will be destructed and released by <src>allocator</src>.
661  // Otherwise, <src>storage</src> is ignored.
662  virtual void takeStorage(const IPosition &shape, T *storage,
663  StorageInitPolicy policy, AbstractAllocator<T> const &allocator);
664 
665  // Since the pointer is const, a copy is always taken.
666  // Storage of a new copy is allocated by <src>DefaultAllocator<T></src>.
667  virtual void takeStorage(const IPosition &shape, const T *storage);
668 
669  // Since the pointer is const, a copy is always taken.
670  // Storage of a new copy is allocated by the specified allocator.
671  virtual void takeStorage(const IPosition &shape, const T *storage,
672  AbstractAllocator<T> const &allocator);
673  // </group>
674 
675 
676  // Used to iterate through Arrays. Derived classes VectorIterator and
677  // MatrixIterator are probably more useful.
678  friend class ArrayIterator<T>;
679 
680  // Create an ArrayIterator object of the correct type.
682 
683  // Needed to be a friend for Matrix<T>::reference()
684  friend class Matrix<T>;
685 
686 
687  // <group name=STL-iterator>
688  // See the function begin() and end() for a detailed description
689  // of the STL iterator capability.
690  class BaseIteratorSTL
691  {
692  public:
693  // Create the begin const_iterator object for an Array.
694  explicit BaseIteratorSTL (const Array<T>&);
695  // Create the end const_iterator object for an Array.
696  // It also acts as the default constructor.
697  explicit BaseIteratorSTL (const T* end = 0)
699  itsArray(0), itsContig(False) {}
700 
701  void nextElem()
702  {
703  itsPos++;
704  if (!itsContig) {
705  itsPos += itsLineIncr;
706  if (itsPos > itsLineEnd) increment();
707  }
708  }
709  void nextLine()
710  {
711  itsPos = itsLineEnd;
712  increment();
713  }
714 
715  bool operator== (const BaseIteratorSTL& other) const
716  { return itsPos == other.itsPos; }
717 
718  bool operator!= (const BaseIteratorSTL& other) const
719  { return itsPos != other.itsPos; }
720 
721  T* getPos()
722  { return const_cast<T*>(itsPos); }
723 
724  friend ostream& operator<< (ostream& os, const BaseIteratorSTL& iter)
725  { os << iter.itsPos; return os; }
726 
727  protected:
728  // Increment iterator for a non-contiguous array.
729  void increment();
730 
731  const T* itsPos;
732  const T* itsLineEnd;
733  size_t itsLineIncr;
739  };
740 
742  {
743  public:
744  // <group name=STL-iterator-typedefs>
745  typedef T value_type;
746  typedef value_type* pointer;
748  typedef std::size_t size_type;
749  typedef ptrdiff_t difference_type;
750  typedef std::forward_iterator_tag iterator_category;
751  // </group>
752 
753  // Create the begin iterator object for an Array.
754  explicit IteratorSTL (Array<T>& arr)
755  : BaseIteratorSTL (arr) {}
756  // Create the end iterator object for an Array.
757  // It also acts as the default constructor.
758  explicit IteratorSTL (const T* end = 0)
759  : BaseIteratorSTL (end) {}
760 
762  {
763  this->nextElem();
764  return *this;
765  }
767  {
768  IteratorSTL old(*this);
769  this->nextElem();
770  return old;
771  }
772 
774  { return *this->getPos(); }
776  { return this->getPos(); }
777  };
778 
780  {
781  public:
782  // <group name=STL-const-iterator-typedefs>
783  typedef T value_type;
784  typedef const value_type* pointer;
785  typedef const value_type& reference;
786  typedef std::size_t size_type;
787  typedef ptrdiff_t difference_type;
788  typedef std::forward_iterator_tag iterator_category;
789  // </group>
790 
791  // Create the begin const_iterator object for an Array.
792  explicit ConstIteratorSTL (const Array<T>& arr)
793  : BaseIteratorSTL (arr) {}
794  // Create the end const_iterator object for an Array.
795  // It also acts as the default constructor.
796  explicit ConstIteratorSTL (const T* end = 0)
797  : BaseIteratorSTL (end) {}
798  // Create from a non-const iterator.
800  : BaseIteratorSTL (iter) {}
801 
803  {
804  this->nextElem();
805  return *this;
806  }
808  {
809  ConstIteratorSTL old(*this);
810  this->nextElem();
811  return old;
812  }
813 
814  const T& operator*() const
815  { return *this->itsPos; }
816  const T* operator->()
817  { return this->itsPos; }
818 
819  const T* pos() const
820  { return this->itsPos; }
821  };
822  // </group>
823 
824  // Define the STL-style iterator functions (only forward iterator).
825  // It makes it possible to iterate through all data elements of an array
826  // and to use it common STL functions.
827  // The end() function is relatively expensive, so it should not be
828  // used inside a for statement. It is much better to call it beforehand
829  // as shown in the example below. Furthermore it is very important to
830  // use <src>++iter</src>, because <src>iter++</src> is 4 times slower.
831  // <srcblock>
832  // Array<Int> arr(shape);
833  // Array<Int>::iterator iterend(arr.end());
834  // for (Array<Int>::iterator iter=arr.begin(); iter!=iterend; ++iter) {
835  // *iter += 1;
836  // }
837  // </srcblock>
838  // The Array class supports random access, so in principle a random
839  // iterator could be implemented, but its performance would not be great,
840  // especially for non-contiguous arrays.
841  // <br>Some other STL like functions exist for performance reasons.
842  // If the array is contiguous, it is possible to use the
843  // <src>cbegin</src> and <src>cend</src> functions which are
844  // about 10% faster.
845  // <group name=iterator-typedefs>
846  // STL-style typedefs.
847  // <group>
848  typedef T value_type;
849  typedef IteratorSTL iterator;
850  typedef ConstIteratorSTL const_iterator;
851  typedef T* contiter;
852  typedef const T* const_contiter;
853  // </group>
854  // Get the begin iterator object for any array.
855  // <group>
857  { return iterator (*this); }
859  { return const_iterator (*this); }
861  { return iterator(end_p); }
863  { return const_iterator(end_p); }
864  // </group>
865 
866  // Get the begin iterator object for a contiguous array.
867  // <group>
869  { return begin_p; }
871  { return begin_p; }
873  { return end_p; }
875  { return end_p; }
876  // </group>
877 
878  // </group>
879 
880 
881 private:
884  // Makes a copy using the allocator.
886  // If the current allocator is NewDelAllocator<T>, BulkAllocator for DefaultAllocator<T> is returned,
887  // otherwise BulkAllocator for the current allocator is returned.
889 protected:
892  }
893  // pre/post processing hook of takeStorage() for subclasses.
894  virtual void preTakeStorage(const IPosition &) {}
895  virtual void postTakeStorage() {}
896  static void copyToContiguousStorage(T *dst, Array<T> const & src, ArrayInitPolicy policy);
897 
898  // Remove the degenerate axes from the Array object.
899  // This is the implementation of the nonDegenerate functions.
900  // It has a different name to be able to make it virtual without having
901  // the "hide virtual function" message when compiling derived classes.
902  virtual void doNonDegenerate(const Array<T> &other,
903  const IPosition &ignoreAxes);
904 
905 
906  // Reference counted block that contains the storage.
908 
909  // This pointer is adjusted to point to the first element of the array.
910  // It is not necessarily the same thing as data->storage() since
911  // this array might be a section, e.g. have a blc which shifts us forward
912  // into the block.
914 
915  // The end for an STL-style iteration.
916  T* end_p;
917 
918 
919  // Fill the steps and the end for a derived class.
920  void makeSteps()
921  { baseMakeSteps(); this->setEndIter(); }
922 
923  // Set the end iterator.
924  void setEndIter()
925  { end_p = (nels_p==0 ? 0 : (contiguous_p ? begin_p + nels_p :
926  begin_p + size_t(length_p(ndim()-1)) * steps_p(ndim()-1))); }
927 };
928 
929 
930 //# Declare extern templates for often used types.
931  extern template class Array<Bool>;
932  extern template class Array<Char>;
933  extern template class Array<uChar>;
934  extern template class Array<Short>;
935  extern template class Array<uShort>;
936  extern template class Array<Int>;
937  extern template class Array<uInt>;
938  extern template class Array<Int64>;
939  extern template class Array<Float>;
940  extern template class Array<Double>;
941  extern template class Array<Complex>;
942  extern template class Array<DComplex>;
943  extern template class Array<String>;
944 
945 }//#End casa namespace
946 
947 
948 #ifndef CASACORE_NO_AUTO_TEMPLATES
949 #include <casacore/casa/Arrays/Array.tcc>
950 #endif //# CASACORE_NO_AUTO_TEMPLATES
951 #endif
ConstIteratorSTL(const T *end=0)
Create the end const_iterator object for an Array.
Definition: Array.h:796
Bool contiguous_p
Are the data contiguous?
Definition: ArrayBase.h:268
A Vector of integers, for indexing into Array&lt;T&gt; objects.
Definition: IPosition.h:119
ConstIteratorSTL operator++(int)
Definition: Array.h:807
long long Int64
Define the extra non-standard types used by Casacore (like proposed uSize, Size)
Definition: aipsxtype.h:38
virtual Bool ok() const
Check to see if the Array is consistent.
virtual void assignBase(const ArrayBase &other, Bool checkType=True)
Assign the source array to this array.
const_iterator end() const
Definition: Array.h:862
Non-templated base class for templated Array class.
Definition: ArrayBase.h:74
void putStorage(T *&storage, Bool deleteAndCopy)
putStorage() is normally called after a call to getStorage() (cf).
static ArrayInitPolicy defaultArrayInitPolicy()
Definition: Array.h:890
static void copyToContiguousStorage(T *dst, Array< T > const &src, ArrayInitPolicy policy)
const_iterator begin() const
Definition: Array.h:858
Array< T > diagonals(uInt firstAxis=0, Int64 diag=0) const
Get the diagonal of each matrix part in the full array.
virtual void preTakeStorage(const IPosition &)
pre/post processing hook of takeStorage() for subclasses.
Definition: Array.h:894
Map a domain object into a range object via operator().
Definition: Functional.h:122
IteratorSTL(Array< T > &arr)
Create the begin iterator object for an Array.
Definition: Array.h:754
Allocator_private::BulkAllocator< T > * nonNewDelAllocator() const
If the current allocator is NewDelAllocator&lt;T&gt;, BulkAllocator for DefaultAllocator&lt;T&gt; is returned...
static constexpr ArrayInitPolicy NO_INIT
Don&#39;t initialize elements in the array.
Definition: Allocator.h:70
LatticeExprNode mask(const LatticeExprNode &expr)
This function returns the mask of the given expression.
ConstIteratorSTL(const IteratorSTL &iter)
Create from a non-const iterator.
Definition: Array.h:799
IPosition steps_p
Used to hold the step to next element in each dimension.
Definition: ArrayBase.h:273
Array< T > nonDegenerate(uInt startingAxis=0, Bool throwIfError=True) const
These member functions remove degenerate (ie.
const value_type & reference
Definition: Array.h:786
const_contiter cbegin() const
Definition: Array.h:870
bool adjustLastAxis(const IPosition &newShape, uInt resizePercentage=0, bool resizeIfNeeded=True)
Use this method to extend or reduce the last dimension of an array.
virtual ~Array()
Frees up storage only if this array was the last reference to it.
size_t nels_p
Number of elements in the array.
Definition: ArrayBase.h:264
void makeSteps()
Fill the steps and the end for a derived class.
Definition: Array.h:920
static bool init_anyway()
Definition: Block.h:708
const value_type * pointer
Definition: Array.h:785
virtual void * getVStorage(Bool &deleteIt)
The following functions behave the same as the corresponding getStorage functions in the derived temp...
See the function begin() and end() for a detailed description of the STL iterator capability...
Definition: Array.h:691
A 2-D Specialization of the Array class.
T * contiter
Definition: Array.h:851
iterator begin()
Get the begin iterator object for any array.
Definition: Array.h:856
TableExprNode marray(const TableExprNode &array, const TableExprNode &mask)
Form a masked array.
Definition: ExprNode.h:1892
value_type & reference
Definition: Array.h:748
const T * pos() const
Definition: Array.h:819
virtual void assign(const Array< T > &other)
Assign the other array to this array.
Array< T > copy(ArrayInitPolicy policy=ArrayInitPolicies::NO_INIT) const
This makes a copy of the array and returns it.
void copyMatchingPart(const Array< T > &from)
This function copies the matching part of from array to this array.
contiter cbegin()
Get the begin iterator object for a contiguous array.
Definition: Array.h:868
A global enum used by some Array/Block constructors.
Definition: Allocator.h:54
Iterate an Array cursor through another Array.
Definition: Array.h:51
virtual CountedPtr< ArrayPositionIterator > makeIterator(uInt byDim) const
Create an ArrayIterator object of the correct type.
virtual void reference(const Array< T > &other)
After invocation, this array and other reference the same storage.
IPosition length_p
Used to hold the shape, increment into the underlying storage and originalLength of the array...
Definition: ArrayBase.h:271
contiter cend()
Definition: Array.h:872
Bool conform(const Array< T > &other) const
Are the shapes identical?
Definition: Array.h:589
virtual void doNonDegenerate(const Array< T > &other, const IPosition &ignoreAxes)
Remove the degenerate axes from the Array object.
friend ostream & operator<<(ostream &os, const BaseIteratorSTL &iter)
Definition: Array.h:724
T * data()
Get a pointer to the beginning of the array.
Definition: Array.h:597
Class for masking an Array for operations on that Array.
T * getStorage(Bool &deleteIt)
Generally use of this should be shunned, except to use a FORTRAN routine or something similar...
virtual void resize()
Make this array a different shape.
bool operator!=(const BaseIteratorSTL &other) const
Definition: Array.h:718
virtual CountedPtr< ArrayBase > getSection(const Slicer &) const
Get a reference to a section of an array.
Array< T > operator[](size_t i) const
Get the subset given by the i-th value of the last axis.
void increment()
Increment iterator for a non-contiguous array.
Referenced counted pointer for constant data.
Definition: VisModelData.h:42
T value_type
Define the STL-style iterator functions (only forward iterator).
Definition: Array.h:848
uInt ndim() const
The dimensionality of this array.
Definition: ArrayBase.h:94
bool operator==(const BaseIteratorSTL &other) const
Definition: Array.h:715
const Array< T > * itsArray
Definition: Array.h:737
virtual Array< T > & operator=(const Array< T > &other)
Copy the values in other to this.
std::forward_iterator_tag iterator_category
Definition: Array.h:789
BaseIteratorSTL(const Array< T > &)
Create the begin const_iterator object for an Array.
void nonDegenerate(const Array< T > &other, const IPosition &ignoreAxes)
Definition: Array.h:469
Array()
Result has dimensionality of zero, and nelements is zero.
IteratorSTL operator++(int)
Definition: Array.h:766
T * end_p
The end for an STL-style iteration.
Definition: Array.h:916
T & operator()(const IPosition &)
Access a single element of the array.
ConstIteratorSTL(const Array< T > &arr)
Create the begin const_iterator object for an Array.
Definition: Array.h:792
const_contiter cend() const
Definition: Array.h:874
vector< T > tovector() const
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
const IteratorSTL & operator++()
Definition: Array.h:761
void removeDegenerate(uInt startingAxis=0, Bool throwIfError=True)
Remove degenerate axes from this Array object.
static constexpr ArrayInitPolicy INIT
Initialize all elements in the array with the default value.
Definition: Allocator.h:72
T * begin_p
This pointer is adjusted to point to the first element of the array.
Definition: Array.h:913
const T * const_contiter
Definition: Array.h:852
void apply(T(*function)(T))
Apply the function to every element of the array.
void setEndIter()
Set the end iterator.
Definition: Array.h:924
const Bool False
Definition: aipstype.h:44
std::forward_iterator_tag iterator_category
Definition: Array.h:751
virtual void postTakeStorage()
Definition: Array.h:895
template &lt;class T, class U&gt; class vector;
Definition: MSFlagger.h:37
void baseMakeSteps()
Make the indexing step sizes.
Specify which elements to extract from an n-dimensional array.
Definition: Slicer.h:289
Bool conform2(const ArrayBase &other) const
Are the shapes identical?
Definition: ArrayBase.h:239
void throwIfError(int errorCode, const casacore::String &prefix, const casacore::String &file, int line, const casacore::String &func=casacore::String())
bool reformOrResize(const IPosition &newShape, uInt resizePercentage=0, Bool resizeIfNeeded=True)
Having an array that can be reused without requiring reallocation can be useful for large arrays...
void set(const T &value)
Set every element of the array to &quot;value.&quot; Also could use the assignment operator which assigns an ar...
Array< T > reform(const IPosition &shape) const
It is occasionally useful to have an array which access the same storage appear to have a different s...
const T & operator*() const
Definition: Array.h:814
iterator end()
Definition: Array.h:860
virtual void takeStorage(const IPosition &shape, T *storage, StorageInitPolicy policy=COPY)
Replace the data values with those in the pointer storage.
CountedPtr< Block< T > > data_p
Reference counted block that contains the storage.
Definition: Array.h:907
virtual CountedPtr< ArrayBase > makeArray() const
Make an empty array of the same template type.
String: the storage and methods of handling collections of characters.
Definition: String.h:223
const ConstIteratorSTL & operator++()
Definition: Array.h:802
const Array< T > addDegenerate(uInt numAxes) const
This member function returns an Array reference with the specified number of extra axes...
COPY is used when an internal copy of the storage is to be made.
Definition: ArrayBase.h:56
StorageInitPolicy
A global enum used by some Array constructors.
Definition: ArrayBase.h:53
void unique()
This ensures that this array does not reference any other storage.
uInt nrefs() const
The number of references the underlying storage has assigned to it.
void freeStorage(const T *&storage, Bool deleteIt) const
If deleteIt is set, delete &quot;storage&quot;.
const Bool True
Definition: aipstype.h:43
const T * data() const
Definition: Array.h:599
void freeVStorage(const void *&storage, Bool deleteIt) const
value_type * pointer
Definition: Array.h:747
const T * getStorage(Bool &deleteIt) const
Definition: Array.h:625
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.
unsigned int uInt
Definition: aipstype.h:51
size_t capacity() const
Returns the number of elements allocated.
const IPosition & shape() const
The length of each axis.
Definition: ArrayBase.h:121
ConstIteratorSTL const_iterator
Definition: Array.h:850
IteratorSTL iterator
Definition: Array.h:849
#define casacore
&lt;X11/Intrinsic.h&gt; #defines true, false, casacore::Bool, and String.
Definition: X11Intrinsic.h:42
IteratorSTL(const T *end=0)
Create the end iterator object for an Array.
Definition: Array.h:758
virtual void putVStorage(void *&storage, Bool deleteAndCopy)