casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Vector.h
Go to the documentation of this file.
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: Vector.h 21130 2011-10-18 07:39:05Z gervandiepen $
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 #include <set>
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     template <class U>
00147     Vector(const std::set<U>& other);
00148 
00149     // Define a destructor, otherwise the compiler makes a static one.
00150     virtual ~Vector();
00151 
00152     // Assign the other array (which must be of dimension one) to this vector.
00153     // If the shapes mismatch, this array is resized.
00154     virtual void assign (const Array<T>& other);
00155 
00156     // Create a reference to "other", which must be of dimension one.
00157     virtual void reference(const Array<T> &other);
00158 
00159     // Resize this Vector to the given length.
00160     // The default copyValues flag is False.
00161     //# Note that the 3rd resize function is necessary, because that
00162     //# function is virtual in the base class (otherwise it would
00163     //# be hidden).
00164     // Resize without argument is equal to resize(0, False).
00165     // <group>
00166     void resize(uInt len, Bool copyValues=False)
00167       { if (len != this->nelements()) resize (IPosition(1,len), copyValues); }
00168     virtual void resize(const IPosition &len, Bool copyValues=False);
00169     virtual void resize();
00170     // </group>
00171 
00172     // Assign to this Vector. If this Vector is zero-length, then resize
00173     // to be the same size as other. Otherwise this and other have to be
00174     // conformant (same size).
00175     // <br>Note that the assign function can be used to assign a
00176     // non-conforming vector.
00177     // <group>
00178     Vector<T> &operator=(const Vector<T> &other);
00179     // Other must be a 1-dimensional array.
00180     virtual Array<T> &operator=(const Array<T> &other);
00181     // </group>
00182 
00183     // Set every element of this Vector to Val.
00184     Array<T> &operator=(const T &val)
00185       { return Array<T>::operator=(val); }
00186 
00187     // Copy to this those values in marray whose corresponding elements
00188     // in marray's mask are True.
00189     Vector<T> &operator= (const MaskedArray<T> &marray)
00190       { Array<T> (*this) = marray; return *this; }
00191 
00192     // Convert a Vector to a Block, resizing the block and copying values.
00193     // This is done this way to avoid having the simpler Block class 
00194     // containing dependencies on the Vector class.
00195     void toBlock(Block<T> &other) const;
00196 
00197     // Single-pixel addressing. If AIPS_ARRAY_INDEX_CHECK is defined,
00198     // bounds checking is performed (not for [])..
00199     // <group>
00200     T &operator[](uInt index)
00201       { return (this->contiguous_p  ?  this->begin_p[index] : this->begin_p[index*this->inc_p(0)]); }
00202     const T &operator[](uInt index) const
00203       { return (this->contiguous_p  ?  this->begin_p[index] : this->begin_p[index*this->inc_p(0)]); }
00204     T &operator()(const IPosition &i)
00205       { return Array<T>::operator()(i); }
00206     const T &operator()(const IPosition &i) const 
00207       { return Array<T>::operator()(i); }
00208     T &operator()(uInt index)
00209       {
00210 #if defined(AIPS_ARRAY_INDEX_CHECK)
00211         this->validateIndex(index);   //# Throws an exception on failure
00212 #endif
00213         return *(this->begin_p + index*this->inc_p(0));
00214       }
00215 
00216     const T &operator()(uInt index) const
00217       {
00218 #if defined(AIPS_ARRAY_INDEX_CHECK)
00219         this->validateIndex(index);   //# Throws an exception on failure
00220 #endif
00221         return *(this->begin_p + index*this->inc_p(0));
00222       }
00223     // </group>
00224 
00225     // Take a slice of this vector. Slices are always indexed starting
00226     // at zero. This uses reference semantics, i.e. changing a value
00227     // in the slice changes the original.
00228     // <srcblock>
00229     // Vector<Double> vd(100);
00230     // //...
00231     // vd(Slice(0,10)) = -1.0; // First 10 elements of vd set to -1
00232     // </srcblock>
00233     // <group>
00234     Vector<T> operator()(const Slice &slice);
00235     const Vector<T> operator()(const Slice &slice) const;
00236     // </group>
00237 
00238     // Slice using IPositions. Required to be defined, otherwise the base
00239     // class versions are hidden.
00240     // <group>
00241     Array<T> operator()(const IPosition &blc, const IPosition &trc,
00242                         const IPosition &incr)
00243       { return Array<T>::operator()(blc,trc,incr); }
00244     const Array<T> operator()(const IPosition &blc, const IPosition &trc,
00245                               const IPosition &incr) const
00246       { return Array<T>::operator()(blc,trc,incr); }
00247     Array<T> operator()(const IPosition &blc, const IPosition &trc)
00248       { return Array<T>::operator()(blc,trc); }
00249     const Array<T> operator()(const IPosition &blc, const IPosition &trc) const
00250       { return Array<T>::operator()(blc,trc); }
00251     Array<T> operator()(const Slicer& slicer)
00252       { return Array<T>::operator()(slicer); }
00253     const Array<T> operator()(const Slicer& slicer) const
00254       { return Array<T>::operator()(slicer); }
00255     // </group>
00256 
00257     // The array is masked by the input LogicalArray.
00258     // This mask must conform to the array.
00259     // <group>
00260 
00261     // Return a MaskedArray.
00262     MaskedArray<T> operator() (const LogicalArray &mask) const
00263       { return Array<T>::operator() (mask); }
00264 
00265     // Return a MaskedArray.
00266     MaskedArray<T> operator() (const LogicalArray &mask)
00267       { return Array<T>::operator() (mask); }
00268 
00269     // </group>
00270 
00271 
00272     // The array is masked by the input MaskedLogicalArray.
00273     // The mask is effectively the AND of the internal LogicalArray
00274     // and the internal mask of the MaskedLogicalArray.
00275     // The MaskedLogicalArray must conform to the array.
00276     // <group>
00277 
00278     // Return a MaskedArray.
00279     MaskedArray<T> operator() (const MaskedLogicalArray &mask) const
00280       { return Array<T>::operator() (mask); }
00281 
00282     // Return a MaskedArray.
00283     MaskedArray<T> operator() (const MaskedLogicalArray &mask)
00284       { return Array<T>::operator() (mask); }
00285 
00286     // </group>
00287 
00288 
00289     // The length of the Vector.
00290     // <group>
00291     void shape(Int &Shape) const
00292       { Shape = this->length_p(0); }
00293     const IPosition &shape() const
00294       { return this->length_p; }
00295     // </group>
00296 
00297     // Replace the data values with those in the pointer <src>storage</src>.
00298     // The results are undefined is storage does not point at nelements() or
00299     // more data elements. After takeStorage() is called, <src>unique()</src>
00300     // is True.
00301     // <group>
00302     virtual void takeStorage(const IPosition &shape, T *storage,
00303                              StorageInitPolicy policy = COPY);
00304     // Since the pointer is const, a copy is always taken.
00305     virtual void takeStorage(const IPosition &shape, const T *storage);
00306     // </group>
00307 
00308     // Verify that dimensionality is 1 and then call Array<T>::ok()
00309     virtual Bool ok() const;
00310 
00311 protected:
00312     // Remove the degenerate axes from other and store result in this vector.
00313     // An exception is thrown if removing degenerate axes does not result
00314     // in a vector.
00315     virtual void doNonDegenerate(const Array<T> &other,
00316                                  const IPosition &ignoreAxes);
00317 
00318 private:
00319     // Helper functions for constructors.
00320     void initVector(const Block<T> &, Int nr);      // copy semantics
00321 };
00322 
00323 } //#End namespace casa
00324 
00325 #ifndef CASACORE_NO_AUTO_TEMPLATES
00326 #include <casa/Arrays/Vector.tcc>
00327 #include <casa/Arrays/Vector2.tcc>
00328 #endif //# CASACORE_NO_AUTO_TEMPLATES
00329 #endif