00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef TNT_VECTOR_H
00023 #define TNT_VECTOR_H
00024
00025 #include "tnt_subscript.h"
00026 #include <cstdlib>
00027 #include <cassert>
00028 #include <iostream>
00029 #include <sstream>
00030 #include <cmath>
00031
00032 using namespace std;
00033
00034 namespace TNT
00035 {
00036
00037
00038
00039
00040
00047 template <class T>
00048 class Vector
00049 {
00050
00051
00052 public:
00053
00054 typedef Subscript size_type;
00055 typedef T value_type;
00056 typedef T element_type;
00057 typedef T* pointer;
00058 typedef T* iterator;
00059 typedef T& reference;
00060 typedef const T* const_iterator;
00061 typedef const T& const_reference;
00062
00063 Subscript lbound() const { return 1;}
00064
00065 private:
00066 T* v_;
00067 T* vm1_;
00068 Subscript n_;
00069
00070
00071
00072
00073 void initialize(Subscript N)
00074 {
00075
00076
00077
00078 assert(v_ == NULL);
00079 v_ = new T[N];
00080 assert(v_ != NULL);
00081 vm1_ = v_-1;
00082 n_ = N;
00083 }
00084
00085 void copy(const T* v)
00086 {
00087 Subscript N = n_;
00088 Subscript i;
00089
00090 #ifdef TNT_UNROLL_LOOPS
00091 Subscript Nmod4 = N & 3;
00092 Subscript N4 = N - Nmod4;
00093
00094 for (i=0; i<N4; i+=4)
00095 {
00096 v_[i] = v[i];
00097 v_[i+1] = v[i+1];
00098 v_[i+2] = v[i+2];
00099 v_[i+3] = v[i+3];
00100 }
00101
00102 for (i=N4; i< N; i++)
00103 v_[i] = v[i];
00104 #else
00105
00106 for (i=0; i< N; i++)
00107 v_[i] = v[i];
00108 #endif
00109 }
00110
00111 void set(const T& val)
00112 {
00113 Subscript N = n_;
00114 Subscript i;
00115
00116 #ifdef TNT_UNROLL_LOOPS
00117 Subscript Nmod4 = N & 3;
00118 Subscript N4 = N - Nmod4;
00119
00120 for (i=0; i<N4; i+=4)
00121 {
00122 v_[i] = val;
00123 v_[i+1] = val;
00124 v_[i+2] = val;
00125 v_[i+3] = val;
00126 }
00127
00128 for (i=N4; i< N; i++)
00129 v_[i] = val;
00130 #else
00131
00132 for (i=0; i< N; i++)
00133 v_[i] = val;
00134
00135 #endif
00136 }
00137
00138
00139
00140 void destroy()
00141 {
00142
00143 if (v_ == NULL) return ;
00144
00145
00146 delete [] (v_);
00147
00148 v_ = NULL;
00149 vm1_ = NULL;
00150 }
00151
00152
00153 public:
00154
00155
00156
00157 iterator begin() { return v_;}
00158 iterator end() { return v_ + n_; }
00159 const iterator begin() const { return v_;}
00160 const iterator end() const { return v_ + n_; }
00161
00162 operator const T* const() { return v_; }
00163 operator T*() { return v_; }
00164
00165
00166
00167 ~Vector()
00168 {
00169 destroy();
00170 }
00171
00172
00173
00174 Vector() : v_(0), vm1_(0), n_(0) {};
00175
00176 Vector(const Vector<T> &A) : v_(0), vm1_(0), n_(0)
00177 {
00178 initialize(A.n_);
00179 copy(A.v_);
00180 }
00181
00182 Vector(Subscript N, const T& value = T()) : v_(0), vm1_(0), n_(0)
00183 {
00184 initialize(N);
00185 set(value);
00186 }
00187
00188 Vector(Subscript N, const T* v) : v_(0), vm1_(0), n_(0)
00189 {
00190 initialize(N);
00191 copy(v);
00192 }
00193
00194 Vector(Subscript N, char *s) : v_(0), vm1_(0), n_(0)
00195 {
00196 initialize(N);
00197 std::istringstream ins(s);
00198
00199 Subscript i;
00200
00201 for (i=0; i<N; i++)
00202 ins >> v_[i];
00203 }
00204
00205
00206
00207
00208 Vector<T>& newsize(Subscript N)
00209 {
00210 if (n_ == N) return *this;
00211
00212 destroy();
00213 initialize(N);
00214
00215 return *this;
00216 }
00217
00218
00219
00220
00221 Vector<T>& operator=(const Vector<T> &A)
00222 {
00223 if (v_ == A.v_)
00224 return *this;
00225
00226 if (n_ == A.n_)
00227 copy(A.v_);
00228
00229 else
00230 {
00231 destroy();
00232 initialize(A.n_);
00233 copy(A.v_);
00234 }
00235
00236 return *this;
00237 }
00238
00239 Vector<T>& operator=(const T& scalar)
00240 {
00241 set(scalar);
00242 return *this;
00243 }
00244
00245 inline Subscript dim() const
00246 {
00247 return n_;
00248 }
00249
00250 inline Subscript size() const
00251 {
00252 return n_;
00253 }
00254
00255
00256 inline reference operator()(Subscript i)
00257 {
00258 #ifdef TNT_BOUNDS_CHECK
00259 assert(1<=i);
00260 assert(i <= n_) ;
00261 #endif
00262 return vm1_[i];
00263 }
00264
00265 inline const_reference operator() (Subscript i) const
00266 {
00267 #ifdef TNT_BOUNDS_CHECK
00268 assert(1<=i);
00269 assert(i <= n_) ;
00270 #endif
00271 return vm1_[i];
00272 }
00273
00274 inline reference operator[](Subscript i)
00275 {
00276 #ifdef TNT_BOUNDS_CHECK
00277 assert(0<=i);
00278 assert(i < n_) ;
00279 #endif
00280 return v_[i];
00281 }
00282
00283 inline const_reference operator[](Subscript i) const
00284 {
00285 #ifdef TNT_BOUNDS_CHECK
00286 assert(0<=i);
00287
00288
00289
00290
00291
00292
00293 assert(i < n_) ;
00294 #endif
00295 return v_[i];
00296 }
00297
00298
00299
00300 };
00301
00302
00303
00304
00305 template <class T>
00306 std::ostream& operator<<(std::ostream &s, const Vector<T> &A)
00307 {
00308 Subscript N=A.dim();
00309
00310 s << N << "\n";
00311
00312 for (Subscript i=0; i<N; i++)
00313 s << A[i] << " " << "\n";
00314 s << "\n";
00315
00316 return s;
00317 }
00318
00319 template <class T>
00320 std::istream & operator>>(std::istream &s, Vector<T> &A)
00321 {
00322
00323 Subscript N;
00324
00325 s >> N;
00326
00327 if ( !(N == A.size() ))
00328 {
00329 A.newsize(N);
00330 }
00331
00332
00333 for (Subscript i=0; i<N; i++)
00334 s >> A[i];
00335
00336
00337 return s;
00338 }
00339
00340
00341
00342
00343 template <class T>
00344 Vector<T> operator+(const Vector<T> &A,
00345 const Vector<T> &B)
00346 {
00347 Subscript N = A.dim();
00348
00349 assert(N==B.dim());
00350
00351 Vector<T> tmp(N);
00352 Subscript i;
00353
00354 for (i=0; i<N; i++)
00355 tmp[i] = A[i] + B[i];
00356
00357 return tmp;
00358 }
00359
00360 template <class T>
00361 Vector<T> operator+=(Vector<T> &A,
00362 const Vector<T> &B)
00363 {
00364 Subscript N = A.dim();
00365
00366 assert(N==B.dim());
00367
00368 Subscript i;
00369
00370 for (i=0; i<N; i++)
00371 A[i] += B[i];
00372
00373 return A;
00374 }
00375
00376 template <class T>
00377 Vector<T> operator-(const Vector<T> &A,
00378 const Vector<T> &B)
00379 {
00380 Subscript N = A.dim();
00381
00382 assert(N==B.dim());
00383
00384 Vector<T> tmp(N);
00385 Subscript i;
00386
00387 for (i=0; i<N; i++)
00388 tmp[i] = A[i] - B[i];
00389
00390 return tmp;
00391 }
00392
00393 template <class T>
00394 Vector<T> operator-=(Vector<T> &A,
00395 const Vector<T> &B)
00396 {
00397 Subscript N = A.dim();
00398
00399 assert(N==B.dim());
00400
00401 Subscript i;
00402
00403 for (i=0; i<N; i++)
00404 A[i] -= B[i];
00405
00406 return A;
00407 }
00408
00409
00410
00411
00412 template <class T>
00413 Vector<T> elementwise_mult(const Vector<T> &A, const Vector<T> &B)
00414 {
00415 Subscript N = A.dim();
00416
00417 assert(N==B.dim());
00418
00419 Vector<T> tmp(N);
00420 Subscript i;
00421
00422 for (i=0; i<N; i++)
00423 tmp[i] = A[i] * B[i];
00424
00425 return tmp;
00426 }
00427
00428
00429 template <class T>
00430 double norm(const Vector<T> &A)
00431 {
00432 Subscript N = A.dim();
00433
00434 double sum = 0.0;
00435 for (int i=0; i<N; i++)
00436 sum += abs(A[i])*abs(A[i]);
00437 return sqrt(sum);
00438 }
00439
00440
00441
00442 template <class T>
00443 T dot_prod(const Vector<T> &A, const Vector<T> &B)
00444 {
00445 Subscript N = A.dim();
00446 assert(N == B.dim());
00447
00448 Subscript i;
00449 T sum = 0;
00450
00451 for (i=0; i<N; i++)
00452 sum += A[i] * B[i];
00453
00454 return sum;
00455 }
00456
00457 template <class T>
00458 inline T dot_product(const Vector<T> &A, const Vector<T> &B)
00459 {
00460 return dot_prod(A, B);
00461 }
00462
00463
00464 template <class T>
00465 inline T operator*(const Vector<T> &A,
00466 const Vector<T> &B)
00467 {
00468 return dot_prod(A,B);
00469 }
00470
00471
00472 template <class T>
00473 Vector<T> operator*(const T &a, const Vector<T> &A)
00474 {
00475 Subscript N = A.dim();
00476 Vector<T> r(N);
00477
00478 for (int i=0; i<N; i++)
00479 r[i] = A[i] * a;
00480
00481 return r;
00482 }
00483
00484 template <class T>
00485 inline Vector<T> operator*(const Vector<T> &A, const T& a)
00486 {
00487 return a * A;
00488 }
00489
00490
00491 }
00492
00493
00494 #endif
00495