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