IT++ Logo
mat.h
Go to the documentation of this file.
1 
29 #ifndef MAT_H
30 #define MAT_H
31 
32 #include <itpp/base/itassert.h>
33 #include <itpp/base/math/misc.h>
34 #include <itpp/base/factory.h>
35 #include <itpp/itexports.h>
36 
37 namespace itpp
38 {
39 
40 // Declaration of Vec
41 template<class Num_T> class Vec;
42 // Declaration of Mat
43 template<class Num_T> class Mat;
44 // Declaration of bin
45 class bin;
46 
48 template<class Num_T>
49 Mat<Num_T> concat_horizontal(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
51 template<class Num_T>
52 Mat<Num_T> concat_vertical(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
53 
55 template<class Num_T>
56 Mat<Num_T> operator+(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
58 template<class Num_T>
59 Mat<Num_T> operator+(const Mat<Num_T> &m, Num_T t);
61 template<class Num_T>
62 Mat<Num_T> operator+(Num_T t, const Mat<Num_T> &m);
63 
65 template<class Num_T>
66 Mat<Num_T> operator-(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
68 template<class Num_T>
69 Mat<Num_T> operator-(const Mat<Num_T> &m, Num_T t);
71 template<class Num_T>
72 Mat<Num_T> operator-(Num_T t, const Mat<Num_T> &m);
74 template<class Num_T>
75 Mat<Num_T> operator-(const Mat<Num_T> &m);
76 
78 template<class Num_T>
79 Mat<Num_T> operator*(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
81 template<class Num_T>
82 Vec<Num_T> operator*(const Mat<Num_T> &m, const Vec<Num_T> &v);
84 template<class Num_T>
85 Mat<Num_T> operator*(const Mat<Num_T> &m, Num_T t);
87 template<class Num_T>
88 Mat<Num_T> operator*(Num_T t, const Mat<Num_T> &m);
89 
91 template<class Num_T>
92 Mat<Num_T> elem_mult(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
94 template<class Num_T>
95 void elem_mult_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2,
96  Mat<Num_T> &out);
98 template<class Num_T>
99 void elem_mult_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2,
100  const Mat<Num_T> &m3, Mat<Num_T> &out);
102 template<class Num_T>
103 void elem_mult_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2,
104  const Mat<Num_T> &m3, const Mat<Num_T> &m4,
105  Mat<Num_T> &out);
107 template<class Num_T>
108 void elem_mult_inplace(const Mat<Num_T> &m1, Mat<Num_T> &m2);
110 template<class Num_T>
111 Num_T elem_mult_sum(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
112 
114 template<class Num_T>
115 Mat<Num_T> operator/(const Mat<Num_T> &m, Num_T t);
117 template<class Num_T>
118 Mat<Num_T> operator/(Num_T t, const Mat<Num_T> &m);
119 
121 template<class Num_T>
122 Mat<Num_T> elem_div(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
124 template<class Num_T>
125 void elem_div_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2,
126  Mat<Num_T> &out);
128 template<class Num_T>
129 Num_T elem_div_sum(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
130 
131 // -------------------------------------------------------------------------------------
132 // Declaration of Mat
133 // -------------------------------------------------------------------------------------
134 
200 template<class Num_T>
201 class Mat
202 {
203 public:
205  typedef Num_T value_type;
206 
208  explicit Mat(const Factory &f = DEFAULT_FACTORY);
210  Mat(int rows, int cols, const Factory &f = DEFAULT_FACTORY);
212  Mat(const Mat<Num_T> &m);
214  Mat(const Mat<Num_T> &m, const Factory &f);
216  Mat(const Vec<Num_T> &v, const Factory &f = DEFAULT_FACTORY);
218  Mat(const std::string &str, const Factory &f = DEFAULT_FACTORY);
220  Mat(const char *str, const Factory &f = DEFAULT_FACTORY);
228  Mat(const Num_T *c_array, int rows, int cols, bool row_major = true,
229  const Factory &f = DEFAULT_FACTORY);
230 
232  ~Mat();
233 
235  int cols() const { return no_cols; }
237  int rows() const { return no_rows; }
239  int size() const { return datasize; }
241  void set_size(int rows, int cols, bool copy = false);
243  void zeros();
245  void clear() { zeros(); }
247  void ones();
249  void set(const std::string &str);
251  void set(const char *str);
252 
254  const Num_T &operator()(int r, int c) const;
256  Num_T &operator()(int r, int c);
258  const Num_T &operator()(int i) const;
260  Num_T &operator()(int i);
262  const Num_T &get(int r, int c) const;
264  const Num_T &get(int i) const;
266  void set(int r, int c, Num_T t);
267 
273  Mat<Num_T> operator()(int r1, int r2, int c1, int c2) const;
279  Mat<Num_T> get(int r1, int r2, int c1, int c2) const;
280 
282  Vec<Num_T> get_row(int r) const;
284  Mat<Num_T> get_rows(int r1, int r2) const;
286  Mat<Num_T> get_rows(const Vec<int> &indexlist) const;
288  Vec<Num_T> get_col(int c) const;
290  Mat<Num_T> get_cols(int c1, int c2) const;
292  Mat<Num_T> get_cols(const Vec<int> &indexlist) const;
294  void set_row(int r, const Vec<Num_T> &v);
296  void set_col(int c, const Vec<Num_T> &v);
298  void set_rows(int r, const Mat<Num_T> &m);
300  void set_cols(int c, const Mat<Num_T> &m);
302  void copy_row(int to, int from);
304  void copy_col(int to, int from);
306  void swap_rows(int r1, int r2);
308  void swap_cols(int c1, int c2);
309 
311  void set_submatrix(int r1, int r2, int c1, int c2, const Mat<Num_T> &m);
313  void set_submatrix(int r, int c, const Mat<Num_T> &m);
315  void set_submatrix(int r1, int r2, int c1, int c2, Num_T t);
316 
318  void del_row(int r);
320  void del_rows(int r1, int r2);
322  void del_col(int c);
324  void del_cols(int c1, int c2);
326  void ins_row(int r, const Vec<Num_T> &v);
328  void ins_col(int c, const Vec<Num_T> &v);
330  void append_row(const Vec<Num_T> &v);
332  void append_col(const Vec<Num_T> &v);
333 
335  Mat<Num_T> transpose() const;
337  Mat<Num_T> T() const { return this->transpose(); }
341  Mat<Num_T> H() const { return this->hermitian_transpose(); }
342 
344  friend Mat<Num_T> concat_horizontal<>(const Mat<Num_T> &m1,
345  const Mat<Num_T> &m2);
347  friend Mat<Num_T> concat_vertical<>(const Mat<Num_T> &m1,
348  const Mat<Num_T> &m2);
349 
351  Mat<Num_T>& operator=(Num_T t);
353  Mat<Num_T>& operator=(const Mat<Num_T> &m);
355  Mat<Num_T>& operator=(const Vec<Num_T> &v);
357  Mat<Num_T>& operator=(const std::string &str);
359  Mat<Num_T>& operator=(const char *str);
360 
362  Mat<Num_T>& operator+=(const Mat<Num_T> &m);
364  Mat<Num_T>& operator+=(Num_T t);
366  friend Mat<Num_T> operator+<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
368  friend Mat<Num_T> operator+<>(const Mat<Num_T> &m, Num_T t);
370  friend Mat<Num_T> operator+<>(Num_T t, const Mat<Num_T> &m);
371 
373  Mat<Num_T>& operator-=(const Mat<Num_T> &m);
375  Mat<Num_T>& operator-=(Num_T t);
377  friend Mat<Num_T> operator-<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
379  friend Mat<Num_T> operator-<>(const Mat<Num_T> &m, Num_T t);
381  friend Mat<Num_T> operator-<>(Num_T t, const Mat<Num_T> &m);
383  friend Mat<Num_T> operator-<>(const Mat<Num_T> &m);
384 
386  Mat<Num_T>& operator*=(const Mat<Num_T> &m);
388  Mat<Num_T>& operator*=(Num_T t);
389 
391  friend Mat<Num_T> elem_mult<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
393  friend void elem_mult_out<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2,
394  Mat<Num_T> &out);
396  friend void elem_mult_out<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2,
397  const Mat<Num_T> &m3, Mat<Num_T> &out);
399  friend void elem_mult_out<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2,
400  const Mat<Num_T> &m3, const Mat<Num_T> &m4,
401  Mat<Num_T> &out);
403  friend void elem_mult_inplace<>(const Mat<Num_T> &m1, Mat<Num_T> &m2);
405  friend Num_T elem_mult_sum<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
406 
408  Mat<Num_T>& operator/=(Num_T t);
410  Mat<Num_T>& operator/=(const Mat<Num_T> &m);
411 
413  friend Mat<Num_T> operator/<>(const Mat<Num_T> &m, Num_T t);
415  friend Mat<Num_T> operator/<>(Num_T t, const Mat<Num_T> &m);
416 
418  friend Mat<Num_T> elem_div<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
420  friend void elem_div_out<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2,
421  Mat<Num_T> &out);
423  friend Num_T elem_div_sum<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2);
424 
426  bool operator==(const Mat<Num_T> &m) const;
428  bool operator!=(const Mat<Num_T> &m) const;
429 
431  Num_T &_elem(int r, int c) { return data[r+c*no_rows]; }
433  const Num_T &_elem(int r, int c) const { return data[r+c*no_rows]; }
435  Num_T &_elem(int i) { return data[i]; }
437  const Num_T &_elem(int i) const { return data[i]; }
438 
440  Num_T *_data() { return data; }
442  const Num_T *_data() const { return data; }
444  int _datasize() const { return datasize; }
445 
446 protected:
448  void alloc(int rows, int cols);
450  void free();
451 
456 
457  Num_T *data;
459  const Factory &factory;
460 
461 private:
463  bool in_range(int r, int c) const {
464  return ((r >= 0) && (r < no_rows) && (c >= 0) && (c < no_cols));
465  }
467  bool row_in_range(int r) const { return ((r >= 0) && (r < no_rows)); }
469  bool col_in_range(int c) const { return ((c >= 0) && (c < no_cols)); }
471  bool in_range(int i) const { return ((i >= 0) && (i < datasize)); }
472 };
473 
474 // -------------------------------------------------------------------------------------
475 // Type definitions of mat, cmat, imat, smat, and bmat
476 // -------------------------------------------------------------------------------------
477 
482 typedef Mat<double> mat;
483 
488 typedef Mat<std::complex<double> > cmat;
489 
494 typedef Mat<int> imat;
495 
500 typedef Mat<short int> smat;
501 
508 typedef Mat<bin> bmat;
509 
510 } //namespace itpp
511 
512 
513 #include <itpp/base/vec.h>
514 
515 namespace itpp
516 {
517 
518 // ----------------------------------------------------------------------
519 // Declaration of input and output streams for Mat
520 // ----------------------------------------------------------------------
521 
526 template <class Num_T>
527 std::ostream &operator<<(std::ostream &os, const Mat<Num_T> &m);
528 
540 template <class Num_T>
541 std::istream &operator>>(std::istream &is, Mat<Num_T> &m);
542 
543 // ----------------------------------------------------------------------
544 // Implementation of templated Mat members and friends
545 // ----------------------------------------------------------------------
546 
547 template<class Num_T> inline
548 void Mat<Num_T>::alloc(int rows, int cols)
549 {
550  if ((rows > 0) && (cols > 0)) {
551  datasize = rows * cols;
552  no_rows = rows;
553  no_cols = cols;
554  create_elements(data, datasize, factory);
555  }
556  else {
557  data = 0;
558  datasize = 0;
559  no_rows = 0;
560  no_cols = 0;
561  }
562 }
563 
564 template<class Num_T> inline
566 {
567  destroy_elements(data, datasize);
568  datasize = 0;
569  no_rows = 0;
570  no_cols = 0;
571 }
572 
573 
574 template<class Num_T> inline
576  datasize(0), no_rows(0), no_cols(0), data(0), factory(f) {}
577 
578 template<class Num_T> inline
579 Mat<Num_T>::Mat(int rows, int cols, const Factory &f) :
580  datasize(0), no_rows(0), no_cols(0), data(0), factory(f)
581 {
582  it_assert_debug((rows >= 0) && (cols >= 0), "Mat<>::Mat(): Wrong size");
583  alloc(rows, cols);
584 }
585 
586 template<class Num_T> inline
588  datasize(0), no_rows(0), no_cols(0), data(0), factory(m.factory)
589 {
590  alloc(m.no_rows, m.no_cols);
591  copy_vector(m.datasize, m.data, data);
592 }
593 
594 template<class Num_T> inline
595 Mat<Num_T>::Mat(const Mat<Num_T> &m, const Factory &f) :
596  datasize(0), no_rows(0), no_cols(0), data(0), factory(f)
597 {
598  alloc(m.no_rows, m.no_cols);
599  copy_vector(m.datasize, m.data, data);
600 }
601 
602 template<class Num_T> inline
603 Mat<Num_T>::Mat(const Vec<Num_T> &v, const Factory &f) :
604  datasize(0), no_rows(0), no_cols(0), data(0), factory(f)
605 {
606  int size = v.size();
607  alloc(size, 1);
608  copy_vector(size, v._data(), data);
609 }
610 
611 template<class Num_T> inline
612 Mat<Num_T>::Mat(const std::string &str, const Factory &f) :
613  datasize(0), no_rows(0), no_cols(0), data(0), factory(f)
614 {
615  set(str);
616 }
617 
618 template<class Num_T> inline
619 Mat<Num_T>::Mat(const char *str, const Factory &f) :
620  datasize(0), no_rows(0), no_cols(0), data(0), factory(f)
621 {
622  set(std::string(str));
623 }
624 
625 template<class Num_T>
626 Mat<Num_T>::Mat(const Num_T *c_array, int rows, int cols, bool row_major,
627  const Factory &f):
628  datasize(0), no_rows(0), no_cols(0), data(0), factory(f)
629 {
630  alloc(rows, cols);
631  if (!row_major)
632  copy_vector(datasize, c_array, data);
633  else
634  for (int i = 0; i < rows; i++)
635  for (int j = 0; j < cols; j++)
636  data[i+j*no_rows] = c_array[i*no_cols+j];
637 }
638 
639 template<class Num_T> inline
641 {
642  free();
643 }
644 
645 
646 template<class Num_T>
647 void Mat<Num_T>::set_size(int rows, int cols, bool copy)
648 {
649  it_assert_debug((rows >= 0) && (cols >= 0),
650  "Mat<>::set_size(): Wrong size");
651  // check if we have to resize the current matrix
652  if ((no_rows == rows) && (no_cols == cols))
653  return;
654  // check if one of dimensions is zero
655  if ((rows == 0) || (cols == 0)) {
656  free();
657  return;
658  }
659  // conditionally copy previous matrix content
660  if (copy) {
661  // create a temporary pointer to the allocated data
662  Num_T* tmp = data;
663  // store the current number of elements and number of rows
664  int old_datasize = datasize;
665  int old_rows = no_rows;
666  // check the boundaries of the copied data
667  int min_r = (no_rows < rows) ? no_rows : rows;
668  int min_c = (no_cols < cols) ? no_cols : cols;
669  // allocate new memory
670  alloc(rows, cols);
671  // copy the previous data into the allocated memory
672  for (int i = 0; i < min_c; ++i) {
673  copy_vector(min_r, &tmp[i*old_rows], &data[i*no_rows]);
674  }
675  // fill-in the rest of matrix with zeros
676  for (int i = min_r; i < rows; ++i)
677  for (int j = 0; j < cols; ++j)
678  data[i+j*rows] = Num_T(0);
679  for (int j = min_c; j < cols; ++j)
680  for (int i = 0; i < min_r; ++i)
681  data[i+j*rows] = Num_T(0);
682  // delete old elements
683  destroy_elements(tmp, old_datasize);
684  }
685  // if possible, reuse the allocated memory
686  else if (datasize == rows * cols) {
687  no_rows = rows;
688  no_cols = cols;
689  }
690  // finally release old memory and allocate a new one
691  else {
692  free();
693  alloc(rows, cols);
694  }
695 }
696 
697 template<class Num_T> inline
699 {
700  for (int i = 0; i < datasize; i++)
701  data[i] = Num_T(0);
702 }
703 
704 template<class Num_T> inline
706 {
707  for (int i = 0; i < datasize; i++)
708  data[i] = Num_T(1);
709 }
710 
711 template<class Num_T> inline
712 const Num_T& Mat<Num_T>::operator()(int r, int c) const
713 {
714  it_assert_debug(in_range(r, c),
715  "Mat<>::operator(): Indexing out of range");
716  return data[r+c*no_rows];
717 }
718 
719 template<class Num_T> inline
720 Num_T& Mat<Num_T>::operator()(int r, int c)
721 {
722  it_assert_debug(in_range(r, c),
723  "Mat<>::operator(): Indexing out of range");
724  return data[r+c*no_rows];
725 }
726 
727 template<class Num_T> inline
729 {
730  it_assert_debug(in_range(i), "Mat<>::operator(): Index out of range");
731  return data[i];
732 }
733 
734 template<class Num_T> inline
735 const Num_T& Mat<Num_T>::operator()(int i) const
736 {
737  it_assert_debug(in_range(i), "Mat<>::operator(): Index out of range");
738  return data[i];
739 }
740 
741 template<class Num_T> inline
742 const Num_T& Mat<Num_T>::get(int r, int c) const
743 {
744  return (*this)(r, c);
745 }
746 
747 template<class Num_T> inline
748 const Num_T& Mat<Num_T>::get(int i) const
749 {
750  return (*this)(i);
751 }
752 
753 template<class Num_T> inline
754 void Mat<Num_T>::set(int r, int c, Num_T t)
755 {
756  it_assert_debug(in_range(r, c), "Mat<>::set(): Indexing out of range");
757  data[r+c*no_rows] = t;
758 }
759 
760 
761 template<class Num_T>
762 void Mat<Num_T>::set(const std::string &str)
763 {
764  // actual row counter
765  int rows = 0;
766  // number of rows to allocate next time (8, 16, 32, 64, etc.)
767  int maxrows = 8;
768 
769  // clean the current matrix content
770  free();
771 
772  // variable to store the start of a current vector
773  std::string::size_type beg = 0;
774  std::string::size_type end = 0;
775  while (end != std::string::npos) {
776  // find next occurrence of a semicolon in string str
777  end = str.find(';', beg);
778  // parse first row into a vector v
779  Vec<Num_T> v(str.substr(beg, end - beg));
780  int v_size = v.size();
781 
782  // this check is necessary to parse the following two strings as the
783  // same matrix: "1 0 1; ; 1 1; " and "1 0 1; 0 0 0; 1 1 0"
784  if ((end != std::string::npos) || (v_size > 0)) {
785  // matrix empty -> insert v as a first row and allocate maxrows
786  if (rows == 0) {
787  set_size(maxrows, v_size, true);
788  set_row(rows++, v);
789  }
790  else {
791  // check if we need to resize the matrix
792  if ((rows == maxrows) || (v_size != no_cols)) {
793  // we need to add new rows
794  if (rows == maxrows) {
795  maxrows *= 2;
796  }
797  // check if we need to add new columns
798  if (v_size > no_cols) {
799  set_size(maxrows, v_size, true);
800  }
801  else {
802  set_size(maxrows, no_cols, true);
803  // set the size of the parsed vector to the number of columns
804  v.set_size(no_cols, true);
805  }
806  }
807  // set the parsed vector as the next row
808  set_row(rows++, v);
809  }
810  }
811  // update the starting position of the next vector in the parsed
812  // string
813  beg = end + 1;
814  } // if ((end != std::string::npos) || (v.size > 0))
815 
816  set_size(rows, no_cols, true);
817 }
818 
819 template<class Num_T> inline
820 void Mat<Num_T>::set(const char *str)
821 {
822  set(std::string(str));
823 }
824 
825 template<class Num_T> inline
826 Mat<Num_T> Mat<Num_T>::operator()(int r1, int r2, int c1, int c2) const
827 {
828  if (r1 == -1) r1 = no_rows - 1;
829  if (r2 == -1) r2 = no_rows - 1;
830  if (c1 == -1) c1 = no_cols - 1;
831  if (c2 == -1) c2 = no_cols - 1;
832 
833  it_assert_debug((r1 >= 0) && (r1 <= r2) && (r2 < no_rows) &&
834  (c1 >= 0) && (c1 <= c2) && (c2 < no_cols),
835  "Mat<>::operator()(r1, r2, c1, c2): Wrong indexing");
836 
837  Mat<Num_T> s(r2 - r1 + 1, c2 - c1 + 1);
838 
839  for (int i = 0;i < s.no_cols;i++)
840  copy_vector(s.no_rows, data + r1 + (c1 + i)*no_rows, s.data + i*s.no_rows);
841 
842  return s;
843 }
844 
845 template<class Num_T> inline
846 Mat<Num_T> Mat<Num_T>::get(int r1, int r2, int c1, int c2) const
847 {
848  return (*this)(r1, r2, c1, c2);
849 }
850 
851 template<class Num_T> inline
853 {
854  it_assert_debug(row_in_range(r), "Mat<>::get_row(): Index out of range");
855  Vec<Num_T> a(no_cols);
856 
857  copy_vector(no_cols, data + r, no_rows, a._data(), 1);
858  return a;
859 }
860 
861 template<class Num_T>
862 Mat<Num_T> Mat<Num_T>::get_rows(int r1, int r2) const
863 {
864  it_assert_debug((r1 >= 0) && (r1 <= r2) && (r2 < no_rows),
865  "Mat<>::get_rows(): Wrong indexing");
866  Mat<Num_T> m(r2 - r1 + 1, no_cols);
867 
868  for (int i = 0; i < m.rows(); i++)
869  copy_vector(no_cols, data + i + r1, no_rows, m.data + i, m.no_rows);
870 
871  return m;
872 }
873 
874 template<class Num_T>
875 Mat<Num_T> Mat<Num_T>::get_rows(const Vec<int> &indexlist) const
876 {
877  Mat<Num_T> m(indexlist.size(), no_cols);
878 
879  for (int i = 0;i < indexlist.size();i++) {
880  it_assert_debug(row_in_range(indexlist(i)),
881  "Mat<>::get_rows(indexlist): Indexing out of range");
882  copy_vector(no_cols, data + indexlist(i), no_rows, m.data + i, m.no_rows);
883  }
884 
885  return m;
886 }
887 
888 template<class Num_T> inline
890 {
891  it_assert_debug(col_in_range(c), "Mat<>::get_col(): Index out of range");
892  Vec<Num_T> a(no_rows);
893 
894  copy_vector(no_rows, data + c*no_rows, a._data());
895 
896  return a;
897 }
898 
899 template<class Num_T>
900 Mat<Num_T> Mat<Num_T>::get_cols(int c1, int c2) const
901 {
902  it_assert_debug((c1 >= 0) && (c1 <= c2) && (c2 < no_cols),
903  "Mat<>::get_cols(): Wrong indexing");
904  Mat<Num_T> m(no_rows, c2 - c1 + 1);
905 
906  for (int i = 0; i < m.cols(); i++)
907  copy_vector(no_rows, data + (i + c1)*no_rows, m.data + i*m.no_rows);
908 
909  return m;
910 }
911 
912 template<class Num_T>
913 Mat<Num_T> Mat<Num_T>::get_cols(const Vec<int> &indexlist) const
914 {
915  Mat<Num_T> m(no_rows, indexlist.size());
916 
917  for (int i = 0; i < indexlist.size(); i++) {
918  it_assert_debug(col_in_range(indexlist(i)),
919  "Mat<>::get_cols(indexlist): Indexing out of range");
920  copy_vector(no_rows, data + indexlist(i)*no_rows, m.data + i*m.no_rows);
921  }
922 
923  return m;
924 }
925 
926 template<class Num_T> inline
927 void Mat<Num_T>::set_row(int r, const Vec<Num_T> &v)
928 {
929  it_assert_debug(row_in_range(r), "Mat<>::set_row(): Index out of range");
930  it_assert_debug(v.size() == no_cols,
931  "Mat<>::set_row(): Wrong size of input vector");
932  copy_vector(v.size(), v._data(), 1, data + r, no_rows);
933 }
934 
935 template<class Num_T> inline
936 void Mat<Num_T>::set_col(int c, const Vec<Num_T> &v)
937 {
938  it_assert_debug(col_in_range(c), "Mat<>::set_col(): Index out of range");
939  it_assert_debug(v.size() == no_rows,
940  "Mat<>::set_col(): Wrong size of input vector");
941  copy_vector(v.size(), v._data(), data + c*no_rows);
942 }
943 
944 
945 template<class Num_T>
946 void Mat<Num_T>::set_rows(int r, const Mat<Num_T> &m)
947 {
948  it_assert_debug(row_in_range(r), "Mat<>::set_rows(): Index out of range");
949  it_assert_debug(no_cols == m.cols(),
950  "Mat<>::set_rows(): Column sizes do not match");
951  it_assert_debug(m.rows() + r <= no_rows,
952  "Mat<>::set_rows(): Not enough rows");
953 
954  for (int i = 0; i < m.rows(); ++i) {
955  copy_vector(no_cols, m.data + i, m.no_rows, data + i + r, no_rows);
956  }
957 }
958 
959 template<class Num_T>
960 void Mat<Num_T>::set_cols(int c, const Mat<Num_T> &m)
961 {
962  it_assert_debug(col_in_range(c), "Mat<>::set_cols(): Index out of range");
963  it_assert_debug(no_rows == m.rows(),
964  "Mat<>::set_cols(): Row sizes do not match");
965  it_assert_debug(m.cols() + c <= no_cols,
966  "Mat<>::set_cols(): Not enough colums");
967 
968  for (int i = 0; i < m.cols(); ++i) {
969  copy_vector(no_rows, m.data + i*no_rows, data + (i + c)*no_rows);
970  }
971 }
972 
973 
974 template<class Num_T> inline
975 void Mat<Num_T>::copy_row(int to, int from)
976 {
977  it_assert_debug(row_in_range(to) && row_in_range(from),
978  "Mat<>::copy_row(): Indexing out of range");
979  if (from == to)
980  return;
981 
982  copy_vector(no_cols, data + from, no_rows, data + to, no_rows);
983 }
984 
985 template<class Num_T> inline
986 void Mat<Num_T>::copy_col(int to, int from)
987 {
988  it_assert_debug(col_in_range(to) && col_in_range(from),
989  "Mat<>::copy_col(): Indexing out of range");
990  if (from == to)
991  return;
992 
993  copy_vector(no_rows, data + from*no_rows, data + to*no_rows);
994 }
995 
996 template<class Num_T> inline
997 void Mat<Num_T>::swap_rows(int r1, int r2)
998 {
999  it_assert_debug(row_in_range(r1) && row_in_range(r2),
1000  "Mat<>::swap_rows(): Indexing out of range");
1001  if (r1 == r2)
1002  return;
1003 
1004  swap_vector(no_cols, data + r1, no_rows, data + r2, no_rows);
1005 }
1006 
1007 template<class Num_T> inline
1008 void Mat<Num_T>::swap_cols(int c1, int c2)
1009 {
1010  it_assert_debug(col_in_range(c1) && col_in_range(c2),
1011  "Mat<>::swap_cols(): Indexing out of range");
1012  if (c1 == c2)
1013  return;
1014 
1015  swap_vector(no_rows, data + c1*no_rows, data + c2*no_rows);
1016 }
1017 
1018 template<class Num_T>
1019 void Mat<Num_T>::set_submatrix(int r1, int, int c1, int, const Mat<Num_T> &m)
1020 {
1021  it_warning("Mat<>::set_submatrix(r1, r2, r3, r4, m): This function is "
1022  "deprecated and might be removed from future IT++ releases. "
1023  "Please use Mat<>::set_submatrix(r, c, m) function instead.");
1024  set_submatrix(r1, c1, m);
1025 }
1026 
1027 template<class Num_T> inline
1028 void Mat<Num_T>::set_submatrix(int r, int c, const Mat<Num_T> &m)
1029 {
1030  it_assert_debug((r >= 0) && (r + m.no_rows <= no_rows) &&
1031  (c >= 0) && (c + m.no_cols <= no_cols),
1032  "Mat<>::set_submatrix(): Indexing out of range "
1033  "or wrong input matrix");
1034  for (int i = 0; i < m.no_cols; i++)
1035  copy_vector(m.no_rows, m.data + i*m.no_rows, data + (c + i)*no_rows + r);
1036 }
1037 
1038 
1039 
1040 template<class Num_T> inline
1041 void Mat<Num_T>::set_submatrix(int r1, int r2, int c1, int c2, Num_T t)
1042 {
1043  if (r1 == -1) r1 = no_rows - 1;
1044  if (r2 == -1) r2 = no_rows - 1;
1045  if (c1 == -1) c1 = no_cols - 1;
1046  if (c2 == -1) c2 = no_cols - 1;
1047  it_assert_debug((r1 >= 0) && (r1 <= r2) && (r2 < no_rows) &&
1048  (c1 >= 0) && (c1 <= c2) && (c2 < no_cols),
1049  "Mat<>::set_submatrix(): Wrong indexing");
1050  for (int i = c1; i <= c2; i++) {
1051  int pos = i * no_rows + r1;
1052  for (int j = r1; j <= r2; j++)
1053  data[pos++] = t;
1054  }
1055 }
1056 
1057 template<class Num_T>
1059 {
1060  it_assert_debug(row_in_range(r), "Mat<>::del_row(): Index out of range");
1061  Mat<Num_T> Temp(*this);
1062  set_size(no_rows - 1, no_cols, false);
1063  for (int i = 0 ; i < r ; i++) {
1064  copy_vector(no_cols, &Temp.data[i], no_rows + 1, &data[i], no_rows);
1065  }
1066  for (int i = r ; i < no_rows ; i++) {
1067  copy_vector(no_cols, &Temp.data[i+1], no_rows + 1, &data[i], no_rows);
1068  }
1069 
1070 }
1071 
1072 template<class Num_T>
1073 void Mat<Num_T>::del_rows(int r1, int r2)
1074 {
1075  it_assert_debug((r1 >= 0) && (r1 <= r2) && (r2 < no_rows),
1076  "Mat<>::del_rows(): Indexing out of range");
1077  Mat<Num_T> Temp(*this);
1078  int no_del_rows = r2 - r1 + 1;
1079  set_size(no_rows - no_del_rows, no_cols, false);
1080  for (int i = 0; i < r1 ; ++i) {
1081  copy_vector(no_cols, &Temp.data[i], Temp.no_rows, &data[i], no_rows);
1082  }
1083  for (int i = r2 + 1; i < Temp.no_rows; ++i) {
1084  copy_vector(no_cols, &Temp.data[i], Temp.no_rows, &data[i-no_del_rows],
1085  no_rows);
1086  }
1087 }
1088 
1089 template<class Num_T>
1091 {
1092  it_assert_debug(col_in_range(c), "Mat<>::del_col(): Index out of range");
1093  Mat<Num_T> Temp(*this);
1094 
1095  set_size(no_rows, no_cols - 1, false);
1096  copy_vector(c*no_rows, Temp.data, data);
1097  copy_vector((no_cols - c)*no_rows, &Temp.data[(c+1)*no_rows], &data[c*no_rows]);
1098 }
1099 
1100 template<class Num_T>
1101 void Mat<Num_T>::del_cols(int c1, int c2)
1102 {
1103  it_assert_debug((c1 >= 0) && (c1 <= c2) && (c2 < no_cols),
1104  "Mat<>::del_cols(): Indexing out of range");
1105  Mat<Num_T> Temp(*this);
1106  int n_deleted_cols = c2 - c1 + 1;
1107  set_size(no_rows, no_cols - n_deleted_cols, false);
1108  copy_vector(c1*no_rows, Temp.data, data);
1109  copy_vector((no_cols - c1)*no_rows, &Temp.data[(c2+1)*no_rows], &data[c1*no_rows]);
1110 }
1111 
1112 template<class Num_T>
1113 void Mat<Num_T>::ins_row(int r, const Vec<Num_T> &v)
1114 {
1115  it_assert_debug((r >= 0) && (r <= no_rows),
1116  "Mat<>::ins_row(): Index out of range");
1117  it_assert_debug((v.size() == no_cols) || (no_rows == 0),
1118  "Mat<>::ins_row(): Wrong size of the input vector");
1119 
1120  if (no_cols == 0) {
1121  no_cols = v.size();
1122  }
1123 
1124  Mat<Num_T> Temp(*this);
1125  set_size(no_rows + 1, no_cols, false);
1126 
1127  for (int i = 0 ; i < r ; i++) {
1128  copy_vector(no_cols, &Temp.data[i], no_rows - 1, &data[i], no_rows);
1129  }
1130  copy_vector(no_cols, v._data(), 1, &data[r], no_rows);
1131  for (int i = r + 1 ; i < no_rows ; i++) {
1132  copy_vector(no_cols, &Temp.data[i-1], no_rows - 1, &data[i], no_rows);
1133  }
1134 }
1135 
1136 template<class Num_T>
1137 void Mat<Num_T>::ins_col(int c, const Vec<Num_T> &v)
1138 {
1139  it_assert_debug((c >= 0) && (c <= no_cols),
1140  "Mat<>::ins_col(): Index out of range");
1141  it_assert_debug((v.size() == no_rows) || (no_cols == 0),
1142  "Mat<>::ins_col(): Wrong size of the input vector");
1143 
1144  if (no_rows == 0) {
1145  no_rows = v.size();
1146  }
1147 
1148  Mat<Num_T> Temp(*this);
1149  set_size(no_rows, no_cols + 1, false);
1150 
1151  copy_vector(c*no_rows, Temp.data, data);
1152  copy_vector(no_rows, v._data(), &data[c*no_rows]);
1153  copy_vector((no_cols - c - 1)*no_rows, &Temp.data[c*no_rows], &data[(c+1)*no_rows]);
1154 }
1155 
1156 template<class Num_T> inline
1158 {
1159  ins_row(no_rows, v);
1160 }
1161 
1162 template<class Num_T> inline
1164 {
1165  ins_col(no_cols, v);
1166 }
1167 
1168 template<class Num_T>
1170 {
1171  Mat<Num_T> temp(no_cols, no_rows);
1172  for (int i = 0; i < no_rows; ++i) {
1173  copy_vector(no_cols, &data[i], no_rows, &temp.data[i * no_cols], 1);
1174  }
1175  return temp;
1176 }
1177 
1178 template<class Num_T>
1180 {
1181  Mat<Num_T> temp(no_cols, no_rows);
1182  for (int i = 0; i < no_rows; ++i) {
1183  copy_vector(no_cols, &data[i], no_rows, &temp.data[i * no_cols], 1);
1184  }
1185  return temp;
1186 }
1187 
1189 template<>
1190 ITPP_EXPORT cmat cmat::hermitian_transpose() const;
1192 
1193 template<class Num_T>
1195 {
1196  // if one of the input matrix is empty just copy the other one as a result
1197  if (m1.no_cols == 0)
1198  return m2;
1199  if (m2.no_cols == 0)
1200  return m1;
1201  it_assert_debug(m1.no_rows == m2.no_rows,
1202  "Mat<>::concat_horizontal(): Wrong sizes");
1203  int no_rows = m1.no_rows;
1204  Mat<Num_T> temp(no_rows, m1.no_cols + m2.no_cols);
1205  for (int i = 0; i < m1.no_cols; ++i) {
1206  copy_vector(no_rows, &m1.data[i * no_rows], &temp.data[i * no_rows]);
1207  }
1208  for (int i = 0; i < m2.no_cols; ++i) {
1209  copy_vector(no_rows, &m2.data[i * no_rows], &temp.data[(m1.no_cols + i)
1210  * no_rows]);
1211  }
1212  return temp;
1213 }
1214 
1215 template<class Num_T>
1217 {
1218  // if one of the input matrix is empty just copy the other one as a result
1219  if (m1.no_rows == 0)
1220  return m2;
1221  if (m2.no_rows == 0)
1222  return m1;
1223  it_assert_debug(m1.no_cols == m2.no_cols,
1224  "Mat<>::concat_vertical(): Wrong sizes");
1225  int no_cols = m1.no_cols;
1226  Mat<Num_T> temp(m1.no_rows + m2.no_rows, no_cols);
1227  for (int i = 0; i < no_cols; ++i) {
1228  copy_vector(m1.no_rows, &m1.data[i * m1.no_rows],
1229  &temp.data[i * temp.no_rows]);
1230  copy_vector(m2.no_rows, &m2.data[i * m2.no_rows],
1231  &temp.data[i * temp.no_rows + m1.no_rows]);
1232  }
1233  return temp;
1234 }
1235 
1236 template<class Num_T> inline
1238 {
1239  for (int i = 0; i < datasize; i++)
1240  data[i] = t;
1241  return *this;
1242 }
1243 
1244 template<class Num_T> inline
1246 {
1247  if (this != &m) {
1248  set_size(m.no_rows, m.no_cols, false);
1249  if (m.datasize != 0)
1250  copy_vector(m.datasize, m.data, data);
1251  }
1252  return *this;
1253 }
1254 
1255 template<class Num_T> inline
1257 {
1258  it_assert_debug(((no_rows == 1) && (no_cols == v.size()))
1259  || ((no_cols == 1) && (no_rows == v.size())),
1260  "Mat<>::operator=(): Wrong size of the input vector");
1261  set_size(v.size(), 1, false);
1262  copy_vector(v.size(), v._data(), data);
1263  return *this;
1264 }
1265 
1266 template<class Num_T> inline
1267 Mat<Num_T>& Mat<Num_T>::operator=(const std::string &str)
1268 {
1269  set(str);
1270  return *this;
1271 }
1272 
1273 template<class Num_T> inline
1275 {
1276  set(std::string(str));
1277  return *this;
1278 }
1279 
1280 //-------------------- Templated friend functions --------------------------
1281 
1282 template<class Num_T>
1284 {
1285  if (datasize == 0)
1286  operator=(m);
1287  else {
1288  int i, j, m_pos = 0, pos = 0;
1289  it_assert_debug(m.no_rows == no_rows && m.no_cols == no_cols, "Mat<Num_T>::operator+=: wrong sizes");
1290  for (i = 0; i < no_cols; i++) {
1291  for (j = 0; j < no_rows; j++)
1292  data[pos+j] += m.data[m_pos+j];
1293  pos += no_rows;
1294  m_pos += m.no_rows;
1295  }
1296  }
1297  return *this;
1298 }
1299 
1300 template<class Num_T> inline
1302 {
1303  for (int i = 0; i < datasize; i++)
1304  data[i] += t;
1305  return *this;
1306 }
1307 
1308 template<class Num_T>
1310 {
1311  Mat<Num_T> r(m1.no_rows, m1.no_cols);
1312  int i, j, m1_pos = 0, m2_pos = 0, r_pos = 0;
1313 
1314  it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_cols == m2.no_cols),
1315  "Mat<>::operator+(): Wrong sizes");
1316 
1317  for (i = 0; i < r.no_cols; i++) {
1318  for (j = 0; j < r.no_rows; j++)
1319  r.data[r_pos+j] = m1.data[m1_pos+j] + m2.data[m2_pos+j];
1320  // next column
1321  m1_pos += m1.no_rows;
1322  m2_pos += m2.no_rows;
1323  r_pos += r.no_rows;
1324  }
1325 
1326  return r;
1327 }
1328 
1329 
1330 template<class Num_T>
1331 Mat<Num_T> operator+(const Mat<Num_T> &m, Num_T t)
1332 {
1333  Mat<Num_T> r(m.no_rows, m.no_cols);
1334 
1335  for (int i = 0; i < r.datasize; i++)
1336  r.data[i] = m.data[i] + t;
1337 
1338  return r;
1339 }
1340 
1341 template<class Num_T>
1342 Mat<Num_T> operator+(Num_T t, const Mat<Num_T> &m)
1343 {
1344  Mat<Num_T> r(m.no_rows, m.no_cols);
1345 
1346  for (int i = 0; i < r.datasize; i++)
1347  r.data[i] = t + m.data[i];
1348 
1349  return r;
1350 }
1351 
1352 template<class Num_T>
1354 {
1355  int i, j, m_pos = 0, pos = 0;
1356 
1357  if (datasize == 0) {
1358  set_size(m.no_rows, m.no_cols, false);
1359  for (i = 0; i < no_cols; i++) {
1360  for (j = 0; j < no_rows; j++)
1361  data[pos+j] = -m.data[m_pos+j];
1362  // next column
1363  m_pos += m.no_rows;
1364  pos += no_rows;
1365  }
1366  }
1367  else {
1368  it_assert_debug((m.no_rows == no_rows) && (m.no_cols == no_cols),
1369  "Mat<>::operator-=(): Wrong sizes");
1370  for (i = 0; i < no_cols; i++) {
1371  for (j = 0; j < no_rows; j++)
1372  data[pos+j] -= m.data[m_pos+j];
1373  // next column
1374  m_pos += m.no_rows;
1375  pos += no_rows;
1376  }
1377  }
1378  return *this;
1379 }
1380 
1381 template<class Num_T>
1383 {
1384  Mat<Num_T> r(m1.no_rows, m1.no_cols);
1385  int i, j, m1_pos = 0, m2_pos = 0, r_pos = 0;
1386  it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_cols == m2.no_cols),
1387  "Mat<>::operator-(): Wrong sizes");
1388 
1389  for (i = 0; i < r.no_cols; i++) {
1390  for (j = 0; j < r.no_rows; j++)
1391  r.data[r_pos+j] = m1.data[m1_pos+j] - m2.data[m2_pos+j];
1392  // next column
1393  m1_pos += m1.no_rows;
1394  m2_pos += m2.no_rows;
1395  r_pos += r.no_rows;
1396  }
1397 
1398  return r;
1399 }
1400 
1401 template<class Num_T> inline
1403 {
1404  for (int i = 0; i < datasize; i++)
1405  data[i] -= t;
1406  return *this;
1407 }
1408 
1409 template<class Num_T>
1410 Mat<Num_T> operator-(const Mat<Num_T> &m, Num_T t)
1411 {
1412  Mat<Num_T> r(m.no_rows, m.no_cols);
1413  int i, j, m_pos = 0, r_pos = 0;
1414 
1415  for (i = 0; i < r.no_cols; i++) {
1416  for (j = 0; j < r.no_rows; j++)
1417  r.data[r_pos+j] = m.data[m_pos+j] - t;
1418  // next column
1419  m_pos += m.no_rows;
1420  r_pos += r.no_rows;
1421  }
1422 
1423  return r;
1424 }
1425 
1426 template<class Num_T>
1427 Mat<Num_T> operator-(Num_T t, const Mat<Num_T> &m)
1428 {
1429  Mat<Num_T> r(m.no_rows, m.no_cols);
1430  int i, j, m_pos = 0, r_pos = 0;
1431 
1432  for (i = 0; i < r.no_cols; i++) {
1433  for (j = 0; j < r.no_rows; j++)
1434  r.data[r_pos+j] = t - m.data[m_pos+j];
1435  // next column
1436  m_pos += m.no_rows;
1437  r_pos += r.no_rows;
1438  }
1439 
1440  return r;
1441 }
1442 
1443 template<class Num_T>
1445 {
1446  Mat<Num_T> r(m.no_rows, m.no_cols);
1447  int i, j, m_pos = 0, r_pos = 0;
1448 
1449  for (i = 0; i < r.no_cols; i++) {
1450  for (j = 0; j < r.no_rows; j++)
1451  r.data[r_pos+j] = -m.data[m_pos+j];
1452  // next column
1453  m_pos += m.no_rows;
1454  r_pos += r.no_rows;
1455  }
1456 
1457  return r;
1458 }
1459 
1460 template<class Num_T>
1462 {
1463  it_assert_debug(no_cols == m.no_rows, "Mat<>::operator*=(): Wrong sizes");
1464  Mat<Num_T> r(no_rows, m.no_cols);
1465 
1466  Num_T tmp;
1467 
1468  int i, j, k, r_pos = 0, pos = 0, m_pos = 0;
1469 
1470  for (i = 0; i < r.no_cols; i++) {
1471  for (j = 0; j < r.no_rows; j++) {
1472  tmp = Num_T(0);
1473  pos = 0;
1474  for (k = 0; k < no_cols; k++) {
1475  tmp += data[pos+j] * m.data[m_pos+k];
1476  pos += no_rows;
1477  }
1478  r.data[r_pos+j] = tmp;
1479  }
1480  r_pos += r.no_rows;
1481  m_pos += m.no_rows;
1482  }
1483  operator=(r); // time consuming
1484  return *this;
1485 }
1486 
1488 template<> ITPP_EXPORT mat& mat::operator*=(const mat &m);
1489 template<> ITPP_EXPORT cmat& cmat::operator*=(const cmat &m);
1491 
1492 template<class Num_T> inline
1494 {
1495  scal_vector(datasize, t, data);
1496  return *this;
1497 }
1498 
1500 template<class Num_T>
1502 {
1503  it_assert_debug(m1.cols() == m2.rows(),
1504  "Mat<>::operator*(): Wrong sizes");
1505  Mat<Num_T> r(m1.rows(), m2.cols());
1506 
1507  Num_T tmp;
1508  int i, j, k;
1509  Num_T *tr = r._data();
1510  const Num_T *t1; const Num_T *t2 = m2._data();
1511 
1512  for (i = 0; i < r.cols(); i++) {
1513  for (j = 0; j < r.rows(); j++) {
1514  tmp = Num_T(0);
1515  t1 = m1._data() + j;
1516  for (k = m1.cols(); k > 0; k--) {
1517  tmp += *(t1) * *(t2++);
1518  t1 += m1.rows();
1519  }
1520  *(tr++) = tmp;
1521  t2 -= m2.rows();
1522  }
1523  t2 += m2.rows();
1524  }
1525 
1526  return r;
1527 }
1528 
1530 template<> ITPP_EXPORT mat operator*(const mat &m1, const mat &m2);
1531 template<> ITPP_EXPORT cmat operator*(const cmat &m1, const cmat &m2);
1533 
1535 template<class Num_T>
1537 {
1538  it_assert_debug(m.cols() == v.size(),
1539  "Mat<>::operator*(): Wrong sizes");
1540  Vec<Num_T> r(m.rows());
1541  int i, k, m_pos;
1542 
1543  for (i = 0; i < m.rows(); i++) {
1544  r(i) = Num_T(0);
1545  m_pos = 0;
1546  for (k = 0; k < m.cols(); k++) {
1547  r(i) += m._data()[m_pos+i] * v(k);
1548  m_pos += m.rows();
1549  }
1550  }
1551 
1552  return r;
1553 }
1554 
1556 template<> ITPP_EXPORT vec operator*(const mat &m, const vec &v);
1557 template<> ITPP_EXPORT cvec operator*(const cmat &m, const cvec &v);
1559 
1561 template<class Num_T>
1562 Mat<Num_T> operator*(const Mat<Num_T> &m, Num_T t)
1563 {
1564  Mat<Num_T> r(m.rows(), m.cols());
1565 
1566  const Num_T* m_data = m._data();
1567  Num_T* r_data = r._data();
1568  for (int i = 0; i < r._datasize(); i++)
1569  r_data[i] = m_data[i] * t;
1570 
1571  return r;
1572 }
1573 
1575 template<class Num_T> inline
1576 Mat<Num_T> operator*(Num_T t, const Mat<Num_T> &m)
1577 {
1578  return operator*(m, t);
1579 }
1580 
1581 template<class Num_T> inline
1583 {
1584  Mat<Num_T> out;
1585  elem_mult_out(m1, m2, out);
1586  return out;
1587 }
1588 
1589 template<class Num_T>
1590 void elem_mult_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2,
1591  Mat<Num_T> &out)
1592 {
1593  it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_cols == m2.no_cols),
1594  "Mat<>::elem_mult_out(): Wrong sizes");
1595  out.set_size(m1.no_rows, m1.no_cols);
1596  for (int i = 0; i < out.datasize; i++)
1597  out.data[i] = m1.data[i] * m2.data[i];
1598 }
1599 
1600 template<class Num_T>
1601 void elem_mult_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2,
1602  const Mat<Num_T> &m3, Mat<Num_T> &out)
1603 {
1604  it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_rows == m3.no_rows)
1605  && (m1.no_cols == m2.no_cols) && (m1.no_cols == m3.no_cols),
1606  "Mat<>::elem_mult_out(): Wrong sizes");
1607  out.set_size(m1.no_rows, m1.no_cols);
1608  for (int i = 0; i < out.datasize; i++)
1609  out.data[i] = m1.data[i] * m2.data[i] * m3.data[i];
1610 }
1611 
1612 template<class Num_T>
1613 void elem_mult_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2,
1614  const Mat<Num_T> &m3, const Mat<Num_T> &m4,
1615  Mat<Num_T> &out)
1616 {
1617  it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_rows == m3.no_rows)
1618  && (m1.no_rows == m4.no_rows) && (m1.no_cols == m2.no_cols)
1619  && (m1.no_cols == m3.no_cols) && (m1.no_cols == m4.no_cols),
1620  "Mat<>::elem_mult_out(): Wrong sizes");
1621  out.set_size(m1.no_rows, m1.no_cols);
1622  for (int i = 0; i < out.datasize; i++)
1623  out.data[i] = m1.data[i] * m2.data[i] * m3.data[i] * m4.data[i];
1624 }
1625 
1626 template<class Num_T>
1627 #ifndef _MSC_VER
1628 inline
1629 #endif
1631 {
1632  it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_cols == m2.no_cols),
1633  "Mat<>::elem_mult_inplace(): Wrong sizes");
1634  for (int i = 0; i < m2.datasize; i++)
1635  m2.data[i] *= m1.data[i];
1636 }
1637 
1638 template<class Num_T> inline
1639 Num_T elem_mult_sum(const Mat<Num_T> &m1, const Mat<Num_T> &m2)
1640 {
1641  it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_cols == m2.no_cols),
1642  "Mat<>::elem_mult_sum(): Wrong sizes");
1643  Num_T acc = 0;
1644 
1645  for (int i = 0; i < m1.datasize; i++)
1646  acc += m1.data[i] * m2.data[i];
1647 
1648  return acc;
1649 }
1650 
1651 template<class Num_T> inline
1653 {
1654  for (int i = 0; i < datasize; i++)
1655  data[i] /= t;
1656  return *this;
1657 }
1658 
1659 template<class Num_T> inline
1661 {
1662  it_assert_debug((m.no_rows == no_rows) && (m.no_cols == no_cols),
1663  "Mat<>::operator/=(): Wrong sizes");
1664  for (int i = 0; i < datasize; i++)
1665  data[i] /= m.data[i];
1666  return *this;
1667 }
1668 
1669 template<class Num_T>
1670 Mat<Num_T> operator/(const Mat<Num_T> &m, Num_T t)
1671 {
1672  Mat<Num_T> r(m.no_rows, m.no_cols);
1673  for (int i = 0; i < r.datasize; ++i)
1674  r.data[i] = m.data[i] / t;
1675  return r;
1676 }
1677 
1678 template<class Num_T>
1679 Mat<Num_T> operator/(Num_T t, const Mat<Num_T> &m)
1680 {
1681  Mat<Num_T> r(m.no_rows, m.no_cols);
1682  for (int i = 0; i < r.datasize; ++i)
1683  r.data[i] = t / m.data[i];
1684  return r;
1685 }
1686 
1687 template<class Num_T> inline
1689 {
1690  Mat<Num_T> out;
1691  elem_div_out(m1, m2, out);
1692  return out;
1693 }
1694 
1695 template<class Num_T>
1696 void elem_div_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2,
1697  Mat<Num_T> &out)
1698 {
1699  it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_cols == m2.no_cols),
1700  "Mat<>::elem_div_out(): Wrong sizes");
1701 
1702  if ((out.no_rows != m1.no_rows) || (out.no_cols != m1.no_cols))
1703  out.set_size(m1.no_rows, m1.no_cols);
1704 
1705  for (int i = 0; i < out.datasize; i++)
1706  out.data[i] = m1.data[i] / m2.data[i];
1707 }
1708 
1709 template<class Num_T> inline
1710 Num_T elem_div_sum(const Mat<Num_T> &m1, const Mat<Num_T> &m2)
1711 {
1712  it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_cols == m2.no_cols),
1713  "Mat<>::elem_div_sum(): Wrong sizes");
1714  Num_T acc = 0;
1715 
1716  for (int i = 0; i < m1.datasize; i++)
1717  acc += m1.data[i] / m2.data[i];
1718 
1719  return acc;
1720 }
1721 
1722 template<class Num_T>
1724 {
1725  if (no_rows != m.no_rows || no_cols != m.no_cols) return false;
1726  for (int i = 0;i < datasize;i++) {
1727  if (data[i] != m.data[i]) return false;
1728  }
1729  return true;
1730 }
1731 
1732 template<class Num_T>
1734 {
1735  if (no_rows != m.no_rows || no_cols != m.no_cols) return true;
1736  for (int i = 0;i < datasize;i++) {
1737  if (data[i] != m.data[i]) return true;
1738  }
1739  return false;
1740 }
1741 
1742 template <class Num_T>
1743 std::ostream &operator<<(std::ostream &os, const Mat<Num_T> &m)
1744 {
1745  int i;
1746 
1747  switch (m.rows()) {
1748  case 0 :
1749  os << "[]";
1750  break;
1751  case 1 :
1752  os << '[' << m.get_row(0) << ']';
1753  break;
1754  default:
1755  os << '[' << m.get_row(0) << std::endl;
1756  for (i = 1; i < m.rows() - 1; i++)
1757  os << ' ' << m.get_row(i) << std::endl;
1758  os << ' ' << m.get_row(m.rows() - 1) << ']';
1759  }
1760 
1761  return os;
1762 }
1763 
1764 template <class Num_T>
1765 std::istream &operator>>(std::istream &is, Mat<Num_T> &m)
1766 {
1767  std::ostringstream buffer;
1768  bool started = false;
1769  bool finished = false;
1770  bool brackets = false;
1771  bool within_double_brackets = false;
1772  char c;
1773 
1774  while (!finished) {
1775  if (is.eof()) {
1776  finished = true;
1777  }
1778  else {
1779  is.get(c);
1780 
1781  if (is.eof() || (c == '\n')) {
1782  if (brackets) {
1783  // Right bracket missing
1784  is.setstate(std::ios_base::failbit);
1785  finished = true;
1786  }
1787  else if (!((c == '\n') && !started)) {
1788  finished = true;
1789  }
1790  }
1791  else if ((c == ' ') || (c == '\t')) {
1792  if (started) {
1793  buffer << ' ';
1794  }
1795  }
1796  else if (c == '[') {
1797  if ((started && !brackets) || within_double_brackets) {
1798  // Unexpected left bracket
1799  is.setstate(std::ios_base::failbit);
1800  finished = true;
1801  }
1802  else if (!started) {
1803  started = true;
1804  brackets = true;
1805  }
1806  else {
1807  within_double_brackets = true;
1808  }
1809  }
1810  else if (c == ']') {
1811  if (!started || !brackets) {
1812  // Unexpected right bracket
1813  is.setstate(std::ios_base::failbit);
1814  finished = true;
1815  }
1816  else if (within_double_brackets) {
1817  within_double_brackets = false;
1818  buffer << ';';
1819  }
1820  else {
1821  finished = true;
1822  }
1823  while (!is.eof() && (((c = static_cast<char>(is.peek())) == ' ')
1824  || (c == '\t'))) {
1825  is.get();
1826  }
1827  if (!is.eof() && (c == '\n')) {
1828  is.get();
1829  }
1830  }
1831  else {
1832  started = true;
1833  buffer << c;
1834  }
1835  }
1836  }
1837 
1838  if (!started) {
1839  m.set_size(0, false);
1840  }
1841  else {
1842  m.set(buffer.str());
1843  }
1844 
1845  return is;
1846 }
1847 
1849 
1850 // ---------------------------------------------------------------------
1851 // Instantiations
1852 // ---------------------------------------------------------------------
1853 
1854 // class instantiations
1855 
1856 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Mat<double>;
1857 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Mat<std::complex<double> >;
1858 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Mat<int>;
1859 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Mat<short int>;
1860 ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Mat<bin>;
1861 
1862 // addition operators
1863 
1864 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat operator+(const mat &m1, const mat &m2);
1865 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat operator+(const cmat &m1, const cmat &m2);
1866 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat operator+(const imat &m1, const imat &m2);
1867 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat operator+(const smat &m1, const smat &m2);
1868 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat operator+(const bmat &m1, const bmat &m2);
1869 
1870 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat operator+(const mat &m, double t);
1871 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat operator+(const cmat &m, std::complex<double> t);
1872 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat operator+(const imat &m, int t);
1873 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat operator+(const smat &m, short t);
1874 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat operator+(const bmat &m, bin t);
1875 
1876 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat operator+(double t, const mat &m);
1877 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat operator+(std::complex<double> t, const cmat &m);
1878 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat operator+(int t, const imat &m);
1879 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat operator+(short t, const smat &m);
1880 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat operator+(bin t, const bmat &m);
1881 
1882 // subtraction operators
1883 
1884 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat operator-(const mat &m1, const mat &m2);
1885 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat operator-(const cmat &m1, const cmat &m2);
1886 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat operator-(const imat &m1, const imat &m2);
1887 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat operator-(const smat &m1, const smat &m2);
1888 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat operator-(const bmat &m1, const bmat &m2);
1889 
1890 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat operator-(const mat &m, double t);
1891 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat operator-(const cmat &m, std::complex<double> t);
1892 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat operator-(const imat &m, int t);
1893 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat operator-(const smat &m, short t);
1894 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat operator-(const bmat &m, bin t);
1895 
1896 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat operator-(double t, const mat &m);
1897 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat operator-(std::complex<double> t, const cmat &m);
1898 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat operator-(int t, const imat &m);
1899 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat operator-(short t, const smat &m);
1900 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat operator-(bin t, const bmat &m);
1901 
1902 // unary minus
1903 
1904 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat operator-(const mat &m);
1905 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat operator-(const cmat &m);
1906 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat operator-(const imat &m);
1907 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat operator-(const smat &m);
1908 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat operator-(const bmat &m);
1909 
1910 // multiplication operators
1911 
1912 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat operator*(const imat &m1, const imat &m2);
1913 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat operator*(const smat &m1, const smat &m2);
1914 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat operator*(const bmat &m1, const bmat &m2);
1915 
1916 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT ivec operator*(const imat &m, const ivec &v);
1917 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT svec operator*(const smat &m, const svec &v);
1918 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bvec operator*(const bmat &m, const bvec &v);
1919 
1920 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat operator*(const mat &m, double t);
1921 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat operator*(const cmat &m, std::complex<double> t);
1922 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat operator*(const imat &m, int t);
1923 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat operator*(const smat &m, short t);
1924 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat operator*(const bmat &m, bin t);
1925 
1926 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat operator*(double t, const mat &m);
1927 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat operator*(std::complex<double> t, const cmat &m);
1928 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat operator*(int t, const imat &m);
1929 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat operator*(short t, const smat &m);
1930 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat operator*(bin t, const bmat &m);
1931 
1932 // element-wise multiplication
1933 
1934 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat elem_mult(const mat &m1, const mat &m2);
1935 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat elem_mult(const cmat &m1, const cmat &m2);
1936 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat elem_mult(const imat &m1, const imat &m2);
1937 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat elem_mult(const smat &m1, const smat &m2);
1938 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat elem_mult(const bmat &m1, const bmat &m2);
1939 
1940 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const mat &m1, const mat &m2, mat &out);
1941 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const cmat &m1, const cmat &m2,
1942  cmat &out);
1943 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const imat &m1, const imat &m2,
1944  imat &out);
1945 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const smat &m1, const smat &m2,
1946  smat &out);
1947 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const bmat &m1, const bmat &m2,
1948  bmat &out);
1949 
1950 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const mat &m1, const mat &m2,
1951  const mat &m3, mat &out);
1952 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const cmat &m1, const cmat &m2,
1953  const cmat &m3, cmat &out);
1954 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const imat &m1, const imat &m2,
1955  const imat &m3, imat &out);
1956 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const smat &m1, const smat &m2,
1957  const smat &m3, smat &out);
1958 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const bmat &m1, const bmat &m2,
1959  const bmat &m3, bmat &out);
1960 
1961 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const mat &m1, const mat &m2,
1962  const mat &m3, const mat &m4, mat &out);
1963 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const cmat &m1, const cmat &m2,
1964  const cmat &m3, const cmat &m4,
1965  cmat &out);
1966 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const imat &m1, const imat &m2,
1967  const imat &m3, const imat &m4,
1968  imat &out);
1969 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const smat &m1, const smat &m2,
1970  const smat &m3, const smat &m4,
1971  smat &out);
1972 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_out(const bmat &m1, const bmat &m2,
1973  const bmat &m3, const bmat &m4,
1974  bmat &out);
1975 
1976 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_inplace(const mat &m1, mat &m2);
1977 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_inplace(const cmat &m1, cmat &m2);
1978 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_inplace(const imat &m1, imat &m2);
1979 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_inplace(const smat &m1, smat &m2);
1980 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_mult_inplace(const bmat &m1, bmat &m2);
1981 
1982 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT double elem_mult_sum(const mat &m1, const mat &m2);
1983 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::complex<double> elem_mult_sum(const cmat &m1,
1984  const cmat &m2);
1985 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT int elem_mult_sum(const imat &m1, const imat &m2);
1986 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT short elem_mult_sum(const smat &m1, const smat &m2);
1987 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bin elem_mult_sum(const bmat &m1, const bmat &m2);
1988 
1989 // division operator
1990 
1991 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat operator/(double t, const mat &m);
1992 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat operator/(std::complex<double> t, const cmat &m);
1993 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat operator/(int t, const imat &m);
1994 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat operator/(short t, const smat &m);
1995 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat operator/(bin t, const bmat &m);
1996 
1997 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat operator/(const mat &m, double t);
1998 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat operator/(const cmat &m, std::complex<double> t);
1999 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat operator/(const imat &m, int t);
2000 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat operator/(const smat &m, short t);
2001 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat operator/(const bmat &m, bin t);
2002 
2003 // element-wise division
2004 
2005 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat elem_div(const mat &m1, const mat &m2);
2006 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat elem_div(const cmat &m1, const cmat &m2);
2007 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat elem_div(const imat &m1, const imat &m2);
2008 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat elem_div(const smat &m1, const smat &m2);
2009 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat elem_div(const bmat &m1, const bmat &m2);
2010 
2011 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_div_out(const mat &m1, const mat &m2, mat &out);
2012 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_div_out(const cmat &m1, const cmat &m2, cmat &out);
2013 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_div_out(const imat &m1, const imat &m2, imat &out);
2014 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_div_out(const smat &m1, const smat &m2, smat &out);
2015 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT void elem_div_out(const bmat &m1, const bmat &m2, bmat &out);
2016 
2017 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT double elem_div_sum(const mat &m1, const mat &m2);
2018 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::complex<double> elem_div_sum(const cmat &m1,
2019  const cmat &m2);
2020 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT int elem_div_sum(const imat &m1, const imat &m2);
2021 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT short elem_div_sum(const smat &m1, const smat &m2);
2022 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bin elem_div_sum(const bmat &m1, const bmat &m2);
2023 
2024 // concatenation
2025 
2026 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat concat_horizontal(const mat &m1, const mat &m2);
2027 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat concat_horizontal(const cmat &m1, const cmat &m2);
2028 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat concat_horizontal(const imat &m1, const imat &m2);
2029 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat concat_horizontal(const smat &m1, const smat &m2);
2030 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat concat_horizontal(const bmat &m1, const bmat &m2);
2031 
2032 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT mat concat_vertical(const mat &m1, const mat &m2);
2033 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT cmat concat_vertical(const cmat &m1, const cmat &m2);
2034 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT imat concat_vertical(const imat &m1, const imat &m2);
2035 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT smat concat_vertical(const smat &m1, const smat &m2);
2036 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT bmat concat_vertical(const bmat &m1, const bmat &m2);
2037 
2038 // I/O streams
2039 
2040 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::ostream &operator<<(std::ostream &os, const mat &m);
2041 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::ostream &operator<<(std::ostream &os, const cmat &m);
2042 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::ostream &operator<<(std::ostream &os, const imat &m);
2043 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::ostream &operator<<(std::ostream &os, const smat &m);
2044 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::ostream &operator<<(std::ostream &os, const bmat &m);
2045 
2046 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::istream &operator>>(std::istream &is, mat &m);
2047 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::istream &operator>>(std::istream &is, cmat &m);
2048 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::istream &operator>>(std::istream &is, imat &m);
2049 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::istream &operator>>(std::istream &is, smat &m);
2050 ITPP_EXPORT_TEMPLATE template ITPP_EXPORT std::istream &operator>>(std::istream &is, bmat &m);
2051 
2053 
2054 } // namespace itpp
2055 
2056 #endif // #ifndef MAT_H
SourceForge Logo

Generated on Sat Jul 6 2013 10:54:20 for IT++ by Doxygen 1.8.2