|
Blender
V2.59
|
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