Blender V2.61 - r43446
|
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