00001 00030 #ifndef MAT_H 00031 #define MAT_H 00032 00033 #ifndef _MSC_VER 00034 # include <itpp/config.h> 00035 #else 00036 # include <itpp/config_msvc.h> 00037 #endif 00038 00039 #include <itpp/base/itassert.h> 00040 #include <itpp/base/math/misc.h> 00041 #include <itpp/base/factory.h> 00042 00043 00044 namespace itpp 00045 { 00046 00047 // Declaration of Vec 00048 template<class Num_T> class Vec; 00049 // Declaration of Mat 00050 template<class Num_T> class Mat; 00051 // Declaration of bin 00052 class bin; 00053 00055 template<class Num_T> 00056 Mat<Num_T> concat_horizontal(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00058 template<class Num_T> 00059 Mat<Num_T> concat_vertical(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00060 00062 template<class Num_T> 00063 Mat<Num_T> operator+(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00065 template<class Num_T> 00066 Mat<Num_T> operator+(const Mat<Num_T> &m, Num_T t); 00068 template<class Num_T> 00069 Mat<Num_T> operator+(Num_T t, const Mat<Num_T> &m); 00070 00072 template<class Num_T> 00073 Mat<Num_T> operator-(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00075 template<class Num_T> 00076 Mat<Num_T> operator-(const Mat<Num_T> &m, Num_T t); 00078 template<class Num_T> 00079 Mat<Num_T> operator-(Num_T t, const Mat<Num_T> &m); 00081 template<class Num_T> 00082 Mat<Num_T> operator-(const Mat<Num_T> &m); 00083 00085 template<class Num_T> 00086 Mat<Num_T> operator*(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00088 template<class Num_T> 00089 Vec<Num_T> operator*(const Mat<Num_T> &m, const Vec<Num_T> &v); 00091 template<class Num_T> 00092 Mat<Num_T> operator*(const Vec<Num_T> &v, const Mat<Num_T> &m); 00094 template<class Num_T> 00095 Mat<Num_T> operator*(const Mat<Num_T> &m, Num_T t); 00097 template<class Num_T> 00098 Mat<Num_T> operator*(Num_T t, const Mat<Num_T> &m); 00099 00101 template<class Num_T> 00102 Mat<Num_T> elem_mult(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00104 template<class Num_T> 00105 void elem_mult_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2, 00106 Mat<Num_T> &out); 00108 template<class Num_T> 00109 void elem_mult_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2, 00110 const Mat<Num_T> &m3, Mat<Num_T> &out); 00112 template<class Num_T> 00113 void elem_mult_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2, 00114 const Mat<Num_T> &m3, const Mat<Num_T> &m4, 00115 Mat<Num_T> &out); 00117 template<class Num_T> 00118 void elem_mult_inplace(const Mat<Num_T> &m1, Mat<Num_T> &m2); 00120 template<class Num_T> 00121 Num_T elem_mult_sum(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00122 00124 template<class Num_T> 00125 Mat<Num_T> operator/(const Mat<Num_T> &m, Num_T t); 00126 00128 template<class Num_T> 00129 Mat<Num_T> elem_div(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00131 template<class Num_T> 00132 void elem_div_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2, 00133 Mat<Num_T> &out); 00135 template<class Num_T> 00136 Num_T elem_div_sum(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00137 00138 // ------------------------------------------------------------------------------------- 00139 // Declaration of Mat 00140 // ------------------------------------------------------------------------------------- 00141 00207 template<class Num_T> 00208 class Mat 00209 { 00210 public: 00212 typedef Num_T value_type; 00213 00215 explicit Mat(const Factory &f = DEFAULT_FACTORY); 00217 Mat(int rows, int cols, const Factory &f = DEFAULT_FACTORY); 00219 Mat(const Mat<Num_T> &m); 00221 Mat(const Mat<Num_T> &m, const Factory &f); 00223 Mat(const Vec<Num_T> &v, const Factory &f = DEFAULT_FACTORY); 00225 Mat(const std::string &str, const Factory &f = DEFAULT_FACTORY); 00227 Mat(const char *str, const Factory &f = DEFAULT_FACTORY); 00235 Mat(const Num_T *c_array, int rows, int cols, bool row_major = true, 00236 const Factory &f = DEFAULT_FACTORY); 00237 00239 ~Mat(); 00240 00242 int cols() const { return no_cols; } 00244 int rows() const { return no_rows; } 00246 int size() const { return datasize; } 00248 void set_size(int rows, int cols, bool copy = false); 00250 void zeros(); 00252 void clear() { zeros(); } 00254 void ones(); 00256 void set(const char *str); 00258 void set(const std::string &str); 00259 00261 const Num_T &operator()(int r, int c) const; 00263 Num_T &operator()(int r, int c); 00265 const Num_T &operator()(int i) const; 00267 Num_T &operator()(int i); 00269 const Num_T &get(int r, int c) const; 00271 void set(int r, int c, Num_T t); 00272 00278 Mat<Num_T> operator()(int r1, int r2, int c1, int c2) const; 00284 Mat<Num_T> get(int r1, int r2, int c1, int c2) const; 00285 00287 Vec<Num_T> get_row(int r) const; 00289 Mat<Num_T> get_rows(int r1, int r2) const; 00291 Mat<Num_T> get_rows(const Vec<int> &indexlist) const; 00293 Vec<Num_T> get_col(int c) const; 00295 Mat<Num_T> get_cols(int c1, int c2) const; 00297 Mat<Num_T> get_cols(const Vec<int> &indexlist) const; 00299 void set_row(int r, const Vec<Num_T> &v); 00301 void set_col(int c, const Vec<Num_T> &v); 00303 void set_rows(int r, const Mat<Num_T> &m); 00305 void set_cols(int c, const Mat<Num_T> &m); 00307 void copy_row(int to, int from); 00309 void copy_col(int to, int from); 00311 void swap_rows(int r1, int r2); 00313 void swap_cols(int c1, int c2); 00314 00316 void set_submatrix(int r1, int r2, int c1, int c2, const Mat<Num_T> &m); 00318 void set_submatrix(int r, int c, const Mat<Num_T> &m); 00320 void set_submatrix(int r1, int r2, int c1, int c2, Num_T t); 00321 00323 void del_row(int r); 00325 void del_rows(int r1, int r2); 00327 void del_col(int c); 00329 void del_cols(int c1, int c2); 00331 void ins_row(int r, const Vec<Num_T> &v); 00333 void ins_col(int c, const Vec<Num_T> &v); 00335 void append_row(const Vec<Num_T> &v); 00337 void append_col(const Vec<Num_T> &v); 00338 00340 Mat<Num_T> transpose() const; 00342 Mat<Num_T> T() const { return this->transpose(); } 00344 Mat<Num_T> hermitian_transpose() const; 00346 Mat<Num_T> H() const { return this->hermitian_transpose(); } 00347 00349 friend Mat<Num_T> concat_horizontal<>(const Mat<Num_T> &m1, 00350 const Mat<Num_T> &m2); 00352 friend Mat<Num_T> concat_vertical<>(const Mat<Num_T> &m1, 00353 const Mat<Num_T> &m2); 00354 00356 Mat<Num_T>& operator=(Num_T t); 00358 Mat<Num_T>& operator=(const Mat<Num_T> &m); 00360 Mat<Num_T>& operator=(const Vec<Num_T> &v); 00362 Mat<Num_T>& operator=(const char *str); 00363 00365 Mat<Num_T>& operator+=(const Mat<Num_T> &m); 00367 Mat<Num_T>& operator+=(Num_T t); 00369 friend Mat<Num_T> operator+<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00371 friend Mat<Num_T> operator+<>(const Mat<Num_T> &m, Num_T t); 00373 friend Mat<Num_T> operator+<>(Num_T t, const Mat<Num_T> &m); 00374 00376 Mat<Num_T>& operator-=(const Mat<Num_T> &m); 00378 Mat<Num_T>& operator-=(Num_T t); 00380 friend Mat<Num_T> operator-<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00382 friend Mat<Num_T> operator-<>(const Mat<Num_T> &m, Num_T t); 00384 friend Mat<Num_T> operator-<>(Num_T t, const Mat<Num_T> &m); 00386 friend Mat<Num_T> operator-<>(const Mat<Num_T> &m); 00387 00389 Mat<Num_T>& operator*=(const Mat<Num_T> &m); 00391 Mat<Num_T>& operator*=(Num_T t); 00393 friend Mat<Num_T> operator*<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00395 friend Vec<Num_T> operator*<>(const Mat<Num_T> &m, const Vec<Num_T> &v); 00407 friend Mat<Num_T> operator*<>(const Vec<Num_T> &v, const Mat<Num_T> &m); 00409 friend Mat<Num_T> operator*<>(const Mat<Num_T> &m, Num_T t); 00411 friend Mat<Num_T> operator*<>(Num_T t, const Mat<Num_T> &m); 00412 00414 friend Mat<Num_T> elem_mult<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00416 friend void elem_mult_out<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2, 00417 Mat<Num_T> &out); 00419 friend void elem_mult_out<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2, 00420 const Mat<Num_T> &m3, Mat<Num_T> &out); 00422 friend void elem_mult_out<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2, 00423 const Mat<Num_T> &m3, const Mat<Num_T> &m4, 00424 Mat<Num_T> &out); 00426 friend void elem_mult_inplace<>(const Mat<Num_T> &m1, Mat<Num_T> &m2); 00428 friend Num_T elem_mult_sum<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00429 00431 Mat<Num_T>& operator/=(Num_T t); 00433 friend Mat<Num_T> operator/<>(const Mat<Num_T> &m, Num_T t); 00435 Mat<Num_T>& operator/=(const Mat<Num_T> &m); 00436 00438 friend Mat<Num_T> elem_div<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00440 friend void elem_div_out<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2, 00441 Mat<Num_T> &out); 00443 friend Num_T elem_div_sum<>(const Mat<Num_T> &m1, const Mat<Num_T> &m2); 00444 00446 bool operator==(const Mat<Num_T> &m) const; 00448 bool operator!=(const Mat<Num_T> &m) const; 00449 00451 Num_T &_elem(int r, int c) { return data[r+c*no_rows]; } 00453 const Num_T &_elem(int r, int c) const { return data[r+c*no_rows]; } 00455 Num_T &_elem(int i) { return data[i]; } 00457 const Num_T &_elem(int i) const { return data[i]; } 00458 00460 Num_T *_data() { return data; } 00462 const Num_T *_data() const { return data; } 00464 int _datasize() const { return datasize; } 00465 00466 protected: 00468 void alloc(int rows, int cols); 00470 void free(); 00471 00474 int datasize, no_rows, no_cols; 00476 00477 Num_T *data; 00479 const Factory &factory; 00480 00481 private: 00483 bool in_range(int r, int c) const { 00484 return ((r >= 0) && (r < no_rows) && (c >= 0) && (c < no_cols)); 00485 } 00487 bool row_in_range(int r) const { return ((r >= 0) && (r < no_rows)); } 00489 bool col_in_range(int c) const { return ((c >= 0) && (c < no_cols)); } 00491 bool in_range(int i) const { return ((i >= 0) && (i < datasize)); } 00492 }; 00493 00494 // ------------------------------------------------------------------------------------- 00495 // Type definitions of mat, cmat, imat, smat, and bmat 00496 // ------------------------------------------------------------------------------------- 00497 00502 typedef Mat<double> mat; 00503 00508 typedef Mat<std::complex<double> > cmat; 00509 00514 typedef Mat<int> imat; 00515 00520 typedef Mat<short int> smat; 00521 00528 typedef Mat<bin> bmat; 00529 00530 } //namespace itpp 00531 00532 00533 #include <itpp/base/vec.h> 00534 00535 namespace itpp 00536 { 00537 00538 // ---------------------------------------------------------------------- 00539 // Declaration of input and output streams for Mat 00540 // ---------------------------------------------------------------------- 00541 00546 template <class Num_T> 00547 std::ostream &operator<<(std::ostream &os, const Mat<Num_T> &m); 00548 00560 template <class Num_T> 00561 std::istream &operator>>(std::istream &is, Mat<Num_T> &m); 00562 00563 // ---------------------------------------------------------------------- 00564 // Implementation of templated Mat members and friends 00565 // ---------------------------------------------------------------------- 00566 00567 template<class Num_T> inline 00568 void Mat<Num_T>::alloc(int rows, int cols) 00569 { 00570 if ((rows > 0) && (cols > 0)) { 00571 datasize = rows * cols; 00572 no_rows = rows; 00573 no_cols = cols; 00574 create_elements(data, datasize, factory); 00575 } 00576 else { 00577 data = 0; 00578 datasize = 0; 00579 no_rows = 0; 00580 no_cols = 0; 00581 } 00582 } 00583 00584 template<class Num_T> inline 00585 void Mat<Num_T>::free() 00586 { 00587 destroy_elements(data, datasize); 00588 datasize = 0; 00589 no_rows = 0; 00590 no_cols = 0; 00591 } 00592 00593 00594 template<class Num_T> inline 00595 Mat<Num_T>::Mat(const Factory &f) : 00596 datasize(0), no_rows(0), no_cols(0), data(0), factory(f) {} 00597 00598 template<class Num_T> inline 00599 Mat<Num_T>::Mat(int rows, int cols, const Factory &f) : 00600 datasize(0), no_rows(0), no_cols(0), data(0), factory(f) 00601 { 00602 it_assert_debug((rows >= 0) && (cols >= 0), "Mat<>::Mat(): Wrong size"); 00603 alloc(rows, cols); 00604 } 00605 00606 template<class Num_T> inline 00607 Mat<Num_T>::Mat(const Mat<Num_T> &m) : 00608 datasize(0), no_rows(0), no_cols(0), data(0), factory(m.factory) 00609 { 00610 alloc(m.no_rows, m.no_cols); 00611 copy_vector(m.datasize, m.data, data); 00612 } 00613 00614 template<class Num_T> inline 00615 Mat<Num_T>::Mat(const Mat<Num_T> &m, const Factory &f) : 00616 datasize(0), no_rows(0), no_cols(0), data(0), factory(f) 00617 { 00618 alloc(m.no_rows, m.no_cols); 00619 copy_vector(m.datasize, m.data, data); 00620 } 00621 00622 template<class Num_T> inline 00623 Mat<Num_T>::Mat(const Vec<Num_T> &v, const Factory &f) : 00624 datasize(0), no_rows(0), no_cols(0), data(0), factory(f) 00625 { 00626 int size = v.size(); 00627 alloc(size, 1); 00628 copy_vector(size, v._data(), data); 00629 } 00630 00631 template<class Num_T> inline 00632 Mat<Num_T>::Mat(const std::string &str, const Factory &f) : 00633 datasize(0), no_rows(0), no_cols(0), data(0), factory(f) 00634 { 00635 set(str); 00636 } 00637 00638 template<class Num_T> inline 00639 Mat<Num_T>::Mat(const char *str, const Factory &f) : 00640 datasize(0), no_rows(0), no_cols(0), data(0), factory(f) 00641 { 00642 set(str); 00643 } 00644 00645 template<class Num_T> 00646 Mat<Num_T>::Mat(const Num_T *c_array, int rows, int cols, bool row_major, 00647 const Factory &f): 00648 datasize(0), no_rows(0), no_cols(0), data(0), factory(f) 00649 { 00650 alloc(rows, cols); 00651 if (!row_major) 00652 copy_vector(datasize, c_array, data); 00653 else 00654 for (int i = 0; i < rows; i++) 00655 for (int j = 0; j < cols; j++) 00656 data[i+j*no_rows] = c_array[i*no_cols+j]; 00657 } 00658 00659 template<class Num_T> inline 00660 Mat<Num_T>::~Mat() 00661 { 00662 free(); 00663 } 00664 00665 00666 template<class Num_T> 00667 void Mat<Num_T>::set_size(int rows, int cols, bool copy) 00668 { 00669 it_assert_debug((rows >= 0) && (cols >= 0), 00670 "Mat<>::set_size(): Wrong size"); 00671 // check if we have to resize the current matrix 00672 if ((no_rows == rows) && (no_cols == cols)) 00673 return; 00674 // check if one of dimensions is zero 00675 if ((rows == 0) || (cols == 0)) { 00676 free(); 00677 return; 00678 } 00679 // conditionally copy previous matrix content 00680 if (copy) { 00681 // create a temporary pointer to the allocated data 00682 Num_T* tmp = data; 00683 // store the current number of elements and number of rows 00684 int old_datasize = datasize; 00685 int old_rows = no_rows; 00686 // check the boundaries of the copied data 00687 int min_r = (no_rows < rows) ? no_rows : rows; 00688 int min_c = (no_cols < cols) ? no_cols : cols; 00689 // allocate new memory 00690 alloc(rows, cols); 00691 // copy the previous data into the allocated memory 00692 for (int i = 0; i < min_c; ++i) { 00693 copy_vector(min_r, &tmp[i*old_rows], &data[i*no_rows]); 00694 } 00695 // fill-in the rest of matrix with zeros 00696 for (int i = min_r; i < rows; ++i) 00697 for (int j = 0; j < cols; ++j) 00698 data[i+j*rows] = Num_T(0); 00699 for (int j = min_c; j < cols; ++j) 00700 for (int i = 0; i < min_r; ++i) 00701 data[i+j*rows] = Num_T(0); 00702 // delete old elements 00703 destroy_elements(tmp, old_datasize); 00704 } 00705 // if possible, reuse the allocated memory 00706 else if (datasize == rows * cols) { 00707 no_rows = rows; 00708 no_cols = cols; 00709 } 00710 // finally release old memory and allocate a new one 00711 else { 00712 free(); 00713 alloc(rows, cols); 00714 } 00715 } 00716 00717 template<class Num_T> inline 00718 void Mat<Num_T>::zeros() 00719 { 00720 for (int i = 0; i < datasize; i++) 00721 data[i] = Num_T(0); 00722 } 00723 00724 template<class Num_T> inline 00725 void Mat<Num_T>::ones() 00726 { 00727 for (int i = 0; i < datasize; i++) 00728 data[i] = Num_T(1); 00729 } 00730 00731 template<class Num_T> inline 00732 const Num_T& Mat<Num_T>::operator()(int r, int c) const 00733 { 00734 it_assert_debug(in_range(r, c), 00735 "Mat<>::operator(): Indexing out of range"); 00736 return data[r+c*no_rows]; 00737 } 00738 00739 template<class Num_T> inline 00740 Num_T& Mat<Num_T>::operator()(int r, int c) 00741 { 00742 it_assert_debug(in_range(r, c), 00743 "Mat<>::operator(): Indexing out of range"); 00744 return data[r+c*no_rows]; 00745 } 00746 00747 template<class Num_T> inline 00748 Num_T& Mat<Num_T>::operator()(int i) 00749 { 00750 it_assert_debug(in_range(i), "Mat<>::operator(): Index out of range"); 00751 return data[i]; 00752 } 00753 00754 template<class Num_T> inline 00755 const Num_T& Mat<Num_T>::operator()(int i) const 00756 { 00757 it_assert_debug(in_range(i), "Mat<>::operator(): Index out of range"); 00758 return data[i]; 00759 } 00760 00761 template<class Num_T> inline 00762 const Num_T& Mat<Num_T>::get(int r, int c) const 00763 { 00764 it_assert_debug(in_range(r, c), "Mat<>::get(): Indexing out of range"); 00765 return data[r+c*no_rows]; 00766 } 00767 00768 template<class Num_T> inline 00769 void Mat<Num_T>::set(int r, int c, Num_T t) 00770 { 00771 it_assert_debug(in_range(r, c), "Mat<>::set(): Indexing out of range"); 00772 data[r+c*no_rows] = t; 00773 } 00774 00775 00776 template<class Num_T> 00777 void Mat<Num_T>::set(const std::string &str) 00778 { 00779 // actual row counter 00780 int rows = 0; 00781 // number of rows to allocate next time (8, 16, 32, 64, etc.) 00782 int maxrows = 8; 00783 00784 // clean the current matrix content 00785 free(); 00786 00787 // variable to store the start of a current vector 00788 std::string::size_type beg = 0; 00789 std::string::size_type end = 0; 00790 while (end != std::string::npos) { 00791 // find next occurrence of a semicolon in string str 00792 end = str.find(';', beg); 00793 // parse first row into a vector v 00794 Vec<Num_T> v(str.substr(beg, end - beg)); 00795 int v_size = v.size(); 00796 00797 // this check is necessary to parse the following two strings as the 00798 // same matrix: "1 0 1; ; 1 1; " and "1 0 1; 0 0 0; 1 1 0" 00799 if ((end != std::string::npos) || (v_size > 0)) { 00800 // matrix empty -> insert v as a first row and allocate maxrows 00801 if (rows == 0) { 00802 set_size(maxrows, v_size, true); 00803 set_row(rows++, v); 00804 } 00805 else { 00806 // check if we need to resize the matrix 00807 if ((rows == maxrows) || (v_size != no_cols)) { 00808 // we need to add new rows 00809 if (rows == maxrows) { 00810 maxrows *= 2; 00811 } 00812 // check if we need to add new columns 00813 if (v_size > no_cols) { 00814 set_size(maxrows, v_size, true); 00815 } 00816 else { 00817 set_size(maxrows, no_cols, true); 00818 // set the size of the parsed vector to the number of columns 00819 v.set_size(no_cols, true); 00820 } 00821 } 00822 // set the parsed vector as the next row 00823 set_row(rows++, v); 00824 } 00825 } 00826 // update the starting position of the next vector in the parsed 00827 // string 00828 beg = end + 1; 00829 } // if ((end != std::string::npos) || (v.size > 0)) 00830 00831 set_size(rows, no_cols, true); 00832 } 00833 00834 template<class Num_T> 00835 void Mat<Num_T>::set(const char *str) 00836 { 00837 set(std::string(str)); 00838 } 00839 00840 template<class Num_T> inline 00841 Mat<Num_T> Mat<Num_T>::operator()(int r1, int r2, int c1, int c2) const 00842 { 00843 if (r1 == -1) r1 = no_rows - 1; 00844 if (r2 == -1) r2 = no_rows - 1; 00845 if (c1 == -1) c1 = no_cols - 1; 00846 if (c2 == -1) c2 = no_cols - 1; 00847 00848 it_assert_debug((r1 >= 0) && (r1 <= r2) && (r2 < no_rows) && 00849 (c1 >= 0) && (c1 <= c2) && (c2 < no_cols), 00850 "Mat<>::operator()(r1, r2, c1, c2): Wrong indexing"); 00851 00852 Mat<Num_T> s(r2 - r1 + 1, c2 - c1 + 1); 00853 00854 for (int i = 0;i < s.no_cols;i++) 00855 copy_vector(s.no_rows, data + r1 + (c1 + i)*no_rows, s.data + i*s.no_rows); 00856 00857 return s; 00858 } 00859 00860 template<class Num_T> inline 00861 Mat<Num_T> Mat<Num_T>::get(int r1, int r2, int c1, int c2) const 00862 { 00863 return (*this)(r1, r2, c1, c2); 00864 } 00865 00866 template<class Num_T> inline 00867 Vec<Num_T> Mat<Num_T>::get_row(int r) const 00868 { 00869 it_assert_debug(row_in_range(r), "Mat<>::get_row(): Index out of range"); 00870 Vec<Num_T> a(no_cols); 00871 00872 copy_vector(no_cols, data + r, no_rows, a._data(), 1); 00873 return a; 00874 } 00875 00876 template<class Num_T> 00877 Mat<Num_T> Mat<Num_T>::get_rows(int r1, int r2) const 00878 { 00879 it_assert_debug((r1 >= 0) && (r1 <= r2) && (r2 < no_rows), 00880 "Mat<>::get_rows(): Wrong indexing"); 00881 Mat<Num_T> m(r2 - r1 + 1, no_cols); 00882 00883 for (int i = 0; i < m.rows(); i++) 00884 copy_vector(no_cols, data + i + r1, no_rows, m.data + i, m.no_rows); 00885 00886 return m; 00887 } 00888 00889 template<class Num_T> 00890 Mat<Num_T> Mat<Num_T>::get_rows(const Vec<int> &indexlist) const 00891 { 00892 Mat<Num_T> m(indexlist.size(), no_cols); 00893 00894 for (int i = 0;i < indexlist.size();i++) { 00895 it_assert_debug(row_in_range(indexlist(i)), 00896 "Mat<>::get_rows(indexlist): Indexing out of range"); 00897 copy_vector(no_cols, data + indexlist(i), no_rows, m.data + i, m.no_rows); 00898 } 00899 00900 return m; 00901 } 00902 00903 template<class Num_T> inline 00904 Vec<Num_T> Mat<Num_T>::get_col(int c) const 00905 { 00906 it_assert_debug(col_in_range(c), "Mat<>::get_col(): Index out of range"); 00907 Vec<Num_T> a(no_rows); 00908 00909 copy_vector(no_rows, data + c*no_rows, a._data()); 00910 00911 return a; 00912 } 00913 00914 template<class Num_T> 00915 Mat<Num_T> Mat<Num_T>::get_cols(int c1, int c2) const 00916 { 00917 it_assert_debug((c1 >= 0) && (c1 <= c2) && (c2 < no_cols), 00918 "Mat<>::get_cols(): Wrong indexing"); 00919 Mat<Num_T> m(no_rows, c2 - c1 + 1); 00920 00921 for (int i = 0; i < m.cols(); i++) 00922 copy_vector(no_rows, data + (i + c1)*no_rows, m.data + i*m.no_rows); 00923 00924 return m; 00925 } 00926 00927 template<class Num_T> 00928 Mat<Num_T> Mat<Num_T>::get_cols(const Vec<int> &indexlist) const 00929 { 00930 Mat<Num_T> m(no_rows, indexlist.size()); 00931 00932 for (int i = 0; i < indexlist.size(); i++) { 00933 it_assert_debug(col_in_range(indexlist(i)), 00934 "Mat<>::get_cols(indexlist): Indexing out of range"); 00935 copy_vector(no_rows, data + indexlist(i)*no_rows, m.data + i*m.no_rows); 00936 } 00937 00938 return m; 00939 } 00940 00941 template<class Num_T> inline 00942 void Mat<Num_T>::set_row(int r, const Vec<Num_T> &v) 00943 { 00944 it_assert_debug(row_in_range(r), "Mat<>::set_row(): Index out of range"); 00945 it_assert_debug(v.size() == no_cols, 00946 "Mat<>::set_row(): Wrong size of input vector"); 00947 copy_vector(v.size(), v._data(), 1, data + r, no_rows); 00948 } 00949 00950 template<class Num_T> inline 00951 void Mat<Num_T>::set_col(int c, const Vec<Num_T> &v) 00952 { 00953 it_assert_debug(col_in_range(c), "Mat<>::set_col(): Index out of range"); 00954 it_assert_debug(v.size() == no_rows, 00955 "Mat<>::set_col(): Wrong size of input vector"); 00956 copy_vector(v.size(), v._data(), data + c*no_rows); 00957 } 00958 00959 00960 template<class Num_T> 00961 void Mat<Num_T>::set_rows(int r, const Mat<Num_T> &m) 00962 { 00963 it_assert_debug(row_in_range(r), "Mat<>::set_rows(): Index out of range"); 00964 it_assert_debug(no_cols == m.cols(), 00965 "Mat<>::set_rows(): Column sizes do not match"); 00966 it_assert_debug(m.rows() + r <= no_rows, 00967 "Mat<>::set_rows(): Not enough rows"); 00968 00969 for (int i = 0; i < m.rows(); ++i) { 00970 copy_vector(no_cols, m.data + i, m.no_rows, data + i + r, no_rows); 00971 } 00972 } 00973 00974 template<class Num_T> 00975 void Mat<Num_T>::set_cols(int c, const Mat<Num_T> &m) 00976 { 00977 it_assert_debug(col_in_range(c), "Mat<>::set_cols(): Index out of range"); 00978 it_assert_debug(no_rows == m.rows(), 00979 "Mat<>::set_cols(): Row sizes do not match"); 00980 it_assert_debug(m.cols() + c <= no_cols, 00981 "Mat<>::set_cols(): Not enough colums"); 00982 00983 for (int i = 0; i < m.cols(); ++i) { 00984 copy_vector(no_rows, m.data + i*no_rows, data + (i + c)*no_rows); 00985 } 00986 } 00987 00988 00989 template<class Num_T> inline 00990 void Mat<Num_T>::copy_row(int to, int from) 00991 { 00992 it_assert_debug(row_in_range(to) && row_in_range(from), 00993 "Mat<>::copy_row(): Indexing out of range"); 00994 if (from == to) 00995 return; 00996 00997 copy_vector(no_cols, data + from, no_rows, data + to, no_rows); 00998 } 00999 01000 template<class Num_T> inline 01001 void Mat<Num_T>::copy_col(int to, int from) 01002 { 01003 it_assert_debug(col_in_range(to) && col_in_range(from), 01004 "Mat<>::copy_col(): Indexing out of range"); 01005 if (from == to) 01006 return; 01007 01008 copy_vector(no_rows, data + from*no_rows, data + to*no_rows); 01009 } 01010 01011 template<class Num_T> inline 01012 void Mat<Num_T>::swap_rows(int r1, int r2) 01013 { 01014 it_assert_debug(row_in_range(r1) && row_in_range(r2), 01015 "Mat<>::swap_rows(): Indexing out of range"); 01016 if (r1 == r2) 01017 return; 01018 01019 swap_vector(no_cols, data + r1, no_rows, data + r2, no_rows); 01020 } 01021 01022 template<class Num_T> inline 01023 void Mat<Num_T>::swap_cols(int c1, int c2) 01024 { 01025 it_assert_debug(col_in_range(c1) && col_in_range(c2), 01026 "Mat<>::swap_cols(): Indexing out of range"); 01027 if (c1 == c2) 01028 return; 01029 01030 swap_vector(no_rows, data + c1*no_rows, data + c2*no_rows); 01031 } 01032 01033 template<class Num_T> 01034 void Mat<Num_T>::set_submatrix(int r1, int r2, int c1, int c2, 01035 const Mat<Num_T> &m) 01036 { 01037 01038 if (r1 == -1) r1 = no_rows - 1; 01039 if (r2 == -1) r2 = no_rows - 1; 01040 if (c1 == -1) c1 = no_cols - 1; 01041 if (c2 == -1) c2 = no_cols - 1; 01042 01043 it_assert_debug(r1 >= 0 && r2 >= 0 && r1 < no_rows && r2 < no_rows && 01044 c1 >= 0 && c2 >= 0 && c1 < no_cols && c2 < no_cols, "Mat<Num_T>::set_submatrix(): index out of range"); 01045 01046 it_assert_debug(r2 >= r1 && c2 >= c1, "Mat<Num_T>::set_submatrix: r2<r1 or c2<c1"); 01047 it_assert_debug(m.no_rows == r2 - r1 + 1 && m.no_cols == c2 - c1 + 1, "Mat<Num_T>::set_submatrix(): sizes don't match"); 01048 01049 for (int i = 0; i < m.no_cols; i++) 01050 copy_vector(m.no_rows, m.data + i*m.no_rows, data + (c1 + i)*no_rows + r1); 01051 } 01052 01053 01054 01055 template<class Num_T> inline 01056 void Mat<Num_T>::set_submatrix(int r, int c, const Mat<Num_T> &m) 01057 { 01058 it_assert_debug((r >= 0) && (r + m.no_rows <= no_rows) && 01059 (c >= 0) && (c + m.no_cols <= no_cols), 01060 "Mat<>::set_submatrix(): Indexing out of range " 01061 "or wrong input matrix"); 01062 for (int i = 0; i < m.no_cols; i++) 01063 copy_vector(m.no_rows, m.data + i*m.no_rows, data + (c + i)*no_rows + r); 01064 } 01065 01066 01067 01068 template<class Num_T> inline 01069 void Mat<Num_T>::set_submatrix(int r1, int r2, int c1, int c2, Num_T t) 01070 { 01071 01072 if (r1 == -1) r1 = no_rows - 1; 01073 if (r2 == -1) r2 = no_rows - 1; 01074 if (c1 == -1) c1 = no_cols - 1; 01075 if (c2 == -1) c2 = no_cols - 1; 01076 it_assert_debug((r1 >= 0) && (r1 <= r2) && (r2 < no_rows) && 01077 (c1 >= 0) && (c1 <= c2) && (c2 < no_cols), 01078 "Mat<>::set_submatrix(): Wrong indexing"); 01079 01080 int i, j, pos, rows = r2 - r1 + 1; 01081 01082 for (i = c1; i <= c2; i++) { 01083 pos = i * no_rows + r1; 01084 for (j = 0; j < rows; j++) { 01085 data[pos++] = t; 01086 } 01087 } 01088 } 01089 01090 template<class Num_T> 01091 void Mat<Num_T>::del_row(int r) 01092 { 01093 it_assert_debug(row_in_range(r), "Mat<>::del_row(): Index out of range"); 01094 Mat<Num_T> Temp(*this); 01095 set_size(no_rows - 1, no_cols, false); 01096 for (int i = 0 ; i < r ; i++) { 01097 copy_vector(no_cols, &Temp.data[i], no_rows + 1, &data[i], no_rows); 01098 } 01099 for (int i = r ; i < no_rows ; i++) { 01100 copy_vector(no_cols, &Temp.data[i+1], no_rows + 1, &data[i], no_rows); 01101 } 01102 01103 } 01104 01105 template<class Num_T> 01106 void Mat<Num_T>::del_rows(int r1, int r2) 01107 { 01108 it_assert_debug((r1 >= 0) && (r1 <= r2) && (r2 < no_rows), 01109 "Mat<>::del_rows(): Indexing out of range"); 01110 Mat<Num_T> Temp(*this); 01111 int no_del_rows = r2 - r1 + 1; 01112 set_size(no_rows - no_del_rows, no_cols, false); 01113 for (int i = 0; i < r1 ; ++i) { 01114 copy_vector(no_cols, &Temp.data[i], Temp.no_rows, &data[i], no_rows); 01115 } 01116 for (int i = r2 + 1; i < Temp.no_rows; ++i) { 01117 copy_vector(no_cols, &Temp.data[i], Temp.no_rows, &data[i-no_del_rows], 01118 no_rows); 01119 } 01120 } 01121 01122 template<class Num_T> 01123 void Mat<Num_T>::del_col(int c) 01124 { 01125 it_assert_debug(col_in_range(c), "Mat<>::del_col(): Index out of range"); 01126 Mat<Num_T> Temp(*this); 01127 01128 set_size(no_rows, no_cols - 1, false); 01129 copy_vector(c*no_rows, Temp.data, data); 01130 copy_vector((no_cols - c)*no_rows, &Temp.data[(c+1)*no_rows], &data[c*no_rows]); 01131 } 01132 01133 template<class Num_T> 01134 void Mat<Num_T>::del_cols(int c1, int c2) 01135 { 01136 it_assert_debug((c1 >= 0) && (c1 <= c2) && (c2 < no_cols), 01137 "Mat<>::del_cols(): Indexing out of range"); 01138 Mat<Num_T> Temp(*this); 01139 int n_deleted_cols = c2 - c1 + 1; 01140 set_size(no_rows, no_cols - n_deleted_cols, false); 01141 copy_vector(c1*no_rows, Temp.data, data); 01142 copy_vector((no_cols - c1)*no_rows, &Temp.data[(c2+1)*no_rows], &data[c1*no_rows]); 01143 } 01144 01145 template<class Num_T> 01146 void Mat<Num_T>::ins_row(int r, const Vec<Num_T> &v) 01147 { 01148 it_assert_debug((r >= 0) && (r <= no_rows), 01149 "Mat<>::ins_row(): Index out of range"); 01150 it_assert_debug((v.size() == no_cols) || (no_rows == 0), 01151 "Mat<>::ins_row(): Wrong size of the input vector"); 01152 01153 if (no_cols == 0) { 01154 no_cols = v.size(); 01155 } 01156 01157 Mat<Num_T> Temp(*this); 01158 set_size(no_rows + 1, no_cols, false); 01159 01160 for (int i = 0 ; i < r ; i++) { 01161 copy_vector(no_cols, &Temp.data[i], no_rows - 1, &data[i], no_rows); 01162 } 01163 copy_vector(no_cols, v._data(), 1, &data[r], no_rows); 01164 for (int i = r + 1 ; i < no_rows ; i++) { 01165 copy_vector(no_cols, &Temp.data[i-1], no_rows - 1, &data[i], no_rows); 01166 } 01167 } 01168 01169 template<class Num_T> 01170 void Mat<Num_T>::ins_col(int c, const Vec<Num_T> &v) 01171 { 01172 it_assert_debug((c >= 0) && (c <= no_cols), 01173 "Mat<>::ins_col(): Index out of range"); 01174 it_assert_debug((v.size() == no_rows) || (no_cols == 0), 01175 "Mat<>::ins_col(): Wrong size of the input vector"); 01176 01177 if (no_rows == 0) { 01178 no_rows = v.size(); 01179 } 01180 01181 Mat<Num_T> Temp(*this); 01182 set_size(no_rows, no_cols + 1, false); 01183 01184 copy_vector(c*no_rows, Temp.data, data); 01185 copy_vector(no_rows, v._data(), &data[c*no_rows]); 01186 copy_vector((no_cols - c - 1)*no_rows, &Temp.data[c*no_rows], &data[(c+1)*no_rows]); 01187 } 01188 01189 template<class Num_T> inline 01190 void Mat<Num_T>::append_row(const Vec<Num_T> &v) 01191 { 01192 ins_row(no_rows, v); 01193 } 01194 01195 template<class Num_T> inline 01196 void Mat<Num_T>::append_col(const Vec<Num_T> &v) 01197 { 01198 ins_col(no_cols, v); 01199 } 01200 01201 template<class Num_T> 01202 Mat<Num_T> Mat<Num_T>::transpose() const 01203 { 01204 Mat<Num_T> temp(no_cols, no_rows); 01205 for (int i = 0; i < no_rows; ++i) { 01206 copy_vector(no_cols, &data[i], no_rows, &temp.data[i * no_cols], 1); 01207 } 01208 return temp; 01209 } 01210 01212 template<> 01213 cmat cmat::hermitian_transpose() const; 01215 01216 template<class Num_T> 01217 Mat<Num_T> Mat<Num_T>::hermitian_transpose() const 01218 { 01219 Mat<Num_T> temp(no_cols, no_rows); 01220 for (int i = 0; i < no_rows; ++i) { 01221 copy_vector(no_cols, &data[i], no_rows, &temp.data[i * no_cols], 1); 01222 } 01223 return temp; 01224 } 01225 01226 template<class Num_T> 01227 Mat<Num_T> concat_horizontal(const Mat<Num_T> &m1, const Mat<Num_T> &m2) 01228 { 01229 // if one of the input matrix is empty just copy the other one as a result 01230 if (m1.no_cols == 0) 01231 return m2; 01232 if (m2.no_cols == 0) 01233 return m1; 01234 it_assert_debug(m1.no_rows == m2.no_rows, 01235 "Mat<>::concat_horizontal(): Wrong sizes"); 01236 int no_rows = m1.no_rows; 01237 Mat<Num_T> temp(no_rows, m1.no_cols + m2.no_cols); 01238 for (int i = 0; i < m1.no_cols; ++i) { 01239 copy_vector(no_rows, &m1.data[i * no_rows], &temp.data[i * no_rows]); 01240 } 01241 for (int i = 0; i < m2.no_cols; ++i) { 01242 copy_vector(no_rows, &m2.data[i * no_rows], &temp.data[(m1.no_cols + i) 01243 * no_rows]); 01244 } 01245 return temp; 01246 } 01247 01248 template<class Num_T> 01249 Mat<Num_T> concat_vertical(const Mat<Num_T> &m1, const Mat<Num_T> &m2) 01250 { 01251 // if one of the input matrix is empty just copy the other one as a result 01252 if (m1.no_rows == 0) 01253 return m2; 01254 if (m2.no_rows == 0) 01255 return m1; 01256 it_assert_debug(m1.no_cols == m2.no_cols, 01257 "Mat<>::concat_vertical(): Wrong sizes"); 01258 int no_cols = m1.no_cols; 01259 Mat<Num_T> temp(m1.no_rows + m2.no_rows, no_cols); 01260 for (int i = 0; i < no_cols; ++i) { 01261 copy_vector(m1.no_rows, &m1.data[i * m1.no_rows], 01262 &temp.data[i * temp.no_rows]); 01263 copy_vector(m2.no_rows, &m2.data[i * m2.no_rows], 01264 &temp.data[i * temp.no_rows + m1.no_rows]); 01265 } 01266 return temp; 01267 } 01268 01269 template<class Num_T> inline 01270 Mat<Num_T>& Mat<Num_T>::operator=(Num_T t) 01271 { 01272 for (int i = 0; i < datasize; i++) 01273 data[i] = t; 01274 return *this; 01275 } 01276 01277 template<class Num_T> inline 01278 Mat<Num_T>& Mat<Num_T>::operator=(const Mat<Num_T> &m) 01279 { 01280 if (this != &m) { 01281 set_size(m.no_rows, m.no_cols, false); 01282 if (m.datasize != 0) 01283 copy_vector(m.datasize, m.data, data); 01284 } 01285 return *this; 01286 } 01287 01288 template<class Num_T> inline 01289 Mat<Num_T>& Mat<Num_T>::operator=(const Vec<Num_T> &v) 01290 { 01291 it_assert_debug(((no_rows == 1) && (no_cols == v.size())) 01292 || ((no_cols == 1) && (no_rows == v.size())), 01293 "Mat<>::operator=(): Wrong size of the input vector"); 01294 set_size(v.size(), 1, false); 01295 copy_vector(v.size(), v._data(), data); 01296 return *this; 01297 } 01298 01299 template<class Num_T> inline 01300 Mat<Num_T>& Mat<Num_T>::operator=(const char *str) 01301 { 01302 set(str); 01303 return *this; 01304 } 01305 01306 //-------------------- Templated friend functions -------------------------- 01307 01308 template<class Num_T> 01309 Mat<Num_T>& Mat<Num_T>::operator+=(const Mat<Num_T> &m) 01310 { 01311 if (datasize == 0) 01312 operator=(m); 01313 else { 01314 int i, j, m_pos = 0, pos = 0; 01315 it_assert_debug(m.no_rows == no_rows && m.no_cols == no_cols, "Mat<Num_T>::operator+=: wrong sizes"); 01316 for (i = 0; i < no_cols; i++) { 01317 for (j = 0; j < no_rows; j++) 01318 data[pos+j] += m.data[m_pos+j]; 01319 pos += no_rows; 01320 m_pos += m.no_rows; 01321 } 01322 } 01323 return *this; 01324 } 01325 01326 template<class Num_T> inline 01327 Mat<Num_T>& Mat<Num_T>::operator+=(Num_T t) 01328 { 01329 for (int i = 0; i < datasize; i++) 01330 data[i] += t; 01331 return *this; 01332 } 01333 01334 template<class Num_T> 01335 Mat<Num_T> operator+(const Mat<Num_T> &m1, const Mat<Num_T> &m2) 01336 { 01337 Mat<Num_T> r(m1.no_rows, m1.no_cols); 01338 int i, j, m1_pos = 0, m2_pos = 0, r_pos = 0; 01339 01340 it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_cols == m2.no_cols), 01341 "Mat<>::operator+(): Wrong sizes"); 01342 01343 for (i = 0; i < r.no_cols; i++) { 01344 for (j = 0; j < r.no_rows; j++) 01345 r.data[r_pos+j] = m1.data[m1_pos+j] + m2.data[m2_pos+j]; 01346 // next column 01347 m1_pos += m1.no_rows; 01348 m2_pos += m2.no_rows; 01349 r_pos += r.no_rows; 01350 } 01351 01352 return r; 01353 } 01354 01355 01356 template<class Num_T> 01357 Mat<Num_T> operator+(const Mat<Num_T> &m, Num_T t) 01358 { 01359 Mat<Num_T> r(m.no_rows, m.no_cols); 01360 01361 for (int i = 0; i < r.datasize; i++) 01362 r.data[i] = m.data[i] + t; 01363 01364 return r; 01365 } 01366 01367 template<class Num_T> 01368 Mat<Num_T> operator+(Num_T t, const Mat<Num_T> &m) 01369 { 01370 Mat<Num_T> r(m.no_rows, m.no_cols); 01371 01372 for (int i = 0; i < r.datasize; i++) 01373 r.data[i] = t + m.data[i]; 01374 01375 return r; 01376 } 01377 01378 template<class Num_T> 01379 Mat<Num_T>& Mat<Num_T>::operator-=(const Mat<Num_T> &m) 01380 { 01381 int i, j, m_pos = 0, pos = 0; 01382 01383 if (datasize == 0) { 01384 set_size(m.no_rows, m.no_cols, false); 01385 for (i = 0; i < no_cols; i++) { 01386 for (j = 0; j < no_rows; j++) 01387 data[pos+j] = -m.data[m_pos+j]; 01388 // next column 01389 m_pos += m.no_rows; 01390 pos += no_rows; 01391 } 01392 } 01393 else { 01394 it_assert_debug((m.no_rows == no_rows) && (m.no_cols == no_cols), 01395 "Mat<>::operator-=(): Wrong sizes"); 01396 for (i = 0; i < no_cols; i++) { 01397 for (j = 0; j < no_rows; j++) 01398 data[pos+j] -= m.data[m_pos+j]; 01399 // next column 01400 m_pos += m.no_rows; 01401 pos += no_rows; 01402 } 01403 } 01404 return *this; 01405 } 01406 01407 template<class Num_T> 01408 Mat<Num_T> operator-(const Mat<Num_T> &m1, const Mat<Num_T> &m2) 01409 { 01410 Mat<Num_T> r(m1.no_rows, m1.no_cols); 01411 int i, j, m1_pos = 0, m2_pos = 0, r_pos = 0; 01412 it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_cols == m2.no_cols), 01413 "Mat<>::operator-(): Wrong sizes"); 01414 01415 for (i = 0; i < r.no_cols; i++) { 01416 for (j = 0; j < r.no_rows; j++) 01417 r.data[r_pos+j] = m1.data[m1_pos+j] - m2.data[m2_pos+j]; 01418 // next column 01419 m1_pos += m1.no_rows; 01420 m2_pos += m2.no_rows; 01421 r_pos += r.no_rows; 01422 } 01423 01424 return r; 01425 } 01426 01427 template<class Num_T> inline 01428 Mat<Num_T>& Mat<Num_T>::operator-=(Num_T t) 01429 { 01430 for (int i = 0; i < datasize; i++) 01431 data[i] -= t; 01432 return *this; 01433 } 01434 01435 template<class Num_T> 01436 Mat<Num_T> operator-(const Mat<Num_T> &m, Num_T t) 01437 { 01438 Mat<Num_T> r(m.no_rows, m.no_cols); 01439 int i, j, m_pos = 0, r_pos = 0; 01440 01441 for (i = 0; i < r.no_cols; i++) { 01442 for (j = 0; j < r.no_rows; j++) 01443 r.data[r_pos+j] = m.data[m_pos+j] - t; 01444 // next column 01445 m_pos += m.no_rows; 01446 r_pos += r.no_rows; 01447 } 01448 01449 return r; 01450 } 01451 01452 template<class Num_T> 01453 Mat<Num_T> operator-(Num_T t, const Mat<Num_T> &m) 01454 { 01455 Mat<Num_T> r(m.no_rows, m.no_cols); 01456 int i, j, m_pos = 0, r_pos = 0; 01457 01458 for (i = 0; i < r.no_cols; i++) { 01459 for (j = 0; j < r.no_rows; j++) 01460 r.data[r_pos+j] = t - m.data[m_pos+j]; 01461 // next column 01462 m_pos += m.no_rows; 01463 r_pos += r.no_rows; 01464 } 01465 01466 return r; 01467 } 01468 01469 template<class Num_T> 01470 Mat<Num_T> operator-(const Mat<Num_T> &m) 01471 { 01472 Mat<Num_T> r(m.no_rows, m.no_cols); 01473 int i, j, m_pos = 0, r_pos = 0; 01474 01475 for (i = 0; i < r.no_cols; i++) { 01476 for (j = 0; j < r.no_rows; j++) 01477 r.data[r_pos+j] = -m.data[m_pos+j]; 01478 // next column 01479 m_pos += m.no_rows; 01480 r_pos += r.no_rows; 01481 } 01482 01483 return r; 01484 } 01485 01486 #if defined(HAVE_BLAS) 01487 template<> mat& mat::operator*=(const mat &m); 01488 template<> cmat& cmat::operator*=(const cmat &m); 01489 #endif 01490 01491 template<class Num_T> 01492 Mat<Num_T>& Mat<Num_T>::operator*=(const Mat<Num_T> &m) 01493 { 01494 it_assert_debug(no_cols == m.no_rows, "Mat<>::operator*=(): Wrong sizes"); 01495 Mat<Num_T> r(no_rows, m.no_cols); 01496 01497 Num_T tmp; 01498 01499 int i, j, k, r_pos = 0, pos = 0, m_pos = 0; 01500 01501 for (i = 0; i < r.no_cols; i++) { 01502 for (j = 0; j < r.no_rows; j++) { 01503 tmp = Num_T(0); 01504 pos = 0; 01505 for (k = 0; k < no_cols; k++) { 01506 tmp += data[pos+j] * m.data[m_pos+k]; 01507 pos += no_rows; 01508 } 01509 r.data[r_pos+j] = tmp; 01510 } 01511 r_pos += r.no_rows; 01512 m_pos += m.no_rows; 01513 } 01514 operator=(r); // time consuming 01515 return *this; 01516 } 01517 01518 template<class Num_T> inline 01519 Mat<Num_T>& Mat<Num_T>::operator*=(Num_T t) 01520 { 01521 scal_vector(datasize, t, data); 01522 return *this; 01523 } 01524 01525 #if defined(HAVE_BLAS) 01526 template<> mat operator*(const mat &m1, const mat &m2); 01527 template<> cmat operator*(const cmat &m1, const cmat &m2); 01528 #endif 01529 01530 01531 template<class Num_T> 01532 Mat<Num_T> operator*(const Mat<Num_T> &m1, const Mat<Num_T> &m2) 01533 { 01534 it_assert_debug(m1.no_cols == m2.no_rows, 01535 "Mat<>::operator*(): Wrong sizes"); 01536 Mat<Num_T> r(m1.no_rows, m2.no_cols); 01537 01538 Num_T tmp; 01539 int i, j, k; 01540 Num_T *tr = r.data, *t1, *t2 = m2.data; 01541 01542 for (i = 0; i < r.no_cols; i++) { 01543 for (j = 0; j < r.no_rows; j++) { 01544 tmp = Num_T(0); 01545 t1 = m1.data + j; 01546 for (k = m1.no_cols; k > 0; k--) { 01547 tmp += *(t1) * *(t2++); 01548 t1 += m1.no_rows; 01549 } 01550 *(tr++) = tmp; 01551 t2 -= m2.no_rows; 01552 } 01553 t2 += m2.no_rows; 01554 } 01555 01556 return r; 01557 } 01558 01559 #if defined(HAVE_BLAS) 01560 template<> vec operator*(const mat &m, const vec &v); 01561 template<> cvec operator*(const cmat &m, const cvec &v); 01562 #endif 01563 01564 template<class Num_T> 01565 Vec<Num_T> operator*(const Mat<Num_T> &m, const Vec<Num_T> &v) 01566 { 01567 it_assert_debug(m.no_cols == v.size(), 01568 "Mat<>::operator*(): Wrong sizes"); 01569 Vec<Num_T> r(m.no_rows); 01570 int i, k, m_pos; 01571 01572 for (i = 0; i < m.no_rows; i++) { 01573 r(i) = Num_T(0); 01574 m_pos = 0; 01575 for (k = 0; k < m.no_cols; k++) { 01576 r(i) += m.data[m_pos+i] * v(k); 01577 m_pos += m.no_rows; 01578 } 01579 } 01580 01581 return r; 01582 } 01583 01584 template<class Num_T> 01585 Mat<Num_T> operator*(const Vec<Num_T> &v, const Mat<Num_T> &m) 01586 { 01587 it_assert((m.no_rows == 1), "Mat<Num_T>::operator*(): wrong sizes"); 01588 it_warning("Mat<Num_T>::operator*(v, m): This operator is deprecated. " 01589 "Please use outer_product(v, m.get_row(0)) instead."); 01590 return outer_product(v, m.get_row(0)); 01591 } 01592 01593 template<class Num_T> 01594 Mat<Num_T> operator*(const Mat<Num_T> &m, Num_T t) 01595 { 01596 Mat<Num_T> r(m.no_rows, m.no_cols); 01597 01598 for (int i = 0; i < r.datasize; i++) 01599 r.data[i] = m.data[i] * t; 01600 01601 return r; 01602 } 01603 01604 template<class Num_T> inline 01605 Mat<Num_T> operator*(Num_T t, const Mat<Num_T> &m) 01606 { 01607 return operator*(m, t); 01608 } 01609 01610 template<class Num_T> inline 01611 Mat<Num_T> elem_mult(const Mat<Num_T> &m1, const Mat<Num_T> &m2) 01612 { 01613 Mat<Num_T> out; 01614 elem_mult_out(m1, m2, out); 01615 return out; 01616 } 01617 01618 template<class Num_T> 01619 void elem_mult_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2, 01620 Mat<Num_T> &out) 01621 { 01622 it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_cols == m2.no_cols), 01623 "Mat<>::elem_mult_out(): Wrong sizes"); 01624 out.set_size(m1.no_rows, m1.no_cols); 01625 for (int i = 0; i < out.datasize; i++) 01626 out.data[i] = m1.data[i] * m2.data[i]; 01627 } 01628 01629 template<class Num_T> 01630 void elem_mult_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2, 01631 const Mat<Num_T> &m3, Mat<Num_T> &out) 01632 { 01633 it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_rows == m3.no_rows) 01634 && (m1.no_cols == m2.no_cols) && (m1.no_cols == m3.no_cols), 01635 "Mat<>::elem_mult_out(): Wrong sizes"); 01636 out.set_size(m1.no_rows, m1.no_cols); 01637 for (int i = 0; i < out.datasize; i++) 01638 out.data[i] = m1.data[i] * m2.data[i] * m3.data[i]; 01639 } 01640 01641 template<class Num_T> 01642 void elem_mult_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2, 01643 const Mat<Num_T> &m3, const Mat<Num_T> &m4, 01644 Mat<Num_T> &out) 01645 { 01646 it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_rows == m3.no_rows) 01647 && (m1.no_rows == m4.no_rows) && (m1.no_cols == m2.no_cols) 01648 && (m1.no_cols == m3.no_cols) && (m1.no_cols == m4.no_cols), 01649 "Mat<>::elem_mult_out(): Wrong sizes"); 01650 out.set_size(m1.no_rows, m1.no_cols); 01651 for (int i = 0; i < out.datasize; i++) 01652 out.data[i] = m1.data[i] * m2.data[i] * m3.data[i] * m4.data[i]; 01653 } 01654 01655 template<class Num_T> 01656 #ifndef _MSC_VER 01657 inline 01658 #endif 01659 void elem_mult_inplace(const Mat<Num_T> &m1, Mat<Num_T> &m2) 01660 { 01661 it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_cols == m2.no_cols), 01662 "Mat<>::elem_mult_inplace(): Wrong sizes"); 01663 for (int i = 0; i < m2.datasize; i++) 01664 m2.data[i] *= m1.data[i]; 01665 } 01666 01667 template<class Num_T> inline 01668 Num_T elem_mult_sum(const Mat<Num_T> &m1, const Mat<Num_T> &m2) 01669 { 01670 it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_cols == m2.no_cols), 01671 "Mat<>::elem_mult_sum(): Wrong sizes"); 01672 Num_T acc = 0; 01673 01674 for (int i = 0; i < m1.datasize; i++) 01675 acc += m1.data[i] * m2.data[i]; 01676 01677 return acc; 01678 } 01679 01680 template<class Num_T> inline 01681 Mat<Num_T>& Mat<Num_T>::operator/=(Num_T t) 01682 { 01683 for (int i = 0; i < datasize; i++) 01684 data[i] /= t; 01685 return *this; 01686 } 01687 01688 template<class Num_T> 01689 Mat<Num_T> operator/(const Mat<Num_T> &m, Num_T t) 01690 { 01691 Mat<Num_T> r(m.no_rows, m.no_cols); 01692 01693 for (int i = 0; i < r.datasize; i++) 01694 r.data[i] = m.data[i] / t; 01695 01696 return r; 01697 } 01698 01699 template<class Num_T> inline 01700 Mat<Num_T>& Mat<Num_T>::operator/=(const Mat<Num_T> &m) 01701 { 01702 it_assert_debug((m.no_rows == no_rows) && (m.no_cols == no_cols), 01703 "Mat<>::operator/=(): Wrong sizes"); 01704 for (int i = 0; i < datasize; i++) 01705 data[i] /= m.data[i]; 01706 return *this; 01707 } 01708 01709 template<class Num_T> inline 01710 Mat<Num_T> elem_div(const Mat<Num_T> &m1, const Mat<Num_T> &m2) 01711 { 01712 Mat<Num_T> out; 01713 elem_div_out(m1, m2, out); 01714 return out; 01715 } 01716 01717 template<class Num_T> 01718 void elem_div_out(const Mat<Num_T> &m1, const Mat<Num_T> &m2, 01719 Mat<Num_T> &out) 01720 { 01721 it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_cols == m2.no_cols), 01722 "Mat<>::elem_div_out(): Wrong sizes"); 01723 01724 if ((out.no_rows != m1.no_rows) || (out.no_cols != m1.no_cols)) 01725 out.set_size(m1.no_rows, m1.no_cols); 01726 01727 for (int i = 0; i < out.datasize; i++) 01728 out.data[i] = m1.data[i] / m2.data[i]; 01729 } 01730 01731 template<class Num_T> inline 01732 Num_T elem_div_sum(const Mat<Num_T> &m1, const Mat<Num_T> &m2) 01733 { 01734 it_assert_debug((m1.no_rows == m2.no_rows) && (m1.no_cols == m2.no_cols), 01735 "Mat<>::elem_div_sum(): Wrong sizes"); 01736 Num_T acc = 0; 01737 01738 for (int i = 0; i < m1.datasize; i++) 01739 acc += m1.data[i] / m2.data[i]; 01740 01741 return acc; 01742 } 01743 01744 template<class Num_T> 01745 bool Mat<Num_T>::operator==(const Mat<Num_T> &m) const 01746 { 01747 if (no_rows != m.no_rows || no_cols != m.no_cols) return false; 01748 for (int i = 0;i < datasize;i++) { 01749 if (data[i] != m.data[i]) return false; 01750 } 01751 return true; 01752 } 01753 01754 template<class Num_T> 01755 bool Mat<Num_T>::operator!=(const Mat<Num_T> &m) const 01756 { 01757 if (no_rows != m.no_rows || no_cols != m.no_cols) return true; 01758 for (int i = 0;i < datasize;i++) { 01759 if (data[i] != m.data[i]) return true; 01760 } 01761 return false; 01762 } 01763 01764 template <class Num_T> 01765 std::ostream &operator<<(std::ostream &os, const Mat<Num_T> &m) 01766 { 01767 int i; 01768 01769 switch (m.rows()) { 01770 case 0 : 01771 os << "[]"; 01772 break; 01773 case 1 : 01774 os << '[' << m.get_row(0) << ']'; 01775 break; 01776 default: 01777 os << '[' << m.get_row(0) << std::endl; 01778 for (i = 1; i < m.rows() - 1; i++) 01779 os << ' ' << m.get_row(i) << std::endl; 01780 os << ' ' << m.get_row(m.rows() - 1) << ']'; 01781 } 01782 01783 return os; 01784 } 01785 01786 template <class Num_T> 01787 std::istream &operator>>(std::istream &is, Mat<Num_T> &m) 01788 { 01789 std::ostringstream buffer; 01790 bool started = false; 01791 bool finished = false; 01792 bool brackets = false; 01793 bool within_double_brackets = false; 01794 char c; 01795 01796 while (!finished) { 01797 if (is.eof()) { 01798 finished = true; 01799 } 01800 else { 01801 is.get(c); 01802 01803 if (is.eof() || (c == '\n')) { 01804 if (brackets) { 01805 // Right bracket missing 01806 is.setstate(std::ios_base::failbit); 01807 finished = true; 01808 } 01809 else if (!((c == '\n') && !started)) { 01810 finished = true; 01811 } 01812 } 01813 else if ((c == ' ') || (c == '\t')) { 01814 if (started) { 01815 buffer << ' '; 01816 } 01817 } 01818 else if (c == '[') { 01819 if ((started && !brackets) || within_double_brackets) { 01820 // Unexpected left bracket 01821 is.setstate(std::ios_base::failbit); 01822 finished = true; 01823 } 01824 else if (!started) { 01825 started = true; 01826 brackets = true; 01827 } 01828 else { 01829 within_double_brackets = true; 01830 } 01831 } 01832 else if (c == ']') { 01833 if (!started || !brackets) { 01834 // Unexpected right bracket 01835 is.setstate(std::ios_base::failbit); 01836 finished = true; 01837 } 01838 else if (within_double_brackets) { 01839 within_double_brackets = false; 01840 buffer << ';'; 01841 } 01842 else { 01843 finished = true; 01844 } 01845 while (!is.eof() && (((c = static_cast<char>(is.peek())) == ' ') 01846 || (c == '\t'))) { 01847 is.get(); 01848 } 01849 if (!is.eof() && (c == '\n')) { 01850 is.get(); 01851 } 01852 } 01853 else { 01854 started = true; 01855 buffer << c; 01856 } 01857 } 01858 } 01859 01860 if (!started) { 01861 m.set_size(0, false); 01862 } 01863 else { 01864 m.set(buffer.str()); 01865 } 01866 01867 return is; 01868 } 01869 01871 01872 // --------------------------------------------------------------------- 01873 // Instantiations 01874 // --------------------------------------------------------------------- 01875 01876 #ifdef HAVE_EXTERN_TEMPLATE 01877 01878 // class instantiations 01879 01880 extern template class Mat<double>; 01881 extern template class Mat<std::complex<double> >; 01882 extern template class Mat<int>; 01883 extern template class Mat<short int>; 01884 extern template class Mat<bin>; 01885 01886 // addition operators 01887 01888 extern template mat operator+(const mat &m1, const mat &m2); 01889 extern template cmat operator+(const cmat &m1, const cmat &m2); 01890 extern template imat operator+(const imat &m1, const imat &m2); 01891 extern template smat operator+(const smat &m1, const smat &m2); 01892 extern template bmat operator+(const bmat &m1, const bmat &m2); 01893 01894 extern template mat operator+(const mat &m, double t); 01895 extern template cmat operator+(const cmat &m, std::complex<double> t); 01896 extern template imat operator+(const imat &m, int t); 01897 extern template smat operator+(const smat &m, short t); 01898 extern template bmat operator+(const bmat &m, bin t); 01899 01900 extern template mat operator+(double t, const mat &m); 01901 extern template cmat operator+(std::complex<double> t, const cmat &m); 01902 extern template imat operator+(int t, const imat &m); 01903 extern template smat operator+(short t, const smat &m); 01904 extern template bmat operator+(bin t, const bmat &m); 01905 01906 // subtraction operators 01907 01908 extern template mat operator-(const mat &m1, const mat &m2); 01909 extern template cmat operator-(const cmat &m1, const cmat &m2); 01910 extern template imat operator-(const imat &m1, const imat &m2); 01911 extern template smat operator-(const smat &m1, const smat &m2); 01912 extern template bmat operator-(const bmat &m1, const bmat &m2); 01913 01914 extern template mat operator-(const mat &m, double t); 01915 extern template cmat operator-(const cmat &m, std::complex<double> t); 01916 extern template imat operator-(const imat &m, int t); 01917 extern template smat operator-(const smat &m, short t); 01918 extern template bmat operator-(const bmat &m, bin t); 01919 01920 extern template mat operator-(double t, const mat &m); 01921 extern template cmat operator-(std::complex<double> t, const cmat &m); 01922 extern template imat operator-(int t, const imat &m); 01923 extern template smat operator-(short t, const smat &m); 01924 extern template bmat operator-(bin t, const bmat &m); 01925 01926 // unary minus 01927 01928 extern template mat operator-(const mat &m); 01929 extern template cmat operator-(const cmat &m); 01930 extern template imat operator-(const imat &m); 01931 extern template smat operator-(const smat &m); 01932 extern template bmat operator-(const bmat &m); 01933 01934 // multiplication operators 01935 01936 #if !defined(HAVE_BLAS) 01937 extern template mat operator*(const mat &m1, const mat &m2); 01938 extern template cmat operator*(const cmat &m1, const cmat &m2); 01939 #endif 01940 extern template imat operator*(const imat &m1, const imat &m2); 01941 extern template smat operator*(const smat &m1, const smat &m2); 01942 extern template bmat operator*(const bmat &m1, const bmat &m2); 01943 01944 #if !defined(HAVE_BLAS) 01945 extern template vec operator*(const mat &m, const vec &v); 01946 extern template cvec operator*(const cmat &m, const cvec &v); 01947 #endif 01948 extern template ivec operator*(const imat &m, const ivec &v); 01949 extern template svec operator*(const smat &m, const svec &v); 01950 extern template bvec operator*(const bmat &m, const bvec &v); 01951 01952 extern template mat operator*(const vec &v, const mat &m); 01953 extern template cmat operator*(const cvec &v, const cmat &m); 01954 extern template imat operator*(const ivec &v, const imat &m); 01955 extern template smat operator*(const svec &v, const smat &m); 01956 extern template bmat operator*(const bvec &v, const bmat &m); 01957 01958 extern template mat operator*(const mat &m, double t); 01959 extern template cmat operator*(const cmat &m, std::complex<double> t); 01960 extern template imat operator*(const imat &m, int t); 01961 extern template smat operator*(const smat &m, short t); 01962 extern template bmat operator*(const bmat &m, bin t); 01963 01964 extern template mat operator*(double t, const mat &m); 01965 extern template cmat operator*(std::complex<double> t, const cmat &m); 01966 extern template imat operator*(int t, const imat &m); 01967 extern template smat operator*(short t, const smat &m); 01968 extern template bmat operator*(bin t, const bmat &m); 01969 01970 // element-wise multiplication 01971 01972 extern template mat elem_mult(const mat &m1, const mat &m2); 01973 extern template cmat elem_mult(const cmat &m1, const cmat &m2); 01974 extern template imat elem_mult(const imat &m1, const imat &m2); 01975 extern template smat elem_mult(const smat &m1, const smat &m2); 01976 extern template bmat elem_mult(const bmat &m1, const bmat &m2); 01977 01978 extern template void elem_mult_out(const mat &m1, const mat &m2, mat &out); 01979 extern template void elem_mult_out(const cmat &m1, const cmat &m2, 01980 cmat &out); 01981 extern template void elem_mult_out(const imat &m1, const imat &m2, 01982 imat &out); 01983 extern template void elem_mult_out(const smat &m1, const smat &m2, 01984 smat &out); 01985 extern template void elem_mult_out(const bmat &m1, const bmat &m2, 01986 bmat &out); 01987 01988 extern template void elem_mult_out(const mat &m1, const mat &m2, 01989 const mat &m3, mat &out); 01990 extern template void elem_mult_out(const cmat &m1, const cmat &m2, 01991 const cmat &m3, cmat &out); 01992 extern template void elem_mult_out(const imat &m1, const imat &m2, 01993 const imat &m3, imat &out); 01994 extern template void elem_mult_out(const smat &m1, const smat &m2, 01995 const smat &m3, smat &out); 01996 extern template void elem_mult_out(const bmat &m1, const bmat &m2, 01997 const bmat &m3, bmat &out); 01998 01999 extern template void elem_mult_out(const mat &m1, const mat &m2, 02000 const mat &m3, const mat &m4, mat &out); 02001 extern template void elem_mult_out(const cmat &m1, const cmat &m2, 02002 const cmat &m3, const cmat &m4, 02003 cmat &out); 02004 extern template void elem_mult_out(const imat &m1, const imat &m2, 02005 const imat &m3, const imat &m4, 02006 imat &out); 02007 extern template void elem_mult_out(const smat &m1, const smat &m2, 02008 const smat &m3, const smat &m4, 02009 smat &out); 02010 extern template void elem_mult_out(const bmat &m1, const bmat &m2, 02011 const bmat &m3, const bmat &m4, 02012 bmat &out); 02013 02014 extern template void elem_mult_inplace(const mat &m1, mat &m2); 02015 extern template void elem_mult_inplace(const cmat &m1, cmat &m2); 02016 extern template void elem_mult_inplace(const imat &m1, imat &m2); 02017 extern template void elem_mult_inplace(const smat &m1, smat &m2); 02018 extern template void elem_mult_inplace(const bmat &m1, bmat &m2); 02019 02020 extern template double elem_mult_sum(const mat &m1, const mat &m2); 02021 extern template std::complex<double> elem_mult_sum(const cmat &m1, 02022 const cmat &m2); 02023 extern template int elem_mult_sum(const imat &m1, const imat &m2); 02024 extern template short elem_mult_sum(const smat &m1, const smat &m2); 02025 extern template bin elem_mult_sum(const bmat &m1, const bmat &m2); 02026 02027 // division operator 02028 02029 extern template mat operator/(const mat &m, double t); 02030 extern template cmat operator/(const cmat &m, std::complex<double> t); 02031 extern template imat operator/(const imat &m, int t); 02032 extern template smat operator/(const smat &m, short t); 02033 extern template bmat operator/(const bmat &m, bin t); 02034 02035 // element-wise division 02036 02037 extern template mat elem_div(const mat &m1, const mat &m2); 02038 extern template cmat elem_div(const cmat &m1, const cmat &m2); 02039 extern template imat elem_div(const imat &m1, const imat &m2); 02040 extern template smat elem_div(const smat &m1, const smat &m2); 02041 extern template bmat elem_div(const bmat &m1, const bmat &m2); 02042 02043 extern template void elem_div_out(const mat &m1, const mat &m2, mat &out); 02044 extern template void elem_div_out(const cmat &m1, const cmat &m2, cmat &out); 02045 extern template void elem_div_out(const imat &m1, const imat &m2, imat &out); 02046 extern template void elem_div_out(const smat &m1, const smat &m2, smat &out); 02047 extern template void elem_div_out(const bmat &m1, const bmat &m2, bmat &out); 02048 02049 extern template double elem_div_sum(const mat &m1, const mat &m2); 02050 extern template std::complex<double> elem_div_sum(const cmat &m1, 02051 const cmat &m2); 02052 extern template int elem_div_sum(const imat &m1, const imat &m2); 02053 extern template short elem_div_sum(const smat &m1, const smat &m2); 02054 extern template bin elem_div_sum(const bmat &m1, const bmat &m2); 02055 02056 // concatenation 02057 02058 extern template mat concat_horizontal(const mat &m1, const mat &m2); 02059 extern template cmat concat_horizontal(const cmat &m1, const cmat &m2); 02060 extern template imat concat_horizontal(const imat &m1, const imat &m2); 02061 extern template smat concat_horizontal(const smat &m1, const smat &m2); 02062 extern template bmat concat_horizontal(const bmat &m1, const bmat &m2); 02063 02064 extern template mat concat_vertical(const mat &m1, const mat &m2); 02065 extern template cmat concat_vertical(const cmat &m1, const cmat &m2); 02066 extern template imat concat_vertical(const imat &m1, const imat &m2); 02067 extern template smat concat_vertical(const smat &m1, const smat &m2); 02068 extern template bmat concat_vertical(const bmat &m1, const bmat &m2); 02069 02070 // I/O streams 02071 02072 extern template std::ostream &operator<<(std::ostream &os, const mat &m); 02073 extern template std::ostream &operator<<(std::ostream &os, const cmat &m); 02074 extern template std::ostream &operator<<(std::ostream &os, const imat &m); 02075 extern template std::ostream &operator<<(std::ostream &os, const smat &m); 02076 extern template std::ostream &operator<<(std::ostream &os, const bmat &m); 02077 02078 extern template std::istream &operator>>(std::istream &is, mat &m); 02079 extern template std::istream &operator>>(std::istream &is, cmat &m); 02080 extern template std::istream &operator>>(std::istream &is, imat &m); 02081 extern template std::istream &operator>>(std::istream &is, smat &m); 02082 extern template std::istream &operator>>(std::istream &is, bmat &m); 02083 02084 #endif // HAVE_EXTERN_TEMPLATE 02085 02087 02088 } // namespace itpp 02089 02090 #endif // #ifndef MAT_H
Generated on Tue Nov 23 08:47:56 2010 for IT++ by Doxygen 1.6.1