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
00032 template<class T>
00033 class Vector {
00034
00035 typedef CountableArray<T> ArrayType;
00036
00037 public:
00038
00040 typedef T value_type;
00041
00043 typedef value_type& reference;
00044
00046 typedef const value_type& const_reference;
00047
00049 typedef std::size_t size_type;
00050
00052 typedef std::ptrdiff_t difference_type;
00053
00055 Vector () : base()
00056 {
00057 n = 0;
00058 data = 0;
00059 }
00060
00062 Vector (size_type _n) : base(new ArrayType(_n))
00063 {
00064 n = _n;
00065 data = &((*base)[0]);
00066 }
00067
00069 Vector (size_type _n, const T& _t) : base(new ArrayType(_n,_t))
00070 {
00071 n = _n;
00072 data = &((*base)[0]);
00073 }
00074
00076 Vector (const Vector& v) : base(v.base)
00077 {
00078 n = v.n;
00079 data = v.data;
00080 }
00081
00083 Vector& operator= (const Vector& v)
00084 {
00085 base = v.base;
00086 data = v.data;
00087 n = v.n;
00088 }
00089
00091 Vector<T> sub (size_type i, size_type m) const
00092 {
00093 Vector<T> v;
00094 v.base = base;
00095 v.data = data+i;
00096 v.n = m;
00097 return v;
00098 }
00099
00101 void resize (size_type _n)
00102 {
00103 if (n==_n) return;
00104 if (base->get_reference_counter()==1 && data==(&((*base)[0])) && n==base->size())
00105 {
00106 base->resize(_n);
00107 n = _n;
00108 data = &((*base)[0]);
00109 }
00110 else
00111 HDNUM_THROW(InvalidStateException,"resize called on subvector or while subvectors exist");
00112 }
00113
00115 void resize (size_type _n, const T& _t)
00116 {
00117 if (n==_n) return;
00118 if (base->get_reference_counter()==1 && data==(&((*base)[0])) && n==base->size())
00119 {
00120 base->resize(_n,_t);
00121 n = _n;
00122 data = &((*base)[0]);
00123 }
00124 else
00125 HDNUM_THROW(InvalidStateException,"resize called on subvector or while subvectors exist");
00126 }
00127
00129 reference operator[] (size_type i)
00130 {
00131 return data[i];
00132 }
00133
00135 const_reference operator[] (size_type i) const
00136 {
00137 return data[i];
00138 }
00139
00141 size_type size () const
00142 {
00143 return n;
00144 }
00145
00147 int iwidth () const
00148 {
00149 return iwidth_;
00150 }
00151
00153 int width () const
00154 {
00155 return width_;
00156 }
00157
00159 int precision () const
00160 {
00161 return precision_;
00162 }
00163
00165 void iwidth (int i) const
00166 {
00167 iwidth_=i;
00168 }
00169
00171 void width (int i) const
00172 {
00173 width_=i;
00174 }
00175
00177 void precision (int i) const
00178 {
00179 precision_=i;
00180 }
00181
00183 class iterator {
00184 private:
00185 T* p;
00186 public:
00187 iterator()
00188 {
00189 p=0;
00190 }
00191 iterator (T* p_)
00192 {
00193 p=p_;
00194 }
00195 bool operator!= (iterator x) const
00196 {
00197 return p!=x.p;
00198 }
00199 bool operator== (iterator x) const
00200 {
00201 return p==x.p;
00202 }
00203 iterator operator++ ()
00204 {
00205 p++;
00206 return *this;
00207 }
00208 iterator operator++ (int)
00209 {
00210 p++;
00211 return *this;
00212 }
00213 iterator operator-- ()
00214 {
00215 p--;
00216 return *this;
00217 }
00218 iterator operator-- (int)
00219 {
00220 p--;
00221 return *this;
00222 }
00223 T& operator[] (size_type i) const
00224 {
00225 return p[i];
00226 }
00227 T& operator* () const
00228 {
00229 return *p;
00230 }
00231 T* operator-> () const
00232 {
00233 return p;
00234 }
00235 } ;
00236
00238 class const_iterator {
00239 private:
00240 T* p;
00241 public:
00242 const_iterator()
00243 {
00244 p=0;
00245 }
00246 const_iterator (T* p_)
00247 {
00248 p=p_;
00249 }
00250 bool operator!= (const_iterator x) const
00251 {
00252 return p!=x.p;
00253 }
00254 bool operator== (const_iterator x) const
00255 {
00256 return p==x.p;
00257 }
00258 const_iterator operator++ ()
00259 {
00260 p++;
00261 return *this;
00262 }
00263 const_iterator operator++ (int)
00264 {
00265 p++;
00266 return *this;
00267 }
00268 const_iterator operator-- ()
00269 {
00270 p--;
00271 return *this;
00272 }
00273 const_iterator operator-- (int)
00274 {
00275 p--;
00276 return *this;
00277 }
00278 const T& operator[] (size_type i) const
00279 {
00280 return p[i];
00281 }
00282 const T& operator* () const
00283 {
00284 return *p;
00285 }
00286 const T* operator-> () const
00287 {
00288 return p;
00289 }
00290 } ;
00291
00293 iterator begin ()
00294 {
00295 return iterator(data);
00296 }
00297
00299 iterator end ()
00300 {
00301 return iterator(data+n);
00302 }
00303
00305 iterator rbegin ()
00306 {
00307 return iterator(data+n-1);
00308 }
00309
00311 iterator rend ()
00312 {
00313 return iterator(data-1);
00314 }
00315
00316
00318 const_iterator begin () const
00319 {
00320 return const_iterator(data);
00321 }
00322
00324 const_iterator end () const
00325 {
00326 return const_iterator(data+n);
00327 }
00328
00330 const_iterator rbegin () const
00331 {
00332 return const_iterator(data+n-1);
00333 }
00334
00336 const_iterator rend () const
00337 {
00338 return const_iterator(data-1);
00339 }
00340
00342 Vector& operator+= (const Vector& y)
00343 {
00344 for (size_type i=0; i<n; ++i)
00345 (*this)[i] += y[i];
00346 return *this;
00347 }
00348
00350 Vector& operator-= (const Vector& y)
00351 {
00352 for (size_type i=0; i<n; ++i)
00353 (*this)[i] -= y[i];
00354 return *this;
00355 }
00356
00358 Vector& operator*= (const T& s)
00359 {
00360 for (size_type i=0; i<n; ++i)
00361 (*this)[i] *= s;
00362 return *this;
00363 }
00364
00366 Vector& operator/= (const T& s)
00367 {
00368 for (size_type i=0; i<n; ++i)
00369 (*this)[i] /= s;
00370 return *this;
00371 }
00372
00374 Vector& update (const T& a, const Vector& y)
00375 {
00376 for (size_type i=0; i<n; ++i)
00377 (*this)[i] += a*y[i];
00378 return *this;
00379 }
00380
00382 T operator* (const Vector& y)
00383 {
00384 T sum(T(0));
00385 for (size_type i=0; i<n; ++i)
00386 sum += (*this)[i]*y[i];
00387 return sum;
00388 }
00389
00390 private:
00391 CP<ArrayType> base;
00392 size_type n;
00393 T* data;
00394 static int iwidth_, width_, precision_;
00395 };
00396
00397 template<class T>
00398 int Vector<T>::iwidth_ = 4;
00399 template<class T>
00400 int Vector<T>::width_ = 15;
00401 template<class T>
00402 int Vector<T>::precision_ = 6;
00403
00405 template <class T>
00406 inline std::ostream& operator<< (std::ostream& s, const Vector<T>& x)
00407 {
00408 for (typename Vector<T>::size_type i=0; i<x.size(); i++)
00409 s << "[" << std::setw(x.iwidth()) << i << "] "
00410 << std::setw(x.width()) << std::scientific << std::showpoint
00411 << std::setprecision(x.precision()) << x[i] << std::endl;
00412 return s;
00413 }
00414
00416 template<class T>
00417 inline Vector<T> copy (const Vector<T>& v)
00418 {
00419 Vector<T> w(v.size());
00420 for (typename Vector<T>::size_type i=0; i<v.size(); i++)
00421 w[i] = v[i];
00422 return w;
00423 }
00424
00426 template<class T>
00427 inline void gnuplot (const std::string& fname, const Vector<T>& v)
00428 {
00429 std::fstream f(fname.c_str(),std::ios::out);
00430 for (typename Vector<T>::size_type i=0; i<v.size(); i++)
00431 f << std::setw(v.width()) << i << std::scientific << std::showpoint
00432 << std::setprecision(v.precision()) << v[i] << std::endl;
00433 f.close();
00434 }
00435
00437 template<class T>
00438 inline void gnuplot (const std::string& fname, const Vector<T>& x, const Vector<T>& y)
00439 {
00440 std::fstream f(fname.c_str(),std::ios::out);
00441 for (typename Vector<T>::size_type i=0; i<x.size(); i++)
00442 f << std::scientific << std::showpoint
00443 << std::setprecision(x.precision()) << x[i]
00444 << " "
00445 << std::scientific << std::showpoint
00446 << std::setprecision(y.precision()) << y[i]
00447 << std::endl;
00448 f.close();
00449 }
00450
00452 template<class T>
00453 inline void fill (Vector<T>& x, const T& t)
00454 {
00455 for (typename Vector<T>::size_type i=0; i<x.size(); i++)
00456 x[i] = t;
00457 }
00458
00460 template<class T>
00461 inline void fill (Vector<T>& x, const T& t, const T& dt)
00462 {
00463 T myt(t);
00464 for (typename Vector<T>::size_type i=0; i<x.size(); i++)
00465 {
00466 x[i] = myt;
00467 myt += dt;
00468 }
00469 }
00470
00472 template<class T>
00473 inline void zero (Vector<T>& x)
00474 {
00475 for (typename Vector<T>::size_type i=0; i<x.size(); i++)
00476 x[i] = T(0);
00477 }
00478
00479 }
00480
00481 #endif