ArrayBase.h

Go to the documentation of this file.
00001 //# ArrayBase.h: Non-templated base class for templated Array class
00002 //# Copyright (C) 1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003
00003 //# Associated Universities, Inc. Washington DC, USA,
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: ArrayBase.h 21521 2014-12-10 08:06:42Z gervandiepen $
00027 
00028 #ifndef CASA_ARRAYBASE_H
00029 #define CASA_ARRAYBASE_H
00030 
00031 
00032 //# Includes
00033 #include <casacore/casa/aips.h>
00034 #include <casacore/casa/Arrays/IPosition.h>
00035 #include <casacore/casa/Utilities/CountedPtr.h>
00036 #include <casacore/casa/Containers/Allocator.h>
00037 
00038 namespace casacore { //# NAMESPACE CASACORE - BEGIN
00039 
00040 //# Forward declarations.
00041 class ArrayPositionIterator;
00042 class Slicer;
00043 
00044 
00045 // <summary>
00046 // A global enum used by some Array constructors.
00047 // </summary>
00048 // <synopsis>
00049 // StorageInitPolicy is used in functions where an array is formed from
00050 // a shape and an ordinary pointer. This enum should be in Array but that
00051 // causes gcc to be unhappy.
00052 // </synopsis>
00053 enum StorageInitPolicy {
00054   // COPY is used when an internal copy of the storage is to be made.
00055   // The array is NOT responsible for deleting the external storage.
00056   COPY,
00057   // TAKE_OVER is used to indicate that the Array should just use the
00058   // external storage (i.e., no copy is made). The Array class is now
00059   // responsible for deleting the storage (hence it must have come from
00060   // a call to new[]).
00061   TAKE_OVER,
00062   // Share means that the Array will just use the pointer (no copy), however
00063   // the Array will NOT delete it upon destruction.
00064   SHARE};
00065 
00066 
00067 // <summary>
00068 // Non-templated base class for templated Array class.
00069 // </summary>
00070 
00071 // ArrayBase is only used to factor out common code from the templated
00072 // Array class.
00073 
00074 class ArrayBase
00075 {
00076 public:
00077   ArrayBase();
00078 
00079   // Create an array of the given shape, i.e. after construction
00080   // array.ndim() == shape.nelements() and array.shape() == shape.
00081   // The origin of the Array is zero.
00082   explicit ArrayBase (const IPosition& shape);
00083 
00084   // Copy constructor.
00085   ArrayBase (const ArrayBase& other);
00086 
00087   // Assignment.
00088   ArrayBase& operator= (const ArrayBase&);
00089 
00090   // Destructor.
00091   virtual ~ArrayBase();
00092 
00093   // The dimensionality of this array.
00094   uInt ndim() const
00095     { return ndimen_p; }
00096 
00097   // How many elements does this array have? Product of all axis lengths.
00098   // <group>
00099   size_t nelements() const
00100     { return nels_p; }
00101   size_t size() const
00102     { return nels_p; }
00103   // </group>
00104 
00105   // Is the array empty (i.e. no elements)?
00106   Bool empty() const
00107     { return nels_p == 0; }
00108 
00109   // Are the array data contiguous?
00110   // If they are not contiguous, <src>getStorage</src> (see below)
00111   // needs to make a copy.
00112   Bool contiguousStorage() const
00113     { return contiguous_p; }
00114 
00115   // Check to see if the Array is consistent. This is about the same thing
00116   // as checking for invariants. If AIPS_DEBUG is defined, this is invoked
00117   // after construction and on entry to most member functions.
00118   virtual Bool ok() const;
00119 
00120   // The length of each axis.
00121   const IPosition& shape() const
00122     { return length_p; }
00123 
00124   // A convenience function: endPosition(i) = shape(i) - 1; i.e. this
00125   // is the IPosition of the last element of the Array.
00126   IPosition endPosition() const;
00127 
00128   // Return steps to be made if stepping one element in a dimension.
00129   // This is the 'physical' step, thus it also works correctly for
00130   // non-contiguous arrays. E.g. <src>data() + steps(0)</src> gives
00131   // the second element of the first axis.
00132   const IPosition& steps() const
00133     { return steps_p; }
00134 
00135   // Array version for major change (used by ArrayIO).
00136   // enum did not work properly with cfront 3.0.1), so replaced
00137   // by a static inline function. Users won't normally use this.
00138   static uInt arrayVersion()
00139     {return 3;}
00140 
00141   // Make an empty array of the same type.
00142   // <br>The default implementation in ArrayBase throws an exception.
00143   virtual CountedPtr<ArrayBase> makeArray() const;
00144 
00145   // Resize the array and optionally copy the values.
00146   // <br>The default implementation in ArrayBase throws an exception.
00147   virtual void resize(const IPosition &newShape, Bool copyValues=False);
00148 
00149   // Resize the array and optionally copy the values.
00150   // <br>The default implementation in ArrayBase throws an exception.
00151   virtual void resize(const IPosition &newShape, Bool copyValues, ArrayInitPolicy policy);
00152 
00153   // Create an ArrayIterator object of the correct type.
00154   // This is implemented in the derived Array classes.
00155   // <br>The default implementation in ArrayBase throws an exception.
00156   virtual CountedPtr<ArrayPositionIterator> makeIterator (uInt byDim) const;
00157 
00158   // Get a reference to a section of an array.
00159   // This is the same as Array<T>::operator(), but without having to know
00160   // the exact template type.
00161   // <br>The default implementation in ArrayBase throws an exception.
00162   virtual CountedPtr<ArrayBase> getSection (const Slicer&) const;
00163 
00164   // Assign the source array to this array.
00165   // If <src>checkType==True</src>, it is checked if the underlying template
00166   // types match. Otherwise, it is only checked in debug mode (for performance).
00167   // <br>The default implementation in ArrayBase throws an exception.
00168   virtual void assignBase (const ArrayBase& source, Bool checkType=True);
00169 
00170   // The following functions behave the same as the corresponding getStorage
00171   // functions in the derived templated Array class.
00172   // They handle a pointer to a contiguous block of array data.
00173   // If the array is not contiguous, a copy is used to make it contiguous.
00174   // <group>
00175   virtual void* getVStorage (Bool& deleteIt);
00176   virtual const void* getVStorage (Bool& deleteIt) const;
00177   virtual void putVStorage(void*& storage, Bool deleteAndCopy);
00178   virtual void freeVStorage(const void*& storage, Bool deleteIt) const;
00179   // <group>
00180 
00181 protected:
00182   void baseCopy (const ArrayBase& that)
00183     { operator= (that); }
00184 
00185   // Either reforms the array if size permits or resizes it to the new shape.
00186   // Implementation of Array<T>::reformOrResize (slightly different signature).
00187 
00188   Bool reformOrResize (const IPosition & newShape,
00189                        Bool resizeIfNeeded,
00190                        uInt nReferences,
00191                        Int64 nElementsAllocated,
00192                        Bool copyDataIfNeeded,
00193                        uInt resizePercentage);
00194 
00195   // Determine if the storage of a subset is contiguous.
00196   Bool isStorageContiguous() const;
00197 
00198   // Check if the shape of a vector is correct. If possible, adjust if not.
00199   // It is possible if at most one axis has length > 1.
00200   void checkVectorShape();
00201 
00202   // Check if the shape of a matrix is correct. Adjust it if smaller.
00203   void checkMatrixShape();
00204 
00205   // Check if the shape of a cube is correct. Adjust it if smaller.
00206   void checkCubeShape();
00207 
00208   // Reform the array to a shape with the same nr of elements.  If nonStrict then
00209   // caller assumes responsibility for not overrunning storage (avoid or use with extreme care).
00210   void baseReform (ArrayBase& tmp, const IPosition& shape, Bool strict=True) const;
00211 
00212   // Remove the degenerate axes from the Array object.
00213   // This is the implementation of the nonDegenerate functions.
00214   // It has a different name to be able to make it virtual without having
00215   // the "hide virtual function" message when compiling derived classes.
00216   void baseNonDegenerate (const ArrayBase& other, const IPosition& ignoreAxes);
00217     
00218   // These member functions return an Array reference with the specified
00219   // number of extra axes, all of length one, appended to the end of the
00220   // Array. Note that the <src>reform</src> function can also be
00221   // used to add extra axes.
00222   void baseAddDegenerate (ArrayBase&, uInt numAxes);
00223 
00224   // Make a subset of an array.
00225   // It checks if start,end,incr are within the array limits.
00226   // It returns the offset of the subset in the (original) array.
00227   size_t makeSubset (ArrayBase& out,
00228                      const IPosition& b,
00229                      const IPosition& e,
00230                      const IPosition& i);
00231 
00232   // Set the length and stride such that the diagonal of the matrices
00233   // defined by two consecutive axes is formed.
00234   // <src>diag</src> == 0 indicates the main diagonal, >0 above, <0 below.
00235   // It returns the offset of the diagonal in the (original) array.
00236   size_t makeDiagonal (uInt firstAxis, Int64 diag);
00237 
00238   // Are the shapes identical?
00239   Bool conform2 (const ArrayBase& other) const
00240     { return length_p.isEqual (other.length_p); }
00241 
00242   // Make the indexing step sizes.
00243   void baseMakeSteps();
00244 
00245   // Throw expection if vector dimensionality is incorrect.
00246   void throwNdimVector();
00247 
00248   // Helper function for templated Vector class.
00249   // It returns if this and other are conformant.
00250   Bool copyVectorHelper (const ArrayBase& other);
00251 
00252 public:
00253   // Various helper functions.
00254   // <group>
00255   void validateConformance (const ArrayBase&) const;
00256   void validateIndex (const IPosition&) const;
00257   void validateIndex (uInt index) const;
00258   void validateIndex (uInt index1, uInt index2) const;
00259   void validateIndex (uInt index1, uInt index2, uInt index3) const;
00260   // </group>
00261 
00262 protected:
00263   // Number of elements in the array. Cached rather than computed.
00264   size_t nels_p;
00265   // Dimensionality of the array.
00266   uInt ndimen_p;
00267   // Are the data contiguous?
00268   Bool contiguous_p;
00269   // Used to hold the shape, increment into the underlying storage
00270   // and originalLength of the array.
00271   IPosition length_p, inc_p, originalLength_p;
00272   // Used to hold the step to next element in each dimension.
00273   IPosition steps_p;
00274 };
00275 
00276 
00277 // <summary> General global functions for Arrays. </summary>
00278 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tArray">
00279 //
00280 // <prerequisite>
00281 //   <li> <linkto class=Array>Array</linkto>
00282 // </prerequisite>
00283 //
00284 // <synopsis>
00285 // These are generally useful global functions which operate on all
00286 // Arrays.
00287 // </synopsis>
00288 //
00289 // <linkfrom anchor="Array general global functions" classes="Array Vector Matrix Cube">
00290 //   <here>Array general global functions</here> -- General global functions
00291 //   for Arrays.
00292 // </linkfrom>
00293 //
00294 // <group name="Array general global functions">
00295 
00296 // 
00297 // What is the volume of an N-dimensional array. 
00298 // Shape[0]*Shape[1]*...*Shape[N-1]. An Array helper function.
00299 //# Implemented in Array2.cc.
00300 size_t ArrayVolume (uInt Ndim, const Int* Shape);
00301 
00302 // 
00303 // What is the linear index into an "Ndim" dimensional array of the given
00304 // "Shape", "Origin", and "Increment" for a given IPosition Index.
00305 //  An Array helper function.
00306 // <group>
00307 //# Implemented in Array2.cc.
00308 size_t ArrayIndexOffset (uInt Ndim, const ssize_t* Shape, 
00309                          const ssize_t* Origin, const ssize_t* Inc, 
00310                          const IPosition& Index);
00311 size_t ArrayIndexOffset (uInt Ndim, const ssize_t* Shape, 
00312                          const ssize_t* Inc, const IPosition& Index);
00313 // </group>
00314 
00315 // Function to check the shapes. It throws an exception if not equal.
00316 // <group>
00317 void throwArrayShapes (const IPosition& shape1,
00318                        const IPosition& shape2,
00319                        const char* name);
00320 inline void checkArrayShapes (const ArrayBase& left, const ArrayBase& right,
00321                               const char* name)
00322 {
00323   if (! left.shape().isEqual (right.shape())) {
00324     throwArrayShapes (left.shape(), right.shape(), name);
00325   }
00326 }
00327 // </group>
00328 
00329 // </group>
00330 
00331 } //# NAMESPACE CASACORE - END
00332 
00333 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1