00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MATRIX_SOURCES_
00027 #define MATRIX_SOURCES_
00028
00029 #include "matrix_global.h"
00030 #include <fstream>
00031 #include <string.h>
00032
00033 #include "matrix.h"
00034
00035
00038 namespace PLib {
00039
00050 template <class T>
00051 Matrix<T>& Matrix<T>::operator=(const Matrix<T> &a){
00052 int i;
00053
00054 if ( this == &a )
00055 return *this;
00056
00057 if ( a.rows() != rows() || a.cols() != cols() ){
00058 resize(a.rows(),a.cols()) ;
00059 }
00060
00061 int sze = rows()*cols() ;
00062 T *ptr, *aptr ;
00063 ptr = m-1 ;
00064 aptr = a.m-1 ;
00065
00066 for (i = sze; i > 0; --i)
00067 *(++ptr) = *(++aptr) ;
00068
00069 by_columns = a.by_columns;
00070
00071 return *this;
00072 }
00073
00098 template <class T>
00099 void Matrix<T>::submatrix(int sr, int sc, Matrix<T> &a)
00100 {
00101 int rwz,coz,i,j;
00102
00103 if ( rows() % a.rows() != 0 || cols() % a.cols() != 0 || rows() < a.rows() || cols() < a.cols() )
00104 {
00105 #ifdef USE_EXCEPTION
00106 throw WrongSize2D(rows(),cols(),a.rows(),a.cols()) ;
00107 #else
00108 Error error("Matrix<T>::submatrix");
00109 error << "Matrix and submatrix incommensurate" ;
00110 error.fatal() ;
00111 #endif
00112 }
00113
00114 if ( sr >= rows()/a.rows() || sr < 0 || sc >= cols()/a.cols() || sc < 0 )
00115 {
00116 #ifdef USE_EXCEPTION
00117 throw OutOfBound2D(sr,sc,0,rows()/a.rows()-1,0,cols()/a.cols()-1) ;
00118 #else
00119 Error error("Matrix<T>::submatrix");
00120 error << "Submatrix location out of bounds.\nrowblock " << sr << ", " << rows()/a.rows() << " colblock " << sc << ", " << a.cols() << endl ;
00121 error.fatal() ;
00122 #endif
00123 }
00124 rwz = sr*a.rows();
00125 coz = sc*a.cols();
00126
00127 #ifdef COLUMN_ORDER
00128 for ( i = a.rows()-1; i >= 0; --i )
00129 for(j=a.cols()-1;j>=0;--j)
00130 elem(i+rwz,j+coz) = a(i,j) ;
00131 #else
00132 T *ptr, *aptr ;
00133 aptr = a.m - 1;
00134 for ( i = a.rows()-1; i >= 0; --i )
00135 {
00136 ptr = &m[(i+rwz)*cols()+coz]-1 ;
00137 for ( j = a.cols(); j > 0; --j)
00138 *(++ptr) = *(++aptr) ;
00139 }
00140 #endif
00141 }
00142
00156 template <class T>
00157 void Matrix<T>::as(int rw, int cl, Matrix<T>& a)
00158 {
00159
00160 int i, j;
00161
00162 if ( (rw + a.rows()) > rows() || ( cl + a.cols()) > cols()) {
00163 #ifdef USE_EXCEPTION
00164 throw MatrixErr();
00165 #else
00166 Error error("Matrix<T>::as") ;
00167 error << "Matrix A will not fit in this Matrix at " << rw << ", " << cl << endl ;
00168 error.fatal() ;
00169 #endif
00170 }
00171
00172 #ifdef COLUMN_ORDER
00173 for(i=0;i<a.rows();++i)
00174 for(j=0;j<a.cols();++j)
00175 elem(i+rw,j+cl) = a(i,j) ;
00176 #else
00177 T *pptr,*aptr ;
00178 aptr = a.m-1 ;
00179 for ( i = 0; i<a.rows(); ++i) {
00180 pptr = &m[(i+rw)*cols()+cl]-1 ;
00181 for ( j = 0; j < a.cols(); ++j)
00182 *(++pptr) = *(++aptr);
00183 }
00184 #endif
00185 }
00186
00207 template <class T>
00208 Matrix<T> Matrix<T>::get(int rw, int cl, int nr, int nc) const
00209 {
00210 Matrix<T> getmat(nr,nc) ;
00211 if ( (rw+nr) > rows() || (cl+nc) > cols()) {
00212 #ifdef USE_EXCEPTION
00213 throw MatrixErr();
00214 #else
00215 Error error("Matrix<T>::get") ;
00216 error << "Matrix of size "<< nr << ", " << nc << " not available at " << rw << ", " << cl << endl ;
00217 error.fatal() ;
00218 #endif
00219 }
00220
00221 int i, j;
00222
00223 #ifdef COLUMN_ORDER
00224 for(i=0;i<nr;++i)
00225 for(j=0;j<nc;++j)
00226 getmat(i,j) = elem(i+rw,j+cl) ;
00227 #else
00228 T *pptr,*aptr ;
00229 aptr = getmat.m-1;
00230 for (i = 0; i < nr; ++i) {
00231 pptr = &m[(i+rw)*cols()+cl]-1 ;
00232 for ( j = 0; j < nc; ++j)
00233 *(++aptr) = *(++pptr) ;
00234 }
00235 #endif
00236 return getmat ;
00237 }
00238
00239
00240
00249 template <class T>
00250 double Matrix<T>::norm(void){
00251 int i,j ;
00252 double sum, maxsum;
00253 int init=0 ;
00254 T *pptr ;
00255 pptr = m-1 ;
00256 maxsum = 0 ;
00257 for(i=0;i<rows();++i){
00258 sum = 0 ;
00259 for ( j = 0; j < cols(); ++j)
00260 sum += *(++pptr) ;
00261 if(init)
00262 maxsum = (maxsum>sum) ? maxsum : sum;
00263 else{
00264 maxsum = sum ;
00265 init = 1;
00266 }
00267 }
00268 return maxsum;
00269 }
00270
00271
00283 template <class T>
00284 void Matrix<T>::diag(const T a)
00285 {
00286 int i, iend;
00287
00288 iend = rows();
00289 if ( iend > cols() )
00290 iend = cols();
00291
00292 for (i = iend-1; i >=0; --i)
00293 elem(i,i) = a;
00294
00295 }
00296
00308 template <class T>
00309 Vector<T> Matrix<T>::getDiag(){
00310 int i, iend;
00311 Vector<T> vec(minimum(rows(),cols())) ;
00312 iend = minimum(rows(),cols());
00313 for (i = iend-1; i >=0; --i)
00314 vec[i] = elem(i,i);
00315 return vec ;
00316 }
00317
00327 template <class T>
00328 Matrix<T>& Matrix<T>::operator+=(double a)
00329 {
00330 T *p1 ;
00331 p1 = m-1 ;
00332 const int size = rows()*cols() ;
00333 for(int i=size; i>0; --i)
00334 *(++p1) += a ;
00335 return *this ;
00336 }
00337
00347 template <class T>
00348 Matrix<T>& Matrix<T>::operator-=(double a)
00349 {
00350 T *p1 ;
00351 p1 = m-1 ;
00352 const int size = rows()*cols() ;
00353 for(int i=size; i>0; --i)
00354 *(++p1) -= a ;
00355 return *this ;
00356 }
00357
00367 template <class T>
00368 Matrix<T>& Matrix<T>::operator*=(double a)
00369 {
00370 T *p1 ;
00371 p1 = m-1 ;
00372 const int size = rows()*cols() ;
00373 for(int i=size; i>0; --i)
00374 *(++p1) *= a ;
00375 return *this ;
00376 }
00377
00387 template <class T>
00388 Matrix<T>& Matrix<T>::operator/=(double a)
00389 {
00390 T *p1 ;
00391 p1 = m-1 ;
00392 const int size = rows()*cols() ;
00393 for(int i=size; i>0; --i)
00394 *(++p1) /= a ;
00395 return *this ;
00396 }
00397
00408 template <class T>
00409 Matrix<T>& Matrix<T>::operator+=(const Matrix<T> &a)
00410 {
00411 if ( a.rows() != rows() || a.cols() != cols() )
00412 {
00413 #ifdef USE_EXCEPTION
00414 throw WrongSize2D(rows(),cols(),a.rows(),a.cols());
00415 #else
00416 Error error("Matrix<T>::operator+=") ;
00417 if ( rows() != a.rows() )
00418 error << "Matrices are of diferent size, a.rows() = " << rows() << " and b.rows() = " << a.rows() << endl ;
00419 if ( cols() != a.cols())
00420 error << "Matrices are of diferent size, a.cols() = " << cols() << " and b.cols() = " << a.cols() << endl ;
00421 error.fatal() ;
00422 #endif
00423 }
00424
00425 int i, sze ;
00426 T *aptr,*sptr ;
00427 aptr = a.m - 1 ;
00428 sptr = m - 1 ;
00429 sze = rows()*cols() ;
00430 for (i = sze; i > 0; --i){
00431 *(++sptr) += *(++aptr) ;
00432 }
00433 return *this ;
00434 }
00435
00446 template <class T>
00447 Matrix<T> operator+(const Matrix<T> &a,const Matrix<T> &b)
00448 {
00449 Matrix<T> sum(a) ;
00450 sum += b ;
00451 return sum;
00452 }
00453
00468 template <class T>
00469 Matrix<T>& Matrix<T>::operator-=(const Matrix<T> &a)
00470 {
00471 if ( a.rows() != rows() || a.cols() != cols() )
00472 {
00473 #ifdef USE_EXCEPTION
00474 throw WrongSize2D(rows(),cols(),a.rows(),a.cols());
00475 #else
00476 Error error("Matrix<T>::operator-=") ;
00477 if ( rows() != a.rows() )
00478 error << "Matrices are of diferent size, a.rows() = " << rows() << " and b.rows() = " << a.rows() << endl ;
00479 if ( cols() != a.cols())
00480 error << "Matrices are of diferent size, a.cols() = " << cols() << " and b.cols() = " << a.cols() << endl ;
00481 error.fatal() ;
00482 #endif
00483 }
00484
00485 int i, size;
00486 T *aptr,*sptr ;
00487 aptr = a.m - 1 ;
00488 sptr = m - 1 ;
00489 size = rows()*cols() ;
00490 for (i = size; i > 0; --i){
00491 *(++sptr) -= *(++aptr) ;
00492 }
00493 return *this ;
00494 }
00495
00496
00497
00510 template <class T>
00511 Matrix<T> operator-(const Matrix<T> &a,const Matrix<T> &b)
00512 {
00513 Matrix<T> diff(a) ;
00514 diff -= b ;
00515 return diff;
00516 }
00517
00531 template <class T>
00532 Matrix<T> operator*(const Matrix<T> &a,const Matrix<T> &b)
00533 {
00534 if ( a.cols() != b.rows() )
00535 {
00536 #ifdef USE_EXCEPTION
00537 throw WrongSize2D(a.rows(),a.cols(),b.rows(),b.cols()) ;
00538 #else
00539 Error error("Matrix<T> operator*(Matrix<T>&,Matrix<T>&)");
00540 error << "Matrix<T> a * Matrix<T> b incommensurate, a.cols() = " << a.cols() << ", b.rows() = " << b.rows() << endl ;
00541 error.fatal() ;
00542 #endif
00543 }
00544
00545 int i, j, k, row=a.rows(), col=b.cols(),size = a.cols();
00546 Matrix<T> prod(row,col);
00547 T zero = (T)0;
00548
00549 #ifdef COLUMN_ORDER
00550 for(i=row-1;i>=0;--i)
00551 for(j=size-1;j>=0;--j)
00552 if(a(i,j) != zero){
00553 for(k=col-1;k>=0; --k)
00554 prod(i,k) += a(i,j)* b(j,k) ;
00555 }
00556 #else
00557 T *pptr,*aptr,*bptr ;
00558 aptr = a.m ;
00559 for (i = 0; i < row; ++i)
00560 for (j = 0; j < size; ++j){
00561 if ( *aptr != zero )
00562 {
00563 pptr = prod[i]-1;
00564 bptr = b[j]-1;
00565 for (k = col; k > 0; --k){
00566 *(++pptr) += *aptr * *(++bptr);
00567 }
00568 }
00569 ++aptr;
00570 }
00571 #endif
00572 return prod;
00573
00574 }
00575
00576
00587 template <class T>
00588 Matrix<T> operator*(const double d, const Matrix<T> &a)
00589 {
00590 int i, size=a.rows()*a.cols() ;
00591 Matrix<T> b(a.rows(),a.cols());
00592
00593 T *bptr,*aptr ;
00594 bptr = b.m - 1 ;
00595 aptr = a.m - 1 ;
00596 for (i = size; i > 0; --i)
00597 *(++bptr) = (T)(d * (*(++aptr))) ;
00598 return b;
00599
00600 }
00601
00613 template <class T>
00614 Matrix<T> operator*(const Complex &d, const Matrix<T> &a)
00615 {
00616 int i, size=a.rows()*a.cols() ;
00617 Matrix<T> b(a.rows(),a.cols());
00618
00619 T *bptr,*aptr ;
00620 bptr = b.m - 1 ;
00621 aptr = a.m - 1 ;
00622 for (i = size; i > 0; --i)
00623 *(++bptr) = (T)real(d) * *(++aptr) ;
00624 return b;
00625 }
00626
00639 template <class T>
00640 Vector<T> operator*(const Matrix<T> &a, const Vector<T> &x)
00641 {
00642 if ( a.cols() != x.size() )
00643 {
00644 #ifdef USE_EXCEPTION
00645 throw WrongSize2D(a.rows(),a.cols(),x.size(),1);
00646 #else
00647 Error error("Matrix<T> operator*(Matrix<T>& a,Vector<T>& b)");
00648 error << "a * b incommensurate, a.cols() = " << a.cols() << ", b.rows() = " << x.size() << endl ;
00649 error.fatal() ;
00650 #endif
00651 }
00652
00653 int i, k, row = a.rows(), size = a.cols();
00654 Vector<T> prod(row);
00655 T zero = (T)0;
00656
00657 T *pptr,*aptr,*xptr ;
00658 aptr = a.m - 1 ;
00659 pptr = &prod[0] ;
00660 for (i = row; i > 0; --i){
00661 xptr = x.memory()-1 ;
00662 for (k = size, *pptr = zero; k > 0 ; --k)
00663 *pptr += *(++aptr) * *(++xptr) ;
00664 ++pptr ;
00665 }
00666
00667 return prod;
00668 }
00669
00670
00687 template <class T>
00688 int operator==(const Matrix<T> &a,const Matrix<T> &b)
00689 {
00690 if ( a.rows() != b.rows() || a.cols() != b.cols() )
00691 {
00692 #ifdef USE_EXCEPTION
00693 throw WrongSize2D(a.rows(),a.cols(),b.rows(),b.cols()) ;
00694 #else
00695 Error error("operator==(const Matrix<T>&,const Matrix<T>&)");
00696 if ( b.rows() != a.rows() )
00697 error << "Matrices are of diferent size, a.rows() = " << a.rows() << " and b.rows() = " << b.rows() << endl ;
00698 if ( b.cols() != a.cols())
00699 error << "Matrices are of diferent size, a.cols() = " << a.cols() << " and b.cols() = " << b.cols() << endl ;
00700 error.fatal() ;
00701 #endif
00702 }
00703
00704 int i, j, row = a.rows(), col = a.cols();
00705 int l = 1;
00706
00707 for (i = 0; i < row; ++i)
00708 for (j = 0; j < col; ++j)
00709 l = l && ( a.elem(i,j) == b.elem(i,j) );
00710
00711 return l;
00712 }
00713
00725 template <class T>
00726 Matrix<T> comm(const Matrix<T> &a,const Matrix<T> &b)
00727 {
00728 Matrix<T> r = a * b - b * a;
00729
00730 return r;
00731 }
00732
00742 template <class T>
00743 T Matrix<T>::trace() const
00744 {
00745 int size = rows();
00746 T sum = (T)0;
00747
00748 if ( size > cols() )
00749 size = cols();
00750
00751 for (int d = 0; d < size; ++d)
00752 sum += elem(d,d) ;
00753
00754 return sum;
00755 }
00756
00757
00770 template <class T>
00771 Matrix<T> Matrix<T>::herm() const
00772 {
00773 int i, j, r = cols(), c = rows();
00774 Matrix<T> adj(r,c);
00775
00776 for (i = 0; i < r; ++i)
00777 for (j = 0; j < c; ++j)
00778 adj.elem(i,j) = elem(j,i) ;
00779
00780 return adj;
00781
00782 }
00783
00794 template <class T>
00795 Matrix<T> Matrix<T>::flop() const
00796 {
00797 Matrix<T> f(rows(),cols()) ;
00798 for(int i=rows()-1;i>=0;--i)
00799 for(int j=cols()-1;j>=0;--j)
00800 {
00801 f(i,j) = elem(i,cols()-j-1);
00802 }
00803 return f;
00804 }
00805
00815 template <class T>
00816 Matrix<T> Matrix<T>::transpose() const
00817 {
00818
00819 int i, j;
00820 const int& r = cols();
00821 const int& c = rows();
00822 Matrix<T> adj(r,c);
00823
00824 for (i = r-1; i >=0; --i)
00825 for (j = c-1; j >=0; --j)
00826 adj.elem(i,j) = elem(j,i) ;
00827
00828
00829 return adj;
00830 }
00831
00832
00843 template <class T>
00844 int Matrix<T>::read(char* filename) {
00845 ifstream fin(filename) ;
00846 if(!fin) {
00847 resize(1,1) ;
00848 return 0 ;
00849 }
00850 int r,c ;
00851 char *type ;
00852 type = new char[6] ;
00853 if(!fin.read(type,sizeof(char)*6)) return 0 ;
00854 r = strncmp(type,"matrix",6) ;
00855 if(r) return 0 ;
00856 if(!fin.read((char*)&r,sizeof(int))) return 0 ;
00857 if(!fin.read((char*)&c,sizeof(int))) return 0 ;
00858 resize(r,c) ;
00859 if(!fin.read((char*)m,sizeof(T)*r*c)) return 0 ;
00860
00861 delete []type ;
00862 return 1 ;
00863 }
00864
00876 template <class T>
00877 int Matrix<T>::read(char* filename,int r, int c) {
00878 ifstream fin(filename) ;
00879 if(!fin) {
00880 resize(1,1) ;
00881 return 0 ;
00882 }
00883 resize(r,c) ;
00884 if(!fin.read((char*)m,sizeof(T)*r*c)) return 0 ;
00885
00886 return 1 ;
00887 }
00888
00889
00901 template <class T>
00902 int Matrix<T>::write(char* filename) {
00903 ofstream fout(filename) ;
00904 if(!fout)
00905 return 0 ;
00906 int r,c ;
00907 r = rows() ; c = cols() ;
00908 if(!fout.write((char*)&"matrix",sizeof(char)*6)) return 0 ;
00909 if(!fout.write((char*)&r,sizeof(int))) return 0 ;
00910 if(!fout.write((char*)&c,sizeof(int))) return 0 ;
00911 if(!fout.write((char*)m,sizeof(T)*r*c)) return 0 ;
00912 return 1;
00913 }
00914
00925 template <class T>
00926 int Matrix<T>::writeRaw(char* filename) {
00927 ofstream fout(filename) ;
00928 if(!fout)
00929 return 0 ;
00930 if(!fout.write((char*)m,sizeof(T)*rows()*cols())) return 0 ;
00931 return 1;
00932 }
00933
00934
00935 template <class T>
00936 void Matrix<T>::qSort(){
00937 #ifdef USE_EXCEPTION
00938 throw MatrixErr();
00939 #else
00940 Error error("Matrix<T>::qSort()");
00941 error << "qSort is not defined for that type.\nPlease defined it in your .cpp file!";
00942 error.fatal() ;
00943 #endif
00944 }
00945
00946
00947 }
00948
00949
00950 #endif