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