casa
$Rev:20696$
|
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