00001
00002 #ifndef HDNUM_VECTOR_HH
00003 #define HDNUM_VECTOR_HH
00004
00005 #include <iostream>
00006 #include <iomanip>
00007 #include <string>
00008 #include <fstream>
00009
00010 #include "countablearray.hh"
00011 #include "exceptions.hh"
00012
00017 namespace hdnum {
00018
00038 template<class T>
00039 class Vector {
00040
00041 typedef CountableArray<T> ArrayType;
00042
00043 public:
00044
00046 typedef T value_type;
00047
00049 typedef value_type& reference;
00050
00052 typedef const value_type& const_reference;
00053
00055 typedef std::size_t size_type;
00056
00058 typedef std::ptrdiff_t difference_type;
00059
00061 Vector () : base()
00062 {
00063 n = 0;
00064 data = 0;
00065 }
00066
00072 Vector (size_type _n) : base(new ArrayType(_n))
00073 {
00074 n = _n;
00075 data = &((*base)[0]);
00076 }
00077
00084 Vector (size_type _n, const T& _t) : base(new ArrayType(_n,_t))
00085 {
00086 n = _n;
00087 data = &((*base)[0]);
00088 }
00089
00098 Vector (const Vector& v) : base(v.base)
00099 {
00100 n = v.n;
00101 data = v.data;
00102 }
00103
00112 Vector& operator= (const Vector& v)
00113 {
00114 base = v.base;
00115 data = v.data;
00116 n = v.n;
00117 return *this;
00118 }
00119
00125 Vector& operator= (const T& t)
00126 {
00127 for (size_type i=0; i<size(); i++)
00128 (*this)[i] = t;
00129 return *this;
00130 }
00131
00141 Vector<T> sub (size_type i, size_type m)
00142 {
00143 Vector<T> v;
00144 v.base = base;
00145 v.data = data+i;
00146 v.n = m;
00147 return v;
00148 }
00149
00157 void resize (size_type _n)
00158 {
00159 if (n==_n) return;
00160 if (base->get_reference_counter()==1 && data==(&((*base)[0])) && n==base->size())
00161 {
00162 base->resize(_n);
00163 n = _n;
00164 data = &((*base)[0]);
00165 }
00166 else
00167 HDNUM_THROW(InvalidStateException,"resize called on subvector or while subvectors exist");
00168 }
00169
00178 void resize (size_type _n, const T& _t)
00179 {
00180 if (n==_n) return;
00181 if (base->get_reference_counter()==1 && data==(&((*base)[0])) && n==base->size())
00182 {
00183 base->resize(_n,_t);
00184 n = _n;
00185 data = &((*base)[0]);
00186 }
00187 else
00188 HDNUM_THROW(InvalidStateException,"resize called on subvector or while subvectors exist");
00189 }
00190
00196 reference operator[] (size_type i)
00197 {
00198 return data[i];
00199 }
00200
00206 const_reference operator[] (size_type i) const
00207 {
00208 return data[i];
00209 }
00210
00214 size_type size () const
00215 {
00216 return n;
00217 }
00218
00220 int iwidth () const
00221 {
00222 return iwidth_;
00223 }
00224
00226 int width () const
00227 {
00228 return width_;
00229 }
00230
00232 int precision () const
00233 {
00234 return precision_;
00235 }
00236
00238 void iwidth (int i) const
00239 {
00240 iwidth_=i;
00241 }
00242
00244 void width (int i) const
00245 {
00246 width_=i;
00247 }
00248
00250 void precision (int i) const
00251 {
00252 precision_=i;
00253 }
00254
00256 class iterator {
00257 private:
00258 T* p;
00259 public:
00260 iterator()
00261 {
00262 p=0;
00263 }
00264 iterator (T* p_)
00265 {
00266 p=p_;
00267 }
00268 bool operator!= (iterator x) const
00269 {
00270 return p!=x.p;
00271 }
00272 bool operator== (iterator x) const
00273 {
00274 return p==x.p;
00275 }
00276 iterator operator++ ()
00277 {
00278 p++;
00279 return *this;
00280 }
00281 iterator operator++ (int)
00282 {
00283 p++;
00284 return *this;
00285 }
00286 iterator operator-- ()
00287 {
00288 p--;
00289 return *this;
00290 }
00291 iterator operator-- (int)
00292 {
00293 p--;
00294 return *this;
00295 }
00296 T& operator[] (size_type i) const
00297 {
00298 return p[i];
00299 }
00300 T& operator* () const
00301 {
00302 return *p;
00303 }
00304 T* operator-> () const
00305 {
00306 return p;
00307 }
00308 } ;
00309
00311 class const_iterator {
00312 private:
00313 T* p;
00314 public:
00315 const_iterator()
00316 {
00317 p=0;
00318 }
00319 const_iterator (T* p_)
00320 {
00321 p=p_;
00322 }
00323 bool operator!= (const_iterator x) const
00324 {
00325 return p!=x.p;
00326 }
00327 bool operator== (const_iterator x) const
00328 {
00329 return p==x.p;
00330 }
00331 const_iterator operator++ ()
00332 {
00333 p++;
00334 return *this;
00335 }
00336 const_iterator operator++ (int)
00337 {
00338 p++;
00339 return *this;
00340 }
00341 const_iterator operator-- ()
00342 {
00343 p--;
00344 return *this;
00345 }
00346 const_iterator operator-- (int)
00347 {
00348 p--;
00349 return *this;
00350 }
00351 const T& operator[] (size_type i) const
00352 {
00353 return p[i];
00354 }
00355 const T& operator* () const
00356 {
00357 return *p;
00358 }
00359 const T* operator-> () const
00360 {
00361 return p;
00362 }
00363 } ;
00364
00366 iterator begin ()
00367 {
00368 return iterator(data);
00369 }
00370
00372 iterator end ()
00373 {
00374 return iterator(data+n);
00375 }
00376
00378 iterator rbegin ()
00379 {
00380 return iterator(data+n-1);
00381 }
00382
00384 iterator rend ()
00385 {
00386 return iterator(data-1);
00387 }
00388
00389
00391 const_iterator begin () const
00392 {
00393 return const_iterator(data);
00394 }
00395
00397 const_iterator end () const
00398 {
00399 return const_iterator(data+n);
00400 }
00401
00403 const_iterator rbegin () const
00404 {
00405 return const_iterator(data+n-1);
00406 }
00407
00409 const_iterator rend () const
00410 {
00411 return const_iterator(data-1);
00412 }
00413
00421 Vector& operator+= (const Vector& y)
00422 {
00423 for (size_type i=0; i<n; ++i)
00424 (*this)[i] += y[i];
00425 return *this;
00426 }
00427
00435 Vector& operator-= (const Vector& y)
00436 {
00437 for (size_type i=0; i<n; ++i)
00438 (*this)[i] -= y[i];
00439 return *this;
00440 }
00441
00449
00450 Vector& operator*= (const T& s)
00451 {
00452 for (size_type i=0; i<n; ++i)
00453 (*this)[i] *= s;
00454 return *this;
00455 }
00456
00464 Vector& operator/= (const T& s)
00465 {
00466 for (size_type i=0; i<n; ++i)
00467 (*this)[i] /= s;
00468 return *this;
00469 }
00470
00471
00480 void update (const T& a, const Vector& y)
00481 {
00482 for (size_type i=0; i<n; ++i)
00483 (*this)[i] += a*y[i];
00484 }
00485
00493 T operator* (const Vector& y)
00494 {
00495 T sum(T(0));
00496 for (size_type i=0; i<n; ++i)
00497 sum += (*this)[i]*y[i];
00498 return sum;
00499 }
00500
00501 private:
00502 CP<ArrayType> base;
00503 size_type n;
00504 T* data;
00505 static int iwidth_, width_, precision_;
00506 };
00507
00508 template<class T>
00509 int Vector<T>::iwidth_ = 4;
00510 template<class T>
00511 int Vector<T>::width_ = 15;
00512 template<class T>
00513 int Vector<T>::precision_ = 6;
00514
00516 template <class T>
00517 inline std::ostream& operator<< (std::ostream& s, const Vector<T>& x)
00518 {
00519 for (typename Vector<T>::size_type i=0; i<x.size(); i++)
00520 s << "[" << std::setw(x.iwidth()) << i << "] "
00521 << std::setw(x.width()) << std::scientific << std::showpoint
00522 << std::setprecision(x.precision()) << x[i] << std::endl;
00523 return s;
00524 }
00525
00527 template<class T>
00528 inline Vector<T> copy (const Vector<T> v)
00529 {
00530 Vector<T> w(v.size());
00531 for (typename Vector<T>::size_type i=0; i<v.size(); i++)
00532 w[i] = v[i];
00533 return w;
00534 }
00535
00537 template<class T>
00538 inline void gnuplot (const std::string& fname, const Vector<T> v)
00539 {
00540 std::fstream f(fname.c_str(),std::ios::out);
00541 for (typename Vector<T>::size_type i=0; i<v.size(); i++)
00542 f << std::setw(v.width()) << i << std::scientific << std::showpoint
00543 << std::setprecision(v.precision()) << v[i] << std::endl;
00544 f.close();
00545 }
00546
00548 template<class T>
00549 inline void gnuplot (const std::string& fname, const Vector<T> x, const Vector<T> y)
00550 {
00551 std::fstream f(fname.c_str(),std::ios::out);
00552 for (typename Vector<T>::size_type i=0; i<x.size(); i++)
00553 f << std::scientific << std::showpoint
00554 << std::setprecision(x.precision()) << x[i]
00555 << " "
00556 << std::scientific << std::showpoint
00557 << std::setprecision(y.precision()) << y[i]
00558 << std::endl;
00559 f.close();
00560 }
00561
00563 template<class T>
00564 inline void fill (Vector<T> x, const T& t)
00565 {
00566 for (typename Vector<T>::size_type i=0; i<x.size(); i++)
00567 x[i] = t;
00568 }
00569
00571 template<class T>
00572 inline void fill (Vector<T> x, const T& t, const T& dt)
00573 {
00574 T myt(t);
00575 for (typename Vector<T>::size_type i=0; i<x.size(); i++)
00576 {
00577 x[i] = myt;
00578 myt += dt;
00579 }
00580 }
00581
00583 template<class T>
00584 inline void zero (Vector<T> x)
00585 {
00586 for (typename Vector<T>::size_type i=0; i<x.size(); i++)
00587 x[i] = T(0);
00588 }
00589
00591 template<class T>
00592 inline void unitvector (Vector<T> x, std::size_t j)
00593 {
00594 for (typename Vector<T>::size_type i=0; i<x.size(); i++)
00595 if (i==j)
00596 x[i] = T(1);
00597 else
00598 x[i] = T(0);
00599 }
00600
00601 }
00602
00603 #endif