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