Blender  V2.59
vec.h
Go to the documentation of this file.
00001 
00005 /*
00006 
00007 *
00008 * Template Numerical Toolkit (TNT): Linear Algebra Module
00009 *
00010 * Mathematical and Computational Sciences Division
00011 * National Institute of Technology,
00012 * Gaithersburg, MD USA
00013 *
00014 *
00015 * This software was developed at the National Institute of Standards and
00016 * Technology (NIST) by employees of the Federal Government in the course
00017 * of their official duties. Pursuant to title 17 Section 105 of the
00018 * United States Code, this software is not subject to copyright protection
00019 * and is in the public domain.  The Template Numerical Toolkit (TNT) is
00020 * an experimental system.  NIST assumes no responsibility whatsoever for
00021 * its use by other parties, and makes no guarantees, expressed or implied,
00022 * about its quality, reliability, or any other characteristic.
00023 *
00024 * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE
00025 * see http://math.nist.gov/tnt for latest updates.
00026 *
00027 */
00028 
00029 
00030 // Basic TNT  numerical vector (0-based [i] AND 1-based (i) indexing )
00031 //
00032 
00033 #ifndef VEC_H
00034 #define VEC_H
00035 
00036 #include "subscript.h"
00037 #include <stdlib.h>
00038 #include <assert.h>
00039 #include <iostream>
00040 
00041 namespace TNT
00042 {
00043 
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     const iterator begin() const { return v_;}
00157     const 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 
00189     // methods
00190     // 
00191     Vector<T>& newsize(Subscript N)
00192     {
00193         if (n_ == N) return *this;
00194 
00195         destroy();
00196         initialize(N);
00197 
00198         return *this;
00199     }
00200 
00201 
00202     // assignments
00203     //
00204     Vector<T>& operator=(const Vector<T> &A)
00205     {
00206         if (v_ == A.v_)
00207             return *this;
00208 
00209         if (n_ == A.n_)         // no need to re-alloc
00210             copy(A.v_);
00211 
00212         else
00213         {
00214             destroy();
00215             initialize(A.n_);
00216             copy(A.v_);
00217         }
00218 
00219         return *this;
00220     }
00221         
00222     Vector<T>& operator=(const T& scalar)
00223     { 
00224         set(scalar);  
00225         return *this;
00226     }
00227 
00228     inline Subscript dim() const 
00229     {
00230         return  n_; 
00231     }
00232 
00233     inline Subscript size() const 
00234     {
00235         return  n_; 
00236     }
00237 
00238 
00239     inline reference operator()(Subscript i)
00240     { 
00241 #ifdef TNT_BOUNDS_CHECK
00242         assert(1<=i);
00243         assert(i <= n_) ;
00244 #endif
00245         return vm1_[i]; 
00246     }
00247 
00248     inline const_reference operator() (Subscript i) const
00249     {
00250 #ifdef TNT_BOUNDS_CHECK
00251         assert(1<=i);
00252         assert(i <= n_) ;
00253 #endif
00254         return vm1_[i]; 
00255     }
00256 
00257     inline reference operator[](Subscript i)
00258     { 
00259 #ifdef TNT_BOUNDS_CHECK
00260         assert(0<=i);
00261         assert(i < n_) ;
00262 #endif
00263         return v_[i]; 
00264     }
00265 
00266     inline const_reference operator[](Subscript i) const
00267     {
00268 #ifdef TNT_BOUNDS_CHECK
00269         assert(0<=i) ;
00270         assert(i < n_) ;
00271 #endif
00272         return v_[i]; 
00273     }
00274 
00275 
00276 
00277 };
00278 
00279 
00280 /* ***************************  I/O  ********************************/
00281 
00282 template <class T>
00283 std::ostream& operator<<(std::ostream &s, const Vector<T> &A)
00284 {
00285     Subscript N=A.dim();
00286 
00287     s <<  N << std::endl;
00288 
00289     for (Subscript i=0; i<N; i++)
00290         s   << A[i] << " " << std::endl;
00291     s << std::endl;
00292 
00293     return s;
00294 }
00295 
00296 template <class T>
00297 std::istream & operator>>(std::istream &s, Vector<T> &A)
00298 {
00299 
00300     Subscript N;
00301 
00302     s >> N;
00303 
00304     if ( !(N == A.size() ))
00305     {
00306         A.newsize(N);
00307     }
00308 
00309 
00310     for (Subscript i=0; i<N; i++)
00311             s >>  A[i];
00312 
00313 
00314     return s;
00315 }
00316 
00317 // *******************[ basic matrix algorithms ]***************************
00318 
00319 
00320 template <class T>
00321 Vector<T> operator+(const Vector<T> &A, 
00322     const Vector<T> &B)
00323 {
00324     Subscript N = A.dim();
00325 
00326     assert(N==B.dim());
00327 
00328     Vector<T> tmp(N);
00329     Subscript i;
00330 
00331     for (i=0; i<N; i++)
00332             tmp[i] = A[i] + B[i];
00333 
00334     return tmp;
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 T &B)
00374 {
00375     Subscript N = A.dim();
00376 
00377     Vector<T> tmp(N);
00378     Subscript i;
00379 
00380     for (i=0; i<N; i++)
00381             tmp[i] = A[i] * B;
00382 
00383     return tmp;
00384 }
00385 
00386 
00387 template <class T>
00388 T dot_prod(const Vector<T> &A, const Vector<T> &B)
00389 {
00390     Subscript N = A.dim();
00391     assert(N == B.dim());
00392 
00393     Subscript i;
00394     T sum = 0;
00395 
00396     for (i=0; i<N; i++)
00397         sum += A[i] * B[i];
00398 
00399     return sum;
00400 }
00401 
00402 // inplace versions of the above template functions
00403 
00404 // A = A + B
00405 
00406 template <class T>
00407 void vectoradd(
00408         Vector<T> &A, 
00409     const Vector<T> &B)
00410 {
00411     const Subscript N = A.dim();
00412     assert(N==B.dim());
00413     Subscript i;
00414 
00415     for (i=0; i<N; i++)
00416             A[i] += B[i];
00417 }
00418 
00419 // same with separate output vector
00420 
00421 template <class T>
00422 void vectoradd(
00423         Vector<T> &C,
00424         const Vector<T> &A, 
00425     const Vector<T> &B)
00426 {
00427     const Subscript N = A.dim();
00428     assert(N==B.dim());
00429     Subscript i;
00430 
00431     for (i=0; i<N; i++)
00432             C[i] = A[i] + B[i];
00433 }
00434 
00435 // A = A - B
00436 
00437 template <class T>
00438 void vectorsub(
00439         Vector<T> &A, 
00440     const Vector<T> &B)
00441 {
00442     const Subscript N = A.dim();
00443     assert(N==B.dim());
00444     Subscript i;
00445 
00446     for (i=0; i<N; i++)
00447             A[i] -= B[i];
00448 }
00449 
00450 template <class T>
00451 void vectorsub(
00452         Vector<T> &C,
00453         const Vector<T> &A, 
00454     const Vector<T> &B)
00455 {
00456     const Subscript N = A.dim();
00457     assert(N==B.dim());
00458     Subscript i;
00459 
00460     for (i=0; i<N; i++)
00461             C[i] = A[i] - B[i];
00462 }
00463 
00464 template <class T>
00465 void vectorscale(
00466         Vector<T> &C,
00467         const Vector<T> &A, 
00468     const T &B)
00469 {
00470     const Subscript N = A.dim();
00471     Subscript i;
00472 
00473     for (i=0; i<N; i++)
00474             C[i] = A[i] * B;
00475 }
00476 
00477 template <class T>
00478 void vectorscale(
00479         Vector<T> &A, 
00480     const T &B)
00481 {
00482     const Subscript N = A.dim();
00483     Subscript i;
00484 
00485     for (i=0; i<N; i++)
00486             A[i] *= B;
00487 }
00488 
00489 }   /* namespace TNT */
00490 
00491 #endif // VEC_H
00492