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

Generated on Sat Jul 9 2011 15:21:31 for IT++ by Doxygen 1.7.4