casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
RigidVector.h
Go to the documentation of this file.
00001 //# RigidVector.h: Fast Vector classes with fixed (templated) length
00002 //# Copyright (C) 1996,1999,2001
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 adressed 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 //#
00027 //# $Id: RigidVector.h 21024 2011-03-01 11:46:18Z gervandiepen $
00028  
00029 #ifndef SCIMATH_RIGIDVECTOR_H
00030 #define SCIMATH_RIGIDVECTOR_H
00031   
00032 #include <casa/aips.h>
00033 #include <casa/Arrays/Vector.h>
00034 #include <casa/BasicSL/Complex.h>
00035 #include <casa/iosfwd.h>
00036 
00037 namespace casa { //# NAMESPACE CASA - BEGIN
00038 
00039 //# forward
00040 template <class T, Int n> class SquareMatrix;
00041 // <summary> Fast Vector classes with fixed (templated) length </summary>
00042  
00043 // <use visibility=export>
00044  
00045 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00046 // </reviewed>
00047  
00048 // <prerequisite>
00049 //   <li> Vector
00050 //   <li> Complex
00051 // </prerequisite>
00052 //
00053 // <etymology>
00054 // RigidVector is a vector with a size fixed at compile time, i.e. Rigid
00055 // as compared to the normal Vector class.
00056 // </etymology>
00057 //
00058 // <synopsis>
00059 // RigidVector is a specialized Vector class for short (<25 elements) vectors.
00060 // It has a size fixed at compile time, avoids new and delete and uses 
00061 // copy semantics throughout. 
00062 // Unlike Vectors, RigidVectors have fixed zero origin and no strides,
00063 // allowing fast indexing.
00064 // The more common mathematical operations are defined for RigidVector, 
00065 // allowing element by element arithmetic, innerproduct and matrix
00066 // multiplication (by a SquareMatrix). Conversion to and from normal
00067 // vectors is provided.
00068 // </synopsis>
00069 //
00070 // <example>
00071 // <srcblock> 
00072 // // Create two RigidVectors
00073 // RigidVector<Float,3> rv1(1.0,2.0,3.0),rv2(3.0,2.0,1.0);
00074 // // Compute sum
00075 // RigidVector<Float,3> rv3=rv1+rv2;
00076 // // Compute innerproduct
00077 // Float inprod=rv1*rv2;
00078 // // Write out results
00079 // cout << "rv1+rv2="<< rv3 <<", rv1*rv2="<< inprod<<endl;
00080 // </srcblock> 
00081 // </example>
00082 //
00083 // <motivation>
00084 // The standard Vector class is rather inefficient for short vectors, this
00085 // class is designed for speed and simplicity.
00086 // </motivation>
00087 //
00088 // <templating arg=T>
00089 //    <li> this class is meant for computation and assumes operators
00090 //          +,-,* to be defined.
00091 // </templating>
00092 //
00093 // <thrown>
00094 //    <li> no exceptions
00095 // </thrown>
00096 //
00097 // <todo asof="1996/11/07">
00098 //   <li> not all operations defined for Vectors are defined 
00099 //   <li> default implementation of innerProduct is wrong for Complex vectors
00100 // </todo>
00101 
00102 template <class T, Int n> class RigidVector {
00103 
00104     //# friends (could be out of line if compiler accepted that)
00105     // Add two RigidVectors.
00106     friend RigidVector<T,n> operator+(const RigidVector<T,n>& l,
00107     const RigidVector<T,n>& r) {
00108         RigidVector<T,n> result=l;
00109         return result+=r;
00110     }
00111     // Subtract two RigidVectors.
00112     friend RigidVector<T,n> operator-(const RigidVector<T,n>& l,
00113     const RigidVector<T,n>& r) {
00114         RigidVector<T,n> result=l;
00115         return result-=r;
00116     }
00117     // The innerproduct of 2 RigidVectors.
00118     friend T operator*(const RigidVector<T,n>& l,
00119                        const RigidVector<T,n>& r) {
00120         T sum=T(0);
00121         for (Int i=0; i<n; i++) sum+=l.v_p[i]*r.v_p[i];
00122         return sum;
00123     }
00124     // Multiply a RigidVector by a scalar.
00125     friend RigidVector<T,n> operator*(const T& f, const RigidVector<T,n>& v) {
00126         RigidVector<T,n> r(v);
00127         return r*=f;
00128     }
00129     // Multiply a RigidVector by a scalar.
00130     friend RigidVector<T,n> operator*(const RigidVector<T,n>& v, const T& f) {
00131         RigidVector<T,n> r(v);
00132         return r*=f;
00133     }
00134     // Write out a RigidVector using the Vector output method.
00135     friend ostream& operator<<(ostream& os, const RigidVector<T,n>& v) {
00136         os << v.vector();
00137         return os;
00138     }
00139     // Special matrix multiply of Complex matrix * Float vector.
00140     friend RigidVector<Complex,4> operator*(const SquareMatrix<Complex,4>& m,
00141                                             const RigidVector<Float,4>& v);
00142 public:
00143   //    RigidVector(Int dummy) {
00144   //      for (Int i=0; i<n; i++) v_p[i]=T(0);
00145   //    }
00146     // Default constructor
00147     RigidVector() {
00148       for (Int i=0; i<n; i++) v_p[i]=T(0);
00149     }
00150     // Construct from scalar, sets all elements to c
00151     RigidVector(const T& c) {
00152         for (Int i=0; i<n; i++) v_p[i]=c;
00153     }
00154     // Construct a 2-element vector, fails for wrong size vectors.
00155     RigidVector(const T& v0, const T& v1) {
00156         if (n!=2) exit(1);
00157         v_p[0]=v0; v_p[1]=v1;
00158     }
00159     // Construct a 3-element vector, fails for wrong size vectors.
00160     RigidVector(const T& v0, const T& v1, const T& v2) {
00161         if (n!=3) exit(1);
00162         v_p[0]=v0; v_p[1]=v1; v_p[2]=v2;
00163     }
00164     // Construct a 4-element vector, fails for wrong size vectors.
00165     RigidVector(const T& v0, const T& v1, const T& v2, const T& v3) {
00166         if (n!=4) exit(1);
00167         v_p[0]=v0; v_p[1]=v1; v_p[2]=v2; v_p[3]=v3;
00168     }
00169     // Construct from a c-array (copy semantics)
00170     RigidVector(const T v[n]) {
00171         for (Int i=0; i<n; i++) v_p[i]=v[i];
00172     }
00173     // Construct from a Vector.
00174     RigidVector(const Vector<T> & v) {
00175         for (Int i=0; i<n; i++) v_p[i]=v(i);
00176     }
00177     // Copy constructor, copy semantics.
00178     RigidVector(const RigidVector<T,n>& v) {
00179         for (Int i=0; i<n; i++) v_p[i]=v.v_p[i];
00180     }
00181     // Assign from a RigidVector.
00182     RigidVector<T,n>& operator=(const RigidVector<T,n>& v) {
00183         for (Int i=0; i<n; i++) v_p[i]=v.v_p[i];
00184         return *this;
00185     }
00186     // Assign from a Vector.
00187     RigidVector<T,n>& operator=(const Vector<T>& v) {
00188         for (Int i=0; i<n; i++) v_p[i]=v(i);
00189         return *this;
00190     }
00191     // Assign a scalar, sets all elements to c.
00192     RigidVector<T,n>& operator=(const T& c) {
00193         for (Int i=0; i<n; i++) v_p[i]=c;
00194         return *this;
00195     }
00196     // Negation
00197     RigidVector<T,n>& operator-() {
00198         for (Int i=0; i<n ;i++) v_p[i]=-v_p[i];
00199         return *this;
00200     }
00201     // Addition 
00202     RigidVector<T,n>& operator+=(const RigidVector<T,n>& v) {
00203         for (Int i=0; i<n; i++) v_p[i]+=v.v_p[i];
00204         return *this;
00205     }
00206     RigidVector<T,n>& operator*=(const RigidVector<T,n>& v) {
00207         for (Int i=0; i<n; i++) v_p[i]*=v.v_p[i];
00208         return *this;
00209     }
00210     // Subtraction
00211     RigidVector<T,n>& operator-=(const RigidVector<T,n>& v) {
00212         for (Int i=0; i<n; i++) v_p[i]-=v.v_p[i];
00213         return *this;
00214     }
00215     // Multiplication by scalar.
00216     RigidVector<T,n>& operator*=(const T& val) {
00217         for (Int i=0; i<n; i++) v_p[i]*=val;
00218         return *this;
00219     }
00220     // Multiply vector by matrix: v*=M is equivalent to v=M*v;
00221     RigidVector<T,n>& operator*=(const SquareMatrix<T,n>& m); 
00222 
00223     // Indexing by reference
00224     T& operator()(Int i) { return v_p[i];}
00225     // Indexing by const reference
00226     const T& operator()(Int i) const { return v_p[i];}
00227     //# Get const access to the underlying c-array
00228     //#const T*& cArray() const { return v_p;}
00229     // Convert to a regular Vector
00230     Vector<T> vector() const {
00231         Vector<T> v(n);
00232         for (Int i=0; i<n; i++) v(i)=v_p[i];
00233         return v;
00234     }
00235     // Square Root
00236     RigidVector<T,n> sqrt(const RigidVector<T,n>& v);
00237 
00238 // // The following are needed for Image<RigidVector>
00239 
00240 //   static IPosition shape() {return IPosition(1,n);}
00241 
00242 //   static void* newCopyInfo (const TableRecord& record,
00243 //                          const IPosition& sourceElementShape);
00244 
00245 //   static void deleteCopyInfo (void*);
00246 
00247 //   static void set (void* copyInfo, void* out,
00248 //                 const Array<T>& in,
00249 //                 const IPosition& shape);
00250 //   static void get (void* copyInfo, Array<T>& out,
00251 //                 const void* in,
00252 //                 const IPosition& shape);
00253 
00254 protected:
00255     T v_p[n];
00256 };
00257 
00258 // <summary> Mathematical operations involving RigidVectors </summary>
00259 
00260 // <group name=math>
00261 //#Fails to compile
00262 //#// Multiply vector by matrix.
00263 //#template <class T, Int n>
00264 //#inline RigidVector<T,n> operator*(const SquareMatrix<T,n>& m,
00265 //#                               const RigidVector<T,n>& v) {
00266 //#    RigidVector<T,n> result(v);
00267 //#    return result*=m;
00268 //#}
00269 // Multiply vector by matrix.
00270 inline RigidVector<Float,4> operator*(const SquareMatrix<Float,4>& m,
00271                                       const RigidVector<Float,4>& v) {
00272     RigidVector<Float,4> result(v);
00273     return result*=m;
00274 }
00275 // Multiply vector by matrix.
00276 inline RigidVector<Complex,4> operator*(const SquareMatrix<Complex,4>& m,
00277                                         const RigidVector<Complex,4>& v) {
00278     RigidVector<Complex,4> result(v);
00279     return result*=m;
00280 }
00281 // </group>
00282 
00283 } //# NAMESPACE CASA - END
00284 
00285 #ifndef CASACORE_NO_AUTO_TEMPLATES
00286 #include <scimath/Mathematics/RigidVector.tcc>
00287 #endif //# CASACORE_NO_AUTO_TEMPLATES
00288 #endif