00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00016
00017
00029 #ifndef _matrixh
00030 #define _matrixh
00031
00032 #include <spuc.h>
00033 #include <iostream>
00034 #include <string>
00035 #include <cstdlib>
00036 #include <cstring>
00037 #include <spucconfig.h>
00038 #include <binary.h>
00039 #include <vector.h>
00040 #include <cmath>
00041
00042
00043 #ifdef HAVE_CBLAS
00044 #include "base/cblas.h"
00045 #endif
00046
00047 #ifdef XXX
00048 using std::cout;
00049 using std::endl;
00050 using std::string;
00051 using std::ostream;
00052 using std::istream;
00053 using std::istringstream;
00054 using std::getline;
00055 using std::swap;
00056 #endif
00057
00058 namespace SPUC {
00059
00061 #define minimum(x,y) (((x)<(y)) ? (x) : (y))
00062 #define Matrix Mat
00063
00064 template<class T> class Vec;
00065 template<class T> class Mat;
00066 class bin;
00067
00068
00069
00071 template<class T> Mat<T> concat_horizontal(const Mat<T> &m1, const Mat<T> &m2);
00073 template<class T> Mat<T> concat_vertical(const Mat<T> &m1, const Mat<T> &m2);
00075 template<class T> Mat<T> operator+(const Mat<T> &m1, const Mat<T> &m2);
00077 template<class T> Mat<T> operator+(const Mat<T> &m, T t);
00079 template<class T> Mat<T> operator+(T t, const Mat<T> &m);
00081 template<class T> Mat<T> operator-(const Mat<T> &m1, const Mat<T> &m2);
00083 template<class T> Mat<T> operator-(const Mat<T> &m, T t);
00085 template<class T> Mat<T> operator-(T t, const Mat<T> &m);
00087 template<class T> Mat<T> operator-(const Mat<T> &m);
00089 template<class T> Mat<T> operator*(const Mat<T> &m1, const Mat<T> &m2);
00091 template<class T> Vec<T> operator*(const Mat<T> &m, const Vec<T> &v);
00093 template<class T> Vec<T> operator*(const Vec<T> &v, const Mat<T> &m);
00095 template<class T> Mat<T> operator*(const Mat<T> &m, T t);
00097 template<class T> Mat<T> operator*(T t, const Mat<T> &m);
00099 template<class T> Mat<T> elem_mult(const Mat<T> &m1, const Mat<T> &m2);
00101 template<class T> Mat<T> operator/(const Mat<T> &m, T t);
00103 template<class T> Mat<T> elem_div(const Mat<T> &m1, const Mat<T> &m2);
00104
00162 template<class T>
00163 class Mat {
00164 public:
00166 Mat() { init(); }
00168 Mat(int inrow, int incol) {
00169 init();
00170
00171 alloc(inrow, incol); }
00173 Mat(const Mat<T> &m);
00175 Mat(const Vec<T> &invector);
00179 Mat(const char *str) { init(); set(str); }
00180
00187 Mat(T *c_array, int rows, int cols, bool RowMajor = true);
00188
00190 ~Mat() { free(); }
00191
00193 int cols() const { return no_cols; }
00195 int rows() const { return no_rows; }
00197 void set_size(int inrow, int incol, bool copy=false);
00199 void zeros();
00201 void clear() { zeros(); }
00203 void ones();
00205 bool set(const char *str);
00208
00210 const T &operator()(int R,int C) const
00211 {
00212
00213 return data[R+C*no_rows]; }
00215 T &operator()(int R,int C)
00216 {
00217
00218 return data[R+C*no_rows]; }
00220 T &operator()(int index)
00221 {
00222
00223 return data[index]; }
00225 const T &operator()(int index) const
00226 {
00227
00228 return data[index]; }
00229
00235 const Mat<T> operator()(int r1, int r2, int c1, int c2) const;
00236
00238 Vec<T> get_row(int Index) const ;
00240 Mat<T> get_rows(int r1, int r2) const;
00242 Mat<T> get_rows(const Vec<int> &indexlist) const;
00244 Vec<T> get_col(int Index) const ;
00246 Mat<T> get_cols(int c1, int c2) const;
00248 Mat<T> get_cols(const Vec<int> &indexlist) const;
00250 void set_row(int Index, const Vec<T> &invector);
00252 void set_col(int Index, const Vec<T> &invector);
00254 void copy_row(int to, int from);
00256 void copy_col(int to, int from);
00258 void swap_rows(int r1, int r2);
00260 void swap_cols(int c1, int c2);
00261
00263 void set_submatrix(int r1, int r2, int c1, int c2, const Mat<T> &m);
00265 void set_submatrix(int r1, int r2, int c1, int c2, const T t);
00266
00268 friend Mat<T> concat_horizontal TEMPLATE_FUN(const Mat<T> &m1, const Mat<T> &m2);
00270 friend Mat<T> concat_vertical TEMPLATE_FUN(const Mat<T> &m1, const Mat<T> &m2);
00271
00273 void operator=(T t);
00275 void operator=(const Mat<T> &m);
00277 void operator=(const Vec<T> &v);
00279 void operator=(const char *values) { set(values); }
00280
00282 void operator+=(const Mat<T> &m);
00284 void operator+=(T t);
00286 friend Mat<T> operator+TEMPLATE_FUN(const Mat<T> &m1, const Mat<T> &m2);
00288 friend Mat<T> operator+TEMPLATE_FUN(const Mat<T> &m, T t);
00290 friend Mat<T> operator+TEMPLATE_FUN(T t, const Mat<T> &m);
00291
00293 void operator-=(const Mat<T> &m);
00295 void operator-=(T t);
00297 friend Mat<T> operator-TEMPLATE_FUN(const Mat<T> &m1, const Mat<T> &m2);
00299 friend Mat<T> operator-TEMPLATE_FUN(const Mat<T> &m, T t);
00301 friend Mat<T> operator-TEMPLATE_FUN(T t, const Mat<T> &m);
00303 friend Mat<T> operator-TEMPLATE_FUN(const Mat<T> &m);
00304
00306 void operator*=(const Mat<T> &m);
00308 void operator*=(T t);
00310 friend Mat<T> operator*TEMPLATE_FUN(const Mat<T> &m1, const Mat<T> &m2);
00312 friend Vec<T> operator*TEMPLATE_FUN(const Mat<T> &m, const Vec<T> &v);
00314 friend Vec<T> operator*TEMPLATE_FUN(const Vec<T> &v, const Mat<T> &m);
00316 friend Mat<T> operator*TEMPLATE_FUN(const Mat<T> &m, T t);
00318 friend Mat<T> operator*TEMPLATE_FUN(T t, const Mat<T> &m);
00320 friend Mat<T> elem_mult TEMPLATE_FUN(const Mat<T> &m1, const Mat<T> &m2);
00321
00323 void operator/=(T t);
00325 friend Mat<T> operator/TEMPLATE_FUN(const Mat<T> &m, T t);
00327 void operator/=(const Mat<T> &m);
00329 friend Mat<T> elem_div TEMPLATE_FUN(const Mat<T> &m1, const Mat<T> &m2);
00330
00332 bool operator==(const Mat<T> &m) const;
00334 bool operator!=(const Mat<T> &m) const;
00335
00337 T &_elem(int R,int C) { return data[R+C*no_rows]; }
00339 const T &_elem(int R,int C) const { return data[R+C*no_rows]; }
00341 T &_elem(int index) { return data[index]; }
00343 const T &_elem(int index) const { return data[index]; }
00344
00346 T *_data() { return data; }
00348 const T *_data() const { return data; }
00350 int _datasize() const { return datasize; }
00351
00352 protected:
00354 void alloc(int rows, int cols)
00355 {
00356 if ( datasize == rows * cols ) {
00357 no_rows = rows; no_cols = cols;
00358 return;
00359 }
00360 free();
00361 if (rows == 0 || cols == 0)
00362 return;
00363
00364 datasize = rows * cols;
00365 data = new T[datasize];
00366 no_rows = rows; no_cols = cols;
00367
00368
00369 }
00370
00372 void free() { delete [] data; init(); }
00373
00375 int datasize, no_rows, no_cols;
00376
00378 T *data;
00379
00380 private:
00381 void init()
00382 {
00383 data = 0;
00384 datasize = no_rows = no_cols = 0;
00385 }
00386 };
00387
00388
00389
00394 #ifdef XXX
00395 template <class T>
00396 std::ostream &operator<<(std::ostream &os, const Mat<T> &m);
00397
00402 template <class T>
00403 std::istream &operator>>(std::istream &is, Mat<T> &m);
00404 #endif
00405
00409 typedef Mat<double> mat;
00410
00415 typedef Mat<complex<double> > cmat;
00416
00421 typedef Mat<int> imat;
00422
00427 typedef Mat<long_long> llmat;
00428
00433 typedef Mat<short int> smat;
00434
00439 typedef Mat<bin> bmat;
00440
00441
00442
00443
00444 template<class T> inline
00445 Mat<T>::Mat(T *c_array, int rows, int cols, bool RowMajor)
00446 {
00447 init();
00448 alloc(rows, cols);
00449
00450 if (!RowMajor)
00451 memcpy(data, c_array, datasize*sizeof(T));
00452 else {
00453 T *ptr = c_array;
00454 for (int i=0; i<rows; i++) {
00455 for (int j=0; j<cols; j++)
00456 data[i+j*no_rows] = *(ptr++);
00457 }
00458 }
00459 }
00460
00461
00462 template<class T> inline
00463 const Mat<T> Mat<T>::operator()(int r1, int r2, int c1, int c2) const
00464 {
00465 if (r1 == -1) r1 = no_rows-1;
00466 if (r2 == -1) r2 = no_rows-1;
00467 if (c1 == -1) c1 = no_cols-1;
00468 if (c2 == -1) c2 = no_cols-1;
00469
00470
00471
00472
00473
00474
00475 Mat<T> s(r2-r1+1, c2-c1+1);
00476
00477 for (int i=0;i<s.no_cols;i++)
00478 memcpy(s.data+i*s.no_rows, data+r1+(c1+i)*no_rows, s.no_rows*sizeof(T));
00479
00480 return s;
00481 }
00482
00483 template<class T> inline
00484 Mat<T>::Mat(const Mat<T> &m)
00485 {
00486 init();
00487 alloc(m.no_rows, m.no_cols);
00488 copy_vector(m.datasize, m.data, data);
00489 }
00490
00491 template<class T> inline
00492 Mat<T>::Mat(const Vec<T> &v)
00493 {
00494 init();
00495 set_size(v.length(), 1, false);
00496 set_col(0,v);
00497 }
00498
00499 template<class T> inline
00500 void Mat<T>::set_size(int inrow, int incol, bool copy)
00501 {
00502
00503 if (no_rows!=inrow || no_cols!=incol) {
00504 if (copy) {
00505 Mat<T> temp(*this);
00506 int i, j;
00507
00508 alloc(inrow, incol);
00509 for (i=0;i<inrow;i++)
00510 for (j=0;j<incol;j++)
00511 data[i+j*inrow] = (i<temp.no_rows && j<temp.no_cols) ? temp(i,j) : T(0);
00512 } else
00513 alloc(inrow, incol);
00514 }
00515 }
00516
00517 template<class T> inline
00518 void Mat<T>::zeros()
00519 {
00520 for(int i=0; i<datasize; i++)
00521 data[i] = T(0);
00522 }
00523
00524 template<class T> inline
00525 void Mat<T>::ones()
00526 {
00527 for(int i=0; i<datasize; i++)
00528 data[i] = T(1);
00529 }
00530
00531 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00532
00533 #ifdef XXX
00534 template<>
00535 bool bmat::set(const char *values)
00536 {
00537 istringstream buffer(values);
00538 int rows=0, maxrows=10, cols=0, nocols=0, maxcols=10;
00539 short intemp;
00540
00541 alloc(maxrows, maxcols);
00542
00543 while(buffer.peek()!=EOF) {
00544 rows++;
00545 if (rows > maxrows) {
00546 maxrows *= 2;
00547 set_size(maxrows, maxcols, true);
00548 }
00549 cols=0;
00550 while(buffer.peek() != ';' && !buffer.eof()) {
00551 if (buffer.peek()==',') {
00552 buffer.get();
00553 } else {
00554 cols++;
00555 if (cols > nocols) {
00556 nocols=cols;
00557 if (cols > maxcols) {
00558 maxcols=maxcols*2;
00559 set_size(maxrows, maxcols, true);
00560 }
00561 }
00562 buffer >> intemp;
00563 this->operator()(rows-1,cols-1)=intemp;
00564 }
00565 }
00566 if (!buffer.eof())
00567 buffer.get();
00568 }
00569 set_size(rows, nocols, true);
00570
00571 return true;
00572 }
00573 #endif
00574 #ifdef _MSC_VER
00575 #ifdef XZZ
00576 template<>
00577 bool llmat::set(const char *values)
00578 {
00579
00580 return false;
00581 }
00582 #endif
00583 #endif
00584
00585 #endif
00586
00587 template<class T>
00588 bool Mat<T>::set(const char *values)
00589 {
00590 istringstream buffer(values);
00591 int rows=0, maxrows=10, cols=0, nocols=0, maxcols=10;
00592
00593 alloc(maxrows, maxcols);
00594
00595 while(buffer.peek()!=EOF) {
00596 rows++;
00597 if (rows > maxrows) {
00598 maxrows=maxrows*2;
00599 set_size(maxrows, maxcols, true);
00600 }
00601
00602 cols=0;
00603 while(buffer.peek() != ';' && !buffer.eof()) {
00604 if (buffer.peek()==',') {
00605 buffer.get();
00606 } else {
00607 cols++;
00608 if (cols > nocols) {
00609 nocols=cols;
00610 if (cols > maxcols) {
00611 maxcols=maxcols*2;
00612 set_size(maxrows, maxcols, true);
00613 }
00614 }
00615 buffer >> this->operator()(rows-1,cols-1);
00616 }
00617 }
00618
00619 if (!buffer.eof())
00620 buffer.get();
00621 }
00622 set_size(rows, nocols, true);
00623
00624 return true;
00625 }
00626 #ifdef XXX
00627 template<class T>
00628 bool Mat<T>::set(const std::string &str)
00629 {
00630 return set(str.c_str());
00631 }
00632 #endif
00633 template<class T> inline
00634 Vec<T> Mat<T>::get_row(int Index) const
00635 {
00636
00637 Vec<T> a(no_cols);
00638
00639 copy_vector(no_cols, data+Index, no_rows, a._data(), 1);
00640 return a;
00641 }
00642
00643 template<class T>
00644 Mat<T> Mat<T>::get_rows(int r1, int r2) const
00645 {
00646
00647 Mat<T> m(r2-r1+1, no_cols);
00648
00649 for (int i=0; i<m.rows(); i++)
00650 copy_vector(no_cols, data+i+r1, no_rows, m.data+i, m.no_rows);
00651
00652 return m;
00653 }
00654
00655 template<class T>
00656 Mat<T> Mat<T>::get_rows(const Vec<int> &indexlist) const
00657 {
00658 Mat<T> m(indexlist.size(),no_cols);
00659
00660 for (int i=0;i<indexlist.size();i++) {
00661
00662 copy_vector(no_cols, data+indexlist(i), no_rows, m.data+i, m.no_rows);
00663 }
00664
00665 return m;
00666 }
00667
00668 template<class T> inline
00669 Vec<T> Mat<T>::get_col(int Index) const
00670 {
00671
00672 Vec<T> a(no_rows);
00673
00674 copy_vector(no_rows, data+Index*no_rows, a._data());
00675
00676 return a;
00677 }
00678
00679 template<class T> inline
00680 Mat<T> Mat<T>::get_cols(int c1, int c2) const
00681 {
00682
00683 Mat<T> m(no_rows, c2-c1+1);
00684
00685 for (int i=0; i<m.cols(); i++)
00686 copy_vector(no_rows, data+(i+c1)*no_rows, m.data+i*m.no_rows);
00687
00688 return m;
00689 }
00690
00691 template<class T> inline
00692 Mat<T> Mat<T>::get_cols(const Vec<int> &indexlist) const
00693 {
00694 Mat<T> m(no_rows,indexlist.size());
00695
00696 for (int i=0; i<indexlist.size(); i++) {
00697
00698 copy_vector(no_rows, data+indexlist(i)*no_rows, m.data+i*m.no_rows);
00699 }
00700
00701 return m;
00702 }
00703
00704 template<class T> inline
00705 void Mat<T>::set_row(int Index, const Vec<T> &v)
00706 {
00707
00708
00709
00710 copy_vector(v.size(), v._data(), 1, data+Index, no_rows);
00711 }
00712
00713 template<class T> inline
00714 void Mat<T>::set_col(int Index, const Vec<T> &v)
00715 {
00716
00717
00718
00719 copy_vector(v.size(), v._data(), data+Index*no_rows);
00720 }
00721
00722 template<class T> inline
00723 void Mat<T>::copy_row(int to, int from)
00724 {
00725
00726
00727
00728 if (from == to)
00729 return;
00730
00731 copy_vector(no_cols, data+from, no_rows, data+to, no_rows);
00732 }
00733
00734 template<class T> inline
00735 void Mat<T>::copy_col(int to, int from)
00736 {
00737
00738
00739
00740 if (from == to)
00741 return;
00742
00743 copy_vector(no_rows, data+from*no_rows, data+to*no_rows);
00744 }
00745
00746 template<class T> inline
00747 void Mat<T>::swap_rows(int r1, int r2)
00748 {
00749
00750
00751
00752 if (r1 == r2)
00753 return;
00754
00755 swap_vector(no_cols, data+r1, no_rows, data+r2, no_rows);
00756 }
00757
00758 template<class T> inline
00759 void Mat<T>::swap_cols(int c1, int c2)
00760 {
00761
00762
00763
00764 if (c1 == c2)
00765 return;
00766
00767 swap_vector(no_rows, data+c1*no_rows, data+c2*no_rows);
00768 }
00769
00770 template<class T> inline
00771 void Mat<T>::set_submatrix(int r1, int r2, int c1, int c2, const Mat<T> &m)
00772 {
00773
00774 if (r1 == -1) r1 = no_rows-1;
00775 if (r2 == -1) r2 = no_rows-1;
00776 if (c1 == -1) c1 = no_cols-1;
00777 if (c2 == -1) c2 = no_cols-1;
00778
00779
00780
00781
00782
00783
00784
00785 for (int i=0; i<m.no_cols; i++)
00786 copy_vector(m.no_rows, m.data+i*m.no_rows, data+(c1+i)*no_rows+r1);
00787 }
00788
00789 template<class T> inline
00790 void Mat<T>::set_submatrix(int r1, int r2, int c1, int c2, const T t)
00791 {
00792
00793 if (r1 == -1) r1 = no_rows-1;
00794 if (r2 == -1) r2 = no_rows-1;
00795 if (c1 == -1) c1 = no_cols-1;
00796 if (c2 == -1) c2 = no_cols-1;
00797
00798
00799
00800
00801
00802
00803 int i, j, pos, rows = r2-r1+1;
00804
00805 for (i=c1; i<=c2; i++) {
00806 pos = i*no_rows+r1;
00807 for (j=0; j<rows; j++) {
00808 data[pos++] = t;
00809 }
00810 }
00811 }
00812
00813 template<class T>
00814 Mat<T> concat_horizontal(const Mat<T> &m1, const Mat<T> &m2)
00815 {
00816
00817
00818 Mat<T> temp(m1.no_rows, m1.no_cols+m2.no_cols);
00819 int i;
00820
00821 for (i=0; i<m1.no_cols; i++) {
00822 temp.set_col(i, m1.get_col(i));
00823 }
00824 for (i=0; i<m2.no_cols; i++) {
00825 temp.set_col(i+m1.no_cols, m2.get_col(i));
00826 }
00827
00828 return temp;
00829 }
00830
00831 template<class T>
00832 Mat<T> concat_vertical(const Mat<T> &m1, const Mat<T> &m2)
00833 {
00834
00835
00836 Mat<T> temp(m1.no_rows+m2.no_rows, m1.no_cols);
00837 int i;
00838
00839 for (i=0; i<m1.no_rows; i++) {
00840 temp.set_row(i, m1.get_row(i));
00841 }
00842 for (i=0; i<m2.no_rows; i++) {
00843 temp.set_row(i+m1.no_rows, m2.get_row(i));
00844 }
00845
00846 return temp;
00847 }
00848
00849 template<class T> inline
00850 void Mat<T>::operator=(T t)
00851 {
00852 for (int i=0; i<datasize; i++)
00853 data[i] = t;
00854 }
00855
00856 template<class T> inline
00857 void Mat<T>::operator=(const Mat<T> &m)
00858 {
00859 set_size(m.no_rows,m.no_cols, false);
00860 if (m.datasize == 0) return;
00861
00862 copy_vector(m.datasize, m.data, data);
00863 }
00864
00865 template<class T> inline
00866 void Mat<T>::operator=(const Vec<T> &v)
00867 {
00868
00869
00870
00871
00872 set_size(v.size(), 1, false);
00873 set_col(0, v);
00874 }
00875
00876
00877
00878 template<class T> inline
00879 void Mat<T>::operator+=(const Mat<T> &m)
00880 {
00881 if (datasize == 0)
00882 operator=(m);
00883 else {
00884 int i, j, m_pos=0, pos=0;
00885
00886 for (i=0; i<no_cols; i++) {
00887 for (j=0; j<no_rows; j++)
00888 data[pos+j] += m.data[m_pos+j];
00889 pos += no_rows;
00890 m_pos += m.no_rows;
00891 }
00892 }
00893 }
00894
00895 template<class T> inline
00896 Mat<T> operator+(const Mat<T> &m1, const Mat<T> &m2)
00897 {
00898 Mat<T> r(m1.no_rows, m1.no_cols);
00899 int i, j, m1_pos=0, m2_pos=0, r_pos=0;
00900
00901
00902
00903 for (i=0; i<r.no_cols; i++) {
00904 for (j=0; j<r.no_rows; j++)
00905 r.data[r_pos+j] = m1.data[m1_pos+j] + m2.data[m2_pos+j];
00906
00907 m1_pos += m1.no_rows;
00908 m2_pos += m2.no_rows;
00909 r_pos += r.no_rows;
00910 }
00911
00912 return r;
00913 }
00914
00915 template<class T> inline
00916 void Mat<T>::operator+=(T t)
00917 {
00918 for (int i=0; i<datasize; i++)
00919 data[i] += t;
00920 }
00921
00922 template<class T> inline
00923 Mat<T> operator+(const Mat<T> &m, T t)
00924 {
00925 Mat<T> r(m.no_rows, m.no_cols);
00926
00927 for (int i=0; i<r.datasize; i++)
00928 r.data[i] = m.data[i] + t;
00929
00930 return r;
00931 }
00932
00933 template<class T> inline
00934 Mat<T> operator+(T t, const Mat<T> &m)
00935 {
00936 Mat<T> r(m.no_rows, m.no_cols);
00937
00938 for (int i=0; i<r.datasize; i++)
00939 r.data[i] = t + m.data[i];
00940
00941 return r;
00942 }
00943
00944 template<class T> inline
00945 void Mat<T>::operator-=(const Mat<T> &m)
00946 {
00947 int i,j, m_pos=0, pos=0;
00948
00949 if (datasize == 0) {
00950 set_size(m.no_rows, m.no_cols, false);
00951 for (i=0; i<no_cols; i++) {
00952 for (j=0; j<no_rows; j++)
00953 data[pos+j] = -m.data[m_pos+j];
00954
00955 m_pos += m.no_rows;
00956 pos += no_rows;
00957 }
00958 } else {
00959
00960 for (i=0; i<no_cols; i++) {
00961 for (j=0; j<no_rows; j++)
00962 data[pos+j] -= m.data[m_pos+j];
00963
00964 m_pos += m.no_rows;
00965 pos += no_rows;
00966 }
00967 }
00968 }
00969
00970 template<class T> inline
00971 Mat<T> operator-(const Mat<T> &m1, const Mat<T> &m2)
00972 {
00973 Mat<T> r(m1.no_rows, m1.no_cols);
00974 int i, j, m1_pos=0, m2_pos=0, r_pos=0;
00975
00976
00977
00978 for (i=0; i<r.no_cols; i++) {
00979 for (j=0; j<r.no_rows; j++)
00980 r.data[r_pos+j] = m1.data[m1_pos+j] - m2.data[m2_pos+j];
00981
00982 m1_pos += m1.no_rows;
00983 m2_pos += m2.no_rows;
00984 r_pos += r.no_rows;
00985 }
00986
00987 return r;
00988 }
00989
00990 template<class T> inline
00991 void Mat<T>::operator-=(T t)
00992 {
00993 for (int i=0; i<datasize; i++)
00994 data[i] -= t;
00995 }
00996
00997 template<class T> inline
00998 Mat<T> operator-(const Mat<T> &m, T t)
00999 {
01000 Mat<T> r(m.no_rows, m.no_cols);
01001 int i, j, m_pos=0, r_pos=0;
01002
01003 for (i=0; i<r.no_cols; i++) {
01004 for (j=0; j<r.no_rows; j++)
01005 r.data[r_pos+j] = m.data[m_pos+j] - t;
01006
01007 m_pos += m.no_rows;
01008 r_pos += r.no_rows;
01009 }
01010
01011 return r;
01012 }
01013
01014 template<class T> inline
01015 Mat<T> operator-(T t, const Mat<T> &m)
01016 {
01017 Mat<T> r(m.no_rows, m.no_cols);
01018 int i, j, m_pos=0, r_pos=0;
01019
01020 for (i=0; i<r.no_cols; i++) {
01021 for (j=0; j<r.no_rows; j++)
01022 r.data[r_pos+j] = t - m.data[m_pos+j];
01023
01024 m_pos += m.no_rows;
01025 r_pos += r.no_rows;
01026 }
01027
01028 return r;
01029 }
01030
01031
01032 template<class T> inline
01033 Mat<T> operator-(const Mat<T> &m)
01034 {
01035 Mat<T> r(m.no_rows, m.no_cols);
01036 int i, j, m_pos=0, r_pos=0;
01037
01038 for (i=0; i<r.no_cols; i++) {
01039 for (j=0; j<r.no_rows; j++)
01040 r.data[r_pos+j] = -m.data[m_pos+j];
01041
01042 m_pos += m.no_rows;
01043 r_pos += r.no_rows;
01044 }
01045
01046 return r;
01047 }
01048
01049
01050
01051 #ifdef HAVE_CBLAS // double and complex specializations using fast CBLAS routines
01052 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01053 #ifndef _MSC_VER
01054 template<>
01055 #endif
01056 void mat::operator*=(const mat &m)
01057 {
01058
01059 mat r(no_rows, m.no_cols);
01060
01061 cblas_dgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, no_rows, m.no_cols, no_cols, 1.0,
01062 data, no_rows, m.data, m.no_rows, 0.0, r.data, r.no_rows);
01063
01064 operator=(r);
01065 }
01066 #ifndef _MSC_VER
01067 template<>
01068 #endif
01069 void cmat::operator*=(const cmat &m)
01070 {
01071
01072 double_complex alpha = double_complex(1.0), beta = double_complex(0.0);
01073 cmat r(no_rows, m.no_cols);
01074
01075 cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, no_rows, m.no_cols, no_cols, (const void *)&alpha,
01076 data, no_rows, m.data, m.no_rows, (const void*)&beta, &r.data, r.no_rows);
01077
01078 operator=(r);
01079 }
01080 #endif
01081 #endif
01082
01083 template<class T> inline
01084 void Mat<T>::operator*=(const Mat<T> &m)
01085 {
01086
01087 Mat<T> r(no_rows, m.no_cols);
01088
01089 T tmp;
01090
01091 int i,j,k, r_pos=0, pos=0, m_pos=0;
01092
01093 for (i=0; i<r.no_cols; i++) {
01094 for (j=0; j<r.no_rows; j++) {
01095 tmp = T(0);
01096 pos = 0;
01097 for (k=0; k<no_cols; k++) {
01098 tmp += data[pos+j] * m.data[m_pos+k];
01099 pos += no_rows;
01100 }
01101 r.data[r_pos+j] = tmp;
01102 }
01103 r_pos += r.no_rows;
01104 m_pos += m.no_rows;
01105 }
01106 operator=(r);
01107 }
01108
01109 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01110 #ifdef HAVE_CBLAS // double and complex specializations using fast CBLAS routines
01111 #ifndef _MSC_VER
01112 template<>
01113 #endif
01114 mat operator*(const mat &m1, const mat &m2)
01115 {
01116
01117 mat r(m1.no_rows, m2.no_cols);
01118
01119 cblas_dgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, m1.no_rows, m2.no_cols, m1.no_cols, 1.0,
01120 m1.data, m1.no_rows, m2.data, m2.no_rows, 0.0, r.data, r.no_rows);
01121
01122 return r;
01123 }
01124
01125 #ifndef _MSC_VER
01126 template<>
01127 #endif
01128 cmat operator*(const cmat &m1, const cmat &m2)
01129 {
01130
01131 double_complex alpha = double_complex(1.0), beta = double_complex(0.0);
01132 cmat r(m1.no_rows, m2.no_cols);
01133
01134 cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, m1.no_rows, m2.no_cols, m1.no_cols, (const void *)&alpha,
01135 m1.data, m1.no_rows, m2.data, m2.no_rows, (const void*)&beta, r.data, r.no_rows);
01136
01137 return r;
01138 }
01139 #endif
01140 #endif //DOXYGEN_SHOULD_SKIP_THIS
01141
01142 template<class T> inline
01143 Mat<T> operator*(const Mat<T> &m1, const Mat<T> &m2)
01144 {
01145
01146 Mat<T> r(m1.no_rows, m2.no_cols);
01147
01148 T tmp;
01149 int i, j, k;
01150 T *tr=r.data, *t1, *t2=m2.data;
01151
01152 for (i=0; i<r.no_cols; i++) {
01153 for (j=0; j<r.no_rows; j++) {
01154 tmp = T(0); t1 = m1.data+j;
01155 for (k=m1.no_cols; k>0; k--) {
01156 tmp += *(t1) * *(t2++);
01157 t1 += m1.no_rows;
01158 }
01159 *(tr++) = tmp; t2 -= m2.no_rows;
01160 }
01161 t2 += m2.no_rows;
01162 }
01163
01164 return r;
01165 }
01166
01167 template<class T> inline
01168 void Mat<T>::operator*=(T t)
01169 {
01170 for (int i=0; i<datasize; i++)
01171 data[i] *= t;
01172 }
01173
01174 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01175 #ifdef HAVE_CBLAS // double and complex specializations using fast CBLAS routines
01176 #ifndef _MSC_VER
01177 template<>
01178 #endif
01179 vec operator*(const mat &m, const vec &v)
01180 {
01181
01182 vec r(m.no_rows);
01183
01184 cblas_dgemv(CblasColMajor, CblasNoTrans, m.no_rows, m.no_cols, 1.0, m.data, m.no_rows, v._data(), 1,
01185 0.0, r._data(), 1);
01186
01187 return r;
01188 }
01189
01190 #ifndef _MSC_VER
01191 template<>
01192 #endif
01193 cvec operator*(const cmat &m, const cvec &v)
01194 {
01195
01196 double_complex alpha = double_complex(1.0), beta = double_complex(0.0);
01197 cvec r(m.no_rows);
01198
01199 cblas_zgemv(CblasColMajor, CblasNoTrans, m.no_rows, m.no_cols, (const void *)&alpha, m.data, m.no_rows,
01200 v._data(), 1, (const void*)&beta, r._data(), 1);
01201
01202 return r;
01203 }
01204 #endif
01205 #endif //DOXYGEN_SHOULD_SKIP_THIS
01206
01207 template<class T> inline
01208 Vec<T> operator*(const Mat<T> &m, const Vec<T> &v)
01209 {
01210
01211 Vec<T> r(m.no_rows);
01212 int i, k, m_pos;
01213
01214 for (i=0; i<m.no_rows; i++) {
01215 r(i) = T(0);
01216 m_pos = 0;
01217 for (k=0; k<m.no_cols; k++) {
01218 r(i) += m.data[m_pos+i] * v(k);
01219 m_pos += m.no_rows;
01220 }
01221 }
01222
01223 return r;
01224 }
01225
01226 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01227 #ifdef HAVE_CBLAS // double and complex specializations using fast CBLAS routines
01228 #ifndef _MSC_VER
01229 template<>
01230 #endif //_MSC_VER
01231 vec operator*(const vec &v, const mat &m)
01232 {
01233
01234 vec r(m.no_cols);
01235
01236 cblas_dgemv(CblasColMajor, CblasTrans, m.no_rows, m.no_cols, 1.0, m.data, m.no_rows, v._data(), 1,
01237 0.0, r._data(), 1);
01238
01239 return r;
01240 }
01241
01242 #ifndef _MSC_VER
01243 template<>
01244 #endif //_MSC_VER
01245 cvec operator*(const cvec &v, const cmat &m)
01246 {
01247
01248 double_complex alpha = double_complex(1.0), beta = double_complex(0.0);
01249 cvec r(m.no_cols);
01250
01251 cblas_zgemv(CblasColMajor, CblasTrans, m.no_rows, m.no_cols, (const void *)&alpha, m.data, m.no_rows,
01252 v._data(), 1, (const void*)&beta, r._data(), 1);
01253
01254 return r;
01255 }
01256 #endif //HAVE_CBLAS
01257 #endif //DOXYGEN_SHOULD_SKIP_THIS
01258
01259 template<class T> inline
01260 Vec<T> operator*(const Vec<T> &v, const Mat<T> &m)
01261 {
01262
01263 Vec<T> r(m.no_cols);
01264 int i, k, m_pos=0;
01265
01266 for (i=0; i<m.no_cols; i++) {
01267 r(i) = T(0);
01268 for (k=0; k<m.no_rows; k++) {
01269 r(i) += m.data[m_pos+k] * v(k);
01270 }
01271 m_pos += m.no_rows;
01272 }
01273
01274 return r;
01275 }
01276
01277
01278 template<class T> inline
01279 Mat<T> operator*(const Mat<T> &m, T t)
01280 {
01281 Mat<T> r(m.no_rows, m.no_cols);
01282
01283 for (int i=0; i<r.datasize; i++)
01284 r.data[i] = m.data[i] * t;
01285
01286 return r;
01287 }
01288
01289
01290 template<class T> inline
01291 Mat<T> operator*(T t, const Mat<T> &m)
01292 {
01293 Mat<T> r(m.no_rows, m.no_cols);
01294
01295 for (int i=0; i<r.datasize; i++)
01296 r.data[i] = m.data[i] * t;
01297
01298 return r;
01299 }
01300
01301
01302 template<class T> inline
01303 Mat<T> elem_mult(const Mat<T> &m1, const Mat<T> &m2)
01304 {
01305
01306 Mat<T> r(m1.no_rows, m1.no_cols);
01307
01308 for (int i=0; i<r.datasize; i++)
01309 r.data[i] = m1.data[i] * m2.data[i];
01310
01311 return r;
01312 }
01313
01314 template<class T> inline
01315 void Mat<T>::operator/=(T t)
01316 {
01317 for (int i=0; i<datasize; i++)
01318 data[i] /= t;
01319 }
01320
01321 template<class T> inline
01322 Mat<T> operator/(const Mat<T> &m, T t)
01323 {
01324 Mat<T> r(m.no_rows, m.no_cols);
01325
01326 for (int i=0; i<r.datasize; i++)
01327 r.data[i] = m.data[i] / t;
01328
01329 return r;
01330 }
01331
01332 template<class T> inline
01333 void Mat<T>::operator/=(const Mat<T> &m)
01334 {
01335
01336
01337 for (int i=0; i<datasize; i++)
01338 data[i] /= m.data[i];
01339 }
01340
01341 template<class T> inline
01342 Mat<T> elem_div(const Mat<T> &m1, const Mat<T> &m2)
01343 {
01344
01345 Mat<T> r(m1.no_rows, m1.no_cols);
01346
01347 for (int i=0; i<r.datasize; i++)
01348 r.data[i] = m1.data[i] / m2.data[i];
01349
01350 return r;
01351 }
01352
01353 template<class T>
01354 bool Mat<T>::operator==(const Mat<T> &m) const
01355 {
01356 if (no_rows!=m.no_rows || no_cols != m.no_cols) return false;
01357 for (int i=0;i<datasize;i++) {
01358 if (data[i]!=m.data[i]) return false;
01359 }
01360 return true;
01361 }
01362
01363
01364 template<class T>
01365 bool Mat<T>::operator!=(const Mat<T> &m) const
01366 {
01367 if (no_rows != m.no_rows || no_cols != m.no_cols) return true;
01368 for (int i=0;i<datasize;i++) {
01369 if (data[i]!=m.data[i]) return true;
01370 }
01371 return false;
01372 }
01373
01374 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01375 #ifdef XXX
01376 template <class T>
01377 ostream &operator<<(ostream &os, const Mat<T> &m)
01378 {
01379 int i;
01380
01381 switch (m.rows()) {
01382 case 0 :
01383 os << "[]";
01384 break;
01385 case 1 :
01386 os << '[' << m.get_row(0) << ']';
01387 break;
01388 default:
01389 os << '[' << m.get_row(0) << endl;
01390 for (i=1; i<m.rows()-1; i++)
01391 os << ' ' << m.get_row(i) << endl;
01392 os << ' ' << m.get_row(m.rows()-1) << ']';
01393 }
01394
01395 return os;
01396 }
01397
01398 template <class T>
01399 istream &operator>>(istream &is, Mat<T> &m)
01400 {
01401 string str, row;
01402 bool first_row=true;
01403
01404 while (1) {
01405 getline(is, row);
01406 if (is.eof() || row.empty())
01407 break;
01408 if (!str.empty())
01409 str += ';';
01410 if (row[row.length()-1] == ']') {
01411 str += row.substr(0, row.length()-1);
01412 break;
01413 }
01414 str += row;
01415 if (first_row && row.find(';') < row.length())
01416 break;
01417 first_row = false;
01418 }
01419 m.set(str);
01420
01421 return is;
01422 }
01423 #endif
01424 #endif //DOXYGEN_SHOULD_SKIP_THIS
01425
01426
01427 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01428
01429 template<class T>
01430 T sum(const Vec<T> &v)
01431 {
01432 T M=0;
01433
01434 for (int i=0;i<v.length();i++)
01435 M+=v[i];
01436
01437 return M;
01438 }
01439
01440
01441
01442 template<class T>
01443 T sum_sqr(const Vec<T> &v)
01444 {
01445 T M=0;
01446
01447 for (int i=0; i<v.length(); i++)
01448 M += v[i] * v[i];
01449
01450 return M;
01451 }
01452
01453 template<class T>
01454 T max(const Vec<T> &in)
01455 {
01456 T maxdata=in[0];
01457 for (int i=1;i<in.length();i++)
01458 if (in[i]>maxdata)
01459 maxdata=in[i];
01460 return maxdata;
01461 }
01462
01463 template<class T>
01464 T min(const Vec<T> &in)
01465 {
01466 T mindata=in[0];
01467 for (int i=1;i<in.length();i++)
01468 if (in[i]<mindata)
01469 mindata=in[i];
01470 return mindata;
01471 }
01472
01473
01474
01475
01476 template<class T>
01477 int max_index(const Vec<T> &in)
01478 {
01479 int maxindex=0;
01480 for (int i=0;i<in.length();i++)
01481 if (in[i]>in[maxindex])
01482 maxindex=i;
01483 return maxindex;
01484 }
01485
01486
01487
01488
01489 template<class T>
01490 int min_index(const Vec<T> &in)
01491 {
01492 int minindex=0;
01493 for (int i=0;i<in.length();i++)
01494 if (in[i]<in[minindex])
01495 minindex=i;
01496 return minindex;
01497 }
01498
01499
01500
01501
01502 template<class T>
01503 T product(const Vec<T> &v)
01504 {
01505 double lnM=0;
01506 for (int i=0;i<v.length();i++)
01507 lnM += log(static_cast<double>(v[i]));
01508 return static_cast<T>(exp(lnM));
01509 }
01510
01511
01512
01513
01514 template<class T>
01515 Vec<T> cross(const Vec<T> &v1, const Vec<T> &v2)
01516 {
01517 it_assert( v1.size() == 3 && v2.size() == 3, "cross: vectors should be of size 3");
01518
01519 Vec<T> r(3);
01520
01521 r(0) = v1(1) * v2(2) - v1(2) * v2(1);
01522 r(1) = v1(2) * v2(0) - v1(0) * v2(2);
01523 r(2) = v1(0) * v2(1) - v1(1) * v2(0);
01524
01525 return r;
01526 }
01527
01528 template<class T>
01529 double geometric_mean(const Vec<T> &v)
01530 {
01531 return exp(log(product(v))/v.length());
01532 }
01533
01534
01535
01536
01537 template<class T>
01538 double median(const Vec<T> &v)
01539 {
01540 Vec<T> invect(v);
01541 sort(invect);
01542 return (double)(invect[(invect.length()-1)/2]+invect[invect.length()/2])/2.0;
01543 }
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557 template<class T>
01558 double norm(const Vec<T> &v)
01559 {
01560 int i;
01561 double e=0.0;
01562
01563 for (i=0; i<v.length(); i++)
01564 e += SQR( v[i] );
01565
01566 return sqrt(e);
01567 }
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583 template<class T>
01584 double norm(const Vec<T> &v, int p)
01585 {
01586 int i;
01587 double e=0;
01588
01589 for (i=0;i<v.length();i++)
01590 e+=pow(fabs(v[i]),(double)p);
01591
01592 return pow(e,1.0/(double)p);
01593 }
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610 template<class T>
01611 double variance(const Vec<T> &v)
01612 {
01613 int len = v.length();
01614 const T *p=v._data();
01615 T sum=0.0;
01616 T sq_sum=0.0;
01617
01618 for (int i=0; i<len; i++, p++) {
01619 sum += *p;
01620 sq_sum += SQR(*p * *p);
01621 }
01622
01623 return (double)(sq_sum - SQR(sum)/len) / (len-1);
01624 }
01625
01626
01627
01628
01629
01630 template<class T>
01631 double energy(const Vec<T> &v)
01632 {
01633 return SQR(norm(v));
01634 }
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655 template<class T>
01656 Vec<T> reverse(const Vec<T> &in)
01657 {
01658 int i, s=in.length();
01659
01660 Vec<T> out(s);
01661 for (i=0;i<s;i++)
01662 out[i]=in[s-1-i];
01663 return out;
01664 }
01665
01666
01667
01668
01669 template<class T>
01670 Vec<T> repeat(const Vec<T> &v, int norepeats)
01671 {
01672 Vec<T> temp(v.length()*norepeats);
01673
01674 for(int i=0;i<v.length();i++) {
01675 for(int j=0;j<norepeats;j++)
01676 temp(i*norepeats+j)=v(i);
01677 }
01678 return temp;
01679 }
01680
01681
01682
01683
01684 template<class T, class fT>
01685 Vec<T> apply_function(fT (*f)(fT), const Vec<T> &data)
01686 {
01687 Vec<T> out(data.length());
01688
01689 for (int i=0;i<data.length();i++)
01690 out[i]=static_cast<T>(f(static_cast<fT>(data[i])));
01691 return out;
01692 }
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722 template<class T> void QS(int low, int high, Vec<T> &data) {
01723 int plow, phigh;
01724 T a,test;
01725
01726 if (high>low) {
01727 a=data[low];
01728 plow=low;
01729 phigh=high;
01730 test=data[phigh];
01731 while (plow<phigh) {
01732 if (test<a) {
01733 data[plow]=test;
01734 plow++;
01735 test=data[plow];
01736 } else {
01737 data[phigh]=test;
01738 phigh--;
01739 test=data[phigh];
01740 }
01741 }
01742 data[plow]=a;
01743 QS(low,plow-1,data);
01744 QS(plow+1,high,data);
01745 }
01746 }
01747
01748
01749 template void QS(int low, int high, vec &data);
01750 template void QS(int low, int high, svec &data);
01751 template void QS(int low, int high, ivec &data);
01752 template void QS(int low, int high, bvec &data);
01753
01754
01755
01756
01757 template<class T>
01758 void sort(Vec<T> &data)
01759 {
01760 QS(0,data.size()-1,data);
01761 }
01762
01763 template<class T>
01764 void QSindex(int low, int high, ivec &indexlist, const Vec<T> &data)
01765 {
01766 int plow,phigh,testindex,aindex;
01767 T a,test;
01768
01769 if (high>low) {
01770 aindex=indexlist[low];
01771 a=data[aindex];
01772 plow=low;
01773 phigh=high;
01774 testindex=indexlist[phigh];
01775 test=data[testindex];
01776 while (plow<phigh) {
01777 if (test<a) {
01778 indexlist[plow]=testindex;
01779 plow++;
01780 testindex=indexlist[plow];
01781 test=data[testindex];
01782 } else {
01783 indexlist[phigh]=testindex;
01784 phigh--;
01785 testindex=indexlist[phigh];
01786 test=data[testindex];
01787 }
01788 }
01789 indexlist[plow]=aindex;
01790 QSindex(low,plow-1,indexlist,data);
01791 QSindex(plow+1,high,indexlist,data);
01792 }
01793 }
01794
01795
01796 template void QSindex(int low, int high, ivec &indexlist, const vec &data);
01797 template void QSindex(int low, int high, ivec &indexlist, const svec &data);
01798 template void QSindex(int low, int high, ivec &indexlist, const ivec &data);
01799 template void QSindex(int low, int high, ivec &indexlist, const bvec &data);
01800
01801
01802
01803
01804 template<class T>
01805 ivec sort_index(const Vec<T> &data)
01806 {
01807 int N=data.length(),i;
01808 ivec indexlist(N);
01809
01810 for(i=0;i<N;i++) {
01811 indexlist(i)=i;
01812 }
01813 QSindex(0,N-1,indexlist,data);
01814 return indexlist;
01815 }
01816
01817
01818
01819
01820 template<class T>
01821 Vec<T> zero_pad(const Vec<T> &v, int n)
01822 {
01823 it_assert(n>=v.size(), "zero_pad() cannot shrink the vector!");
01824 Vec<T> v2(n);
01825 v2.set_subvector(0, v.size()-1, v);
01826 if (n > v.size())
01827 v2.set_subvector(v.size(), n-1, T(0));
01828
01829 return v2;
01830 }
01831
01832
01833
01834
01835 template<class T>
01836 Vec<T> zero_pad(const Vec<T> &v)
01837 {
01838 int n = pow2(needed_bits(v.size()));
01839
01840 return n==v.size() ? v : zero_pad(v, n);
01841 }
01842
01843
01844
01845
01846 template<class T>
01847 Mat<T> zero_pad(const Mat<T> &m, int rows, int cols)
01848 {
01849 it_assert(rows>=m.rows() && cols>=m.cols(), "zero_pad() cannot shrink the matrix!");
01850 Mat<T> m2(rows, cols);
01851 m2.set_submatrix(0,m.rows()-1,0,m.cols()-1, m);
01852 if (cols > m.cols())
01853 m2.set_submatrix(0,m.rows()-1, m.cols(),cols-1, T(0));
01854 if (rows > m.rows())
01855 m2.set_submatrix(m.rows(), rows-1, 0, cols-1, T(0));
01856
01857 return m2;
01858 }
01859
01860
01861
01862
01863
01864 template<class T>
01865 T sum(const Mat<T> &v)
01866 {
01867 int i, j;
01868 T M=0;
01869
01870 for (i=0; i<v.rows(); i++)
01871 for (j=0; j<v.cols(); j++)
01872 M += v(i,j);
01873
01874 return M;
01875 }
01876
01877
01878
01879
01880 template<class T>
01881 T sum_sqr(const Mat<T> &v)
01882 {
01883 int i, j;
01884 T M=0;
01885
01886 for (i=0; i<v.rows(); i++)
01887 for (j=0; j<v.cols(); j++)
01888 M += v(i,j) * v(i,j);
01889
01890 return M;
01891 }
01892
01893
01894
01895
01896 template<class T>
01897 T max(const Mat<T> &m)
01898 {
01899 T maxdata = m(0,0);
01900 int i, j;
01901
01902 for (i=0; i<m.rows(); i++)
01903 for (j=0; j<m.cols(); j++)
01904 if (m(i,j) > maxdata)
01905 maxdata = m(i,j);
01906
01907 return maxdata;
01908 }
01909
01910
01911
01912
01913 template<class T>
01914 T min(const Mat<T> &m)
01915 {
01916 T mindata = m(0,0);
01917 int i, j;
01918
01919 for (i=0; i<m.rows(); i++)
01920 for (j=0; j<m.cols(); j++)
01921 if (m(i,j) < mindata)
01922 mindata = m(i,j);
01923
01924 return mindata;
01925 }
01926
01927
01928
01929
01930 template<class T>
01931 void max_index(const Mat<T> &m, int &row, int &col)
01932 {
01933 T maxdata = m(0,0);
01934 int i, j;
01935
01936 row = col = 0;
01937 for (i=0; i<m.rows(); i++)
01938 for (j=0; j<m.cols(); j++)
01939 if (m(i,j) > maxdata) {
01940 row = i;
01941 col = j;
01942 maxdata = m(i,j);
01943 }
01944 }
01945
01946
01947
01948
01949 template<class T>
01950 void min_index(const Mat<T> &m, int &row, int &col)
01951 {
01952 T mindata = m(0,0);
01953 int i, j;
01954
01955 row = col = 0;
01956 for (i=0; i<m.rows(); i++)
01957 for (j=0; j<m.cols(); j++)
01958 if (m(i,j) < mindata) {
01959 row = i;
01960 col = j;
01961 mindata = m(i,j);
01962 }
01963 }
01964
01965
01966
01967
01968 template<class T>
01969 T product(const Mat<T> &m)
01970 {
01971 int i, j;
01972 double lnM=0;
01973
01974 for (i=0; i<m.rows(); i++)
01975 for (j=0; j<m.cols(); j++)
01976 lnM += log(m(i,j));
01977
01978 return static_cast<T>(exp(lnM));
01979 }
01980
01981
01982
01983 template<class T>
01984 Mat<T> diag(const Vec<T> &in)
01985 {
01986 Mat<T> m(in.size(), in.size());
01987 m = T(0);
01988 for (int i=in.size()-1; i>=0; i--)
01989 m(i,i) = in(i);
01990 return m;
01991 }
01992
01993 template<class T>
01994 void diag(const Vec<T> &in, Mat<T> &m)
01995 {
01996 m.set_size(in.size(), in.size(), false);
01997 m = T(0);
01998 for (int i=in.size()-1; i>=0; i--)
01999 m(i,i) = in(i);
02000 }
02001
02002
02003
02004
02005 template<class T>
02006 Vec<T> diag(const Mat<T> &in)
02007 {
02008 Vec<T> t(std::min(in.rows(), in.cols()));
02009
02010 for (int i=0; i<t.size(); i++)
02011 t(i) = in(i,i);
02012
02013 return t;
02014 }
02015
02016
02017 template<class T>
02018 Mat<T> bidiag(const Vec<T> &main, const Vec<T> &sup)
02019 {
02020 it_assert(main.size() == sup.size()+1, "bidiag()");
02021
02022 int n=main.size();
02023 Mat<T> m(n, n);
02024 m = T(0);
02025 for (int i=0; i<n-1; i++) {
02026 m(i,i) = main(i);
02027 m(i,i+1) = sup(i);
02028 }
02029 m(n-1,n-1) = main(n-1);
02030
02031 return m;
02032 }
02033
02034 template<class T>
02035 void bidiag(const Vec<T> &main, const Vec<T> &sup, Mat<T> &m)
02036 {
02037 it_assert(main.size() == sup.size()+1, "bidiag()");
02038
02039 int n=main.size();
02040 m.set_size(n, n);
02041 m = T(0);
02042 for (int i=0; i<n-1; i++) {
02043 m(i,i) = main(i);
02044 m(i,i+1) = sup(i);
02045 }
02046 m(n-1,n-1) = main(n-1);
02047 }
02048
02049 template<class T>
02050 void bidiag(const Mat<T> &m, Vec<T> &main, Vec<T> &sup)
02051 {
02052 it_assert(m.rows() == m.cols(), "bidiag(): Matrix must be square!");
02053
02054 int n=m.cols();
02055 main.set_size(n);
02056 sup.set_size(n-1);
02057 for (int i=0; i<n-1; i++) {
02058 main(i) = m(i,i);
02059 sup(i) = m(i,i+1);
02060 }
02061 main(n-1) = m(n-1,n-1);
02062 }
02063
02064
02065 template<class T>
02066 Mat<T> tridiag(const Vec<T> &main, const Vec<T> &sup, const Vec<T> &sub)
02067 {
02068 it_assert(main.size()==sup.size()+1 && main.size()==sub.size()+1, "bidiag()");
02069
02070 int n=main.size();
02071 Mat<T> m(n, n);
02072 m = T(0);
02073 for (int i=0; i<n-1; i++) {
02074 m(i,i) = main(i);
02075 m(i,i+1) = sup(i);
02076 m(i+1,i) = sub(i);
02077 }
02078 m(n-1,n-1) = main(n-1);
02079
02080 return m;
02081 }
02082
02083 template<class T>
02084 void tridiag(const Vec<T> &main, const Vec<T> &sup, const Vec<T> &sub, Mat<T> &m)
02085 {
02086 it_assert(main.size()==sup.size()+1 && main.size()==sub.size()+1, "bidiag()");
02087
02088 int n=main.size();
02089 m.set_size(n, n);
02090 m = T(0);
02091 for (int i=0; i<n-1; i++) {
02092 m(i,i) = main(i);
02093 m(i,i+1) = sup(i);
02094 m(i+1,i) = sub(i);
02095 }
02096 m(n-1,n-1) = main(n-1);
02097 }
02098
02099 template<class T>
02100 void tridiag(const Mat<T> &m, Vec<T> &main, Vec<T> &sup, Vec<T> &sub)
02101 {
02102 it_assert(m.rows() == m.cols(), "tridiag(): Matrix must be square!");
02103
02104 int n=m.cols();
02105 main.set_size(n);
02106 sup.set_size(n-1);
02107 sub.set_size(n-1);
02108 for (int i=0; i<n-1; i++) {
02109 main(i) = m(i,i);
02110 sup(i) = m(i,i+1);
02111 sub(i) = m(i+1,i);
02112 }
02113 main(n-1) = m(n-1,n-1);
02114 }
02115
02116
02117
02118
02119 template<class T>
02120 T trace(const Mat<T> &in)
02121 {
02122 return sum(diag(in));
02123 }
02124
02125
02126
02127
02128 template<class T>
02129 void transpose(const Mat<T> &m, Mat<T> &out)
02130 {
02131 out.set_size(m.cols(),m.rows(), false);
02132
02133 for (int i=0; i<m.rows(); i++) {
02134 for (int j=0; j<m.cols(); j++) {
02135 out(j,i) = m(i,j);
02136 }
02137 }
02138 }
02139
02140
02141
02142
02143 template<class T>
02144 Mat<T> transpose(const Mat<T> &m)
02145 {
02146 Mat<T> temp(m.cols(),m.rows());
02147
02148 for (int i=0; i<m.rows(); i++) {
02149 for (int j=0; j<m.cols(); j++) {
02150 temp(j,i) = m(i,j);
02151 }
02152 }
02153 return temp;
02154 }
02155
02156
02157
02158
02159 template<class T>
02160 Mat<T> repeat(const Mat<T> &v, int norepeats)
02161 {
02162 Mat<T> temp(v.rows(),v.cols()*norepeats);
02163 for (int j=0;j<v.cols();j++) {
02164 for (int i=0;i<norepeats;i++) {
02165 temp.set_col(j*norepeats+i,v.get_col(j));
02166 }
02167 }
02168 return temp;
02169 }
02170
02171
02172
02173 template<class T, class fT>
02174 Mat<T> apply_function(fT (*f)(fT), const Mat<T> &data)
02175 {
02176 Mat<T> out(data.rows(),data.cols());
02177
02178 for (int i=0;i<out.rows();i++)
02179 for (int j=0;j<out.cols();j++)
02180 out(i,j)=static_cast<T>(f(static_cast<fT>(data(i,j))));
02181
02182 return out;
02183 }
02184
02185
02186 #define absolut(x) (((x)>0) ? (x) : (-(x)))
02187
02188
02189
02190
02191
02192 template<class T>
02193 Vec<T> rvectorize(const Mat<T> &m)
02194 {
02195 int i, j, n=0, r=m.rows(), c=m.cols();
02196 Vec<T> v(r * c);
02197
02198 for (i=0; i<r; i++)
02199 for (j=0; j<c; j++)
02200 v(n++) = m(i,j);
02201
02202 return v;
02203 }
02204
02205
02206
02207
02208
02209 template<class T>
02210 Vec<T> cvectorize(const Mat<T> &m)
02211 {
02212 int i, j, n=0, r=m.rows(), c=m.cols();
02213 Vec<T> v(r * c);
02214
02215 for (j=0; j<c; j++)
02216 for (i=0; i<r; i++)
02217 v(n++) = m(i,j);
02218
02219 return v;
02220 }
02221
02222
02223
02224
02225
02226 template<class T>
02227 Mat<T> reshape(const Mat<T> &m, int rows, int cols)
02228 {
02229 it_assert1(m.rows()*m.cols() == rows*cols, "Mat<T>::reshape: Sizes must match");
02230 Mat<T> temp(rows, cols);
02231 int i, j, ii=0, jj=0;
02232 for (j=0; j<m.cols(); j++) {
02233 for (i=0; i<m.rows(); i++) {
02234 temp(ii++,jj) = m(i,j);
02235 if (ii == rows) {
02236 jj++; ii=0;
02237 }
02238 }
02239 }
02240 return temp;
02241 }
02242
02243
02244
02245
02246 template<class T>
02247 Mat<T> reshape(const Vec<T> &v, int rows, int cols)
02248 {
02249
02250 Mat<T> temp(rows, cols);
02251 int i, j, ii=0;
02252 for (j=0; j<cols; j++) {
02253 for (i=0; i<rows; i++) {
02254 temp(i,j) = v(ii++);
02255 }
02256 }
02257 return temp;
02258 }
02259
02260
02261
02262
02263
02264
02265 template<class T>
02266 void upsample(const Vec<T> &v, int usf, Vec<T> &u)
02267 {
02268
02269 u.set_size(v.length()*usf);
02270 u.clear();
02271 for(long i=0;i<v.length();i++)
02272 u(i*usf)=v(i);
02273 }
02274
02275
02276 template<class T>
02277 Vec<T> upsample(const Vec<T> &v, int usf)
02278 {
02279 Vec<T> u;
02280 upsample(v,usf,u);
02281 return u;
02282 }
02283
02284
02285
02286
02287 template<class T>
02288 void upsample(const Mat<T> &v, int usf, Mat<T> &u)
02289 {
02290
02291 u.set_size(v.rows(),v.cols()*usf);
02292 u.clear();
02293 for (long j=0;j<v.cols();j++)
02294 u.set_col(j*usf,v.get_col(j));
02295 }
02296
02297 template<class T>
02298 Mat<T> upsample(const Mat<T> &v, int usf)
02299 {
02300 Mat<T> u;
02301 upsample(v,usf,u);
02302 return u;
02303 }
02304
02305
02306
02307
02308 template<class T>
02309 void lininterp(const Mat<T> &v, int usf, Mat<T> &u)
02310 {
02311
02312 long L = (v.cols()-1)*usf+1;
02313 u.set_size(v.rows(),L);
02314 for (long i = 0; i < v.rows(); i++){
02315 for (long j = 0; j < L-1; j++)
02316
02317 u(i,j) = (v(i,j/usf) + (j % usf)/((double)usf)*(v(i,(j+usf)/usf)-v(i,j/usf)));
02318 u(i,L-1) = v(i,v.cols()-1);
02319 }
02320 }
02321
02322
02323
02324
02325 template<class T>
02326 Mat<T> lininterp(const Mat<T> &v, int usf)
02327 {
02328 Mat<T> u;
02329 upsample(v,usf,u);
02330 return u;
02331 }
02332
02333
02334
02335
02336
02337 template<class T>
02338 void lininterp(const Vec<T> &v, int usf, Vec<T> &u)
02339 {
02340
02341 long L = (v.length()-1)*usf+1;
02342 u.set_size(L);
02343 for (long j = 0; j < L-1; j++) {
02344
02345 u(j) = (v(j/usf) + (j % usf)/((double)usf)*(v((j+usf)/usf)-v(j/usf)));
02346 }
02347 u(L-1) = v(v.length()-1);
02348 }
02349
02350
02351
02352
02353
02354 template<class T>
02355 Vec<T> lininterp(const Vec<T> &v, int usf)
02356 {
02357 Vec<T> u;
02358 upsample(v,usf,u);
02359 return u;
02360 }
02361
02362
02363 #endif //DOXYGEN_SHOULD_SKIP_THIS
02364 }
02365 #endif
02366