casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
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 21130 2011-10-18 07:39:05Z gervandiepen $
00027 
00028 #ifndef CASA_ARRAYBASE_H
00029 #define CASA_ARRAYBASE_H
00030 
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <casa/Arrays/IPosition.h>
00035 
00036 namespace casa { //# NAMESPACE CASA - BEGIN
00037 
00038 //# Forward declarations.
00039 class ArrayPositionIterator;
00040 class Slicer;
00041 
00042 
00043 // <summary>
00044 // A global enum used by some Array constructors.
00045 // </summary>
00046 // <synopsis>
00047 // StorageInitPolicy is used in functions where an array is formed from
00048 // a shape and an ordinary pointer. This enum should be in Array but that
00049 // causes gcc to be unhappy.
00050 // </synopsis>
00051 enum StorageInitPolicy {
00052   // COPY is used when an internal copy of the storage is to be made.
00053   // The array is NOT responsible for deleting the external storage.
00054   COPY,
00055   // TAKE_OVER is used to indicate that the Array should just use the
00056   // external storage (i.e., no copy is made). The Array class is now
00057   // responsible for deleting the storage (hence it must have come from
00058   // a call to new[]).
00059   TAKE_OVER,
00060   // Share means that the Array will just use the pointer (no copy), however
00061   // the Array will NOT delete it upon destruction.
00062   SHARE};
00063 
00064 
00065 // <summary>
00066 // Non-templated base class for templated Array class.
00067 // </summary>
00068 
00069 // ArrayBase is only used to factor out common code from the templated
00070 // Array class.
00071 
00072 class ArrayBase
00073 {
00074 public:
00075   ArrayBase();
00076 
00077   // Create an array of the given shape, i.e. after construction
00078   // array.ndim() == shape.nelements() and array.shape() == shape.
00079   // The origin of the Array is zero.
00080   explicit ArrayBase (const IPosition& shape);
00081 
00082   // Copy constructor.
00083   ArrayBase (const ArrayBase& other);
00084 
00085   // Assignment.
00086   ArrayBase& operator= (const ArrayBase&);
00087 
00088   // Destructor.
00089   virtual ~ArrayBase();
00090 
00091   // The dimensionality of this array.
00092   uInt ndim() const
00093     { return ndimen_p; }
00094 
00095   // How many elements does this array have? Product of all axis lengths.
00096   // <group>
00097   size_t nelements() const
00098     { return nels_p; }
00099   size_t size() const
00100     { return nels_p; }
00101   // </group>
00102 
00103   // Is the array empty (i.e. no elements)?
00104   Bool empty() const
00105     { return nels_p == 0; }
00106 
00107   // Are the array data contiguous?
00108   // If they are not contiguous, <src>getStorage</src> (see below)
00109   // needs to make a copy.
00110   Bool contiguousStorage() const
00111     { return contiguous_p; }
00112 
00113   // Check to see if the Array is consistent. This is about the same thing
00114   // as checking for invariants. If AIPS_DEBUG is defined, this is invoked
00115   // after construction and on entry to most member functions.
00116   virtual Bool ok() const;
00117 
00118   // The length of each axis.
00119   const IPosition& shape() const
00120     { return length_p; }
00121 
00122   // A convenience function: endPosition(i) = shape(i) - 1; i.e. this
00123   // is the IPosition of the last element of the Array.
00124   IPosition endPosition() const;
00125 
00126   // Return steps to be made if stepping one element in a dimension.
00127   // This is the 'physical' step, thus it also works correctly for
00128   // non-contiguous arrays. E.g. <src>data() + steps(0)</src> gives
00129   // the second element of the first axis.
00130   const IPosition& steps() const
00131     { return steps_p; }
00132 
00133   // Array version for major change (used by ArrayIO).
00134   // enum did not work properly with cfront 3.0.1), so replaced
00135   // by a static inline function. Users won't normally use this.
00136   static uInt arrayVersion()
00137     {return 3;}
00138 
00139   // Create an ArrayIterator object of the correct type.
00140   // This is implemented in the derived Array classes.
00141   // <br>ArrayBase throws an exception.
00142   virtual ArrayPositionIterator* makeIterator (uInt byDim);
00143 
00144   // Get a reference to a section of an array.
00145   // This is the same as Array<T>::operator(), but without having to know
00146   // the exact template type.
00147   // <br>ArrayBase throws an exception.
00148   virtual ArrayBase* getSection (const Slicer&);
00149 
00150 protected:
00151   void baseCopy (const ArrayBase& that)
00152     { operator= (that); }
00153 
00154   // Determine if the storage of a subset is contiguous.
00155   Bool isStorageContiguous() const;
00156 
00157   // Check if the shape of a vector is correct. If possible, adjust if not.
00158   // It is possible if at most one axis has length > 1.
00159   void checkVectorShape();
00160 
00161   // Check if the shape of a matrix is correct. Adjust it if smaller.
00162   void checkMatrixShape();
00163 
00164   // Check if the shape of a cube is correct. Adjust it if smaller.
00165   void checkCubeShape();
00166 
00167   // Reform the array to a shape with the same nr of elements.
00168   void baseReform (ArrayBase& tmp, const IPosition& shape) const;
00169 
00170   // Remove the degenerate axes from the Array object.
00171   // This is the implementation of the nonDegenerate functions.
00172   // It has a different name to be able to make it virtual without having
00173   // the "hide virtual function" message when compiling derived classes.
00174   void baseNonDegenerate (const ArrayBase& other, const IPosition& ignoreAxes);
00175     
00176   // These member functions return an Array reference with the specified
00177   // number of extra axes, all of length one, appended to the end of the
00178   // Array. Note that the <src>reform</src> function can also be
00179   // used to add extra axes.
00180   void baseAddDegenerate (ArrayBase&, uInt numAxes);
00181 
00182   // Make a subset of an array.
00183   // It checks if start,end,incr are within the array limits.
00184   // It returns the offset of the subset in the array.
00185   size_t makeSubset (ArrayBase& out,
00186                      const IPosition& b,
00187                      const IPosition& e,
00188                      const IPosition& i);
00189 
00190   // Are the shapes identical?
00191   Bool conform2 (const ArrayBase& other) const
00192     { return length_p.isEqual (other.length_p); }
00193 
00194   // Make the indexing step sizes.
00195   void baseMakeSteps();
00196 
00197   // Throw expection if vector dimensionality is incorrect.
00198   void throwNdimVector();
00199 
00200   // Helper function for templated Vector class.
00201   // It returns if this and other are conformant.
00202   Bool copyVectorHelper (const ArrayBase& other);
00203 
00204 public:
00205   // Various helper functions.
00206   // <group>
00207   void validateConformance (const ArrayBase&) const;
00208   void validateIndex (const IPosition&) const;
00209   void validateIndex (uInt index) const;
00210   void validateIndex (uInt index1, uInt index2) const;
00211   void validateIndex (uInt index1, uInt index2, uInt index3) const;
00212   // </group>
00213 
00214 protected:
00215   // Number of elements in the array. Cached rather than computed.
00216   size_t nels_p;
00217   // Dimensionality of the array.
00218   uInt ndimen_p;
00219   // Are the data contiguous?
00220   Bool contiguous_p;
00221   // Used to hold the shape, increment into the underlying storage
00222   // and originalLength of the array.
00223   IPosition length_p, inc_p, originalLength_p;
00224   // Used to hold the step to next element in each dimension.
00225   IPosition steps_p;
00226 };
00227 
00228 
00229 // <summary> General global functions for Arrays. </summary>
00230 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tArray">
00231 //
00232 // <prerequisite>
00233 //   <li> <linkto class=Array>Array</linkto>
00234 // </prerequisite>
00235 //
00236 // <synopsis>
00237 // These are generally useful global functions which operate on all
00238 // Arrays.
00239 // </synopsis>
00240 //
00241 // <linkfrom anchor="Array general global functions" classes="Array Vector Matrix Cube">
00242 //   <here>Array general global functions</here> -- General global functions
00243 //   for Arrays.
00244 // </linkfrom>
00245 //
00246 // <group name="Array general global functions">
00247 
00248 // 
00249 // What is the volume of an N-dimensional array. 
00250 // Shape[0]*Shape[1]*...*Shape[N-1]. An Array helper function.
00251 //# Implemented in Array2.cc.
00252 size_t ArrayVolume (uInt Ndim, const Int* Shape);
00253 
00254 // 
00255 // What is the linear index into an "Ndim" dimensional array of the given
00256 // "Shape", "Origin", and "Increment" for a given IPosition Index.
00257 //  An Array helper function.
00258 // <group>
00259 //# Implemented in Array2.cc.
00260 size_t ArrayIndexOffset (uInt Ndim, const ssize_t* Shape, 
00261                          const ssize_t* Origin, const ssize_t* Inc, 
00262                          const IPosition& Index);
00263 size_t ArrayIndexOffset (uInt Ndim, const ssize_t* Shape, 
00264                          const ssize_t* Inc, const IPosition& Index);
00265 // </group>
00266 
00267 // </group>
00268 
00269 } //# NAMESPACE CASA - END
00270 
00271 #endif