00001 //# Vector.h: A 1-D Specialization of the Array Class 00002 //# Copyright (C) 1993,1994,1995,1996,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$ 00027 00028 #ifndef CASA_VECTOR_H 00029 #define CASA_VECTOR_H 00030 00031 //# Includes 00032 #include <casa/Arrays/Array.h> 00033 00034 //# Forward declarations 00035 //template <class T, class U> class vector; 00036 #if defined(WHATEVER_VECTOR_FORWARD_DEC) 00037 WHATEVER_VECTOR_FORWARD_DEC; 00038 #else 00039 #include <casa/stdvector.h> 00040 #endif 00041 00042 using std::vector; 00043 00044 namespace casa { //#Begin namespace casa 00045 00046 // <summary> A 1-D Specialization of the Array class </summary> 00047 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos=""> 00048 // </reviewed> 00049 // 00050 // Vector objects are one-dimensional specializations (e.g., more convenient 00051 // and efficient indexing) of the general Array class. You might also want 00052 // to look at the Array documentation to see inherited functionality. A 00053 // tutorial on using the array classes in general is available in the 00054 // "AIPS++ Programming Manual". 00055 // 00056 // Generally the member functions of Array are also available in 00057 // Vector versions 00058 // which take an integer where the array needs an IPosition. Since the Vector 00059 // is one-dimensional, the IPositions are overkill, although you may 00060 // use those versions if you want to. 00061 // <srcblock> 00062 // Vector<Int> vi(100); // Vector 100 elements long. 00063 // vi.resize(50); // Now only 50 long. 00064 // </srcblock> 00065 // 00066 // Slices may be taken with the Slice class. To take a slice, one "indexes" 00067 // with Slice(start, length, inc) where end and inc are optional. 00068 // <srcblock> 00069 // Vector<Float> vf(100); 00070 // //... 00071 // vf(Slice(0,50,2)) = vf(Slice(1,50,2)); // Copy values from odd onto even 00072 // Vector<Float> firstHalf, secondHalf; 00073 // firstHalf.reference(vf(Slice(0,50))); 00074 // secondHalf.reference(vf(Slice(50,50))); 00075 // // Now we have aliases for two slices into the Vector 00076 // </srcblock> 00077 // 00078 // Element-by-element arithmetic and logical operations are available (in 00079 // aips/ArrayMath.h and aips/ArrayLogical.h) as well as dot and cross 00080 // products (in aips/MatrixMath.h). 00081 // 00082 // A Vector can be constructed from an STL <src>vector</src>. The reverse 00083 // operation (<src>Array::tovector()</src>) can construct an STL 00084 // <src>vector</src> from any Array. 00085 // <note role=tip> To create any other STL container from an Array (or 00086 // the reverse), always create from/to a <src>vector</src>, and use the 00087 // range constructor to create from/to others (like set, list, deque). </note> 00088 // 00089 // As with the Arrays, if the preprocessor symbol AIPS_DEBUG is 00090 // defined at compile time invariants will be checked on entry to most 00091 // member functions. Additionally, if AIPS_ARRAY_INDEX_CHECK is defined 00092 // index operations will be bounds-checked. Neither of these should 00093 // be defined for production code. 00094 00095 template<class T> class Vector : public Array<T> 00096 { 00097 public: 00098 // A zero-length Vector. 00099 Vector(); 00100 00101 // A Vector with a defined length and origin of zero. 00102 // <group> 00103 explicit Vector(uInt Length); 00104 explicit Vector(const IPosition& Length); 00105 // </group> 00106 00107 // A Vector with a defined length and origin of zero. 00108 // Fill it with the initial value. 00109 // <group> 00110 Vector(uInt Length, const T &initialValue); 00111 Vector(const IPosition& Length, const T &initialValue); 00112 // </group> 00113 00114 // Create a Vector from the given Block "other." Make it length "nr" 00115 // and copy over that many elements. 00116 Vector(const Block<T> &other, Int nr); 00117 // Create a Vector of lenght other.nelements() and copy over its values. 00118 explicit Vector(const Block<T> &other); 00119 00120 // Create a reference to other. 00121 Vector(const Vector<T> &other); 00122 00123 // Create a reference to the other array. 00124 // It is always possible if the array has zero or one axes. 00125 // If it has > 1 axes, it is only possible if the array has at most 00126 // one axis with length > 1. In that case the degenerated axes are removed. 00127 Vector(const Array<T> &other); 00128 00129 // Create an Vector of a given shape from a pointer. 00130 Vector(const IPosition &shape, T *storage, StorageInitPolicy policy = COPY); 00131 // Create an Vector of a given shape from a pointer. Because the pointer 00132 // is const, a copy is always made. 00133 Vector(const IPosition &shape, const T *storage); 00134 00135 // Create a Vector from an STL vector (see <src>tovector()</src> in 00136 // <linkto class=Array>Array</linkto> for the reverse operation). 00137 // <note role=tip> Both this constructor and the tovector() are 00138 // defined in <src>Vector2.cc</src>. In case of DIY template instantiation 00139 // the appropriate templates are instantiated using the macro 00140 // <src>AIPS_VECTOR2_AUX_TEMPLATES(X)</src> 00141 // defined in <src>Vector2.cc</src> (<src>X</src> is the template 00142 // argument needed). </note> 00143 template <class U> 00144 Vector(const vector<T, U> &other); 00145 00146 // Define a destructor, otherwise the compiler makes a static one. 00147 virtual ~Vector(); 00148 00149 // Assign the other array (which must be of dimension one) to this vector. 00150 // If the shapes mismatch, this array is resized. 00151 virtual void assign (const Array<T>& other); 00152 00153 // Create a reference to "other", which must be of dimension one. 00154 virtual void reference(const Array<T> &other); 00155 00156 // Resize this Vector to the given length. 00157 // The default copyValues flag is False. 00158 //# Note that the 3rd resize function is necessary, because that 00159 //# function is virtual in the base class (otherwise it would 00160 //# be hidden). 00161 // Resize without argument is equal to resize(0, False). 00162 // <group> 00163 void resize(uInt len, Bool copyValues=False) 00164 { if (len != this->nelements()) resize (IPosition(1,len), copyValues); } 00165 virtual void resize(const IPosition &len, Bool copyValues=False); 00166 virtual void resize(); 00167 // </group> 00168 00169 // Assign to this Vector. If this Vector is zero-length, then resize 00170 // to be the same size as other. Otherwise this and other have to be 00171 // conformant (same size). 00172 // <br>Note that the assign function can be used to assign a 00173 // non-conforming vector. 00174 // <group> 00175 Vector<T> &operator=(const Vector<T> &other); 00176 // Other must be a 1-dimensional array. 00177 virtual Array<T> &operator=(const Array<T> &other); 00178 // </group> 00179 00180 // Set every element of this Vector to Val. 00181 Array<T> &operator=(const T &val) 00182 { return Array<T>::operator=(val); } 00183 00184 // Copy to this those values in marray whose corresponding elements 00185 // in marray's mask are True. 00186 Vector<T> &operator= (const MaskedArray<T> &marray) 00187 { Array<T> (*this) = marray; return *this; } 00188 00189 // Convert a Vector to a Block, resizing the block and copying values. 00190 // This is done this way to avoid having the simpler Block class 00191 // containing dependencies on the Vector class. 00192 void toBlock(Block<T> &other) const; 00193 00194 // Single-pixel addressing. If AIPS_ARRAY_INDEX_CHECK is defined, 00195 // bounds checking is performed (not for []).. 00196 // <group> 00197 T &operator[](uInt index) 00198 { return (this->contiguous_p ? this->begin_p[index] : this->begin_p[index*this->inc_p(0)]); } 00199 const T &operator[](uInt index) const 00200 { return (this->contiguous_p ? this->begin_p[index] : this->begin_p[index*this->inc_p(0)]); } 00201 T &operator()(const IPosition &i) 00202 { return Array<T>::operator()(i); } 00203 const T &operator()(const IPosition &i) const 00204 { return Array<T>::operator()(i); } 00205 T &operator()(uInt index) 00206 { 00207 #if defined(AIPS_ARRAY_INDEX_CHECK) 00208 //# It would be better performance wise for this to be static, but 00209 //# CFront 3.0.1 doesn't like that. 00210 IPosition IndexCopy(1); 00211 IndexCopy(0) = index; 00212 this->validateIndex(IndexCopy); //# Throws an exception on failure 00213 #endif 00214 return *(this->begin_p + index*this->inc_p(0)); 00215 } 00216 00217 const T &operator()(uInt index) const 00218 { 00219 #if defined(AIPS_ARRAY_INDEX_CHECK) 00220 //# It would be better performance wise for this to be static, but 00221 //# CFront 3.0.1 doesn't like that. 00222 IPosition IndexCopy(1); 00223 IndexCopy(0) = index; 00224 this->validateIndex(IndexCopy); //# Throws an exception on failure 00225 #endif 00226 return *(this->begin_p + index*this->inc_p(0)); 00227 } 00228 // </group> 00229 00230 // Take a slice of this vector. Slices are always indexed starting 00231 // at zero. This uses reference semantics, i.e. changing a value 00232 // in the slice changes the original. 00233 // <srcblock> 00234 // Vector<Double> vd(100); 00235 // //... 00236 // vd(Slice(0,10)) = -1.0; // First 10 elements of vd set to -1 00237 // </srcblock> 00238 Vector<T> operator()(const Slice &slice); 00239 00240 // Slice using IPositions. Required to be defined, otherwise the base 00241 // class versions are hidden. 00242 // <group> 00243 Array<T> operator()(const IPosition &blc, const IPosition &trc, 00244 const IPosition &incr) 00245 { return Array<T>::operator()(blc,trc,incr); } 00246 Array<T> operator()(const IPosition &blc, const IPosition &trc) 00247 { return Array<T>::operator()(blc,trc); } 00248 Array<T> operator()(const Slicer& slicer) 00249 { return Array<T>::operator()(slicer); } 00250 // </group> 00251 00252 // The array is masked by the input LogicalArray. 00253 // This mask must conform to the array. 00254 // <group> 00255 00256 // Return a MaskedArray. 00257 MaskedArray<T> operator() (const LogicalArray &mask) const 00258 { return Array<T>::operator() (mask); } 00259 00260 // Return a MaskedArray. 00261 MaskedArray<T> operator() (const LogicalArray &mask) 00262 { return Array<T>::operator() (mask); } 00263 00264 // </group> 00265 00266 00267 // The array is masked by the input MaskedLogicalArray. 00268 // The mask is effectively the AND of the internal LogicalArray 00269 // and the internal mask of the MaskedLogicalArray. 00270 // The MaskedLogicalArray must conform to the array. 00271 // <group> 00272 00273 // Return a MaskedArray. 00274 MaskedArray<T> operator() (const MaskedLogicalArray &mask) const 00275 { return Array<T>::operator() (mask); } 00276 00277 // Return a MaskedArray. 00278 MaskedArray<T> operator() (const MaskedLogicalArray &mask) 00279 { return Array<T>::operator() (mask); } 00280 00281 // </group> 00282 00283 00284 // The length of the Vector. 00285 // <group> 00286 void shape(Int &Shape) const 00287 { Shape = this->length_p(0); } 00288 const IPosition &shape() const 00289 { return this->length_p; } 00290 // </group> 00291 00292 // Replace the data values with those in the pointer <src>storage</src>. 00293 // The results are undefined is storage does not point at nelements() or 00294 // more data elements. After takeStorage() is called, <src>unique()</src> 00295 // is True. 00296 // <group> 00297 virtual void takeStorage(const IPosition &shape, T *storage, 00298 StorageInitPolicy policy = COPY); 00299 // Since the pointer is const, a copy is always taken. 00300 virtual void takeStorage(const IPosition &shape, const T *storage); 00301 // </group> 00302 00303 // Verify that dimensionality is 1 and then call Array<T>::ok() 00304 virtual Bool ok() const; 00305 00306 protected: 00307 // Remove the degenerate axes from other and store result in this vector. 00308 // An exception is thrown if removing degenerate axes does not result 00309 // in a vector. 00310 virtual void doNonDegenerate(Array<T> &other, const IPosition &ignoreAxes); 00311 00312 private: 00313 // Helper functions for constructors. 00314 void initVector(const Block<T> &, Int nr); // copy semantics 00315 }; 00316 00317 } //#End namespace casa 00318 00319 #ifndef AIPS_NO_TEMPLATE_SRC 00320 #include <casa/Arrays/Vector.cc> 00321 #include <casa/Arrays/Vector2.cc> 00322 #endif //# AIPS_NO_TEMPLATE_SRC 00323 #endif
1.5.1