Blender V2.61 - r43446

vec.h

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