IT++ Logo

vec.h

Go to the documentation of this file.
00001 
00030 #ifndef VEC_H
00031 #define VEC_H
00032 
00033 #ifndef _MSC_VER
00034 #  include <itpp/config.h>
00035 #else
00036 #  include <itpp/config_msvc.h>
00037 #endif
00038 
00039 #include <itpp/base/itassert.h>
00040 #include <itpp/base/math/misc.h>
00041 #include <itpp/base/copy_vector.h>
00042 #include <itpp/base/factory.h>
00043 
00044 
00045 namespace itpp
00046 {
00047 
00048 // Declaration of Vec
00049 template<class Num_T> class Vec;
00050 // Declaration of Mat
00051 template<class Num_T> class Mat;
00052 // Declaration of bin
00053 class bin;
00054 
00055 //-----------------------------------------------------------------------------------
00056 // Declaration of Vec Friends
00057 //-----------------------------------------------------------------------------------
00058 
00060 template<class Num_T>
00061 Vec<Num_T> operator+(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
00063 template<class Num_T>
00064 Vec<Num_T> operator+(const Vec<Num_T> &v, Num_T t);
00066 template<class Num_T>
00067 Vec<Num_T> operator+(Num_T t, const Vec<Num_T> &v);
00068 
00070 template<class Num_T>
00071 Vec<Num_T> operator-(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
00073 template<class Num_T>
00074 Vec<Num_T> operator-(const Vec<Num_T> &v, Num_T t);
00076 template<class Num_T>
00077 Vec<Num_T> operator-(Num_T t, const Vec<Num_T> &v);
00079 template<class Num_T>
00080 Vec<Num_T> operator-(const Vec<Num_T> &v);
00081 
00083 template<class Num_T>
00084 Num_T dot(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
00086 template<class Num_T>
00087 Num_T operator*(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
00096 template<class Num_T>
00097 Mat<Num_T> outer_product(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
00098                          bool hermitian = false);
00100 template<class Num_T>
00101 Vec<Num_T> operator*(const Vec<Num_T> &v, Num_T t);
00103 template<class Num_T>
00104 Vec<Num_T> operator*(Num_T t, const Vec<Num_T> &v);
00105 
00107 template<class Num_T>
00108 Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b);
00110 template<class Num_T>
00111 Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b,
00112                      const Vec<Num_T> &c);
00114 template<class Num_T>
00115 Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b,
00116                      const Vec<Num_T> &c, const Vec<Num_T> &d);
00117 
00119 template<class Num_T>
00120 void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b,
00121                    Vec<Num_T> &out);
00123 template<class Num_T>
00124 void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b,
00125                    const Vec<Num_T> &c, Vec<Num_T> &out);
00127 template<class Num_T>
00128 void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b,
00129                    const Vec<Num_T> &c, const Vec<Num_T> &d,
00130                    Vec<Num_T> &out);
00131 
00133 template<class Num_T>
00134 void elem_mult_inplace(const Vec<Num_T> &a, Vec<Num_T> &b);
00136 template<class Num_T>
00137 Num_T elem_mult_sum(const Vec<Num_T> &a, const Vec<Num_T> &b);
00138 
00140 template<class Num_T>
00141 Vec<Num_T> operator/(const Vec<Num_T> &v, Num_T t);
00143 template<class Num_T>
00144 Vec<Num_T> operator/(Num_T t, const Vec<Num_T> &v);
00145 
00147 template<class Num_T>
00148 Vec<Num_T> elem_div(const Vec<Num_T> &a, const Vec<Num_T> &b);
00150 template<class Num_T>
00151 Vec<Num_T> elem_div(Num_T t, const Vec<Num_T> &v);
00153 template<class Num_T>
00154 void elem_div_out(const Vec<Num_T> &a, const Vec<Num_T> &b, Vec<Num_T> &out);
00156 template<class Num_T>
00157 Num_T elem_div_sum(const Vec<Num_T> &a, const Vec<Num_T> &b);
00158 
00160 template<class Num_T>
00161 Vec<Num_T> concat(const Vec<Num_T> &v, Num_T a);
00163 template<class Num_T>
00164 Vec<Num_T> concat(Num_T a, const Vec<Num_T> &v);
00166 template<class Num_T>
00167 Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
00169 template<class Num_T>
00170 Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
00171                   const Vec<Num_T> &v3);
00173 template<class Num_T>
00174 Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
00175                   const Vec<Num_T> &v3, const Vec<Num_T> &v4);
00177 template<class Num_T>
00178 Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
00179                   const Vec<Num_T> &v3, const Vec<Num_T> &v4,
00180                   const Vec<Num_T> &v5);
00181 
00182 //-----------------------------------------------------------------------------------
00183 // Declaration of Vec
00184 //-----------------------------------------------------------------------------------
00185 
00249 template<class Num_T>
00250 class Vec
00251 {
00252 public:
00254   typedef Num_T value_type;
00255 
00257   explicit Vec(const Factory &f = DEFAULT_FACTORY);
00259   explicit Vec(int size, const Factory &f = DEFAULT_FACTORY);
00261   Vec(const Vec<Num_T> &v);
00263   Vec(const Vec<Num_T> &v, const Factory &f);
00265   Vec(const char *values, const Factory &f = DEFAULT_FACTORY);
00267   Vec(const std::string &values, const Factory &f = DEFAULT_FACTORY);
00269   Vec(const Num_T *c_array, int size, const Factory &f = DEFAULT_FACTORY);
00270 
00272   ~Vec();
00273 
00275   int length() const { return datasize; }
00277   int size() const { return datasize; }
00278 
00280   void set_size(int size, bool copy = false);
00282   void set_length(int size, bool copy = false) { set_size(size, copy); }
00284   void zeros();
00286   void clear() { zeros(); }
00288   void ones();
00290   void set(const char *str);
00292   void set(const std::string &str);
00293 
00295   const Num_T &operator[](int i) const;
00297   const Num_T &operator()(int i) const;
00299   Num_T &operator[](int i);
00301   Num_T &operator()(int i);
00303   const Vec<Num_T> operator()(int i1, int i2) const;
00305   const Vec<Num_T> operator()(const Vec<int> &indexlist) const;
00306 
00308   const Num_T &get(int i) const;
00310   Vec<Num_T> get(int i1, int i2) const;
00312   Vec<Num_T> get(const Vec<bin> &binlist) const;
00313 
00315   void set(int i, Num_T t);
00316 
00318   Mat<Num_T> transpose() const;
00320   Mat<Num_T> T() const { return this->transpose(); }
00322   Mat<Num_T> hermitian_transpose() const;
00324   Mat<Num_T> H() const { return this->hermitian_transpose(); }
00325 
00327   Vec<Num_T>& operator+=(const Vec<Num_T> &v);
00329   Vec<Num_T>& operator+=(Num_T t);
00331   friend Vec<Num_T> operator+<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
00333   friend Vec<Num_T> operator+<>(const Vec<Num_T> &v, Num_T t);
00335   friend Vec<Num_T> operator+<>(Num_T t, const Vec<Num_T> &v);
00336 
00338   Vec<Num_T>& operator-=(const Vec<Num_T> &v);
00340   Vec<Num_T>& operator-=(Num_T t);
00342   friend Vec<Num_T> operator-<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
00344   friend Vec<Num_T> operator-<>(const Vec<Num_T> &v, Num_T t);
00346   friend Vec<Num_T> operator-<>(Num_T t, const Vec<Num_T> &v);
00348   friend Vec<Num_T> operator-<>(const Vec<Num_T> &v);
00349 
00351   Vec<Num_T>& operator*=(Num_T t);
00353   friend Num_T operator*<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
00355   friend Num_T dot<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
00357   friend Mat<Num_T> outer_product<>(const Vec<Num_T> &v1,
00358                                     const Vec<Num_T> &v2, bool hermitian);
00360   friend Vec<Num_T> operator*<>(const Vec<Num_T> &v, Num_T t);
00362   friend Vec<Num_T> operator*<>(Num_T t, const Vec<Num_T> &v);
00363 
00365   friend Vec<Num_T> elem_mult<>(const Vec<Num_T> &a, const Vec<Num_T> &b);
00367   friend Vec<Num_T> elem_mult<>(const Vec<Num_T> &a, const Vec<Num_T> &b,
00368                                 const Vec<Num_T> &c);
00370   friend Vec<Num_T> elem_mult<>(const Vec<Num_T> &a, const Vec<Num_T> &b,
00371                                 const Vec<Num_T> &c, const Vec<Num_T> &d);
00372 
00374   friend void elem_mult_out<>(const Vec<Num_T> &a, const Vec<Num_T> &b,
00375                               Vec<Num_T> &out);
00377   friend void elem_mult_out<>(const Vec<Num_T> &a, const Vec<Num_T> &b,
00378                               const Vec<Num_T> &c, Vec<Num_T> &out);
00380   friend void elem_mult_out<>(const Vec<Num_T> &a, const Vec<Num_T> &b,
00381                               const Vec<Num_T> &c, const Vec<Num_T> &d,
00382                               Vec<Num_T> &out);
00383 
00385   friend void elem_mult_inplace<>(const Vec<Num_T> &a, Vec<Num_T> &b);
00387   friend Num_T elem_mult_sum<>(const Vec<Num_T> &a, const Vec<Num_T> &b);
00388 
00390   Vec<Num_T>& operator/=(Num_T t);
00392   Vec<Num_T>& operator/=(const Vec<Num_T> &v);
00393 
00395   friend Vec<Num_T> operator/<>(const Vec<Num_T> &v, Num_T t);
00397   friend Vec<Num_T> operator/<>(Num_T t, const Vec<Num_T> &v);
00398 
00400   friend Vec<Num_T> elem_div<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
00402   friend Vec<Num_T> elem_div<>(Num_T t, const Vec<Num_T> &v);
00404   friend void elem_div_out<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
00405                              Vec<Num_T> &out);
00407   friend Num_T elem_div_sum<>(const Vec<Num_T> &a, const Vec<Num_T> &b);
00408 
00410   Vec<Num_T> right(int nr) const;
00412   Vec<Num_T> left(int nr) const;
00414   Vec<Num_T> mid(int start, int nr) const;
00416   Vec<Num_T> split(int pos);
00418   void shift_right(Num_T t, int n = 1);
00420   void shift_right(const Vec<Num_T> &v);
00422   void shift_left(Num_T t, int n = 1);
00424   void shift_left(const Vec<Num_T> &v);
00425 
00427   friend Vec<Num_T> concat<>(const Vec<Num_T> &v, Num_T t);
00429   friend Vec<Num_T> concat<>(Num_T t, const Vec<Num_T> &v);
00431   friend Vec<Num_T> concat<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
00433   friend Vec<Num_T> concat<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
00434                              const Vec<Num_T> &v3);
00436   friend Vec<Num_T> concat<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
00437                              const Vec<Num_T> &v3, const Vec<Num_T> &v4);
00439   friend Vec<Num_T> concat<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
00440                              const Vec<Num_T> &v3, const Vec<Num_T> &v4,
00441                              const Vec<Num_T> &v5);
00442 
00444   void set_subvector(int i1, int i2, const Vec<Num_T> &v);
00446   void set_subvector(int i, const Vec<Num_T> &v);
00448   void set_subvector(int i1, int i2, Num_T t);
00450   void replace_mid(int i, const Vec<Num_T> &v);
00452   void del(int i);
00454   void del(int i1, int i2);
00456   void ins(int i, Num_T t);
00458   void ins(int i, const Vec<Num_T> &v);
00459 
00461   Vec<Num_T>& operator=(Num_T t);
00463   Vec<Num_T>& operator=(const Vec<Num_T> &v);
00465   Vec<Num_T>& operator=(const Mat<Num_T> &m);
00467   Vec<Num_T>& operator=(const char *values);
00468 
00470   Vec<bin> operator==(Num_T t) const;
00472   Vec<bin> operator!=(Num_T t) const;
00474   Vec<bin> operator<(Num_T t) const;
00476   Vec<bin> operator<=(Num_T t) const;
00478   Vec<bin> operator>(Num_T t) const;
00480   Vec<bin> operator>=(Num_T t) const;
00481 
00483   bool operator==(const Vec<Num_T> &v) const;
00485   bool operator!=(const Vec<Num_T> &v) const;
00486 
00488   Num_T &_elem(int i) { return data[i]; }
00490   const Num_T &_elem(int i) const { return data[i]; }
00491 
00493   Num_T *_data() { return data; }
00495   const Num_T *_data() const { return data; }
00496 
00497 protected:
00499   void alloc(int size);
00501   void free();
00502 
00504   int datasize;
00506   Num_T *data;
00508   const Factory &factory;
00509 private:
00510   // This function is used in set() methods to replace commas with spaces
00511   std::string replace_commas(const std::string &str);
00513   bool in_range(int i) const { return ((i < datasize) && (i >= 0)); }
00514 };
00515 
00516 //-----------------------------------------------------------------------------------
00517 // Type definitions of vec, cvec, ivec, svec, and bvec
00518 //-----------------------------------------------------------------------------------
00519 
00524 typedef Vec<double> vec;
00525 
00530 typedef Vec<std::complex<double> > cvec;
00531 
00536 typedef Vec<int> ivec;
00537 
00542 typedef Vec<short int> svec;
00543 
00548 typedef Vec<bin> bvec;
00549 
00550 } //namespace itpp
00551 
00552 
00553 #include <itpp/base/mat.h>
00554 
00555 namespace itpp
00556 {
00557 
00558 //-----------------------------------------------------------------------------------
00559 // Declaration of input and output streams for Vec
00560 //-----------------------------------------------------------------------------------
00561 
00566 template<class Num_T>
00567 std::ostream &operator<<(std::ostream &os, const Vec<Num_T> &v);
00568 
00580 template<class Num_T>
00581 std::istream &operator>>(std::istream &is, Vec<Num_T> &v);
00582 
00583 //-----------------------------------------------------------------------------------
00584 // Implementation of templated Vec members and friends
00585 //-----------------------------------------------------------------------------------
00586 
00587 template<class Num_T> inline
00588 void Vec<Num_T>::alloc(int size)
00589 {
00590   if (size > 0) {
00591     create_elements(data, size, factory);
00592     datasize = size;
00593   }
00594   else {
00595     data = 0;
00596     datasize = 0;
00597   }
00598 }
00599 
00600 template<class Num_T> inline
00601 void Vec<Num_T>::free()
00602 {
00603   destroy_elements(data, datasize);
00604   datasize = 0;
00605 }
00606 
00607 
00608 template<class Num_T> inline
00609 Vec<Num_T>::Vec(const Factory &f) : datasize(0), data(0), factory(f) {}
00610 
00611 template<class Num_T> inline
00612 Vec<Num_T>::Vec(int size, const Factory &f) : datasize(0), data(0), factory(f)
00613 {
00614   it_assert_debug(size >= 0, "Negative size in Vec::Vec(int)");
00615   alloc(size);
00616 }
00617 
00618 template<class Num_T> inline
00619 Vec<Num_T>::Vec(const Vec<Num_T> &v) : datasize(0), data(0), factory(v.factory)
00620 {
00621   alloc(v.datasize);
00622   copy_vector(datasize, v.data, data);
00623 }
00624 
00625 template<class Num_T> inline
00626 Vec<Num_T>::Vec(const Vec<Num_T> &v, const Factory &f) : datasize(0), data(0), factory(f)
00627 {
00628   alloc(v.datasize);
00629   copy_vector(datasize, v.data, data);
00630 }
00631 
00632 template<class Num_T> inline
00633 Vec<Num_T>::Vec(const char *values, const Factory &f) : datasize(0), data(0), factory(f)
00634 {
00635   set(values);
00636 }
00637 
00638 template<class Num_T> inline
00639 Vec<Num_T>::Vec(const std::string &values, const Factory &f) : datasize(0), data(0), factory(f)
00640 {
00641   set(values);
00642 }
00643 
00644 template<class Num_T> inline
00645 Vec<Num_T>::Vec(const Num_T *c_array, int size, const Factory &f) : datasize(0), data(0), factory(f)
00646 {
00647   alloc(size);
00648   copy_vector(size, c_array, data);
00649 }
00650 
00651 template<class Num_T> inline
00652 Vec<Num_T>::~Vec()
00653 {
00654   free();
00655 }
00656 
00657 template<class Num_T>
00658 void Vec<Num_T>::set_size(int size, bool copy)
00659 {
00660   it_assert_debug(size >= 0, "Vec::set_size(): New size must not be negative");
00661   if (datasize == size)
00662     return;
00663   if (copy) {
00664     // create a temporary pointer to the allocated data
00665     Num_T* tmp = data;
00666     // store the current number of elements
00667     int old_datasize = datasize;
00668     // check how many elements we need to copy
00669     int min = datasize < size ? datasize : size;
00670     // allocate new memory
00671     alloc(size);
00672     // copy old elements into a new memory region
00673     copy_vector(min, tmp, data);
00674     // initialize the rest of resized vector
00675     for (int i = min; i < size; ++i)
00676       data[i] = Num_T(0);
00677     // delete old elements
00678     destroy_elements(tmp, old_datasize);
00679   }
00680   else {
00681     free();
00682     alloc(size);
00683   }
00684 }
00685 
00686 template<class Num_T> inline
00687 const Num_T& Vec<Num_T>::operator[](int i) const
00688 {
00689   it_assert_debug(in_range(i), "Vec<>::operator[]: Index out of range");
00690   return data[i];
00691 }
00692 
00693 template<class Num_T> inline
00694 const Num_T& Vec<Num_T>::operator()(int i) const
00695 {
00696   it_assert_debug(in_range(i), "Vec<>::operator(): Index out of range");
00697   return data[i];
00698 }
00699 
00700 template<class Num_T> inline
00701 Num_T& Vec<Num_T>::operator[](int i)
00702 {
00703   it_assert_debug(in_range(i), "Vec<>::operator[]: Index out of range");
00704   return data[i];
00705 }
00706 
00707 template<class Num_T> inline
00708 Num_T& Vec<Num_T>::operator()(int i)
00709 {
00710   it_assert_debug(in_range(i), "Vec<>::operator(): Index out of range");
00711   return data[i];
00712 }
00713 
00714 template<class Num_T> inline
00715 const Vec<Num_T> Vec<Num_T>::operator()(int i1, int i2) const
00716 {
00717   if (i1 == -1) i1 = datasize - 1;
00718   if (i2 == -1) i2 = datasize - 1;
00719 
00720   it_assert_debug((i1 >= 0) && (i1 <= i2) && (i2 < datasize),
00721                   "Vec<>::operator()(i1, i2): Indexing out of range");
00722 
00723   Vec<Num_T> s(i2 - i1 + 1);
00724   copy_vector(s.datasize, data + i1, s.data);
00725 
00726   return s;
00727 }
00728 
00729 template<class Num_T>
00730 const Vec<Num_T> Vec<Num_T>::operator()(const Vec<int> &indexlist) const
00731 {
00732   Vec<Num_T> temp(indexlist.length());
00733   for (int i = 0;i < indexlist.length();i++) {
00734     it_assert_debug(in_range(indexlist(i)), "Vec<>::operator()(ivec &): "
00735                     "Index i=" << i << " out of range");
00736     temp(i) = data[indexlist(i)];
00737   }
00738   return temp;
00739 }
00740 
00741 
00742 template<class Num_T> inline
00743 const Num_T& Vec<Num_T>::get(int i) const
00744 {
00745   it_assert_debug(in_range(i), "Vec<>::get(): Index out of range");
00746   return data[i];
00747 }
00748 
00749 template<class Num_T> inline
00750 Vec<Num_T> Vec<Num_T>::get(int i1, int i2) const
00751 {
00752   return (*this)(i1, i2);
00753 }
00754 
00755 
00756 template<class Num_T> inline
00757 void Vec<Num_T>::zeros()
00758 {
00759   for (int i = 0; i < datasize; i++)
00760     data[i] = Num_T(0);
00761 }
00762 
00763 template<class Num_T> inline
00764 void Vec<Num_T>::ones()
00765 {
00766   for (int i = 0; i < datasize; i++)
00767     data[i] = Num_T(1);
00768 }
00769 
00770 template<class Num_T> inline
00771 void Vec<Num_T>::set(int i, Num_T t)
00772 {
00773   it_assert_debug(in_range(i), "Vec<>::set(i, t): Index out of range");
00774   data[i] = t;
00775 }
00776 
00778 template<>
00779 void Vec<double>::set(const std::string &str);
00780 template<>
00781 void Vec<std::complex<double> >::set(const std::string &str);
00782 template<>
00783 void Vec<int>::set(const std::string &str);
00784 template<>
00785 void Vec<short int>::set(const std::string &str);
00786 template<>
00787 void Vec<bin>::set(const std::string &str);
00789 
00790 template<class Num_T>
00791 void Vec<Num_T>::set(const std::string &str)
00792 {
00793   it_error("Vec::set(): Only `double', `complex<double>', `int', "
00794            "`short int' and `bin' types supported");
00795 }
00796 
00797 template<class Num_T> inline
00798 void Vec<Num_T>::set(const char *str)
00799 {
00800   set(std::string(str));
00801 }
00802 
00803 
00804 template<class Num_T>
00805 Mat<Num_T> Vec<Num_T>::transpose() const
00806 {
00807   Mat<Num_T> temp(1, datasize);
00808   copy_vector(datasize, data, temp._data());
00809   return temp;
00810 }
00811 
00813 template<>
00814 Mat<std::complex<double> > Vec<std::complex<double> >::hermitian_transpose() const;
00816 
00817 template<class Num_T>
00818 Mat<Num_T> Vec<Num_T>::hermitian_transpose() const
00819 {
00820   Mat<Num_T> temp(1, datasize);
00821   copy_vector(datasize, data, temp._data());
00822   return temp;
00823 }
00824 
00825 template<class Num_T>
00826 Vec<Num_T>& Vec<Num_T>::operator+=(const Vec<Num_T> &v)
00827 {
00828   if (datasize == 0) { // if not assigned a size.
00829     if (this != &v) { // check for self addition
00830       alloc(v.datasize);
00831       copy_vector(datasize, v.data, data);
00832     }
00833   }
00834   else {
00835     it_assert_debug(datasize == v.datasize, "Vec::operator+=: Wrong sizes");
00836     for (int i = 0; i < datasize; i++)
00837       data[i] += v.data[i];
00838   }
00839   return *this;
00840 }
00841 
00842 template<class Num_T> inline
00843 Vec<Num_T>& Vec<Num_T>::operator+=(Num_T t)
00844 {
00845   for (int i = 0;i < datasize;i++)
00846     data[i] += t;
00847   return *this;
00848 }
00849 
00850 template<class Num_T>
00851 Vec<Num_T> operator+(const Vec<Num_T> &v1, const Vec<Num_T> &v2)
00852 {
00853   int i;
00854   Vec<Num_T> r(v1.datasize);
00855 
00856   it_assert_debug(v1.datasize == v2.datasize, "Vec::operator+: wrong sizes");
00857   for (i = 0; i < v1.datasize; i++)
00858     r.data[i] = v1.data[i] + v2.data[i];
00859 
00860   return r;
00861 }
00862 
00863 template<class Num_T>
00864 Vec<Num_T> operator+(const Vec<Num_T> &v, Num_T t)
00865 {
00866   int i;
00867   Vec<Num_T> r(v.datasize);
00868 
00869   for (i = 0; i < v.datasize; i++)
00870     r.data[i] = v.data[i] + t;
00871 
00872   return r;
00873 }
00874 
00875 template<class Num_T>
00876 Vec<Num_T> operator+(Num_T t, const Vec<Num_T> &v)
00877 {
00878   int i;
00879   Vec<Num_T> r(v.datasize);
00880 
00881   for (i = 0; i < v.datasize; i++)
00882     r.data[i] = t + v.data[i];
00883 
00884   return r;
00885 }
00886 
00887 template<class Num_T>
00888 Vec<Num_T>& Vec<Num_T>::operator-=(const Vec<Num_T> &v)
00889 {
00890   if (datasize == 0) { // if not assigned a size.
00891     if (this != &v) { // check for self decrementation
00892       alloc(v.datasize);
00893       for (int i = 0; i < v.datasize; i++)
00894         data[i] = -v.data[i];
00895     }
00896   }
00897   else {
00898     it_assert_debug(datasize == v.datasize, "Vec::operator-=: Wrong sizes");
00899     for (int i = 0; i < datasize; i++)
00900       data[i] -= v.data[i];
00901   }
00902   return *this;
00903 }
00904 
00905 template<class Num_T> inline
00906 Vec<Num_T>& Vec<Num_T>::operator-=(Num_T t)
00907 {
00908   for (int i = 0;i < datasize;i++)
00909     data[i] -= t;
00910   return *this;
00911 }
00912 
00913 template<class Num_T>
00914 Vec<Num_T> operator-(const Vec<Num_T> &v1, const Vec<Num_T> &v2)
00915 {
00916   int i;
00917   Vec<Num_T> r(v1.datasize);
00918 
00919   it_assert_debug(v1.datasize == v2.datasize, "Vec::operator-: wrong sizes");
00920   for (i = 0; i < v1.datasize; i++)
00921     r.data[i] = v1.data[i] - v2.data[i];
00922 
00923   return r;
00924 }
00925 
00926 template<class Num_T>
00927 Vec<Num_T> operator-(const Vec<Num_T> &v, Num_T t)
00928 {
00929   int i;
00930   Vec<Num_T> r(v.datasize);
00931 
00932   for (i = 0; i < v.datasize; i++)
00933     r.data[i] = v.data[i] - t;
00934 
00935   return r;
00936 }
00937 
00938 template<class Num_T>
00939 Vec<Num_T> operator-(Num_T t, const Vec<Num_T> &v)
00940 {
00941   int i;
00942   Vec<Num_T> r(v.datasize);
00943 
00944   for (i = 0; i < v.datasize; i++)
00945     r.data[i] = t - v.data[i];
00946 
00947   return r;
00948 }
00949 
00950 template<class Num_T>
00951 Vec<Num_T> operator-(const Vec<Num_T> &v)
00952 {
00953   int i;
00954   Vec<Num_T> r(v.datasize);
00955 
00956   for (i = 0; i < v.datasize; i++)
00957     r.data[i] = -v.data[i];
00958 
00959   return r;
00960 }
00961 
00962 template<class Num_T> inline
00963 Vec<Num_T>& Vec<Num_T>::operator*=(Num_T t)
00964 {
00965   scal_vector(datasize, t, data);
00966   return *this;
00967 }
00968 
00969 #if defined(HAVE_BLAS)
00970 template<> inline
00971 double dot(const vec &v1, const vec &v2)
00972 {
00973   it_assert_debug(v1.datasize == v2.datasize, "vec::dot: wrong sizes");
00974   int incr = 1;
00975   return blas::ddot_(&v1.datasize, v1.data, &incr, v2.data, &incr);
00976 }
00977 
00978 #if defined(HAVE_ZDOTUSUB) || defined(HAVE_ZDOTU_VOID)
00979 template<> inline
00980 std::complex<double> dot(const cvec &v1, const cvec &v2)
00981 {
00982   it_assert_debug(v1.datasize == v2.datasize, "cvec::dot: wrong sizes");
00983   int incr = 1;
00984   std::complex<double> output;
00985   blas::zdotusub_(&output, &v1.datasize, v1.data, &incr, v2.data, &incr);
00986   return output;
00987 }
00988 #endif // HAVE_ZDOTUSUB || HAVE_ZDOTU_VOID
00989 #endif // HAVE_BLAS
00990 
00991 template<class Num_T>
00992 Num_T dot(const Vec<Num_T> &v1, const Vec<Num_T> &v2)
00993 {
00994   int i;
00995   Num_T r = Num_T(0);
00996 
00997   it_assert_debug(v1.datasize == v2.datasize, "Vec::dot: wrong sizes");
00998   for (i = 0; i < v1.datasize; i++)
00999     r += v1.data[i] * v2.data[i];
01000 
01001   return r;
01002 }
01003 
01004 template<class Num_T> inline
01005 Num_T operator*(const Vec<Num_T> &v1, const Vec<Num_T> &v2)
01006 {
01007   return dot(v1, v2);
01008 }
01009 
01010 
01011 #if defined(HAVE_BLAS)
01012 template<> inline
01013 mat outer_product(const vec &v1, const vec &v2, bool)
01014 {
01015   it_assert_debug((v1.datasize > 0) && (v2.datasize > 0),
01016                   "Vec::outer_product():: Input vector of zero size");
01017 
01018   mat out(v1.datasize, v2.datasize);
01019   out.zeros();
01020   double alpha = 1.0;
01021   int incr = 1;
01022   blas::dger_(&v1.datasize, &v2.datasize, &alpha, v1.data, &incr,
01023               v2.data, &incr, out._data(), &v1.datasize);
01024   return out;
01025 }
01026 
01027 template<> inline
01028 cmat outer_product(const cvec &v1, const cvec &v2, bool hermitian)
01029 {
01030   it_assert_debug((v1.datasize > 0) && (v2.datasize > 0),
01031                   "Vec::outer_product():: Input vector of zero size");
01032 
01033   cmat out(v1.datasize, v2.datasize);
01034   out.zeros();
01035   std::complex<double> alpha(1.0);
01036   int incr = 1;
01037   if (hermitian) {
01038     blas::zgerc_(&v1.datasize, &v2.datasize, &alpha, v1.data, &incr,
01039                  v2.data, &incr, out._data(), &v1.datasize);
01040   }
01041   else {
01042     blas::zgeru_(&v1.datasize, &v2.datasize, &alpha, v1.data, &incr,
01043                  v2.data, &incr, out._data(), &v1.datasize);
01044   }
01045   return out;
01046 }
01047 #else
01049 template<> inline
01050 cmat outer_product(const cvec &v1, const cvec &v2, bool hermitian)
01051 {
01052   it_assert_debug((v1.datasize > 0) && (v2.datasize > 0),
01053                   "Vec::outer_product():: Input vector of zero size");
01054 
01055   cmat out(v1.datasize, v2.datasize);
01056   if (hermitian) {
01057     for (int i = 0; i < v1.datasize; ++i) {
01058       for (int j = 0; j < v2.datasize; ++j) {
01059         out(i, j) = v1.data[i] * conj(v2.data[j]);
01060       }
01061     }
01062   }
01063   else {
01064     for (int i = 0; i < v1.datasize; ++i) {
01065       for (int j = 0; j < v2.datasize; ++j) {
01066         out(i, j) = v1.data[i] * v2.data[j];
01067       }
01068     }
01069   }
01070   return out;
01071 }
01072 #endif // HAVE_BLAS
01073 
01074 template<class Num_T>
01075 Mat<Num_T> outer_product(const Vec<Num_T> &v1, const Vec<Num_T> &v2, bool)
01076 {
01077   int i, j;
01078 
01079   it_assert_debug((v1.datasize > 0) && (v2.datasize > 0),
01080                   "Vec::outer_product:: Input vector of zero size");
01081 
01082   Mat<Num_T> r(v1.datasize, v2.datasize);
01083   for (i = 0; i < v1.datasize; i++) {
01084     for (j = 0; j < v2.datasize; j++) {
01085       r(i, j) = v1.data[i] * v2.data[j];
01086     }
01087   }
01088 
01089   return r;
01090 }
01091 
01092 template<class Num_T>
01093 Vec<Num_T> operator*(const Vec<Num_T> &v, Num_T t)
01094 {
01095   int i;
01096   Vec<Num_T> r(v.datasize);
01097   for (i = 0; i < v.datasize; i++)
01098     r.data[i] = v.data[i] * t;
01099 
01100   return r;
01101 }
01102 
01103 template<class Num_T> inline
01104 Vec<Num_T> operator*(Num_T t, const Vec<Num_T> &v)
01105 {
01106   return operator*(v, t);
01107 }
01108 
01109 template<class Num_T> inline
01110 Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b)
01111 {
01112   Vec<Num_T> out;
01113   elem_mult_out(a, b, out);
01114   return out;
01115 }
01116 
01117 template<class Num_T> inline
01118 Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b,
01119                      const Vec<Num_T> &c)
01120 {
01121   Vec<Num_T> out;
01122   elem_mult_out(a, b, c, out);
01123   return out;
01124 }
01125 
01126 template<class Num_T> inline
01127 Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b,
01128                      const Vec<Num_T> &c, const Vec<Num_T> &d)
01129 {
01130   Vec<Num_T> out;
01131   elem_mult_out(a, b, c, d, out);
01132   return out;
01133 }
01134 
01135 template<class Num_T>
01136 void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b, Vec<Num_T> &out)
01137 {
01138   it_assert_debug(a.datasize == b.datasize,
01139                   "Vec<>::elem_mult_out(): Wrong sizes");
01140   out.set_size(a.datasize);
01141   for (int i = 0; i < a.datasize; i++)
01142     out.data[i] = a.data[i] * b.data[i];
01143 }
01144 
01145 template<class Num_T>
01146 void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b,
01147                    const Vec<Num_T> &c, Vec<Num_T> &out)
01148 {
01149   it_assert_debug((a.datasize == b.datasize) && (a.datasize == c.datasize),
01150                   "Vec<>::elem_mult_out(): Wrong sizes");
01151   out.set_size(a.datasize);
01152   for (int i = 0; i < a.datasize; i++)
01153     out.data[i] = a.data[i] * b.data[i] * c.data[i];
01154 }
01155 
01156 template<class Num_T>
01157 void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b,
01158                    const Vec<Num_T> &c, const Vec<Num_T> &d, Vec<Num_T> &out)
01159 {
01160   it_assert_debug((a.datasize == b.datasize) && (a.datasize == c.datasize)
01161                   && (a.datasize == d.datasize),
01162                   "Vec<>::elem_mult_out(): Wrong sizes");
01163   out.set_size(a.datasize);
01164   for (int i = 0; i < a.datasize; i++)
01165     out.data[i] = a.data[i] * b.data[i] * c.data[i] * d.data[i];
01166 }
01167 
01168 template<class Num_T> inline
01169 void elem_mult_inplace(const Vec<Num_T> &a, Vec<Num_T> &b)
01170 {
01171   it_assert_debug(a.datasize == b.datasize,
01172                   "Vec<>::elem_mult_inplace(): Wrong sizes");
01173   for (int i = 0; i < a.datasize; i++)
01174     b.data[i] *= a.data[i];
01175 }
01176 
01177 template<class Num_T> inline
01178 Num_T elem_mult_sum(const Vec<Num_T> &a, const Vec<Num_T> &b)
01179 {
01180   it_assert_debug(a.datasize == b.datasize,
01181                   "Vec<>::elem_mult_sum(): Wrong sizes");
01182   Num_T acc = 0;
01183   for (int i = 0; i < a.datasize; i++)
01184     acc += a.data[i] * b.data[i];
01185   return acc;
01186 }
01187 
01188 template<class Num_T>
01189 Vec<Num_T> operator/(const Vec<Num_T> &v, Num_T t)
01190 {
01191   int i;
01192   Vec<Num_T> r(v.datasize);
01193 
01194   for (i = 0; i < v.datasize; i++)
01195     r.data[i] = v.data[i] / t;
01196 
01197   return r;
01198 }
01199 
01200 template<class Num_T>
01201 Vec<Num_T> operator/(Num_T t, const Vec<Num_T> &v)
01202 {
01203   int i;
01204   Vec<Num_T> r(v.datasize);
01205 
01206   for (i = 0; i < v.datasize; i++)
01207     r.data[i] = t / v.data[i];
01208 
01209   return r;
01210 }
01211 
01212 template<class Num_T> inline
01213 Vec<Num_T>& Vec<Num_T>::operator/=(Num_T t)
01214 {
01215   for (int i = 0; i < datasize; ++i) {
01216     data[i] /= t;
01217   }
01218   return *this;
01219 }
01220 
01221 template<class Num_T> inline
01222 Vec<Num_T>& Vec<Num_T>::operator/=(const Vec<Num_T> &v)
01223 {
01224   it_assert_debug(datasize == v.datasize, "Vec::operator/=(): wrong sizes");
01225   for (int i = 0; i < datasize; ++i) {
01226     data[i] /= v.data[i];
01227   }
01228   return *this;
01229 }
01230 
01231 template<class Num_T> inline
01232 Vec<Num_T> elem_div(const Vec<Num_T> &a, const Vec<Num_T> &b)
01233 {
01234   Vec<Num_T> out;
01235   elem_div_out(a, b, out);
01236   return out;
01237 }
01238 
01239 template<class Num_T>
01240 Vec<Num_T> elem_div(Num_T t, const Vec<Num_T> &v)
01241 {
01242   int i;
01243   Vec<Num_T> r(v.datasize);
01244 
01245   for (i = 0; i < v.datasize; i++)
01246     r.data[i] = t / v.data[i];
01247 
01248   return r;
01249 }
01250 
01251 template<class Num_T>
01252 void elem_div_out(const Vec<Num_T> &a, const Vec<Num_T> &b, Vec<Num_T> &out)
01253 {
01254   it_assert_debug(a.datasize == b.datasize,
01255                   "Vec<>::elem_div_out(): Wrong sizes");
01256   out.set_size(a.datasize);
01257   for (int i = 0; i < a.datasize; i++)
01258     out.data[i] = a.data[i] / b.data[i];
01259 }
01260 
01261 template<class Num_T> inline
01262 Num_T elem_div_sum(const Vec<Num_T> &a, const Vec<Num_T> &b)
01263 {
01264   it_assert_debug(a.datasize == b.datasize, "Vec::elem_div_sum: wrong sizes");
01265 
01266   Num_T acc = 0;
01267 
01268   for (int i = 0; i < a.datasize; i++)
01269     acc += a.data[i] / b.data[i];
01270 
01271   return acc;
01272 }
01273 
01274 template<class Num_T>
01275 Vec<Num_T> Vec<Num_T>::get(const Vec<bin> &binlist) const
01276 {
01277   int size = binlist.size();
01278   it_assert_debug(datasize == size, "Vec::get(bvec &): wrong sizes");
01279   Vec<Num_T> temp(size);
01280   int j = 0;
01281   for (int i = 0; i < size; ++i) {
01282     if (binlist(i) == bin(1)) {
01283       temp(j) = data[i];
01284       j++;
01285     }
01286   }
01287   temp.set_size(j, true);
01288   return temp;
01289 }
01290 
01291 template<class Num_T>
01292 Vec<Num_T> Vec<Num_T>::right(int nr) const
01293 {
01294   it_assert_debug(nr <= datasize, "Vec::right(): index out of range");
01295   Vec<Num_T> temp(nr);
01296   if (nr > 0) {
01297     copy_vector(nr, &data[datasize-nr], temp.data);
01298   }
01299   return temp;
01300 }
01301 
01302 template<class Num_T>
01303 Vec<Num_T> Vec<Num_T>::left(int nr) const
01304 {
01305   it_assert_debug(nr <= datasize, "Vec::left(): index out of range");
01306   Vec<Num_T> temp(nr);
01307   if (nr > 0) {
01308     copy_vector(nr, data, temp.data);
01309   }
01310   return temp;
01311 }
01312 
01313 template<class Num_T>
01314 Vec<Num_T> Vec<Num_T>::mid(int start, int nr) const
01315 {
01316   it_assert_debug((start >= 0) && ((start + nr) <= datasize),
01317                   "Vec::mid(): indexing out of range");
01318   Vec<Num_T> temp(nr);
01319   if (nr > 0) {
01320     copy_vector(nr, &data[start], temp.data);
01321   }
01322   return temp;
01323 }
01324 
01325 template<class Num_T>
01326 Vec<Num_T> Vec<Num_T>::split(int pos)
01327 {
01328   it_assert_debug(in_range(pos), "Vec<>::split(): Index out of range");
01329   Vec<Num_T> temp1(pos);
01330   Vec<Num_T> temp2(datasize - pos);
01331   copy_vector(pos, data, temp1.data);
01332   copy_vector(datasize - pos, &data[pos], temp2.data);
01333   (*this) = temp2;
01334   return temp1;
01335 }
01336 
01337 template<class Num_T>
01338 void Vec<Num_T>::shift_right(Num_T t, int n)
01339 {
01340   int i = datasize;
01341 
01342   it_assert_debug(n >= 0, "Vec::shift_right: index out of range");
01343   while (--i >= n)
01344     data[i] = data[i-n];
01345   while (i >= 0)
01346     data[i--] = t;
01347 }
01348 
01349 template<class Num_T>
01350 void Vec<Num_T>::shift_right(const Vec<Num_T> &v)
01351 {
01352   for (int i = datasize - 1; i >= v.datasize; i--)
01353     data[i] = data[i-v.datasize];
01354   for (int i = 0; i < v.datasize; i++)
01355     data[i] = v[i];
01356 }
01357 
01358 template<class Num_T>
01359 void Vec<Num_T>::shift_left(Num_T t, int n)
01360 {
01361   int i;
01362 
01363   it_assert_debug(n >= 0, "Vec::shift_left: index out of range");
01364   for (i = 0; i < datasize - n; i++)
01365     data[i] = data[i+n];
01366   while (i < datasize)
01367     data[i++] = t;
01368 }
01369 
01370 template<class Num_T>
01371 void Vec<Num_T>::shift_left(const Vec<Num_T> &v)
01372 {
01373   for (int i = 0; i < datasize - v.datasize; i++)
01374     data[i] = data[i+v.datasize];
01375   for (int i = datasize - v.datasize; i < datasize; i++)
01376     data[i] = v[i-datasize+v.datasize];
01377 }
01378 
01379 template<class Num_T>
01380 Vec<Num_T> concat(const Vec<Num_T> &v, Num_T t)
01381 {
01382   int size = v.size();
01383   Vec<Num_T> temp(size + 1);
01384   copy_vector(size, v.data, temp.data);
01385   temp(size) = t;
01386   return temp;
01387 }
01388 
01389 template<class Num_T>
01390 Vec<Num_T> concat(Num_T t, const Vec<Num_T> &v)
01391 {
01392   int size = v.size();
01393   Vec<Num_T> temp(size + 1);
01394   temp(0) = t;
01395   copy_vector(size, v.data, &temp.data[1]);
01396   return temp;
01397 }
01398 
01399 template<class Num_T>
01400 Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2)
01401 {
01402   int size1 = v1.size();
01403   int size2 = v2.size();
01404   Vec<Num_T> temp(size1 + size2);
01405   copy_vector(size1, v1.data, temp.data);
01406   copy_vector(size2, v2.data, &temp.data[size1]);
01407   return temp;
01408 }
01409 
01410 template<class Num_T>
01411 Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
01412                   const Vec<Num_T> &v3)
01413 {
01414   int size1 = v1.size();
01415   int size2 = v2.size();
01416   int size3 = v3.size();
01417   Vec<Num_T> temp(size1 + size2 + size3);
01418   copy_vector(size1, v1.data, temp.data);
01419   copy_vector(size2, v2.data, &temp.data[size1]);
01420   copy_vector(size3, v3.data, &temp.data[size1+size2]);
01421   return temp;
01422 }
01423 
01424 template<class Num_T>
01425 Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
01426                   const Vec<Num_T> &v3, const Vec<Num_T> &v4)
01427 {
01428   int size1 = v1.size();
01429   int size2 = v2.size();
01430   int size3 = v3.size();
01431   int size4 = v4.size();
01432   Vec<Num_T> temp(size1 + size2 + size3 + size4);
01433   copy_vector(size1, v1.data, temp.data);
01434   copy_vector(size2, v2.data, &temp.data[size1]);
01435   copy_vector(size3, v3.data, &temp.data[size1+size2]);
01436   copy_vector(size4, v4.data, &temp.data[size1+size2+size3]);
01437   return temp;
01438 }
01439 
01440 template<class Num_T>
01441 Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
01442                   const Vec<Num_T> &v3, const Vec<Num_T> &v4,
01443                   const Vec<Num_T> &v5)
01444 {
01445   int size1 = v1.size();
01446   int size2 = v2.size();
01447   int size3 = v3.size();
01448   int size4 = v4.size();
01449   int size5 = v5.size();
01450   Vec<Num_T> temp(size1 + size2 + size3 + size4 + size5);
01451   copy_vector(size1, v1.data, temp.data);
01452   copy_vector(size2, v2.data, &temp.data[size1]);
01453   copy_vector(size3, v3.data, &temp.data[size1+size2]);
01454   copy_vector(size4, v4.data, &temp.data[size1+size2+size3]);
01455   copy_vector(size5, v5.data, &temp.data[size1+size2+size3+size4]);
01456   return temp;
01457 }
01458 
01459 template<class Num_T>
01460 void Vec<Num_T>::set_subvector(int i1, int i2, const Vec<Num_T> &v)
01461 {
01462   if (i1 == -1) i1 = datasize - 1;
01463   if (i2 == -1) i2 = datasize - 1;
01464 
01465   it_assert_debug(i1 >= 0 && i2 >= 0 && i1 < datasize && i2 < datasize, "Vec::set_subvector(): indicies out of range");
01466   it_assert_debug(i2 >= i1, "Vec::set_subvector(): i2 >= i1 necessary");
01467   it_assert_debug(i2 - i1 + 1 == v.datasize, "Vec::set_subvector(): wrong sizes");
01468 
01469   copy_vector(v.datasize, v.data, data + i1);
01470 }
01471 
01472 template<class Num_T> inline
01473 void Vec<Num_T>:: set_subvector(int i, const Vec<Num_T> &v)
01474 {
01475   it_assert_debug((i >= 0) && (i + v.datasize <= datasize),
01476                   "Vec<>::set_subvector(int, const Vec<> &): "
01477                   "Index out of range or too long input vector");
01478   copy_vector(v.datasize, v.data, data + i);
01479 }
01480 
01481 template<class Num_T> inline
01482 void Vec<Num_T>::set_subvector(int i1, int i2, Num_T t)
01483 {
01484   if (i1 == -1) i1 = datasize - 1;
01485   if (i2 == -1) i2 = datasize - 1;
01486   it_assert_debug((i1 >= 0) && (i1 <= i2) && (i2 < datasize),
01487                   "Vec<>::set_subvector(int, int, Num_T): Indexing out "
01488                   "of range");
01489   for (int i = i1; i <= i2; i++)
01490     data[i] = t;
01491 }
01492 
01493 template<class Num_T> inline
01494 void Vec<Num_T>::replace_mid(int i, const Vec<Num_T> &v)
01495 {
01496   it_assert_debug((i >= 0) && ((i + v.length()) <= datasize),
01497                   "Vec<>::replace_mid(): Indexing out of range");
01498   copy_vector(v.datasize, v.data, &data[i]);
01499 }
01500 
01501 template<class Num_T>
01502 void Vec<Num_T>::del(int index)
01503 {
01504   it_assert_debug(in_range(index), "Vec<>::del(int): Index out of range");
01505   Vec<Num_T> temp(*this);
01506   set_size(datasize - 1, false);
01507   copy_vector(index, temp.data, data);
01508   copy_vector(datasize - index, &temp.data[index+1], &data[index]);
01509 }
01510 
01511 template<class Num_T>
01512 void Vec<Num_T>::del(int i1, int i2)
01513 {
01514   if (i1 == -1) i1 = datasize - 1;
01515   if (i2 == -1) i2 = datasize - 1;
01516   it_assert_debug((i1 >= 0) && (i1 <= i2) && (i2 < datasize),
01517                   "Vec<>::del(int, int): Indexing out of range");
01518   Vec<Num_T> temp(*this);
01519   int new_size = datasize - (i2 - i1 + 1);
01520   set_size(new_size, false);
01521   copy_vector(i1, temp.data, data);
01522   copy_vector(datasize - i1, &temp.data[i2+1], &data[i1]);
01523 }
01524 
01525 template<class Num_T>
01526 void Vec<Num_T>::ins(int index, const Num_T t)
01527 {
01528   it_assert_debug((index >= 0) && (index <= datasize),
01529                   "Vec<>::ins(): Index out of range");
01530   Vec<Num_T> Temp(*this);
01531 
01532   set_size(datasize + 1, false);
01533   copy_vector(index, Temp.data, data);
01534   data[index] = t;
01535   copy_vector(Temp.datasize - index, Temp.data + index, data + index + 1);
01536 }
01537 
01538 template<class Num_T>
01539 void Vec<Num_T>::ins(int index, const Vec<Num_T> &v)
01540 {
01541   it_assert_debug((index >= 0) && (index <= datasize),
01542                   "Vec<>::ins(): Index out of range");
01543   Vec<Num_T> Temp(*this);
01544 
01545   set_size(datasize + v.length(), false);
01546   copy_vector(index, Temp.data, data);
01547   copy_vector(v.size(), v.data, &data[index]);
01548   copy_vector(Temp.datasize - index, Temp.data + index, data + index + v.size());
01549 }
01550 
01551 template<class Num_T> inline
01552 Vec<Num_T>& Vec<Num_T>::operator=(Num_T t)
01553 {
01554   for (int i = 0;i < datasize;i++)
01555     data[i] = t;
01556   return *this;
01557 }
01558 
01559 template<class Num_T> inline
01560 Vec<Num_T>& Vec<Num_T>::operator=(const Vec<Num_T> &v)
01561 {
01562   if (this != &v) {
01563     set_size(v.datasize, false);
01564     copy_vector(datasize, v.data, data);
01565   }
01566   return *this;
01567 }
01568 
01569 template<class Num_T>
01570 Vec<Num_T>& Vec<Num_T>::operator=(const Mat<Num_T> &m)
01571 {
01572   if (m.cols() == 1) {
01573     set_size(m.rows(), false);
01574     copy_vector(m.rows(), m._data(), data);
01575   }
01576   else if (m.rows() == 1) {
01577     set_size(m.cols(), false);
01578     copy_vector(m.cols(), m._data(), m.rows(), data, 1);
01579   }
01580   else
01581     it_error("Vec<>::operator=(Mat<Num_T> &): Wrong size of input matrix");
01582   return *this;
01583 }
01584 
01585 template<class Num_T> inline
01586 Vec<Num_T>& Vec<Num_T>::operator=(const char *values)
01587 {
01588   set(values);
01589   return *this;
01590 }
01591 
01593 template<>
01594 bvec Vec<std::complex<double> >::operator==(std::complex<double>) const;
01596 
01597 template<class Num_T>
01598 bvec Vec<Num_T>::operator==(Num_T t) const
01599 {
01600   it_assert_debug(datasize > 0, "Vec<>::operator==(): Wrong size");
01601   bvec temp(datasize);
01602   for (int i = 0; i < datasize; i++)
01603     temp(i) = (data[i] == t);
01604   return temp;
01605 }
01606 
01608 template<>
01609 bvec Vec<std::complex<double> >::operator!=(std::complex<double>) const;
01611 
01612 template<class Num_T>
01613 bvec Vec<Num_T>::operator!=(Num_T t) const
01614 {
01615   it_assert_debug(datasize > 0, "Vec<>::operator!=(): Wrong size");
01616   bvec temp(datasize);
01617   for (int i = 0; i < datasize; i++)
01618     temp(i) = (data[i] != t);
01619   return temp;
01620 }
01621 
01623 template<>
01624 bvec Vec<std::complex<double> >::operator<(std::complex<double>) const;
01626 
01627 template<class Num_T>
01628 bvec Vec<Num_T>::operator<(Num_T t) const
01629 {
01630   it_assert_debug(datasize > 0, "Vec<>::operator<(): Wrong size");
01631   bvec temp(datasize);
01632   for (int i = 0; i < datasize; i++)
01633     temp(i) = (data[i] < t);
01634   return temp;
01635 }
01636 
01638 template<>
01639 bvec Vec<std::complex<double> >::operator<=(std::complex<double>) const;
01641 
01642 template<class Num_T>
01643 bvec Vec<Num_T>::operator<=(Num_T t) const
01644 {
01645   it_assert_debug(datasize > 0, "Vec<>::operator<=(): Wrong size");
01646   bvec temp(datasize);
01647   for (int i = 0; i < datasize; i++)
01648     temp(i) = (data[i] <= t);
01649   return temp;
01650 }
01651 
01653 template<>
01654 bvec Vec<std::complex<double> >::operator>(std::complex<double>) const;
01656 
01657 template<class Num_T>
01658 bvec Vec<Num_T>::operator>(Num_T t) const
01659 {
01660   it_assert_debug(datasize > 0, "Vec<>::operator>(): Wrong size");
01661   bvec temp(datasize);
01662   for (int i = 0; i < datasize; i++)
01663     temp(i) = (data[i] > t);
01664   return temp;
01665 }
01666 
01668 template<>
01669 bvec Vec<std::complex<double> >::operator>=(std::complex<double>) const;
01671 
01672 template<class Num_T>
01673 bvec Vec<Num_T>::operator>=(Num_T t) const
01674 {
01675   it_assert_debug(datasize > 0, "Vec<>::operator>=(): Wrong size");
01676   bvec temp(datasize);
01677   for (int i = 0; i < datasize; i++)
01678     temp(i) = (data[i] >= t);
01679   return temp;
01680 }
01681 
01682 template<class Num_T>
01683 bool Vec<Num_T>::operator==(const Vec<Num_T> &invector) const
01684 {
01685   // OBS ! if wrong size, return false
01686   if (datasize != invector.datasize) return false;
01687   for (int i = 0;i < datasize;i++) {
01688     if (data[i] != invector.data[i]) return false;
01689   }
01690   return true;
01691 }
01692 
01693 template<class Num_T>
01694 bool Vec<Num_T>::operator!=(const Vec<Num_T> &invector) const
01695 {
01696   if (datasize != invector.datasize) return true;
01697   for (int i = 0;i < datasize;i++) {
01698     if (data[i] != invector.data[i]) return true;
01699   }
01700   return false;
01701 }
01702 
01704 template<class Num_T>
01705 std::ostream &operator<<(std::ostream &os, const Vec<Num_T> &v)
01706 {
01707   int i, sz = v.length();
01708 
01709   os << "[" ;
01710   for (i = 0; i < sz; i++) {
01711     os << v(i) ;
01712     if (i < sz - 1)
01713       os << " ";
01714   }
01715   os << "]" ;
01716 
01717   return os;
01718 }
01719 
01721 template<class Num_T>
01722 std::istream &operator>>(std::istream &is, Vec<Num_T> &v)
01723 {
01724   std::ostringstream buffer;
01725   bool started = false;
01726   bool finished = false;
01727   bool brackets = false;
01728   char c;
01729 
01730   while (!finished) {
01731     if (is.eof()) {
01732       finished = true;
01733     }
01734     else {
01735       is.get(c);
01736 
01737       if (is.eof() || (c == '\n')) {
01738         if (brackets) {
01739           // Right bracket missing
01740           is.setstate(std::ios_base::failbit);
01741           finished = true;
01742         }
01743         else if (!((c == '\n') && !started)) {
01744           finished = true;
01745         }
01746       }
01747       else if ((c == ' ') || (c == '\t')) {
01748         if (started) {
01749           buffer << ' ';
01750         }
01751       }
01752       else if (c == '[') {
01753         if (started) {
01754           // Unexpected left bracket
01755           is.setstate(std::ios_base::failbit);
01756           finished = true;
01757         }
01758         else {
01759           started = true;
01760           brackets = true;
01761         }
01762       }
01763       else if (c == ']') {
01764         if (!started || !brackets) {
01765           // Unexpected right bracket
01766           is.setstate(std::ios_base::failbit);
01767           finished = true;
01768         }
01769         else {
01770           finished = true;
01771         }
01772         while (!is.eof() && (((c = static_cast<char>(is.peek())) == ' ')
01773                              || (c == '\t'))) {
01774           is.get();
01775         }
01776         if (!is.eof() && (c == '\n')) {
01777           is.get();
01778         }
01779       }
01780       else {
01781         started = true;
01782         buffer << c;
01783       }
01784     }
01785   }
01786 
01787   if (!started) {
01788     v.set_size(0, false);
01789   }
01790   else {
01791     v.set(buffer.str());
01792   }
01793 
01794   return is;
01795 }
01796 
01798 
01799 // ----------------------------------------------------------------------
01800 // Instantiations
01801 // ----------------------------------------------------------------------
01802 
01803 #ifdef HAVE_EXTERN_TEMPLATE
01804 
01805 extern template class Vec<double>;
01806 extern template class Vec<int>;
01807 extern template class Vec<short int>;
01808 extern template class Vec<std::complex<double> >;
01809 extern template class Vec<bin>;
01810 
01811 // addition operator
01812 
01813 extern template vec operator+(const vec &v1, const vec &v2);
01814 extern template cvec operator+(const cvec &v1, const cvec &v2);
01815 extern template ivec operator+(const ivec &v1, const ivec &v2);
01816 extern template svec operator+(const svec &v1, const svec &v2);
01817 extern template bvec operator+(const bvec &v1, const bvec &v2);
01818 
01819 extern template vec operator+(const vec &v1, double t);
01820 extern template cvec operator+(const cvec &v1, std::complex<double> t);
01821 extern template ivec operator+(const ivec &v1, int t);
01822 extern template svec operator+(const svec &v1, short t);
01823 extern template bvec operator+(const bvec &v1, bin t);
01824 
01825 extern template vec operator+(double t, const vec &v1);
01826 extern template cvec operator+(std::complex<double> t, const cvec &v1);
01827 extern template ivec operator+(int t, const ivec &v1);
01828 extern template svec operator+(short t, const svec &v1);
01829 extern template bvec operator+(bin t, const bvec &v1);
01830 
01831 // subtraction operator
01832 
01833 extern template vec operator-(const vec &v1, const vec &v2);
01834 extern template cvec operator-(const cvec &v1, const cvec &v2);
01835 extern template ivec operator-(const ivec &v1, const ivec &v2);
01836 extern template svec operator-(const svec &v1, const svec &v2);
01837 extern template bvec operator-(const bvec &v1, const bvec &v2);
01838 
01839 extern template vec operator-(const vec &v, double t);
01840 extern template cvec operator-(const cvec &v, std::complex<double> t);
01841 extern template ivec operator-(const ivec &v, int t);
01842 extern template svec operator-(const svec &v, short t);
01843 extern template bvec operator-(const bvec &v, bin t);
01844 
01845 extern template vec operator-(double t, const vec &v);
01846 extern template cvec operator-(std::complex<double> t, const cvec &v);
01847 extern template ivec operator-(int t, const ivec &v);
01848 extern template svec operator-(short t, const svec &v);
01849 extern template bvec operator-(bin t, const bvec &v);
01850 
01851 // unary minus
01852 
01853 extern template vec operator-(const vec &v);
01854 extern template cvec operator-(const cvec &v);
01855 extern template ivec operator-(const ivec &v);
01856 extern template svec operator-(const svec &v);
01857 extern template bvec operator-(const bvec &v);
01858 
01859 // multiplication operator
01860 
01861 #if !defined(HAVE_BLAS)
01862 extern template double dot(const vec &v1, const vec &v2);
01863 #if !(defined(HAVE_ZDOTUSUB) || defined(HAVE_ZDOTU_VOID))
01864 extern template std::complex<double> dot(const cvec &v1, const cvec &v2);
01865 #endif // !(HAVE_ZDOTUSUB || HAVE_ZDOTU_VOID)
01866 #endif // HAVE_BLAS
01867 extern template int dot(const ivec &v1, const ivec &v2);
01868 extern template short dot(const svec &v1, const svec &v2);
01869 extern template bin dot(const bvec &v1, const bvec &v2);
01870 
01871 #if !defined(HAVE_BLAS)
01872 extern template double operator*(const vec &v1, const vec &v2);
01873 extern template std::complex<double> operator*(const cvec &v1,
01874     const cvec &v2);
01875 #endif
01876 extern template int operator*(const ivec &v1, const ivec &v2);
01877 extern template short operator*(const svec &v1, const svec &v2);
01878 extern template bin operator*(const bvec &v1, const bvec &v2);
01879 
01880 #if !defined(HAVE_BLAS)
01881 extern template mat outer_product(const vec &v1, const vec &v2,
01882                                     bool hermitian);
01883 #endif
01884 extern template imat outer_product(const ivec &v1, const ivec &v2,
01885                                      bool hermitian);
01886 extern template smat outer_product(const svec &v1, const svec &v2,
01887                                      bool hermitian);
01888 extern template bmat outer_product(const bvec &v1, const bvec &v2,
01889                                      bool hermitian);
01890 
01891 extern template vec operator*(const vec &v, double t);
01892 extern template cvec operator*(const cvec &v, std::complex<double> t);
01893 extern template ivec operator*(const ivec &v, int t);
01894 extern template svec operator*(const svec &v, short t);
01895 extern template bvec operator*(const bvec &v, bin t);
01896 
01897 extern template vec operator*(double t, const vec &v);
01898 extern template cvec operator*(std::complex<double> t, const cvec &v);
01899 extern template ivec operator*(int t, const ivec &v);
01900 extern template svec operator*(short t, const svec &v);
01901 extern template bvec operator*(bin t, const bvec &v);
01902 
01903 // elementwise multiplication
01904 
01905 extern template vec elem_mult(const vec &a, const vec &b);
01906 extern template cvec elem_mult(const cvec &a, const cvec &b);
01907 extern template ivec elem_mult(const ivec &a, const ivec &b);
01908 extern template svec elem_mult(const svec &a, const svec &b);
01909 extern template bvec elem_mult(const bvec &a, const bvec &b);
01910 
01911 extern template void elem_mult_out(const vec &a, const vec &b, vec &out);
01912 extern template void elem_mult_out(const cvec &a, const cvec &b, cvec &out);
01913 extern template void elem_mult_out(const ivec &a, const ivec &b, ivec &out);
01914 extern template void elem_mult_out(const svec &a, const svec &b, svec &out);
01915 extern template void elem_mult_out(const bvec &a, const bvec &b, bvec &out);
01916 
01917 extern template vec elem_mult(const vec &a, const vec &b, const vec &c);
01918 extern template cvec elem_mult(const cvec &a, const cvec &b, const cvec &c);
01919 extern template ivec elem_mult(const ivec &a, const ivec &b, const ivec &c);
01920 extern template svec elem_mult(const svec &a, const svec &b, const svec &c);
01921 extern template bvec elem_mult(const bvec &a, const bvec &b, const bvec &c);
01922 
01923 extern template void elem_mult_out(const vec &a, const vec &b,
01924                                      const vec &c, vec &out);
01925 extern template void elem_mult_out(const cvec &a, const cvec &b,
01926                                      const cvec &c, cvec &out);
01927 extern template void elem_mult_out(const ivec &a, const ivec &b,
01928                                      const ivec &c, ivec &out);
01929 extern template void elem_mult_out(const svec &a, const svec &b,
01930                                      const svec &c, svec &out);
01931 extern template void elem_mult_out(const bvec &a, const bvec &b,
01932                                      const bvec &c, bvec &out);
01933 
01934 extern template vec elem_mult(const vec &a, const vec &b,
01935                                 const vec &c, const vec &d);
01936 extern template cvec elem_mult(const cvec &a, const cvec &b,
01937                                  const cvec &c, const cvec &d);
01938 extern template ivec elem_mult(const ivec &a, const ivec &b,
01939                                  const ivec &c, const ivec &d);
01940 extern template svec elem_mult(const svec &a, const svec &b,
01941                                  const svec &c, const svec &d);
01942 extern template bvec elem_mult(const bvec &a, const bvec &b,
01943                                  const bvec &c, const bvec &d);
01944 
01945 extern template void elem_mult_out(const vec &a, const vec &b, const vec &c,
01946                                      const vec &d, vec &out);
01947 extern template void elem_mult_out(const cvec &a, const cvec &b,
01948                                      const cvec &c, const cvec &d, cvec &out);
01949 extern template void elem_mult_out(const ivec &a, const ivec &b,
01950                                      const ivec &c, const ivec &d, ivec &out);
01951 extern template void elem_mult_out(const svec &a, const svec &b,
01952                                      const svec &c, const svec &d, svec &out);
01953 extern template void elem_mult_out(const bvec &a, const bvec &b,
01954                                      const bvec &c, const bvec &d, bvec &out);
01955 
01956 // in-place elementwise multiplication
01957 
01958 extern template void elem_mult_inplace(const vec &a, vec &b);
01959 extern template void elem_mult_inplace(const cvec &a, cvec &b);
01960 extern template void elem_mult_inplace(const ivec &a, ivec &b);
01961 extern template void elem_mult_inplace(const svec &a, svec &b);
01962 extern template void elem_mult_inplace(const bvec &a, bvec &b);
01963 
01964 // elementwise multiplication followed by summation
01965 
01966 extern template double elem_mult_sum(const vec &a, const vec &b);
01967 extern template std::complex<double> elem_mult_sum(const cvec &a,
01968     const cvec &b);
01969 extern template int elem_mult_sum(const ivec &a, const ivec &b);
01970 extern template short elem_mult_sum(const svec &a, const svec &b);
01971 extern template bin elem_mult_sum(const bvec &a, const bvec &b);
01972 
01973 // division operator
01974 
01975 extern template vec operator/(const vec &v, double t);
01976 extern template cvec operator/(const cvec &v, std::complex<double> t);
01977 extern template ivec operator/(const ivec &v, int t);
01978 extern template svec operator/(const svec &v, short t);
01979 extern template bvec operator/(const bvec &v, bin t);
01980 
01981 extern template vec operator/(double t, const vec &v);
01982 extern template cvec operator/(std::complex<double> t, const cvec &v);
01983 extern template ivec operator/(int t, const ivec &v);
01984 extern template svec operator/(short t, const svec &v);
01985 extern template bvec operator/(bin t, const bvec &v);
01986 
01987 // elementwise division operator
01988 
01989 extern template vec elem_div(const vec &a, const vec &b);
01990 extern template cvec elem_div(const cvec &a, const cvec &b);
01991 extern template ivec elem_div(const ivec &a, const ivec &b);
01992 extern template svec elem_div(const svec &a, const svec &b);
01993 extern template bvec elem_div(const bvec &a, const bvec &b);
01994 
01995 extern template vec elem_div(double t, const vec &v);
01996 extern template cvec elem_div(std::complex<double> t, const cvec &v);
01997 extern template ivec elem_div(int t, const ivec &v);
01998 extern template svec elem_div(short t, const svec &v);
01999 extern template bvec elem_div(bin t, const bvec &v);
02000 
02001 extern template void elem_div_out(const vec &a, const vec &b, vec &out);
02002 extern template void elem_div_out(const cvec &a, const cvec &b, cvec &out);
02003 extern template void elem_div_out(const ivec &a, const ivec &b, ivec &out);
02004 extern template void elem_div_out(const svec &a, const svec &b, svec &out);
02005 extern template void elem_div_out(const bvec &a, const bvec &b, bvec &out);
02006 
02007 // elementwise division followed by summation
02008 
02009 extern template double elem_div_sum(const vec &a, const vec &b);
02010 extern template std::complex<double> elem_div_sum(const cvec &a,
02011     const cvec &b);
02012 extern template int elem_div_sum(const ivec &a, const ivec &b);
02013 extern template short elem_div_sum(const svec &a, const svec &b);
02014 extern template bin elem_div_sum(const bvec &a, const bvec &b);
02015 
02016 // concat operator
02017 
02018 extern template vec concat(const vec &v, double a);
02019 extern template cvec concat(const cvec &v, std::complex<double> a);
02020 extern template ivec concat(const ivec &v, int a);
02021 extern template svec concat(const svec &v, short a);
02022 extern template bvec concat(const bvec &v, bin a);
02023 
02024 extern template vec concat(double a, const vec &v);
02025 extern template cvec concat(std::complex<double> a, const cvec &v);
02026 extern template ivec concat(int a, const ivec &v);
02027 extern template svec concat(short a, const svec &v);
02028 extern template bvec concat(bin a, const bvec &v);
02029 
02030 extern template vec concat(const vec &v1, const vec &v2);
02031 extern template cvec concat(const cvec &v1, const cvec &v2);
02032 extern template ivec concat(const ivec &v1, const ivec &v2);
02033 extern template svec concat(const svec &v1, const svec &v2);
02034 extern template bvec concat(const bvec &v1, const bvec &v2);
02035 
02036 extern template vec concat(const vec &v1, const vec &v2, const vec &v3);
02037 extern template cvec concat(const cvec &v1, const cvec &v2, const cvec &v3);
02038 extern template ivec concat(const ivec &v1, const ivec &v2, const ivec &v3);
02039 extern template svec concat(const svec &v1, const svec &v2, const svec &v3);
02040 extern template bvec concat(const bvec &v1, const bvec &v2, const bvec &v3);
02041 
02042 extern template vec concat(const vec &v1, const vec &v2,
02043                              const vec &v3, const vec &v4);
02044 extern template cvec concat(const cvec &v1, const cvec &v2,
02045                               const cvec &v3, const cvec &v4);
02046 extern template ivec concat(const ivec &v1, const ivec &v2,
02047                               const ivec &v3, const ivec &v4);
02048 extern template svec concat(const svec &v1, const svec &v2,
02049                               const svec &v3, const svec &v4);
02050 extern template bvec concat(const bvec &v1, const bvec &v2,
02051                               const bvec &v3, const bvec &v4);
02052 
02053 extern template vec concat(const vec &v1, const vec &v2, const vec &v3,
02054                              const vec &v4, const vec &v5);
02055 extern template cvec concat(const cvec &v1, const cvec &v2, const cvec &v3,
02056                               const cvec &v4, const cvec &v5);
02057 extern template ivec concat(const ivec &v1, const ivec &v2, const ivec &v3,
02058                               const ivec &v4, const ivec &v5);
02059 extern template svec concat(const svec &v1, const svec &v2, const svec &v3,
02060                               const svec &v4, const svec &v5);
02061 extern template bvec concat(const bvec &v1, const bvec &v2, const bvec &v3,
02062                               const bvec &v4, const bvec &v5);
02063 
02064 // I/O streams
02065 
02066 extern template std::ostream &operator<<(std::ostream& os, const vec &vect);
02067 extern template std::ostream &operator<<(std::ostream& os, const cvec &vect);
02068 extern template std::ostream &operator<<(std::ostream& os, const svec &vect);
02069 extern template std::ostream &operator<<(std::ostream& os, const ivec &vect);
02070 extern template std::ostream &operator<<(std::ostream& os, const bvec &vect);
02071 extern template std::istream &operator>>(std::istream& is, vec &vect);
02072 extern template std::istream &operator>>(std::istream& is, cvec &vect);
02073 extern template std::istream &operator>>(std::istream& is, svec &vect);
02074 extern template std::istream &operator>>(std::istream& is, ivec &vect);
02075 extern template std::istream &operator>>(std::istream& is, bvec &vect);
02076 
02077 #endif // HAVE_EXTERN_TEMPLATE
02078 
02080 
02081 } // namespace itpp
02082 
02083 #endif // #ifndef VEC_H
SourceForge Logo

Generated on Fri Jul 25 12:42:58 2008 for IT++ by Doxygen 1.5.4