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