Blender V2.61 - r43446

tnt_vec.h

Go to the documentation of this file.
00001 
00004 /*
00005 *
00006 * Template Numerical Toolkit (TNT)
00007 *
00008 * Mathematical and Computational Sciences Division
00009 * National Institute of Technology,
00010 * Gaithersburg, MD USA
00011 *
00012 *
00013 * This software was developed at the National Institute of Standards and
00014 * Technology (NIST) by employees of the Federal Government in the course
00015 * of their official duties. Pursuant to title 17 Section 105 of the
00016 * United States Code, this software is not subject to copyright protection
00017 * and is in the public domain. NIST assumes no responsibility whatsoever for
00018 * its use by other parties, and makes no guarantees, expressed or implied,
00019 * about its quality, reliability, or any other characteristic.
00020 *
00021 */
00022 
00023 
00024 
00025 #ifndef TNT_VEC_H
00026 #define TNT_VEC_H
00027 
00028 #include "tnt_subscript.h"
00029 #include <cstdlib>
00030 #include <cassert>
00031 #include <iostream>
00032 #include <sstream>
00033 
00034 namespace TNT
00035 {
00036 
00044 template <class T>
00045 class Vector 
00046 {
00047 
00048 
00049   public:
00050 
00051     typedef Subscript   size_type;
00052     typedef         T   value_type;
00053     typedef         T   element_type;
00054     typedef         T*  pointer;
00055     typedef         T*  iterator;
00056     typedef         T&  reference;
00057     typedef const   T*  const_iterator;
00058     typedef const   T&  const_reference;
00059 
00060     Subscript lbound() const { return 1;}
00061  
00062   protected:
00063     T* v_;                  
00064     T* vm1_;        // pointer adjustment for optimzied 1-offset indexing
00065     Subscript n_;
00066 
00067     // internal helper function to create the array
00068     // of row pointers
00069 
00070     void initialize(Subscript N)
00071     {
00072         // adjust pointers so that they are 1-offset:
00073         // v_[] is the internal contiguous array, it is still 0-offset
00074         //
00075         assert(v_ == NULL);
00076         v_ = new T[N];
00077         assert(v_  != NULL);
00078         vm1_ = v_-1;
00079         n_ = N;
00080     }
00081    
00082     void copy(const T*  v)
00083     {
00084         Subscript N = n_;
00085         Subscript i;
00086 
00087 #ifdef TNT_UNROLL_LOOPS
00088         Subscript Nmod4 = N & 3;
00089         Subscript N4 = N - Nmod4;
00090 
00091         for (i=0; i<N4; i+=4)
00092         {
00093             v_[i] = v[i];
00094             v_[i+1] = v[i+1];
00095             v_[i+2] = v[i+2];
00096             v_[i+3] = v[i+3];
00097         }
00098 
00099         for (i=N4; i< N; i++)
00100             v_[i] = v[i];
00101 #else
00102 
00103         for (i=0; i< N; i++)
00104             v_[i] = v[i];
00105 #endif      
00106     }
00107 
00108     void set(const T& val)
00109     {
00110         Subscript N = n_;
00111         Subscript i;
00112 
00113 #ifdef TNT_UNROLL_LOOPS
00114         Subscript Nmod4 = N & 3;
00115         Subscript N4 = N - Nmod4;
00116 
00117         for (i=0; i<N4; i+=4)
00118         {
00119             v_[i] = val;
00120             v_[i+1] = val;
00121             v_[i+2] = val;
00122             v_[i+3] = val; 
00123         }
00124 
00125         for (i=N4; i< N; i++)
00126             v_[i] = val;
00127 #else
00128 
00129         for (i=0; i< N; i++)
00130             v_[i] = val;
00131         
00132 #endif      
00133     }
00134     
00135 
00136 
00137     void destroy()
00138     {     
00139         /* do nothing, if no memory has been previously allocated */
00140         if (v_ == NULL) return ;
00141 
00142         /* if we are here, then matrix was previously allocated */
00143         delete [] (v_);     
00144 
00145         v_ = NULL;
00146         vm1_ = NULL;
00147     }
00148 
00149 
00150   public:
00151 
00152     // access
00153 
00154     iterator begin() { return v_;}
00155     iterator end()   { return v_ + n_; }
00156     iterator begin() const { return v_;}
00157     iterator end() const  { return v_ + n_; }
00158 
00159     // destructor
00160 
00161     ~Vector() 
00162     {
00163         destroy();
00164     }
00165 
00166     // constructors
00167 
00168     Vector() : v_(0), vm1_(0), n_(0)  {};
00169 
00170     Vector(const Vector<T> &A) : v_(0), vm1_(0), n_(0)
00171     {
00172         initialize(A.n_);
00173         copy(A.v_);
00174     }
00175 
00176     Vector(Subscript N, const T& value = T()) :  v_(0), vm1_(0), n_(0)
00177     {
00178         initialize(N);
00179         set(value);
00180     }
00181 
00182     Vector(Subscript N, const T* v) :  v_(0), vm1_(0), n_(0)
00183     {
00184         initialize(N);
00185         copy(v);
00186     }
00187 
00188     Vector(Subscript N, char *s) :  v_(0), vm1_(0), n_(0)
00189     {
00190         initialize(N);
00191         std::istringstream ins(s);
00192 
00193         Subscript i;
00194 
00195         for (i=0; i<N; i++)
00196                 ins >> v_[i];
00197     }
00198 
00199 
00200     // methods
00201     // 
00202     Vector<T>& newsize(Subscript N)
00203     {
00204         if (n_ == N) return *this;
00205 
00206         destroy();
00207         initialize(N);
00208 
00209         return *this;
00210     }
00211 
00212 
00213     // assignments
00214     //
00215     Vector<T>& operator=(const Vector<T> &A)
00216     {
00217         if (v_ == A.v_)
00218             return *this;
00219 
00220         if (n_ == A.n_)         // no need to re-alloc
00221             copy(A.v_);
00222 
00223         else
00224         {
00225             destroy();
00226             initialize(A.n_);
00227             copy(A.v_);
00228         }
00229 
00230         return *this;
00231     }
00232         
00233     Vector<T>& operator=(const T& scalar)
00234     { 
00235         set(scalar);  
00236         return *this;
00237     }
00238 
00239     inline Subscript dim() const 
00240     {
00241         return  n_; 
00242     }
00243 
00244     inline Subscript size() const 
00245     {
00246         return  n_; 
00247     }
00248 
00249 
00250     inline reference operator()(Subscript i)
00251     { 
00252 #ifdef TNT_BOUNDS_CHECK
00253         assert(1<=i);
00254         assert(i <= n_) ;
00255 #endif
00256         return vm1_[i]; 
00257     }
00258 
00259     inline const_reference operator() (Subscript i) const
00260     {
00261 #ifdef TNT_BOUNDS_CHECK
00262         assert(1<=i);
00263         assert(i <= n_) ;
00264 #endif
00265         return vm1_[i]; 
00266     }
00267 
00268     inline reference operator[](Subscript i)
00269     { 
00270 #ifdef TNT_BOUNDS_CHECK
00271         assert(0<=i);
00272         assert(i < n_) ;
00273 #endif
00274         return v_[i]; 
00275     }
00276 
00277     inline const_reference operator[](Subscript i) const
00278     {
00279 #ifdef TNT_BOUNDS_CHECK
00280         assert(0<=i);
00281 
00282 
00283 
00284 
00285 
00286 
00287         assert(i < n_) ;
00288 #endif
00289         return v_[i]; 
00290     }
00291 
00292 
00293 
00294 };
00295 
00296 
00297 /* ***************************  I/O  ********************************/
00298 
00299 template <class T>
00300 std::ostream& operator<<(std::ostream &s, const Vector<T> &A)
00301 {
00302     Subscript N=A.dim();
00303 
00304     s <<  N << "\n";
00305 
00306     for (Subscript i=0; i<N; i++)
00307         s   << A[i] << " " << "\n";
00308     s << "\n";
00309 
00310     return s;
00311 }
00312 
00313 template <class T>
00314 std::istream & operator>>(std::istream &s, Vector<T> &A)
00315 {
00316 
00317     Subscript N;
00318 
00319     s >> N;
00320 
00321     if ( !(N == A.size() ))
00322     {
00323         A.newsize(N);
00324     }
00325 
00326 
00327     for (Subscript i=0; i<N; i++)
00328             s >>  A[i];
00329 
00330 
00331     return s;
00332 }
00333 
00334 // *******************[ basic matrix algorithms ]***************************
00335 
00336 
00337 template <class T>
00338 Vector<T> operator+(const Vector<T> &A, 
00339     const Vector<T> &B)
00340 {
00341     Subscript N = A.dim();
00342 
00343     assert(N==B.dim());
00344 
00345     Vector<T> tmp(N);
00346     Subscript i;
00347 
00348     for (i=0; i<N; i++)
00349             tmp[i] = A[i] + B[i];
00350 
00351     return tmp;
00352 }
00353 
00354 template <class T>
00355 Vector<T> operator-(const Vector<T> &A, 
00356     const Vector<T> &B)
00357 {
00358     Subscript N = A.dim();
00359 
00360     assert(N==B.dim());
00361 
00362     Vector<T> tmp(N);
00363     Subscript i;
00364 
00365     for (i=0; i<N; i++)
00366             tmp[i] = A[i] - B[i];
00367 
00368     return tmp;
00369 }
00370 
00371 template <class T>
00372 Vector<T> operator*(const Vector<T> &A, 
00373     const Vector<T> &B)
00374 {
00375     Subscript N = A.dim();
00376 
00377     assert(N==B.dim());
00378 
00379     Vector<T> tmp(N);
00380     Subscript i;
00381 
00382     for (i=0; i<N; i++)
00383             tmp[i] = A[i] * B[i];
00384 
00385     return tmp;
00386 }
00387 
00388 
00389 template <class T>
00390 T dot_prod(const Vector<T> &A, const Vector<T> &B)
00391 {
00392     Subscript N = A.dim();
00393     assert(N == B.dim());
00394 
00395     Subscript i;
00396     T sum = 0;
00397 
00398     for (i=0; i<N; i++)
00399         sum += A[i] * B[i];
00400 
00401     return sum;
00402 }
00403 
00404 }   /* namespace TNT */
00405 
00406 #endif
00407 // TNT_VEC_H