00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 #ifndef SCPPNT_VEC_H
00051 #define SCPPNT_VEC_H
00052 
00053 #include <iterator>
00054 
00055 #ifdef SCPPNT_NO_DIR_PREFIX
00056 #include "scppnt.h"
00057 #include "scppnt_error.h"
00058 #else
00059 #include "scppnt/scppnt.h"
00060 #include "scppnt/scppnt_error.h"
00061 #endif
00062 
00063 #ifdef SCPPNT_BOUNDS_CHECK
00064 #ifdef SCPPNT_NO_DIR_PREFIX
00065 #include "slice_pointer.h"
00066 #else
00067 #include "scppnt/slice_pointer.h"
00068 #endif
00069 #endif
00070 
00071 
00072 
00073 #ifndef SCPPNT_NO_IO
00074 #include <string>
00075 #include <iostream>
00076 #include <strstream>
00077 #endif
00078 #include <cstdlib> 
00079 #include <iterator>
00080 #include <algorithm>
00081 
00082 namespace SCPPNT
00083 {
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099   template<class T> class Vector
00100   {
00101 
00102 public:
00103 
00104     typedef Subscript size_type; 
00105     typedef T value_type; 
00106     typedef T element_type; 
00107     typedef T& reference; 
00108     typedef const T& const_reference;
00109 
00110     
00111     
00112     
00113 #ifdef SCPPNT_BOUNDS_CHECK
00114     typedef slice_pointer_base<T, T*, T&> pointer;
00115     typedef slice_pointer_base<T, T*, T&> iterator;
00116     typedef slice_pointer_base<T, const T*, const T&> const_iterator;
00117 #else
00118     typedef T* pointer; 
00119     typedef T* iterator; 
00120     typedef const T* const_iterator; 
00121 #endif
00122 
00123 
00124     Subscript lbound() const;
00125 
00126     
00127 
00128     iterator begin(); 
00129     iterator end(); 
00130     const_iterator begin() const; 
00131     const_iterator end() const; 
00132 
00133 
00134     ~Vector();
00135 
00136 
00137     Vector();
00138 
00139 
00140     Vector(Subscript N);
00141 
00142 
00143     Vector(const Vector<T> &A);
00144 
00145 
00146     Vector(Subscript N, const T& value);
00147 
00148 #ifndef SCPPNT_NO_IO
00149 
00150     Vector(Subscript N, const std::string &s);
00151 #endif
00152 
00153     
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166     template<class IT> Vector(IT begin, IT end) :
00167       v_(0)
00168     {
00169 #ifndef BOOST_MSVC
00170       
00171       typename std::iterator_traits<IT>::difference_type N = std::distance(begin, end);
00172 #else
00173       
00174       
00175       unsigned long N = std::distance(begin, end);
00176 #endif
00177       initialize(N);
00178 
00179       iterator i = this->begin();
00180       while (N--)
00181       {
00182         *i = *begin;
00183         ++i;
00184         ++begin;
00185       }
00186     }
00187 
00188 
00189     Vector<T>& newsize(Subscript N);
00190 
00191     
00192     
00193 
00194 
00195     Vector<T>& operator=(const Vector<T> &A);
00196 
00197 
00198     Vector<T>& operator=(const T& scalar);
00199 
00200     
00201 
00202 
00203     Vector<T>& operator+=(const Vector<T> &rhs);
00204 
00205 
00206     Vector<T>& operator+=(const T& value);
00207 
00208 
00209     Vector<T>& operator-=(const Vector<T> &rhs);
00210 
00211 
00212     Vector<T>& operator-=(const T& value);
00213 
00214 
00215     Vector<T>& operator*=(const Vector<T> &rhs);
00216 
00217 
00218     Vector<T>& operator*=(const T& value);
00219 
00220 
00221     Vector<T>& operator/=(const T& value);
00222 
00223 
00224     Subscript dim() const;
00225 
00226 
00227     Subscript size() const;
00228 
00229     
00230 
00231 
00232     inline reference operator()(Subscript i);
00233 
00234 
00235     inline const_reference operator()(Subscript i) const;
00236 
00237 
00238     inline reference operator[](Subscript i);
00239 
00240 
00241     inline const_reference operator[](Subscript i) const;
00242 
00243 protected:
00244     T* v_; 
00245     T* vm1_; 
00246     Subscript n_; 
00247 
00248     
00249 
00250 
00251     void initialize(Subscript N);
00252 
00253 
00254     void copy(const T* v);
00255 
00256 
00257     void set(const T& val);
00258 
00259 
00260     void destroy();
00261 
00262   };
00263 
00264   
00265 
00266   template<class T> void Vector<T>::initialize(Subscript N)
00267   {
00268     
00269     
00270     
00271 
00272     if (v_ != NULL)
00273       throw LogicError(0, "v_ is not NULL", "SCPPNT::Vector::initialize");
00274 
00275     v_ = new T[N];
00276 
00277     vm1_ = v_-1;
00278     n_ = N;
00279   }
00280 
00281   template<class T> void Vector<T>::copy(const T* v)
00282   {
00283     Subscript N = n_;
00284     Subscript i;
00285 
00286 #ifdef SCPPNT_UNROLL_LOOPS
00287     Subscript Nmod4 = N & 3;
00288     Subscript N4 = N - Nmod4;
00289 
00290     for (i=0; i<N4; i+=4)
00291     {
00292       v_[i] = v[i];
00293       v_[i+1] = v[i+1];
00294       v_[i+2] = v[i+2];
00295       v_[i+3] = v[i+3];
00296     }
00297 
00298     for (i=N4; i< N; i++)
00299     v_[i] = v[i];
00300 #else
00301 
00302     for (i=0; i< N; i++)
00303       v_[i] = v[i];
00304 #endif      
00305   }
00306 
00307   template<class T> void Vector<T>::set(const T& val)
00308   {
00309     Subscript N = n_;
00310     Subscript i;
00311 
00312 #ifdef SCPPNT_UNROLL_LOOPS
00313     Subscript Nmod4 = N & 3;
00314     Subscript N4 = N - Nmod4;
00315 
00316     for (i=0; i<N4; i+=4)
00317     {
00318       v_[i] = val;
00319       v_[i+1] = val;
00320       v_[i+2] = val;
00321       v_[i+3] = val;
00322     }
00323 
00324     for (i=N4; i< N; i++)
00325     v_[i] = val;
00326 #else
00327 
00328     for (i=0; i< N; i++)
00329       v_[i] = val;
00330 
00331 #endif      
00332   }
00333 
00334   template<class T> void Vector<T>::destroy()
00335   {
00336     
00337     if (v_ == NULL)
00338       return;
00339 
00340     
00341     delete [] (v_);
00342 
00343     v_ = NULL;
00344     vm1_ = NULL;
00345   }
00346 
00347   
00348   template<class T> Vector<T>::~Vector()
00349   {
00350     destroy();
00351   }
00352 
00353   
00354 
00355   template<class T> Vector<T>::Vector() :
00356     v_(0), vm1_(0), n_(0)
00357   {
00358   }
00359 
00360   template<class T> Vector<T>::Vector(Subscript N) :
00361     v_(0), vm1_(0)
00362   {
00363     initialize(N);
00364   }
00365 
00366   template<class T> Vector<T>::Vector(const Vector<T> &A) :
00367     v_(0), vm1_(0), n_(0)
00368   {
00369     initialize(A.n_);
00370     copy(A.v_);
00371   }
00372 
00373   template<class T> Vector<T>::Vector(Subscript N, const T& value) :
00374     v_(0), vm1_(0)
00375   {
00376     initialize(N);
00377     set(value);
00378   }
00379 
00380   
00381   
00382   
00383   
00384   
00385   
00386 
00387 #ifndef SCPPNT_NO_IO
00388 
00389 
00390 
00391 
00392 
00393 
00394 
00395 
00396 
00397   template<class T> Vector<T>::Vector(Subscript N, const std::string &s) :
00398     v_(0), vm1_(0), n_(0)
00399   {
00400     initialize(N);
00401     std::istrstream ins(s.c_str());
00402 
00403     Subscript i;
00404 
00405     for (i=0; i<N; i++)
00406       ins >> v_[i];
00407   }
00408 #endif
00409 
00410   
00411   
00412   template<class T> Vector<T>& Vector<T>::newsize(Subscript N)
00413   {
00414     if (n_ == N)
00415       return *this;
00416 
00417     destroy();
00418     initialize(N);
00419 
00420     return *this;
00421   }
00422 
00423   
00424   
00425   template<class T> Vector<T>& Vector<T>::operator=(const Vector<T> &A)
00426   {
00427     if (v_ == A.v_)
00428     return *this;
00429 
00430     if (n_ == A.n_) 
00431     copy(A.v_);
00432 
00433     else
00434     {
00435       destroy();
00436       initialize(A.n_);
00437       copy(A.v_);
00438     }
00439 
00440     return *this;
00441   }
00442 
00443   
00444   template <class T>
00445   Vector<T>& Vector<T>::operator=(const T& scalar)
00446   {
00447     set(scalar);
00448     return *this;
00449   }
00450 
00451   
00452   
00453   
00454   template <class T>
00455   Vector<T>& Vector<T>::operator+=(const Vector<T> &rhs)
00456   {
00457 
00458     if (n_ != rhs.dim()) throw BadDimension("SCPPNT::Vector::operator+=");
00459 
00460     const_iterator rhsiter = rhs.begin();
00461     iterator end = this->end();
00462     for (iterator p = begin(); p != end; ++p, ++rhsiter)
00463     {
00464       *p += *rhsiter;
00465     }
00466 
00467     return *this;
00468 
00469   }
00470 
00471   
00472   template <class T>
00473   Vector<T>& Vector<T>::operator+=(const T& value)
00474   {
00475     iterator end = this->end();
00476     for (iterator p = begin(); p != end; ++p)
00477     {
00478       *p += value;
00479     }
00480 
00481     return *this;
00482 
00483   }
00484 
00485   
00486   
00487   
00488   template <class T>
00489   Vector<T>& Vector<T>::operator-=(const Vector<T> &rhs)
00490   {
00491 
00492     if (n_ != rhs.dim()) throw BadDimension("SCPPNT::Vector::operator-=");
00493 
00494     const_iterator rhsiter = rhs.begin();
00495     iterator end = this->end();
00496     for (iterator p = begin(); p != end; ++p, ++rhsiter)
00497     {
00498       *p -= *rhsiter;
00499     }
00500 
00501     return *this;
00502 
00503   }
00504 
00505   
00506   template <class T>
00507   Vector<T>& Vector<T>::operator-=(const T& value)
00508   {
00509     iterator end = this->end();
00510     for (iterator p = begin(); p != end; ++p)
00511     {
00512       *p -= value;
00513     }
00514 
00515     return *this;
00516 
00517   }
00518 
00519   
00520   
00521   
00522   template <class T>
00523   Vector<T>& Vector<T>::operator*=(const Vector<T> &rhs)
00524   {
00525 
00526     if (n_ != rhs.dim()) throw BadDimension("SCPPNT::Vector::operator*=");
00527 
00528     const_iterator rhsiter = rhs.begin();
00529     iterator end = this->end();
00530     for (iterator p = begin(); p != end; ++p, ++rhsiter)
00531     {
00532       *p *= *rhsiter;
00533     }
00534 
00535     return *this;
00536 
00537   }
00538 
00539   
00540   template <class T>
00541   Vector<T>& Vector<T>::operator*=(const T& value)
00542   {
00543     iterator end = this->end();
00544     for (iterator p = begin(); p != end; ++p)
00545     {
00546       *p *= value;
00547     }
00548 
00549     return *this;
00550 
00551   }
00552 
00553   
00554   template <class T>
00555   Vector<T>& Vector<T>::operator/=(const T& value)
00556   {
00557     iterator end = this->end();
00558     for (iterator p = begin(); p != end; ++p)
00559     {
00560       *p /= value;
00561     }
00562 
00563     return *this;
00564 
00565   }
00566 
00567   template <class T>
00568   inline Subscript Vector<T>::lbound() const
00569   { return 1;}
00570 
00571   template <class T>
00572   inline Subscript Vector<T>::dim() const
00573   {
00574     return n_;
00575   }
00576 
00577   template <class T>
00578   inline Subscript Vector<T>::size() const
00579   {
00580     return n_;
00581   }
00582 
00583   
00584   template <class T>
00585   inline typename Vector<T>::reference Vector<T>::operator()(Subscript i)
00586   {
00587 #ifdef SCPPNT_BOUNDS_CHECK
00588     if (i < 1 || i > n_) throw BoundsError("SCPPNT::Vector::operator()");
00589 #endif
00590     return vm1_[i];
00591   }
00592 
00593   template <class T>
00594   inline typename Vector<T>::const_reference Vector<T>::operator() (Subscript i) const
00595   {
00596 #ifdef SCPPNT_BOUNDS_CHECK
00597     if (i < 1 || i > n_) throw BoundsError("SCPPNT::Vector::operator() const");
00598 #endif
00599     return vm1_[i];
00600   }
00601 
00602   template <class T>
00603   inline typename Vector<T>::reference Vector<T>::operator[](Subscript i)
00604   {
00605 #ifdef SCPPNT_BOUNDS_CHECK
00606     if (i < 0 || i >= n_) throw BoundsError("SCPPNT::Vector::operator[]");
00607 #endif
00608     return v_[i];
00609   }
00610 
00611   template <class T>
00612   inline typename Vector<T>::const_reference Vector<T>::operator[](Subscript i) const
00613   {
00614 #ifdef SCPPNT_BOUNDS_CHECK
00615     if (i < 0 || i >= n_) throw BoundsError("SCPPNT::Vector::operator[] const");
00616 #endif
00617     return v_[i];
00618   }
00619 
00620   
00621   template <class T>
00622   inline typename Vector<T>::iterator Vector<T>::begin()
00623   {
00624 #ifdef SCPPNT_BOUNDS_CHECK
00625     return iterator(v_, 1, n_);
00626 #else
00627     return v_;
00628 #endif
00629   }
00630 
00631   template <class T>
00632   inline typename Vector<T>::iterator Vector<T>::end()
00633   {
00634 #ifdef SCPPNT_BOUNDS_CHECK
00635     iterator p(v_, 1, n_);
00636     return p + n_;
00637 #else
00638     return v_ + n_;
00639 #endif
00640   }
00641 
00642   template <class T>
00643   inline typename Vector<T>::const_iterator Vector<T>::begin() const
00644   {
00645 #ifdef SCPPNT_BOUNDS_CHECK
00646     return const_iterator(v_, 1, n_);
00647 #else
00648     return v_;
00649 #endif
00650   }
00651 
00652   template <class T>
00653   inline typename Vector<T>::const_iterator Vector<T>::end() const
00654   {
00655 #ifdef SCPPNT_BOUNDS_CHECK
00656     const const_iterator p(v_, 1, n_);
00657     return p + n_;
00658 #else
00659     return v_ + n_;
00660 #endif
00661   }
00662 
00663 #ifndef SCPPNT_NO_IO
00664   
00665 
00666 
00667 
00668 
00669 
00670 
00671 
00672 
00673   template <class T>
00674   std::ostream& operator<<(std::ostream &s, const Vector<T> &A)
00675   {
00676     Subscript N=A.dim();
00677 
00678     s << N << std::endl;
00679 
00680     for (Subscript i=0; i<N; i++)
00681     s << A[i] << " " << std::endl;
00682     s << std::endl;
00683 
00684     return s;
00685   }
00686 
00687 
00688 
00689 
00690 
00691 
00692 
00693 
00694   template <class T>
00695   std::istream & operator>>(std::istream &s, Vector<T> &A)
00696   {
00697 
00698     Subscript N;
00699 
00700     s >> N;
00701 
00702     A.newsize(N);
00703 
00704     for (Subscript i=0; i<N; i++)
00705     s >> A[i];
00706 
00707     return s;
00708   }
00709 #endif
00710 
00711   
00712 
00713 
00714   template <class T>
00715   Vector<T> operator+(const Vector<T> &lhs,
00716       const Vector<T> &rhs)
00717   {
00718     return Vector<T>(lhs) += rhs;
00719   }
00720 
00721 
00722   template <class T>
00723   Vector<T> operator+(const Vector<T> &lhs,
00724       const T value)
00725   {
00726     return Vector<T>(lhs) += value;
00727   }
00728 
00729 
00730   template <class T>
00731   Vector<T> operator-(const Vector<T> &lhs,
00732       const Vector<T> &rhs)
00733   {
00734     return Vector<T>(lhs) -= rhs;
00735   }
00736 
00737 
00738   template <class T>
00739   Vector<T> operator-(const Vector<T> &lhs,
00740       const T value)
00741   {
00742     return Vector<T>(lhs) -= value;
00743   }
00744 
00745 
00746   template <class T>
00747   Vector<T> operator*(const Vector<T> &lhs,
00748       const Vector<T> &rhs)
00749   {
00750     return Vector<T>(lhs) *= rhs;
00751   }
00752 
00753 
00754   template <class T>
00755   Vector<T> operator*(const Vector<T> &lhs,
00756       const T value)
00757   {
00758     return Vector<T>(lhs) *= value;
00759   }
00760 
00761   
00762 
00763 
00764 
00765 
00766 
00767 
00768 
00769 
00770 
00771 
00772 
00773   template <class IT1, class IT2>
00774   typename std::iterator_traits<IT1>::value_type dot_prod(Subscript N, IT1 i1, IT2 i2)
00775   {
00776 
00777     typename std::iterator_traits<IT1>::value_type sum = 0;
00778     while(N--)
00779     {
00780       sum += *i1 * *i2;
00781       ++i1;
00782       ++i2;
00783     }
00784 
00785     return sum;
00786   }
00787 
00788 
00789   template <class T>
00790   inline T dot_prod(const Vector<T> &A, const Vector<T> &B)
00791   {
00792     Subscript N = A.dim();
00793 
00794     if (N != B.dim()) throw BadDimension("SCPPNT::dot_prod()");
00795 
00796     return dot_prod(N, A.begin(), B.begin());
00797   }
00798 
00799 } 
00800 
00801 #endif
00802