IT++ Logo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
vec.h
Go to the documentation of this file.
1 
29 #ifndef VEC_H
30 #define VEC_H
31 
32 #include <itpp/base/itassert.h>
33 #include <itpp/base/math/misc.h>
34 #include <itpp/base/copy_vector.h>
35 #include <itpp/base/factory.h>
36 #include <vector>
37 
38 
39 namespace itpp
40 {
41 
42 // Declaration of Vec
43 template<class Num_T> class Vec;
44 // Declaration of Mat
45 template<class Num_T> class Mat;
46 // Declaration of bin
47 class bin;
48 
49 //-----------------------------------------------------------------------------------
50 // Declaration of Vec Friends
51 //-----------------------------------------------------------------------------------
52 
54 template<class Num_T>
55 Vec<Num_T> operator+(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
57 template<class Num_T>
58 Vec<Num_T> operator+(const Vec<Num_T> &v, Num_T t);
60 template<class Num_T>
61 Vec<Num_T> operator+(Num_T t, const Vec<Num_T> &v);
62 
64 template<class Num_T>
65 Vec<Num_T> operator-(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
67 template<class Num_T>
68 Vec<Num_T> operator-(const Vec<Num_T> &v, Num_T t);
70 template<class Num_T>
71 Vec<Num_T> operator-(Num_T t, const Vec<Num_T> &v);
73 template<class Num_T>
74 Vec<Num_T> operator-(const Vec<Num_T> &v);
75 
77 template<class Num_T>
78 Num_T dot(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
80 template<class Num_T>
81 Num_T operator*(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
90 template<class Num_T>
91 Mat<Num_T> outer_product(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
92  bool hermitian = false);
94 template<class Num_T>
95 Vec<Num_T> operator*(const Vec<Num_T> &v, Num_T t);
97 template<class Num_T>
98 Vec<Num_T> operator*(Num_T t, const Vec<Num_T> &v);
99 
101 template<class Num_T>
102 Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b);
104 template<class Num_T>
105 Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b,
106  const Vec<Num_T> &c);
108 template<class Num_T>
109 Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b,
110  const Vec<Num_T> &c, const Vec<Num_T> &d);
111 
113 template<class Num_T>
114 void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b,
115  Vec<Num_T> &out);
117 template<class Num_T>
118 void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b,
119  const Vec<Num_T> &c, Vec<Num_T> &out);
121 template<class Num_T>
122 void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b,
123  const Vec<Num_T> &c, const Vec<Num_T> &d,
124  Vec<Num_T> &out);
125 
127 template<class Num_T>
128 void elem_mult_inplace(const Vec<Num_T> &a, Vec<Num_T> &b);
130 template<class Num_T>
131 Num_T elem_mult_sum(const Vec<Num_T> &a, const Vec<Num_T> &b);
132 
134 template<class Num_T>
135 Vec<Num_T> operator/(const Vec<Num_T> &v, Num_T t);
137 template<class Num_T>
138 Vec<Num_T> operator/(Num_T t, const Vec<Num_T> &v);
139 
141 template<class Num_T>
142 Vec<Num_T> elem_div(const Vec<Num_T> &a, const Vec<Num_T> &b);
144 template<class Num_T>
145 Vec<Num_T> elem_div(Num_T t, const Vec<Num_T> &v);
147 template<class Num_T>
148 void elem_div_out(const Vec<Num_T> &a, const Vec<Num_T> &b, Vec<Num_T> &out);
150 template<class Num_T>
151 Num_T elem_div_sum(const Vec<Num_T> &a, const Vec<Num_T> &b);
152 
154 template<class Num_T>
155 Vec<Num_T> concat(const Vec<Num_T> &v, Num_T a);
157 template<class Num_T>
158 Vec<Num_T> concat(Num_T a, const Vec<Num_T> &v);
160 template<class Num_T>
161 Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
163 template<class Num_T>
164 Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
165  const Vec<Num_T> &v3);
167 template<class Num_T>
168 Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
169  const Vec<Num_T> &v3, const Vec<Num_T> &v4);
171 template<class Num_T>
172 Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
173  const Vec<Num_T> &v3, const Vec<Num_T> &v4,
174  const Vec<Num_T> &v5);
175 
176 //-----------------------------------------------------------------------------------
177 // Declaration of Vec
178 //-----------------------------------------------------------------------------------
179 
243 template<class Num_T>
244 class Vec
245 {
246 public:
248  typedef Num_T value_type;
249 
251  explicit Vec(const Factory &f = DEFAULT_FACTORY);
253  explicit Vec(int size, const Factory &f = DEFAULT_FACTORY);
255  Vec(const Vec<Num_T> &v);
257  Vec(const Vec<Num_T> &v, const Factory &f);
259  Vec(const char *str, const Factory &f = DEFAULT_FACTORY);
261  Vec(const std::string &str, const Factory &f = DEFAULT_FACTORY);
263  Vec(const Num_T *c_array, int size, const Factory &f = DEFAULT_FACTORY);
264 
266  ~Vec();
267 
269  int length() const { return datasize; }
271  int size() const { return datasize; }
272 
274  void set_size(int size, bool copy = false);
276  void set_length(int size, bool copy = false) { set_size(size, copy); }
278  void zeros();
280  void clear() { zeros(); }
282  void ones();
284  void set(const char *str);
286  void set(const std::string &str);
287 
289  const Num_T &operator[](int i) const;
291  const Num_T &operator()(int i) const;
293  Num_T &operator[](int i);
295  Num_T &operator()(int i);
297  Vec<Num_T> operator()(int i1, int i2) const;
299  Vec<Num_T> operator()(const Vec<int> &indexlist) const;
301  Vec<Num_T> operator()(const Vec<bin> &binlist) const;
302 
304  const Num_T &get(int i) const;
306  Vec<Num_T> get(int i1, int i2) const;
308  Vec<Num_T> get(const Vec<int> &indexlist) const;
310  Vec<Num_T> get(const Vec<bin> &binlist) const;
311 
313  void set(int i, Num_T t);
314 
316  Mat<Num_T> transpose() const;
318  Mat<Num_T> T() const { return this->transpose(); }
322  Mat<Num_T> H() const { return this->hermitian_transpose(); }
323 
325  Vec<Num_T>& operator+=(const Vec<Num_T> &v);
327  Vec<Num_T>& operator+=(Num_T t);
329  friend Vec<Num_T> operator+<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
331  friend Vec<Num_T> operator+<>(const Vec<Num_T> &v, Num_T t);
333  friend Vec<Num_T> operator+<>(Num_T t, const Vec<Num_T> &v);
334 
336  Vec<Num_T>& operator-=(const Vec<Num_T> &v);
338  Vec<Num_T>& operator-=(Num_T t);
340  friend Vec<Num_T> operator-<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
342  friend Vec<Num_T> operator-<>(const Vec<Num_T> &v, Num_T t);
344  friend Vec<Num_T> operator-<>(Num_T t, const Vec<Num_T> &v);
346  friend Vec<Num_T> operator-<>(const Vec<Num_T> &v);
347 
349  Vec<Num_T>& operator*=(Num_T t);
351  friend Num_T operator*<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
353  friend Num_T dot<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
355  friend Mat<Num_T> outer_product<>(const Vec<Num_T> &v1,
356  const Vec<Num_T> &v2, bool hermitian);
358  friend Vec<Num_T> operator*<>(const Vec<Num_T> &v, Num_T t);
360  friend Vec<Num_T> operator*<>(Num_T t, const Vec<Num_T> &v);
361 
363  friend Vec<Num_T> elem_mult<>(const Vec<Num_T> &a, const Vec<Num_T> &b);
365  friend Vec<Num_T> elem_mult<>(const Vec<Num_T> &a, const Vec<Num_T> &b,
366  const Vec<Num_T> &c);
368  friend Vec<Num_T> elem_mult<>(const Vec<Num_T> &a, const Vec<Num_T> &b,
369  const Vec<Num_T> &c, const Vec<Num_T> &d);
370 
372  friend void elem_mult_out<>(const Vec<Num_T> &a, const Vec<Num_T> &b,
373  Vec<Num_T> &out);
375  friend void elem_mult_out<>(const Vec<Num_T> &a, const Vec<Num_T> &b,
376  const Vec<Num_T> &c, Vec<Num_T> &out);
378  friend void elem_mult_out<>(const Vec<Num_T> &a, const Vec<Num_T> &b,
379  const Vec<Num_T> &c, const Vec<Num_T> &d,
380  Vec<Num_T> &out);
381 
383  friend void elem_mult_inplace<>(const Vec<Num_T> &a, Vec<Num_T> &b);
385  friend Num_T elem_mult_sum<>(const Vec<Num_T> &a, const Vec<Num_T> &b);
386 
388  Vec<Num_T>& operator/=(Num_T t);
390  Vec<Num_T>& operator/=(const Vec<Num_T> &v);
391 
393  friend Vec<Num_T> operator/<>(const Vec<Num_T> &v, Num_T t);
395  friend Vec<Num_T> operator/<>(Num_T t, const Vec<Num_T> &v);
396 
398  friend Vec<Num_T> elem_div<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
400  friend Vec<Num_T> elem_div<>(Num_T t, const Vec<Num_T> &v);
402  friend void elem_div_out<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
403  Vec<Num_T> &out);
405  friend Num_T elem_div_sum<>(const Vec<Num_T> &a, const Vec<Num_T> &b);
406 
408  Vec<Num_T> right(int nr) const;
410  Vec<Num_T> left(int nr) const;
412  Vec<Num_T> mid(int start, int nr) const;
420  Vec<Num_T> split(int pos);
422  void shift_right(Num_T t, int n = 1);
424  void shift_right(const Vec<Num_T> &v);
426  void shift_left(Num_T t, int n = 1);
428  void shift_left(const Vec<Num_T> &v);
429 
431  friend Vec<Num_T> concat<>(const Vec<Num_T> &v, Num_T t);
433  friend Vec<Num_T> concat<>(Num_T t, const Vec<Num_T> &v);
435  friend Vec<Num_T> concat<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
437  friend Vec<Num_T> concat<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
438  const Vec<Num_T> &v3);
440  friend Vec<Num_T> concat<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
441  const Vec<Num_T> &v3, const Vec<Num_T> &v4);
443  friend Vec<Num_T> concat<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
444  const Vec<Num_T> &v3, const Vec<Num_T> &v4,
445  const Vec<Num_T> &v5);
446 
448  void set_subvector(int i1, int i2, const Vec<Num_T> &v);
450  void set_subvector(int i, const Vec<Num_T> &v);
452  void set_subvector(int i1, int i2, Num_T t);
454  void replace_mid(int i, const Vec<Num_T> &v);
456  void del(int i);
458  void del(int i1, int i2);
460  void ins(int i, Num_T t);
462  void ins(int i, const Vec<Num_T> &v);
463 
465  Vec<Num_T>& operator=(Num_T t);
467  Vec<Num_T>& operator=(const Vec<Num_T> &v);
469  Vec<Num_T>& operator=(const Mat<Num_T> &m);
471  Vec<Num_T>& operator=(const char *str);
473  Vec<Num_T>& operator=(const std::string &str);
474 
476  Vec<bin> operator==(Num_T t) const;
478  Vec<bin> operator!=(Num_T t) const;
480  Vec<bin> operator<(Num_T t) const;
482  Vec<bin> operator<=(Num_T t) const;
484  Vec<bin> operator>(Num_T t) const;
486  Vec<bin> operator>=(Num_T t) const;
487 
489  bool operator==(const Vec<Num_T> &v) const;
491  bool operator!=(const Vec<Num_T> &v) const;
492 
494  Num_T &_elem(int i) { return data[i]; }
496  const Num_T &_elem(int i) const { return data[i]; }
497 
499  Num_T *_data() { return data; }
501  const Num_T *_data() const { return data; }
502 
503 protected:
505  void alloc(int size);
507  void free();
508 
510  int datasize;
512  Num_T *data;
514  const Factory &factory;
515 private:
516  // Clean up and tokenize input initialisation string
517  std::vector<std::string> tokenize(const std::string &str,
518  bool &abc_format) const;
519  // Parse double and integer values from string tokens
520  Num_T parse_token(const std::string &s) const;
521  // Parse \c a, \c b and \c c values from "a:b:c" format
522  void parse_abc_token(const std::string &s, Num_T &a, Num_T &b,
523  Num_T &c) const;
525  bool in_range(int i) const { return ((i < datasize) && (i >= 0)); }
526 };
527 
528 //-----------------------------------------------------------------------------------
529 // Type definitions of vec, cvec, ivec, svec, and bvec
530 //-----------------------------------------------------------------------------------
531 
536 typedef Vec<double> vec;
537 
543 
548 typedef Vec<int> ivec;
549 
555 
560 typedef Vec<bin> bvec;
561 
562 } //namespace itpp
563 
564 
565 #include <itpp/base/mat.h>
566 
567 namespace itpp
568 {
569 
570 //-----------------------------------------------------------------------------------
571 // Declaration of input and output streams for Vec
572 //-----------------------------------------------------------------------------------
573 
578 template<class Num_T>
579 std::ostream &operator<<(std::ostream &os, const Vec<Num_T> &v);
580 
592 template<class Num_T>
593 std::istream &operator>>(std::istream &is, Vec<Num_T> &v);
594 
595 //-----------------------------------------------------------------------------------
596 // Implementation of templated Vec members and friends
597 //-----------------------------------------------------------------------------------
598 
599 template<class Num_T> inline
601 {
602  if (size > 0) {
603  create_elements(data, size, factory);
604  datasize = size;
605  }
606  else {
607  data = 0;
608  datasize = 0;
609  }
610 }
611 
612 template<class Num_T> inline
614 {
615  destroy_elements(data, datasize);
616  datasize = 0;
617 }
618 
619 
620 template<class Num_T> inline
621 Vec<Num_T>::Vec(const Factory &f) : datasize(0), data(0), factory(f) {}
622 
623 template<class Num_T> inline
624 Vec<Num_T>::Vec(int size, const Factory &f) : datasize(0), data(0), factory(f)
625 {
626  it_assert_debug(size >= 0, "Negative size in Vec::Vec(int)");
627  alloc(size);
628 }
629 
630 template<class Num_T> inline
631 Vec<Num_T>::Vec(const Vec<Num_T> &v) : datasize(0), data(0), factory(v.factory)
632 {
633  alloc(v.datasize);
634  copy_vector(datasize, v.data, data);
635 }
636 
637 template<class Num_T> inline
638 Vec<Num_T>::Vec(const Vec<Num_T> &v, const Factory &f) : datasize(0), data(0), factory(f)
639 {
640  alloc(v.datasize);
641  copy_vector(datasize, v.data, data);
642 }
643 
644 template<class Num_T> inline
645 Vec<Num_T>::Vec(const char *str, const Factory &f) : datasize(0), data(0), factory(f)
646 {
647  set(std::string(str));
648 }
649 
650 template<class Num_T> inline
651 Vec<Num_T>::Vec(const std::string &str, const Factory &f) : datasize(0), data(0), factory(f)
652 {
653  set(str);
654 }
655 
656 template<class Num_T> inline
657 Vec<Num_T>::Vec(const Num_T *c_array, int size, const Factory &f) : datasize(0), data(0), factory(f)
658 {
659  alloc(size);
660  copy_vector(size, c_array, data);
661 }
662 
663 template<class Num_T> inline
665 {
666  free();
667 }
668 
669 template<class Num_T>
670 void Vec<Num_T>::set_size(int size, bool copy)
671 {
672  it_assert_debug(size >= 0, "Vec::set_size(): New size must not be negative");
673  if (datasize == size)
674  return;
675  if (copy) {
676  // create a temporary pointer to the allocated data
677  Num_T* tmp = data;
678  // store the current number of elements
679  int old_datasize = datasize;
680  // check how many elements we need to copy
681  int min = datasize < size ? datasize : size;
682  // allocate new memory
683  alloc(size);
684  // copy old elements into a new memory region
685  copy_vector(min, tmp, data);
686  // initialize the rest of resized vector
687  for (int i = min; i < size; ++i)
688  data[i] = Num_T(0);
689  // delete old elements
690  destroy_elements(tmp, old_datasize);
691  }
692  else {
693  free();
694  alloc(size);
695  }
696 }
697 
698 template<class Num_T> inline
699 const Num_T& Vec<Num_T>::operator[](int i) const
700 {
701  it_assert_debug(in_range(i), "Vec<>::operator[]: Index out of range");
702  return data[i];
703 }
704 
705 template<class Num_T> inline
706 const Num_T& Vec<Num_T>::operator()(int i) const
707 {
708  return (*this)[i];
709 }
710 
711 template<class Num_T> inline
713 {
714  it_assert_debug(in_range(i), "Vec<>::operator[]: Index out of range");
715  return data[i];
716 }
717 
718 template<class Num_T> inline
720 {
721  return (*this)[i];
722 }
723 
724 template<class Num_T> inline
725 Vec<Num_T> Vec<Num_T>::operator()(int i1, int i2) const
726 {
727  if (i1 == -1) i1 = datasize - 1;
728  if (i2 == -1) i2 = datasize - 1;
729 
730  it_assert_debug((i1 >= 0) && (i1 <= i2) && (i2 < datasize),
731  "Vec<>::operator()(i1, i2): Indexing out of range");
732 
733  Vec<Num_T> s(i2 - i1 + 1);
734  copy_vector(s.datasize, data + i1, s.data);
735 
736  return s;
737 }
738 
739 template<class Num_T>
741 {
742  int size = indexlist.size();
743  Vec<Num_T> temp(size);
744  for (int i = 0; i < size; ++i) {
745  it_assert_debug(in_range(indexlist(i)), "Vec<>::operator()(ivec &): "
746  "Index i=" << i << " out of range");
747  temp(i) = data[indexlist(i)];
748  }
749  return temp;
750 }
751 
752 template<class Num_T>
754 {
755  int size = binlist.size();
756  it_assert_debug(datasize == size, "Vec<>::operator()(bvec &): "
757  "Wrong size of binlist vector");
758  Vec<Num_T> temp(size);
759  int j = 0;
760  for (int i = 0; i < size; ++i)
761  if (binlist(i) == bin(1))
762  temp(j++) = data[i];
763  temp.set_size(j, true);
764  return temp;
765 }
766 
767 
768 template<class Num_T> inline
769 const Num_T& Vec<Num_T>::get(int i) const
770 {
771  return (*this)[i];
772 }
773 
774 template<class Num_T> inline
775 Vec<Num_T> Vec<Num_T>::get(int i1, int i2) const
776 {
777  return (*this)(i1, i2);
778 }
779 
780 template<class Num_T> inline
781 Vec<Num_T> Vec<Num_T>::get(const Vec<int> &indexlist) const
782 {
783  return (*this)(indexlist);
784 }
785 
786 template<class Num_T> inline
787 Vec<Num_T> Vec<Num_T>::get(const Vec<bin> &binlist) const
788 {
789  return (*this)(binlist);
790 }
791 
792 template<class Num_T> inline
794 {
795  for (int i = 0; i < datasize; i++)
796  data[i] = Num_T(0);
797 }
798 
799 template<class Num_T> inline
801 {
802  for (int i = 0; i < datasize; i++)
803  data[i] = Num_T(1);
804 }
805 
806 template<class Num_T> inline
807 void Vec<Num_T>::set(int i, Num_T t)
808 {
809  it_assert_debug(in_range(i), "Vec<>::set(i, t): Index out of range");
810  data[i] = t;
811 }
812 
814 template<>
815 void Vec<double>::set(const std::string &str);
816 template<>
817 void Vec<std::complex<double> >::set(const std::string &str);
818 template<>
819 void Vec<int>::set(const std::string &str);
820 template<>
821 void Vec<short int>::set(const std::string &str);
822 template<>
823 void Vec<bin>::set(const std::string &str);
825 
826 template<class Num_T>
827 void Vec<Num_T>::set(const std::string &str)
828 {
829  it_error("Vec::set(): Only `double', `complex<double>', `int', "
830  "`short int' and `bin' types supported");
831 }
832 
833 template<class Num_T> inline
834 void Vec<Num_T>::set(const char *str)
835 {
836  set(std::string(str));
837 }
838 
839 
840 template<class Num_T>
842 {
843  Mat<Num_T> temp(1, datasize);
844  copy_vector(datasize, data, temp._data());
845  return temp;
846 }
847 
849 template<>
852 
853 template<class Num_T>
855 {
856  Mat<Num_T> temp(1, datasize);
857  copy_vector(datasize, data, temp._data());
858  return temp;
859 }
860 
861 template<class Num_T>
863 {
864  if (datasize == 0) { // if not assigned a size.
865  if (this != &v) { // check for self addition
866  alloc(v.datasize);
867  copy_vector(datasize, v.data, data);
868  }
869  }
870  else {
871  it_assert_debug(datasize == v.datasize, "Vec::operator+=: Wrong sizes");
872  for (int i = 0; i < datasize; i++)
873  data[i] += v.data[i];
874  }
875  return *this;
876 }
877 
878 template<class Num_T> inline
880 {
881  for (int i = 0;i < datasize;i++)
882  data[i] += t;
883  return *this;
884 }
885 
886 template<class Num_T>
888 {
889  int i;
890  Vec<Num_T> r(v1.datasize);
891 
892  it_assert_debug(v1.datasize == v2.datasize, "Vec::operator+: wrong sizes");
893  for (i = 0; i < v1.datasize; i++)
894  r.data[i] = v1.data[i] + v2.data[i];
895 
896  return r;
897 }
898 
899 template<class Num_T>
900 Vec<Num_T> operator+(const Vec<Num_T> &v, Num_T t)
901 {
902  int i;
903  Vec<Num_T> r(v.datasize);
904 
905  for (i = 0; i < v.datasize; i++)
906  r.data[i] = v.data[i] + t;
907 
908  return r;
909 }
910 
911 template<class Num_T>
912 Vec<Num_T> operator+(Num_T t, const Vec<Num_T> &v)
913 {
914  int i;
915  Vec<Num_T> r(v.datasize);
916 
917  for (i = 0; i < v.datasize; i++)
918  r.data[i] = t + v.data[i];
919 
920  return r;
921 }
922 
923 template<class Num_T>
925 {
926  if (datasize == 0) { // if not assigned a size.
927  if (this != &v) { // check for self decrementation
928  alloc(v.datasize);
929  for (int i = 0; i < v.datasize; i++)
930  data[i] = -v.data[i];
931  }
932  }
933  else {
934  it_assert_debug(datasize == v.datasize, "Vec::operator-=: Wrong sizes");
935  for (int i = 0; i < datasize; i++)
936  data[i] -= v.data[i];
937  }
938  return *this;
939 }
940 
941 template<class Num_T> inline
943 {
944  for (int i = 0;i < datasize;i++)
945  data[i] -= t;
946  return *this;
947 }
948 
949 template<class Num_T>
951 {
952  int i;
953  Vec<Num_T> r(v1.datasize);
954 
955  it_assert_debug(v1.datasize == v2.datasize, "Vec::operator-: wrong sizes");
956  for (i = 0; i < v1.datasize; i++)
957  r.data[i] = v1.data[i] - v2.data[i];
958 
959  return r;
960 }
961 
962 template<class Num_T>
963 Vec<Num_T> operator-(const Vec<Num_T> &v, Num_T t)
964 {
965  int i;
966  Vec<Num_T> r(v.datasize);
967 
968  for (i = 0; i < v.datasize; i++)
969  r.data[i] = v.data[i] - t;
970 
971  return r;
972 }
973 
974 template<class Num_T>
975 Vec<Num_T> operator-(Num_T t, const Vec<Num_T> &v)
976 {
977  int i;
978  Vec<Num_T> r(v.datasize);
979 
980  for (i = 0; i < v.datasize; i++)
981  r.data[i] = t - v.data[i];
982 
983  return r;
984 }
985 
986 template<class Num_T>
988 {
989  int i;
990  Vec<Num_T> r(v.datasize);
991 
992  for (i = 0; i < v.datasize; i++)
993  r.data[i] = -v.data[i];
994 
995  return r;
996 }
997 
998 template<class Num_T> inline
1000 {
1001  scal_vector(datasize, t, data);
1002  return *this;
1003 }
1004 
1005 
1007 template<>
1008 double dot(const vec &v1, const vec &v2);
1010 
1011 template<class Num_T>
1012 Num_T dot(const Vec<Num_T> &v1, const Vec<Num_T> &v2)
1013 {
1014  it_assert_debug(v1.datasize == v2.datasize, "Vec::dot(): Wrong sizes");
1015  Num_T r = Num_T(0);
1016  for (int i = 0; i < v1.datasize; ++i)
1017  r += v1.data[i] * v2.data[i];
1018  return r;
1019 }
1020 
1021 template<class Num_T> inline
1022 Num_T operator*(const Vec<Num_T> &v1, const Vec<Num_T> &v2)
1023 {
1024  return dot(v1, v2);
1025 }
1026 
1027 
1029 template<>
1030 mat outer_product(const vec &v1, const vec &v2, bool);
1031 
1032 template<>
1033 cmat outer_product(const cvec &v1, const cvec &v2, bool hermitian);
1035 
1036 template<class Num_T>
1037 Mat<Num_T> outer_product(const Vec<Num_T> &v1, const Vec<Num_T> &v2, bool)
1038 {
1039  it_assert_debug((v1.datasize > 0) && (v2.datasize > 0),
1040  "Vec::outer_product:: Input vector of zero size");
1041 
1042  Mat<Num_T> r(v1.datasize, v2.datasize);
1043  for (int i = 0; i < v1.datasize; ++i) {
1044  for (int j = 0; j < v2.datasize; ++j) {
1045  r(i, j) = v1.data[i] * v2.data[j];
1046  }
1047  }
1048  return r;
1049 }
1050 
1051 template<class Num_T>
1052 Vec<Num_T> operator*(const Vec<Num_T> &v, Num_T t)
1053 {
1054  int i;
1055  Vec<Num_T> r(v.datasize);
1056  for (i = 0; i < v.datasize; i++)
1057  r.data[i] = v.data[i] * t;
1058 
1059  return r;
1060 }
1061 
1062 template<class Num_T> inline
1063 Vec<Num_T> operator*(Num_T t, const Vec<Num_T> &v)
1064 {
1065  return operator*(v, t);
1066 }
1067 
1068 template<class Num_T> inline
1070 {
1071  Vec<Num_T> out;
1072  elem_mult_out(a, b, out);
1073  return out;
1074 }
1075 
1076 template<class Num_T> inline
1078  const Vec<Num_T> &c)
1079 {
1080  Vec<Num_T> out;
1081  elem_mult_out(a, b, c, out);
1082  return out;
1083 }
1084 
1085 template<class Num_T> inline
1087  const Vec<Num_T> &c, const Vec<Num_T> &d)
1088 {
1089  Vec<Num_T> out;
1090  elem_mult_out(a, b, c, d, out);
1091  return out;
1092 }
1093 
1094 template<class Num_T>
1095 void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b, Vec<Num_T> &out)
1096 {
1098  "Vec<>::elem_mult_out(): Wrong sizes");
1099  out.set_size(a.datasize);
1100  for (int i = 0; i < a.datasize; i++)
1101  out.data[i] = a.data[i] * b.data[i];
1102 }
1103 
1104 template<class Num_T>
1105 void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b,
1106  const Vec<Num_T> &c, Vec<Num_T> &out)
1107 {
1108  it_assert_debug((a.datasize == b.datasize) && (a.datasize == c.datasize),
1109  "Vec<>::elem_mult_out(): Wrong sizes");
1110  out.set_size(a.datasize);
1111  for (int i = 0; i < a.datasize; i++)
1112  out.data[i] = a.data[i] * b.data[i] * c.data[i];
1113 }
1114 
1115 template<class Num_T>
1116 void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b,
1117  const Vec<Num_T> &c, const Vec<Num_T> &d, Vec<Num_T> &out)
1118 {
1119  it_assert_debug((a.datasize == b.datasize) && (a.datasize == c.datasize)
1120  && (a.datasize == d.datasize),
1121  "Vec<>::elem_mult_out(): Wrong sizes");
1122  out.set_size(a.datasize);
1123  for (int i = 0; i < a.datasize; i++)
1124  out.data[i] = a.data[i] * b.data[i] * c.data[i] * d.data[i];
1125 }
1126 
1127 template<class Num_T>
1128 #ifndef _MSC_VER
1129 inline
1130 #endif
1132 {
1134  "Vec<>::elem_mult_inplace(): Wrong sizes");
1135  for (int i = 0; i < a.datasize; i++)
1136  b.data[i] *= a.data[i];
1137 }
1138 
1139 template<class Num_T> inline
1140 Num_T elem_mult_sum(const Vec<Num_T> &a, const Vec<Num_T> &b)
1141 {
1143  "Vec<>::elem_mult_sum(): Wrong sizes");
1144  Num_T acc = 0;
1145  for (int i = 0; i < a.datasize; i++)
1146  acc += a.data[i] * b.data[i];
1147  return acc;
1148 }
1149 
1150 template<class Num_T>
1151 Vec<Num_T> operator/(const Vec<Num_T> &v, Num_T t)
1152 {
1153  int i;
1154  Vec<Num_T> r(v.datasize);
1155 
1156  for (i = 0; i < v.datasize; i++)
1157  r.data[i] = v.data[i] / t;
1158 
1159  return r;
1160 }
1161 
1162 template<class Num_T>
1163 Vec<Num_T> operator/(Num_T t, const Vec<Num_T> &v)
1164 {
1165  int i;
1166  Vec<Num_T> r(v.datasize);
1167 
1168  for (i = 0; i < v.datasize; i++)
1169  r.data[i] = t / v.data[i];
1170 
1171  return r;
1172 }
1173 
1174 template<class Num_T>
1175 Vec<Num_T> elem_div(Num_T t, const Vec<Num_T> &v)
1176 {
1177  it_warning("Vec<>::elem_div(Num_T, const Vec<Num_T> &): This function is "
1178  "deprecated and might be removed from future IT++ releases. "
1179  "Please use Vec<>::operator/(Num_T, const Vec<Num_T> &) "
1180  "instead.");
1181  return operator/(t, v);
1182 }
1183 
1184 template<class Num_T> inline
1186 {
1187  for (int i = 0; i < datasize; ++i) {
1188  data[i] /= t;
1189  }
1190  return *this;
1191 }
1192 
1193 template<class Num_T> inline
1195 {
1196  it_assert_debug(datasize == v.datasize, "Vec::operator/=(): wrong sizes");
1197  for (int i = 0; i < datasize; ++i) {
1198  data[i] /= v.data[i];
1199  }
1200  return *this;
1201 }
1202 
1203 template<class Num_T> inline
1205 {
1206  Vec<Num_T> out;
1207  elem_div_out(a, b, out);
1208  return out;
1209 }
1210 
1211 template<class Num_T>
1212 void elem_div_out(const Vec<Num_T> &a, const Vec<Num_T> &b, Vec<Num_T> &out)
1213 {
1214  it_assert_debug(a.datasize == b.datasize, "Vecelem_div_out: wrong sizes");
1215 
1216  out.set_size(a.size());
1217 
1218  for (int i = 0; i < a.datasize; i++)
1219  out.data[i] = a.data[i] / b.data[i];
1220 }
1221 
1222 template<class Num_T> inline
1223 Num_T elem_div_sum(const Vec<Num_T> &a, const Vec<Num_T> &b)
1224 {
1225  it_assert_debug(a.datasize == b.datasize, "Vec::elem_div_sum: wrong sizes");
1226 
1227  Num_T acc = 0;
1228 
1229  for (int i = 0; i < a.datasize; i++)
1230  acc += a.data[i] / b.data[i];
1231 
1232  return acc;
1233 }
1234 
1235 template<class Num_T>
1237 {
1238  it_assert_debug(nr <= datasize, "Vec::right(): index out of range");
1239  Vec<Num_T> temp(nr);
1240  if (nr > 0) {
1241  copy_vector(nr, &data[datasize-nr], temp.data);
1242  }
1243  return temp;
1244 }
1245 
1246 template<class Num_T>
1248 {
1249  it_assert_debug(nr <= datasize, "Vec::left(): index out of range");
1250  Vec<Num_T> temp(nr);
1251  if (nr > 0) {
1252  copy_vector(nr, data, temp.data);
1253  }
1254  return temp;
1255 }
1256 
1257 template<class Num_T>
1258 Vec<Num_T> Vec<Num_T>::mid(int start, int nr) const
1259 {
1260  it_assert_debug((start >= 0) && ((start + nr) <= datasize),
1261  "Vec::mid(): indexing out of range");
1262  Vec<Num_T> temp(nr);
1263  if (nr > 0) {
1264  copy_vector(nr, &data[start], temp.data);
1265  }
1266  return temp;
1267 }
1268 
1269 template<class Num_T>
1271 {
1272  it_assert_debug((pos >= 0) && (pos <= datasize),
1273  "Vec<>::split(): Index out of range");
1274  Vec<Num_T> temp1(pos);
1275  if (pos > 0) {
1276  copy_vector(pos, data, temp1.data);
1277  if (pos < datasize) {
1278  Vec<Num_T> temp2(datasize - pos);
1279  copy_vector(datasize - pos, &data[pos], temp2.data);
1280  (*this) = temp2;
1281  }
1282  else {
1283  set_size(0);
1284  }
1285  }
1286  return temp1;
1287 }
1288 
1289 template<class Num_T>
1290 void Vec<Num_T>::shift_right(Num_T t, int n)
1291 {
1292  int i = datasize;
1293 
1294  it_assert_debug(n >= 0, "Vec::shift_right: index out of range");
1295  while (--i >= n)
1296  data[i] = data[i-n];
1297  while (i >= 0)
1298  data[i--] = t;
1299 }
1300 
1301 template<class Num_T>
1303 {
1304  for (int i = datasize - 1; i >= v.datasize; i--)
1305  data[i] = data[i-v.datasize];
1306  for (int i = 0; i < v.datasize; i++)
1307  data[i] = v[i];
1308 }
1309 
1310 template<class Num_T>
1311 void Vec<Num_T>::shift_left(Num_T t, int n)
1312 {
1313  int i;
1314 
1315  it_assert_debug(n >= 0, "Vec::shift_left: index out of range");
1316  for (i = 0; i < datasize - n; i++)
1317  data[i] = data[i+n];
1318  while (i < datasize)
1319  data[i++] = t;
1320 }
1321 
1322 template<class Num_T>
1324 {
1325  for (int i = 0; i < datasize - v.datasize; i++)
1326  data[i] = data[i+v.datasize];
1327  for (int i = datasize - v.datasize; i < datasize; i++)
1328  data[i] = v[i-datasize+v.datasize];
1329 }
1330 
1331 template<class Num_T>
1332 Vec<Num_T> concat(const Vec<Num_T> &v, Num_T t)
1333 {
1334  int size = v.size();
1335  Vec<Num_T> temp(size + 1);
1336  copy_vector(size, v.data, temp.data);
1337  temp(size) = t;
1338  return temp;
1339 }
1340 
1341 template<class Num_T>
1342 Vec<Num_T> concat(Num_T t, const Vec<Num_T> &v)
1343 {
1344  int size = v.size();
1345  Vec<Num_T> temp(size + 1);
1346  temp(0) = t;
1347  copy_vector(size, v.data, &temp.data[1]);
1348  return temp;
1349 }
1350 
1351 template<class Num_T>
1353 {
1354  int size1 = v1.size();
1355  int size2 = v2.size();
1356  Vec<Num_T> temp(size1 + size2);
1357  copy_vector(size1, v1.data, temp.data);
1358  copy_vector(size2, v2.data, &temp.data[size1]);
1359  return temp;
1360 }
1361 
1362 template<class Num_T>
1364  const Vec<Num_T> &v3)
1365 {
1366  int size1 = v1.size();
1367  int size2 = v2.size();
1368  int size3 = v3.size();
1369  Vec<Num_T> temp(size1 + size2 + size3);
1370  copy_vector(size1, v1.data, temp.data);
1371  copy_vector(size2, v2.data, &temp.data[size1]);
1372  copy_vector(size3, v3.data, &temp.data[size1+size2]);
1373  return temp;
1374 }
1375 
1376 template<class Num_T>
1378  const Vec<Num_T> &v3, const Vec<Num_T> &v4)
1379 {
1380  int size1 = v1.size();
1381  int size2 = v2.size();
1382  int size3 = v3.size();
1383  int size4 = v4.size();
1384  Vec<Num_T> temp(size1 + size2 + size3 + size4);
1385  copy_vector(size1, v1.data, temp.data);
1386  copy_vector(size2, v2.data, &temp.data[size1]);
1387  copy_vector(size3, v3.data, &temp.data[size1+size2]);
1388  copy_vector(size4, v4.data, &temp.data[size1+size2+size3]);
1389  return temp;
1390 }
1391 
1392 template<class Num_T>
1394  const Vec<Num_T> &v3, const Vec<Num_T> &v4,
1395  const Vec<Num_T> &v5)
1396 {
1397  int size1 = v1.size();
1398  int size2 = v2.size();
1399  int size3 = v3.size();
1400  int size4 = v4.size();
1401  int size5 = v5.size();
1402  Vec<Num_T> temp(size1 + size2 + size3 + size4 + size5);
1403  copy_vector(size1, v1.data, temp.data);
1404  copy_vector(size2, v2.data, &temp.data[size1]);
1405  copy_vector(size3, v3.data, &temp.data[size1+size2]);
1406  copy_vector(size4, v4.data, &temp.data[size1+size2+size3]);
1407  copy_vector(size5, v5.data, &temp.data[size1+size2+size3+size4]);
1408  return temp;
1409 }
1410 
1411 template<class Num_T>
1412 void Vec<Num_T>::set_subvector(int i1, int, const Vec<Num_T> &v)
1413 {
1414  it_warning("Vec<>::set_subvector(int, int, const Vec<> &): This function "
1415  "is deprecated and might be removed from future IT++ releases. "
1416  "Please use Vec<>::set_subvector(int, const Vec<> &) instead.");
1417  set_subvector(i1, v);
1418 }
1419 
1420 template<class Num_T> inline
1422 {
1423  it_assert_debug((i >= 0) && (i + v.datasize <= datasize),
1424  "Vec<>::set_subvector(int, const Vec<> &): "
1425  "Index out of range or too long input vector");
1426  copy_vector(v.datasize, v.data, data + i);
1427 }
1428 
1429 template<class Num_T> inline
1430 void Vec<Num_T>::set_subvector(int i1, int i2, Num_T t)
1431 {
1432  if (i1 == -1) i1 = datasize - 1;
1433  if (i2 == -1) i2 = datasize - 1;
1434  it_assert_debug((i1 >= 0) && (i1 <= i2) && (i2 < datasize),
1435  "Vec<>::set_subvector(int, int, Num_T): Indexing out "
1436  "of range");
1437  for (int i = i1; i <= i2; i++)
1438  data[i] = t;
1439 }
1440 
1441 template<class Num_T> inline
1443 {
1444  set_subvector(i, v);
1445 }
1446 
1447 template<class Num_T>
1448 void Vec<Num_T>::del(int index)
1449 {
1450  it_assert_debug(in_range(index), "Vec<>::del(int): Index out of range");
1451  Vec<Num_T> temp(*this);
1452  set_size(datasize - 1, false);
1453  copy_vector(index, temp.data, data);
1454  copy_vector(datasize - index, &temp.data[index+1], &data[index]);
1455 }
1456 
1457 template<class Num_T>
1458 void Vec<Num_T>::del(int i1, int i2)
1459 {
1460  if (i1 == -1) i1 = datasize - 1;
1461  if (i2 == -1) i2 = datasize - 1;
1462  it_assert_debug((i1 >= 0) && (i1 <= i2) && (i2 < datasize),
1463  "Vec<>::del(int, int): Indexing out of range");
1464  Vec<Num_T> temp(*this);
1465  int new_size = datasize - (i2 - i1 + 1);
1466  set_size(new_size, false);
1467  copy_vector(i1, temp.data, data);
1468  copy_vector(datasize - i1, &temp.data[i2+1], &data[i1]);
1469 }
1470 
1471 template<class Num_T>
1472 void Vec<Num_T>::ins(int index, const Num_T t)
1473 {
1474  it_assert_debug((index >= 0) && (index <= datasize),
1475  "Vec<>::ins(): Index out of range");
1476  Vec<Num_T> Temp(*this);
1477 
1478  set_size(datasize + 1, false);
1479  copy_vector(index, Temp.data, data);
1480  data[index] = t;
1481  copy_vector(Temp.datasize - index, Temp.data + index, data + index + 1);
1482 }
1483 
1484 template<class Num_T>
1485 void Vec<Num_T>::ins(int index, const Vec<Num_T> &v)
1486 {
1487  it_assert_debug((index >= 0) && (index <= datasize),
1488  "Vec<>::ins(): Index out of range");
1489  Vec<Num_T> Temp(*this);
1490 
1491  set_size(datasize + v.length(), false);
1492  copy_vector(index, Temp.data, data);
1493  copy_vector(v.size(), v.data, &data[index]);
1494  copy_vector(Temp.datasize - index, Temp.data + index, data + index + v.size());
1495 }
1496 
1497 template<class Num_T> inline
1499 {
1500  for (int i = 0;i < datasize;i++)
1501  data[i] = t;
1502  return *this;
1503 }
1504 
1505 template<class Num_T> inline
1507 {
1508  if (this != &v) {
1509  set_size(v.datasize, false);
1510  copy_vector(datasize, v.data, data);
1511  }
1512  return *this;
1513 }
1514 
1515 template<class Num_T>
1517 {
1518  if (m.cols() == 1) {
1519  set_size(m.rows(), false);
1520  copy_vector(m.rows(), m._data(), data);
1521  }
1522  else if (m.rows() == 1) {
1523  set_size(m.cols(), false);
1524  copy_vector(m.cols(), m._data(), m.rows(), data, 1);
1525  }
1526  else
1527  it_error("Vec<>::operator=(Mat<Num_T> &): Wrong size of input matrix");
1528  return *this;
1529 }
1530 
1531 template<class Num_T> inline
1533 {
1534  set(std::string(str));
1535  return *this;
1536 }
1537 
1538 template<class Num_T> inline
1539 Vec<Num_T>& Vec<Num_T>::operator=(const std::string &str)
1540 {
1541  set(str);
1542  return *this;
1543 }
1544 
1545 template<class Num_T>
1547 {
1548  it_assert_debug(datasize > 0, "Vec<>::operator==(): Wrong size");
1549  bvec temp(datasize);
1550  for (int i = 0; i < datasize; i++)
1551  temp(i) = (data[i] == t);
1552  return temp;
1553 }
1554 
1555 template<class Num_T>
1557 {
1558  it_assert_debug(datasize > 0, "Vec<>::operator!=(): Wrong size");
1559  bvec temp(datasize);
1560  for (int i = 0; i < datasize; i++)
1561  temp(i) = (data[i] != t);
1562  return temp;
1563 }
1564 
1566 template<>
1567 bvec Vec<std::complex<double> >::operator<(std::complex<double>) const;
1569 
1570 template<class Num_T>
1572 {
1573  it_assert_debug(datasize > 0, "Vec<>::operator<(): Wrong size");
1574  bvec temp(datasize);
1575  for (int i = 0; i < datasize; i++)
1576  temp(i) = (data[i] < t);
1577  return temp;
1578 }
1579 
1581 template<>
1582 bvec Vec<std::complex<double> >::operator<=(std::complex<double>) const;
1584 
1585 template<class Num_T>
1587 {
1588  it_assert_debug(datasize > 0, "Vec<>::operator<=(): Wrong size");
1589  bvec temp(datasize);
1590  for (int i = 0; i < datasize; i++)
1591  temp(i) = (data[i] <= t);
1592  return temp;
1593 }
1594 
1596 template<>
1597 bvec Vec<std::complex<double> >::operator>(std::complex<double>) const;
1599 
1600 template<class Num_T>
1602 {
1603  it_assert_debug(datasize > 0, "Vec<>::operator>(): Wrong size");
1604  bvec temp(datasize);
1605  for (int i = 0; i < datasize; i++)
1606  temp(i) = (data[i] > t);
1607  return temp;
1608 }
1609 
1611 template<>
1612 bvec Vec<std::complex<double> >::operator>=(std::complex<double>) const;
1614 
1615 template<class Num_T>
1617 {
1618  it_assert_debug(datasize > 0, "Vec<>::operator>=(): Wrong size");
1619  bvec temp(datasize);
1620  for (int i = 0; i < datasize; i++)
1621  temp(i) = (data[i] >= t);
1622  return temp;
1623 }
1624 
1625 template<class Num_T>
1626 bool Vec<Num_T>::operator==(const Vec<Num_T> &invector) const
1627 {
1628  // OBS ! if wrong size, return false
1629  if (datasize != invector.datasize) return false;
1630  for (int i = 0;i < datasize;i++) {
1631  if (data[i] != invector.data[i]) return false;
1632  }
1633  return true;
1634 }
1635 
1636 template<class Num_T>
1637 bool Vec<Num_T>::operator!=(const Vec<Num_T> &invector) const
1638 {
1639  if (datasize != invector.datasize) return true;
1640  for (int i = 0;i < datasize;i++) {
1641  if (data[i] != invector.data[i]) return true;
1642  }
1643  return false;
1644 }
1645 
1647 template<class Num_T>
1648 std::ostream &operator<<(std::ostream &os, const Vec<Num_T> &v)
1649 {
1650  int i, sz = v.length();
1651 
1652  os << "[" ;
1653  for (i = 0; i < sz; i++) {
1654  os << v(i) ;
1655  if (i < sz - 1)
1656  os << " ";
1657  }
1658  os << "]" ;
1659 
1660  return os;
1661 }
1662 
1664 template<class Num_T>
1665 std::istream &operator>>(std::istream &is, Vec<Num_T> &v)
1666 {
1667  std::ostringstream buffer;
1668  bool started = false;
1669  bool finished = false;
1670  bool brackets = false;
1671  char c;
1672 
1673  while (!finished) {
1674  if (is.eof()) {
1675  finished = true;
1676  }
1677  else {
1678  is.get(c);
1679 
1680  if (is.eof() || (c == '\n')) {
1681  if (brackets) {
1682  // Right bracket missing
1683  is.setstate(std::ios_base::failbit);
1684  finished = true;
1685  }
1686  else if (!((c == '\n') && !started)) {
1687  finished = true;
1688  }
1689  }
1690  else if ((c == ' ') || (c == '\t')) {
1691  if (started) {
1692  buffer << ' ';
1693  }
1694  }
1695  else if (c == '[') {
1696  if (started) {
1697  // Unexpected left bracket
1698  is.setstate(std::ios_base::failbit);
1699  finished = true;
1700  }
1701  else {
1702  started = true;
1703  brackets = true;
1704  }
1705  }
1706  else if (c == ']') {
1707  if (!started || !brackets) {
1708  // Unexpected right bracket
1709  is.setstate(std::ios_base::failbit);
1710  finished = true;
1711  }
1712  else {
1713  finished = true;
1714  }
1715  while (!is.eof() && (((c = static_cast<char>(is.peek())) == ' ')
1716  || (c == '\t'))) {
1717  is.get();
1718  }
1719  if (!is.eof() && (c == '\n')) {
1720  is.get();
1721  }
1722  }
1723  else {
1724  started = true;
1725  buffer << c;
1726  }
1727  }
1728  }
1729 
1730  if (!started) {
1731  v.set_size(0, false);
1732  }
1733  else {
1734  v.set(buffer.str());
1735  }
1736 
1737  return is;
1738 }
1739 
1741 
1742 // ----------------------------------------------------------------------
1743 // Private functions
1744 // ----------------------------------------------------------------------
1745 
1746 template<class Num_T>
1747 void Vec<Num_T>::parse_abc_token(const std::string &s, Num_T &a, Num_T &b,
1748  Num_T &c) const
1749 {
1750  std::string::size_type beg = 0;
1751  std::string::size_type end = s.find(':', 0);
1752  a = parse_token(s.substr(beg, end-beg));
1753  beg = end + 1;
1754  end = s.find(':', beg);
1755  if (end != std::string::npos) {
1756  b = parse_token(s.substr(beg, end-beg));
1757  c = parse_token(s.substr(end+1, s.size()-end));
1758  }
1759  else {
1760  b = Num_T(1);
1761  c = parse_token(s.substr(beg, end-beg-1));
1762  }
1763 }
1764 
1765 template<class Num_T>
1766 Num_T Vec<Num_T>::parse_token(const std::string &s) const
1767 {
1768  it_error("Vec::parse_token(): Only `double' and `int' types are supported");
1769  return 0;
1770 }
1771 
1772 template<>
1773 double Vec<double>::parse_token(const std::string &s) const;
1774 template<>
1775 int Vec<int>::parse_token(const std::string &s) const;
1776 
1777 
1778 // ----------------------------------------------------------------------
1779 // Instantiations
1780 // ----------------------------------------------------------------------
1781 
1782 #ifndef _MSC_VER
1783 
1784 extern template class Vec<double>;
1785 extern template class Vec<int>;
1786 extern template class Vec<short int>;
1787 extern template class Vec<std::complex<double> >;
1788 extern template class Vec<bin>;
1789 
1790 // addition operator
1791 
1792 extern template vec operator+(const vec &v1, const vec &v2);
1793 extern template cvec operator+(const cvec &v1, const cvec &v2);
1794 extern template ivec operator+(const ivec &v1, const ivec &v2);
1795 extern template svec operator+(const svec &v1, const svec &v2);
1796 extern template bvec operator+(const bvec &v1, const bvec &v2);
1797 
1798 extern template vec operator+(const vec &v1, double t);
1799 extern template cvec operator+(const cvec &v1, std::complex<double> t);
1800 extern template ivec operator+(const ivec &v1, int t);
1801 extern template svec operator+(const svec &v1, short t);
1802 extern template bvec operator+(const bvec &v1, bin t);
1803 
1804 extern template vec operator+(double t, const vec &v1);
1805 extern template cvec operator+(std::complex<double> t, const cvec &v1);
1806 extern template ivec operator+(int t, const ivec &v1);
1807 extern template svec operator+(short t, const svec &v1);
1808 extern template bvec operator+(bin t, const bvec &v1);
1809 
1810 // subtraction operator
1811 
1812 extern template vec operator-(const vec &v1, const vec &v2);
1813 extern template cvec operator-(const cvec &v1, const cvec &v2);
1814 extern template ivec operator-(const ivec &v1, const ivec &v2);
1815 extern template svec operator-(const svec &v1, const svec &v2);
1816 extern template bvec operator-(const bvec &v1, const bvec &v2);
1817 
1818 extern template vec operator-(const vec &v, double t);
1819 extern template cvec operator-(const cvec &v, std::complex<double> t);
1820 extern template ivec operator-(const ivec &v, int t);
1821 extern template svec operator-(const svec &v, short t);
1822 extern template bvec operator-(const bvec &v, bin t);
1823 
1824 extern template vec operator-(double t, const vec &v);
1825 extern template cvec operator-(std::complex<double> t, const cvec &v);
1826 extern template ivec operator-(int t, const ivec &v);
1827 extern template svec operator-(short t, const svec &v);
1828 extern template bvec operator-(bin t, const bvec &v);
1829 
1830 // unary minus
1831 
1832 extern template vec operator-(const vec &v);
1833 extern template cvec operator-(const cvec &v);
1834 extern template ivec operator-(const ivec &v);
1835 extern template svec operator-(const svec &v);
1836 extern template bvec operator-(const bvec &v);
1837 
1838 // multiplication operator
1839 
1840 extern template std::complex<double> dot(const cvec &v1, const cvec &v2);
1841 extern template int dot(const ivec &v1, const ivec &v2);
1842 extern template short dot(const svec &v1, const svec &v2);
1843 extern template bin dot(const bvec &v1, const bvec &v2);
1844 
1845 extern template double operator*(const vec &v1, const vec &v2);
1846 extern template std::complex<double> operator*(const cvec &v1, const cvec &v2);
1847 extern template int operator*(const ivec &v1, const ivec &v2);
1848 extern template short operator*(const svec &v1, const svec &v2);
1849 extern template bin operator*(const bvec &v1, const bvec &v2);
1850 
1851 extern template imat outer_product(const ivec &v1, const ivec &v2,
1852  bool hermitian);
1853 extern template smat outer_product(const svec &v1, const svec &v2,
1854  bool hermitian);
1855 extern template bmat outer_product(const bvec &v1, const bvec &v2,
1856  bool hermitian);
1857 
1858 extern template vec operator*(const vec &v, double t);
1859 extern template cvec operator*(const cvec &v, std::complex<double> t);
1860 extern template ivec operator*(const ivec &v, int t);
1861 extern template svec operator*(const svec &v, short t);
1862 extern template bvec operator*(const bvec &v, bin t);
1863 
1864 extern template vec operator*(double t, const vec &v);
1865 extern template cvec operator*(std::complex<double> t, const cvec &v);
1866 extern template ivec operator*(int t, const ivec &v);
1867 extern template svec operator*(short t, const svec &v);
1868 extern template bvec operator*(bin t, const bvec &v);
1869 
1870 // elementwise multiplication
1871 
1872 extern template vec elem_mult(const vec &a, const vec &b);
1873 extern template cvec elem_mult(const cvec &a, const cvec &b);
1874 extern template ivec elem_mult(const ivec &a, const ivec &b);
1875 extern template svec elem_mult(const svec &a, const svec &b);
1876 extern template bvec elem_mult(const bvec &a, const bvec &b);
1877 
1878 extern template void elem_mult_out(const vec &a, const vec &b, vec &out);
1879 extern template void elem_mult_out(const cvec &a, const cvec &b, cvec &out);
1880 extern template void elem_mult_out(const ivec &a, const ivec &b, ivec &out);
1881 extern template void elem_mult_out(const svec &a, const svec &b, svec &out);
1882 extern template void elem_mult_out(const bvec &a, const bvec &b, bvec &out);
1883 
1884 extern template vec elem_mult(const vec &a, const vec &b, const vec &c);
1885 extern template cvec elem_mult(const cvec &a, const cvec &b, const cvec &c);
1886 extern template ivec elem_mult(const ivec &a, const ivec &b, const ivec &c);
1887 extern template svec elem_mult(const svec &a, const svec &b, const svec &c);
1888 extern template bvec elem_mult(const bvec &a, const bvec &b, const bvec &c);
1889 
1890 extern template void elem_mult_out(const vec &a, const vec &b,
1891  const vec &c, vec &out);
1892 extern template void elem_mult_out(const cvec &a, const cvec &b,
1893  const cvec &c, cvec &out);
1894 extern template void elem_mult_out(const ivec &a, const ivec &b,
1895  const ivec &c, ivec &out);
1896 extern template void elem_mult_out(const svec &a, const svec &b,
1897  const svec &c, svec &out);
1898 extern template void elem_mult_out(const bvec &a, const bvec &b,
1899  const bvec &c, bvec &out);
1900 
1901 extern template vec elem_mult(const vec &a, const vec &b,
1902  const vec &c, const vec &d);
1903 extern template cvec elem_mult(const cvec &a, const cvec &b,
1904  const cvec &c, const cvec &d);
1905 extern template ivec elem_mult(const ivec &a, const ivec &b,
1906  const ivec &c, const ivec &d);
1907 extern template svec elem_mult(const svec &a, const svec &b,
1908  const svec &c, const svec &d);
1909 extern template bvec elem_mult(const bvec &a, const bvec &b,
1910  const bvec &c, const bvec &d);
1911 
1912 extern template void elem_mult_out(const vec &a, const vec &b, const vec &c,
1913  const vec &d, vec &out);
1914 extern template void elem_mult_out(const cvec &a, const cvec &b,
1915  const cvec &c, const cvec &d, cvec &out);
1916 extern template void elem_mult_out(const ivec &a, const ivec &b,
1917  const ivec &c, const ivec &d, ivec &out);
1918 extern template void elem_mult_out(const svec &a, const svec &b,
1919  const svec &c, const svec &d, svec &out);
1920 extern template void elem_mult_out(const bvec &a, const bvec &b,
1921  const bvec &c, const bvec &d, bvec &out);
1922 
1923 // in-place elementwise multiplication
1924 
1925 extern template void elem_mult_inplace(const vec &a, vec &b);
1926 extern template void elem_mult_inplace(const cvec &a, cvec &b);
1927 extern template void elem_mult_inplace(const ivec &a, ivec &b);
1928 extern template void elem_mult_inplace(const svec &a, svec &b);
1929 extern template void elem_mult_inplace(const bvec &a, bvec &b);
1930 
1931 // elementwise multiplication followed by summation
1932 
1933 extern template double elem_mult_sum(const vec &a, const vec &b);
1934 extern template std::complex<double> elem_mult_sum(const cvec &a,
1935  const cvec &b);
1936 extern template int elem_mult_sum(const ivec &a, const ivec &b);
1937 extern template short elem_mult_sum(const svec &a, const svec &b);
1938 extern template bin elem_mult_sum(const bvec &a, const bvec &b);
1939 
1940 // division operator
1941 
1942 extern template vec operator/(const vec &v, double t);
1943 extern template cvec operator/(const cvec &v, std::complex<double> t);
1944 extern template ivec operator/(const ivec &v, int t);
1945 extern template svec operator/(const svec &v, short t);
1946 extern template bvec operator/(const bvec &v, bin t);
1947 
1948 extern template vec operator/(double t, const vec &v);
1949 extern template cvec operator/(std::complex<double> t, const cvec &v);
1950 extern template ivec operator/(int t, const ivec &v);
1951 extern template svec operator/(short t, const svec &v);
1952 extern template bvec operator/(bin t, const bvec &v);
1953 
1954 // elementwise division operator
1955 
1956 extern template vec elem_div(const vec &a, const vec &b);
1957 extern template cvec elem_div(const cvec &a, const cvec &b);
1958 extern template ivec elem_div(const ivec &a, const ivec &b);
1959 extern template svec elem_div(const svec &a, const svec &b);
1960 extern template bvec elem_div(const bvec &a, const bvec &b);
1961 
1962 extern template vec elem_div(double t, const vec &v);
1963 extern template cvec elem_div(std::complex<double> t, const cvec &v);
1964 extern template ivec elem_div(int t, const ivec &v);
1965 extern template svec elem_div(short t, const svec &v);
1966 extern template bvec elem_div(bin t, const bvec &v);
1967 
1968 extern template void elem_div_out(const vec &a, const vec &b, vec &out);
1969 extern template void elem_div_out(const cvec &a, const cvec &b, cvec &out);
1970 extern template void elem_div_out(const ivec &a, const ivec &b, ivec &out);
1971 extern template void elem_div_out(const svec &a, const svec &b, svec &out);
1972 extern template void elem_div_out(const bvec &a, const bvec &b, bvec &out);
1973 
1974 // elementwise division followed by summation
1975 
1976 extern template double elem_div_sum(const vec &a, const vec &b);
1977 extern template std::complex<double> elem_div_sum(const cvec &a,
1978  const cvec &b);
1979 extern template int elem_div_sum(const ivec &a, const ivec &b);
1980 extern template short elem_div_sum(const svec &a, const svec &b);
1981 extern template bin elem_div_sum(const bvec &a, const bvec &b);
1982 
1983 // concat operator
1984 
1985 extern template vec concat(const vec &v, double a);
1986 extern template cvec concat(const cvec &v, std::complex<double> a);
1987 extern template ivec concat(const ivec &v, int a);
1988 extern template svec concat(const svec &v, short a);
1989 extern template bvec concat(const bvec &v, bin a);
1990 
1991 extern template vec concat(double a, const vec &v);
1992 extern template cvec concat(std::complex<double> a, const cvec &v);
1993 extern template ivec concat(int a, const ivec &v);
1994 extern template svec concat(short a, const svec &v);
1995 extern template bvec concat(bin a, const bvec &v);
1996 
1997 extern template vec concat(const vec &v1, const vec &v2);
1998 extern template cvec concat(const cvec &v1, const cvec &v2);
1999 extern template ivec concat(const ivec &v1, const ivec &v2);
2000 extern template svec concat(const svec &v1, const svec &v2);
2001 extern template bvec concat(const bvec &v1, const bvec &v2);
2002 
2003 extern template vec concat(const vec &v1, const vec &v2, const vec &v3);
2004 extern template cvec concat(const cvec &v1, const cvec &v2, const cvec &v3);
2005 extern template ivec concat(const ivec &v1, const ivec &v2, const ivec &v3);
2006 extern template svec concat(const svec &v1, const svec &v2, const svec &v3);
2007 extern template bvec concat(const bvec &v1, const bvec &v2, const bvec &v3);
2008 
2009 extern template vec concat(const vec &v1, const vec &v2,
2010  const vec &v3, const vec &v4);
2011 extern template cvec concat(const cvec &v1, const cvec &v2,
2012  const cvec &v3, const cvec &v4);
2013 extern template ivec concat(const ivec &v1, const ivec &v2,
2014  const ivec &v3, const ivec &v4);
2015 extern template svec concat(const svec &v1, const svec &v2,
2016  const svec &v3, const svec &v4);
2017 extern template bvec concat(const bvec &v1, const bvec &v2,
2018  const bvec &v3, const bvec &v4);
2019 
2020 extern template vec concat(const vec &v1, const vec &v2, const vec &v3,
2021  const vec &v4, const vec &v5);
2022 extern template cvec concat(const cvec &v1, const cvec &v2, const cvec &v3,
2023  const cvec &v4, const cvec &v5);
2024 extern template ivec concat(const ivec &v1, const ivec &v2, const ivec &v3,
2025  const ivec &v4, const ivec &v5);
2026 extern template svec concat(const svec &v1, const svec &v2, const svec &v3,
2027  const svec &v4, const svec &v5);
2028 extern template bvec concat(const bvec &v1, const bvec &v2, const bvec &v3,
2029  const bvec &v4, const bvec &v5);
2030 
2031 // I/O streams
2032 
2033 extern template std::ostream &operator<<(std::ostream& os, const vec &vect);
2034 extern template std::ostream &operator<<(std::ostream& os, const cvec &vect);
2035 extern template std::ostream &operator<<(std::ostream& os, const svec &vect);
2036 extern template std::ostream &operator<<(std::ostream& os, const ivec &vect);
2037 extern template std::ostream &operator<<(std::ostream& os, const bvec &vect);
2038 extern template std::istream &operator>>(std::istream& is, vec &vect);
2039 extern template std::istream &operator>>(std::istream& is, cvec &vect);
2040 extern template std::istream &operator>>(std::istream& is, svec &vect);
2041 extern template std::istream &operator>>(std::istream& is, ivec &vect);
2042 extern template std::istream &operator>>(std::istream& is, bvec &vect);
2043 
2044 #endif // _MSC_VER
2045 
2047 
2048 } // namespace itpp
2049 
2050 #endif // #ifndef VEC_H
SourceForge Logo

Generated on Fri Mar 21 2014 17:14:13 for IT++ by Doxygen 1.8.1.2