Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

matrix.h

Go to the documentation of this file.
00001 //****************************************************
00002 //  April, 1993, University of Illinois
00003 // Copyright (C) 1993, 1994 Tianlin Wang
00004 /* Copyright (C) 1994-2003 Matvec Development Team. 
00005 
00006   This program is free software; you can redistribute it and/or
00007   modify it under the terms of the GNU Library General Public
00008   License as published by the Free Software Foundation; either
00009   version 2 of the License, or (at your option) any later version.
00010   
00011   This program is distributed in the hope that it will be useful,
00012   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014   Library General Public License for more details.
00015     
00016   You should have received a copy of the GNU Library General Public
00017   License along with this library; if not, write to the Free
00018   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00019   MA 02111-1307, USA 
00020 */
00021 
00022 #ifndef MATVEC_MATRIX_H
00023 #define MATVEC_MATRIX_H
00024 
00025 #include <string>
00026 #include <fstream>
00027 #include <cassert>
00028 #include "session.h"
00029 #include "vector.h"
00030 
00031 
00032 namespace matvec {
00033 /*!
00034    \class Matrix  vector.h
00035    \brief  A vector is a on-dimensional array with double precision
00036 
00037   \sa Matrix
00038 */
00039 
00040 
00041 template<class T> class Matrix {
00042 
00043 public:
00044    typedef         int size_type;
00045    typedef         T   value_type;
00046    typedef         T   element_type;
00047    typedef         T*  pointer;
00048    typedef         T*  iterator;
00049    typedef         T&  reference;
00050    typedef const   T*  const_iterator;
00051    typedef const   T*  const_pointer;
00052    typedef const   T&  const_reference;
00053    typedef std::reverse_iterator<iterator>reverse_iterator;
00054    typedef std::reverse_iterator<const_iterator>const_reverse_iterator;
00055 
00056    enum orientation {ROW,COLUMN};
00057 
00058    Matrix(void) { 
00059      //std::cout <<"constructor 1\n";
00060      initialize(0,0,0);  //Constructor 1
00061    } 
00062    Matrix(const size_type m,const size_type n) { 
00063      //std::cout <<"constructor 2\n";
00064      initialize(m,n,0);   //Constructor 2
00065    }
00066    Matrix(const size_type m,const size_type n,const T** a) { 
00067      //std::cout <<"constructor 3\n";
00068      initialize(m,n,a);   //Constructor 3
00069    }
00070    Matrix(const Matrix& a){ 
00071      //std::cout <<"constructor 4\n";
00072      initialize(a.nrow,a.ncol,(const T**)a.me);   //Constructor 4
00073    }
00074 
00075    T**       begin(void)       { return me; }
00076    const T** begin(void) const { return (const T**)me; }
00077 
00078    virtual ~Matrix(void){clear();}                                  // Destructor
00079 
00080    void              copy(const Matrix &a);
00081    Matrix&           assign(const Matrix &a) {copy(a); return *this;}
00082    Matrix&           assign(const T &x);
00083 
00084    Matrix&           resize(const size_type n,const size_type m, const T &val = T());
00085    Matrix&           resize(const size_type n,const size_type m, const T *a);
00086    Matrix&           resize(const Matrix& a){resize(a.ne); return *this;}
00087    Matrix&           reserve(const size_type n,const size_type m);
00088 
00089    Matrix&           operator =  (const Matrix &a) { return assign(a); }
00090    Matrix&           operator =  (const T &x)      { return assign(x); }
00091 
00092    Matrix            operator +  (const Matrix &a) const;
00093    Matrix            operator -  (const Matrix &a) const;
00094    Matrix            operator *  (const Matrix &a) const;
00095    Matrix            operator /  (const Matrix &a) const;
00096 
00097    Vector<T>         operator *  (const Vector<T> &a) const;
00098 
00099    Matrix            operator +  (const T& x) const;
00100    Matrix            operator -  (const T& x) const;
00101    Matrix            operator *  (const T& x) const;
00102    Matrix            operator /  (const T& x) const;
00103 
00104    Matrix&           operator += (const Matrix& a);
00105    Matrix&           operator -= (const Matrix& a);
00106    Matrix&           operator *= (const Matrix& a);
00107    Matrix&           operator /= (const Matrix& a);
00108    Matrix&           operator += (const T& x);
00109    Matrix&           operator -= (const T& x);
00110    Matrix&           operator *= (const T& x);
00111    Matrix&           operator /= (const T& x);
00112 
00113    T*                operator [] (const size_type i) { return me[i]; }
00114    const T*          operator [] (const size_type i) const { return me[i]; }
00115    T&                operator () (const size_type i,const size_type j);
00116    Matrix            operator -  (void) const;               //unary minus
00117    Matrix&           operator +  (void) { return *this; }      //unary plus
00118 
00119    Matrix<bool>      operator !  (void) const;
00120 
00121    Matrix<bool>      operator == (const Matrix &a) const;
00122    Matrix<bool>      operator <  (const Matrix &a) const;
00123    Matrix<bool>      operator >  (const Matrix &a) const;
00124    Matrix<bool>      operator != (const Matrix &a) const;
00125    Matrix<bool>      operator <= (const Matrix &a) const;
00126    Matrix<bool>      operator >= (const Matrix &a) const;
00127 
00128    Matrix<bool>      operator == (const T &x) const;
00129    Matrix<bool>      operator <  (const T &x) const;
00130    Matrix<bool>      operator >  (const T &x) const;
00131    Matrix<bool>      operator != (const T &x) const;
00132    Matrix<bool>      operator <= (const T &x) const;
00133    Matrix<bool>      operator >= (const T &x) const;
00134 
00135    bool              all(void) const;
00136    bool              any(void) const;
00137    bool              symmetric(void) const;
00138    bool              empty(void) const { return (nrow == 0 || ncol == 0); }
00139   bool              save(const std::string &fname,const int io_mode = std::ios::out) const;//SDK|std::ios::noreplace) const;
00140 
00141    Matrix            apply(T (*f)(T)) const;
00142    Matrix            apply(T (*f)(T,T),const Matrix &b) const;
00143    Matrix            apply(T (*f)(T,T),const T &b) const;
00144    Matrix            submat(const size_type idx1,const size_type idx2, const int len1 = 0, const int len2 = 0) const;
00145    Matrix            submat(const Matrix<bool>& a) const;
00146    Matrix            transpose(void) const;
00147    Matrix            kron(const Matrix &b) const;
00148    Matrix            reshape(const size_type m,const size_type n,orientation orient = COLUMN) const;
00149    Matrix            diag(void) const;
00150    Vector<T>         diag(const size_type k) const;
00151    Vector<T>         vec(orientation orient = COLUMN) const;
00152    Vector<T>         sum(orientation orient = COLUMN) const;
00153    Vector<T>         sumsq(orientation orient = COLUMN) const;
00154    Vector<T>         max(orientation orient = COLUMN) const;
00155    Vector<T>         min(orientation orient = COLUMN) const;
00156    virtual std::ostream&  print(std::ostream &os = std::cout) const;
00157    T                 trace(T init = T()) const;
00158    T&                at(const size_type i,const size_type j);
00159 
00160    Matrix&           sortby(orientation orient,const size_type k);
00161    int               size(void)     const { return nrow*ncol; }
00162    int               num_rows(void) const { return nrow; }
00163    int               num_cols(void) const { return ncol; }
00164    void              clear(void);
00165    void              input(const std::string &fname,
00166                            const size_type m,
00167                            const size_type n);
00168 
00169    //protected:
00170    T **me;
00171    int nrow,ncol;
00172 
00173    void initialize(const size_type m,const size_type n,const T **a);
00174 };
00175 
00176 template<class T> inline void Matrix<T>::initialize(const size_type m,const size_type n,const T **a)
00177 {
00178    if (m == 0 || n == 0) {
00179       nrow = 0; ncol = 0; me = 0;
00180    } else {
00181       nrow = m; ncol = n;
00182       me = new T* [nrow];
00183       assert( me != 0 );
00184       for (int j,i=0; i<nrow; ++i) {
00185          me[i] = new T [ncol];
00186          assert( me[i] != 0 );
00187          if (a) {
00188             for (j=0; j<ncol; ++j) me[i][j] = a[i][j];
00189          } else {
00190             for (j=0; j<ncol; ++j) me[i][j] = T();
00191          }
00192       }
00193    }
00194    return;
00195 }
00196 
00197 template<class T> inline T& Matrix<T>::at(const size_type i,const size_type j)
00198 {
00199    if (i < 0 || i >= nrow || j < 0 || j >= ncol) throw exception("Matrix<T>::at(): out of range");
00200    return me[i][j];
00201 }
00202 
00203 template<class T> inline void Matrix<T>::clear(void)
00204 {
00205    if (me) {
00206       for (int i=0; i<nrow; ++i) delete [] me[i];
00207       delete [] me;
00208       me = 0;
00209    }
00210    nrow = 0;
00211    ncol = 0;
00212 }
00213 
00214 template<class T> inline void Matrix<T>::input(const std::string &fname,
00215                                                const size_type m,
00216                                                const size_type n)
00217 {
00218    resize(m,n);
00219    std::ifstream infile(fname.c_str(),std::ios::in);//SDK | std::ios::nocreate);
00220    if (!infile) {
00221       std::cerr << fname << ": cannot open\n";
00222    } else {
00223       for (int j,i=0; i<m; ++i) for (j=0; j<n; ++j) infile >> me[i][j];
00224       infile.close();
00225    }
00226    return;
00227 }
00228 
00229 template<class T> inline void Matrix<T>::copy(const Matrix<T> & a)
00230 {
00231    if (this == &a) return;
00232    reserve(a.nrow,a.ncol);
00233 /*    for (int i=0; i<nrow; ++i) memcpy(me[i],a.me[i],sizeof(T)*ncol);  */
00234 /*    memcopy does not work correctly for complex objects RLF */
00235    for (int i=0; i<nrow; ++i) {
00236      for (int j=0; j<ncol; j++){
00237        me[i][j] = a.me[i][j];
00238      }
00239    }
00240    return;
00241 }
00242 
00243 template<class T> inline Matrix<T>& Matrix<T>::assign(const T& a)
00244 {
00245    if (me) {
00246       resize(nrow,ncol,a);
00247    } else {
00248      resize(1,1,a);
00249    }
00250    return *this;
00251 }
00252 
00253 template<class T> inline Matrix<T>& Matrix<T>::reserve(const size_type m,const size_type n)
00254 {
00255    if (m != nrow || n != ncol) {
00256       clear();
00257       nrow = m;
00258       ncol = n;
00259       if(nrow>0){
00260         me = new T* [nrow];
00261       }
00262       else {
00263         me = 0;
00264         return *this;
00265       }
00266       assert( me != 0 );
00267       for (int i=0; i<nrow; ++i) {
00268         if(ncol>0){
00269           me[i] = new T [ncol];
00270         }
00271         else {
00272           me[i] = 0;
00273         }
00274          assert( me[i] != 0 );
00275       }
00276    }
00277    return *this;
00278 }
00279 
00280 template<class T> inline Matrix<T>& Matrix<T>::resize(const size_type m,const size_type n,const T& val)
00281 {
00282    if (m == 0 || n == 0) {
00283       clear();
00284    } else {
00285       int i,j;
00286       if (m != nrow || n != ncol) {
00287          clear();
00288          nrow = m;
00289          ncol = n;
00290          me = new T* [nrow];
00291          assert( me != 0 );
00292          for (i=0; i<nrow; ++i) {
00293             me[i] = new T [ncol];
00294             assert( me[i] != 0 );
00295          }
00296       }
00297       for (i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) me[i][j] = val;
00298    }
00299    return *this;
00300 }
00301 
00302 template<class T> inline Matrix<T>& Matrix<T>::resize(const size_type m,const size_type n,const T *a)
00303 {
00304    if (m == 0 || n == 0) {
00305       clear();
00306    } else {
00307       int i,j;
00308       if (m != nrow || n != ncol) {
00309          clear();
00310          nrow = m;
00311          ncol = n;
00312          me = new T* [nrow];
00313          assert( me != 0 );
00314          for (i=0; i<nrow; ++i) {
00315             me[i] = new T [ncol];
00316             assert( me[i] != 0 );
00317          }
00318       }
00319       for (i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) me[i][j] = *a++;
00320    }
00321    return *this;
00322 }
00323 
00324 template<class T> inline T& Matrix<T>::operator () (const size_type i,size_type j)
00325 {
00326    if (i < 1 || i > nrow || j < 1 || j > ncol) throw exception("Matrix<T>::operator(): out of range");
00327    return me[i-1][j-1];
00328 }
00329 
00330 template<class T> inline Matrix<T>& Matrix<T>::operator += (const Matrix<T> &a)
00331 {
00332    if (nrow != a.nrow || ncol != a.ncol) throw exception("Matrix<T>::operator+=: size not conformable");
00333    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) me[i][j] += a[i][j];
00334    return *this;
00335 }
00336 
00337 template<class T> inline Matrix<T>& Matrix<T>::operator -= (const Matrix<T> &a)
00338 {
00339    if ( nrow != a.nrow || ncol != a.ncol ) throw exception("Matrix<T>::operator-=: size not conformable");
00340    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) me[i][j] -= a[i][j];
00341    return *this;
00342 }
00343 
00344 template<class T> inline Matrix<T>& Matrix<T>::operator *= (const Matrix<T> &a)
00345 {
00346    if (nrow != a.nrow || ncol != a.ncol) throw exception("Matrix<T>::operator*=: size not conformable");
00347    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) me[i][j] *= a[i][j];
00348    return *this;
00349 }
00350 
00351 template<class T> inline Matrix<T>& Matrix<T>::operator /= (const Matrix<T> &a)
00352 {
00353    if (nrow != a.nrow || ncol != a.ncol) throw exception("Matrix<T>::operator/=: size not conformable");
00354    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) me[i][j] /= a[i][j];
00355    return *this;
00356 }
00357 
00358 template<class T> inline Matrix<T>& Matrix<T>::operator += (const T &s)
00359 {
00360    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) me[i][j] += s;
00361    return *this;
00362 }
00363 
00364 template<class T> inline Matrix<T>& Matrix<T>::operator -= (const T &s)
00365 {
00366    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) me[i][j] -= s;
00367    return *this;
00368 }
00369 
00370 template<class T> inline Matrix<T>& Matrix<T>::operator *= (const T &s)
00371 {
00372    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) me[i][j] *= s;
00373    return *this;
00374 }
00375 
00376 template<class T> inline Matrix<T>& Matrix<T>::operator /= (const T &s)
00377 {
00378    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) me[i][j] /= s;
00379    return *this;
00380 }
00381 
00382 template<class T> inline Matrix<bool> Matrix<T>::operator == (const Matrix<T> &a) const
00383 {
00384    if (nrow != a.nrow || ncol != a.ncol)  throw exception("Matrix<T>::operator==: size not conformable");
00385    Matrix<bool> temp(nrow,ncol);
00386    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (me[i][j] == a[i][j]);
00387    return temp;
00388 }
00389 
00390 template<class T> inline Matrix<bool> Matrix<T>::operator == (const T &x) const
00391 {
00392    Matrix<bool> temp(nrow,ncol);
00393    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (me[i][j] == x);
00394    return temp;
00395 }
00396 
00397 template<class T> inline Matrix<bool> Matrix<T>::operator < (const Matrix<T>& a) const
00398 {
00399    if (nrow != a.nrow || ncol != a.ncol) throw exception("Matrix<T>::operator<: size not conformable");
00400    Matrix<bool> temp(nrow,ncol);
00401    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (me[i][j] < a[i][j]);
00402    return temp;
00403 }
00404 
00405 template<class T> inline Matrix<bool> Matrix<T>::operator < (const T &x) const
00406 {
00407    Matrix<bool> temp(nrow,ncol);
00408    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (me[i][j] < x);
00409    return temp;
00410 }
00411 
00412 template<class T> inline Matrix<bool> Matrix<T>::operator > (const Matrix<T> &a) const
00413 {
00414    if (nrow != a.nrow || ncol != a.ncol) throw exception("Matrix<T>::operator>: size not conformable");
00415    Matrix<bool> temp(nrow,ncol);
00416    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (me[i][j] > a[i][j]);
00417    return temp;
00418 }
00419 
00420 template<class T> inline Matrix<bool> Matrix<T>::operator > (const T &x) const
00421 {
00422    Matrix<bool> temp(nrow,ncol);
00423    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (me[i][j] > x);
00424    return temp;
00425 }
00426 
00427 template<class T> inline Matrix<bool> Matrix<T>::operator != (const Matrix<T> &a) const
00428 {
00429    if (nrow != a.nrow || ncol != a.ncol) throw exception("Matrix<T>::operator!=: size not conformable");
00430    Matrix<bool> temp(nrow,ncol);
00431    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (me[i][j] != a[i][j]);
00432    return temp;
00433 }
00434 
00435 template<class T> inline Matrix<bool> Matrix<T>::operator != (const T &x) const
00436 {
00437    Matrix<bool> temp(nrow,ncol);
00438    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (me[i][j] != x);
00439    return temp;
00440 }
00441 
00442 template<class T> inline Matrix<bool> Matrix<T>::operator <= (const Matrix<T> &a) const
00443 {
00444    if (nrow != a.nrow || ncol != a.ncol) throw exception("Matrix<T>::operator<=: size not conformable");
00445    Matrix<bool> temp(nrow,ncol);
00446    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (me[i][j] <= a[i][j]);
00447    return temp;
00448 }
00449 
00450 template<class T> inline Matrix<bool> Matrix<T>::operator <= (const T &x) const
00451 {
00452    Matrix<bool> temp(nrow,ncol);
00453    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (me[i][j] <= x);
00454    return temp;
00455 }
00456 
00457 
00458 template<class T> inline Matrix<bool> Matrix<T>::operator >= (const Matrix<T> &a) const
00459 {
00460    if (nrow != a.nrow || ncol != a.ncol) throw exception("Matrix<T>::operator>=: size not conformable");
00461    Matrix<bool> temp(nrow,ncol);
00462    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (me[i][j] >= a[i][j]);
00463    return temp;
00464 }
00465 
00466 template<class T> inline Matrix<bool> Matrix<T>::operator >= (const T &x) const
00467 {
00468    Matrix<bool> temp(nrow,ncol);
00469    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (me[i][j] >= x);
00470    return temp;
00471 }
00472 
00473 template<class T> inline Matrix<T> Matrix<T>::operator + (const Matrix<T> &a) const
00474 {
00475    if (nrow != a.nrow || ncol != a.ncol) throw exception("Matrix<T>::operator+: size not conformable");
00476    Matrix<T> temp(nrow,ncol);
00477    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = me[i][j] + a.me[i][j];
00478    return temp;
00479 }
00480 
00481 template<class T> inline Matrix<T> Matrix<T>::operator - (const Matrix<T> &a) const
00482 {
00483    if (nrow != a.nrow || ncol != a.ncol) throw exception("Matrix<T>::operator-: size not conformable");
00484    Matrix<T> temp(nrow,ncol);
00485    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = me[i][j] - a.me[i][j];
00486    return temp;
00487 }
00488 
00489 template<class T> inline Matrix<T> Matrix<T>::operator * (const Matrix<T> &a) const
00490 {
00491    if (ncol != a.nrow) throw exception("Matrix<T>::operator*: size not conformable");
00492    Matrix<T> temp(nrow,a.ncol);
00493    T x;
00494    for (int t,j,i=0; i<nrow; ++i) {
00495       for (j=0; j<a.ncol; ++j) {
00496          x = T();
00497          for (t=0; t<ncol; ++t) x += me[i][t]*a[t][j];
00498          temp[i][j] = x;
00499       }
00500    }
00501    return temp;
00502 }
00503 
00504 template<class T> inline Vector<T> Matrix<T>::operator * (const Vector<T> &a) const
00505 {
00506    if (ncol != a.size()) throw exception("Matrix<T>::operator*: size not conformable");
00507    Vector<T> temp(nrow);
00508    T x;
00509    for (int j,i=0; i<nrow; ++i) {
00510       x = T();
00511       for (j=0; j<ncol; ++j)  x += me[i][j]*a[j];
00512       temp[i] = x;
00513    }
00514    return temp;
00515 }
00516 
00517 template<class T> inline Matrix<T> Matrix<T>::operator / (const Matrix<T> &a) const
00518 {
00519    if (nrow != a.nrow || ncol != a.ncol) throw exception("Matrix<T>::operator/: size not conformable");
00520    Matrix<T> temp(nrow,ncol);
00521    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = me[i][j] / a.me[i][j];
00522    return temp;
00523 }
00524 
00525 
00526 template<class T> inline Matrix<T> Matrix<T>::operator + (const T &a) const
00527 {
00528    Matrix<T> temp(nrow,ncol);
00529    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = me[i][j] + a;
00530    return temp;
00531 }
00532 
00533 template<class T> inline Matrix<T> Matrix<T>::operator - (const T &a) const
00534 {
00535    Matrix<T> temp(nrow,ncol);
00536    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = me[i][j] - a;
00537    return temp;
00538 }
00539 
00540 template<class T> inline Matrix<T> Matrix<T>::operator * (const T &a) const
00541 {
00542    Matrix<T> temp(nrow,ncol);
00543    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = me[i][j] * a;
00544    return temp;
00545 }
00546 
00547 template<class T> inline Matrix<T> Matrix<T>::operator / (const T &a) const
00548 {
00549    Matrix<T> temp(nrow,ncol);
00550    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = me[i][j] / a;
00551    return temp;
00552 }
00553 
00554 template<class T> inline Matrix<T> Matrix<T>::operator - (void) const  //unary minus
00555 {
00556    Matrix<T> temp(nrow,ncol);
00557    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = - me[i][j];
00558    return temp;
00559 }
00560 
00561 template<class T> inline Matrix<bool> Matrix<T>::operator ! (void) const  //unary negative
00562 {
00563    Matrix<bool> temp(nrow,ncol);
00564    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = ! me[i][j];
00565    return temp;
00566 }
00567 
00568 template<class T> inline bool Matrix<T>::all(void) const
00569 {
00570    if (!me) return false;
00571    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) if (me[i][j] == false) return false;
00572    return true;
00573 }
00574 
00575 template<class T> inline bool Matrix<T>::any(void) const
00576 {
00577    if (!me) return false;
00578    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) if (me[i][j] == true) return true;
00579    return false;
00580 }
00581 
00582 template<class T> inline bool Matrix<T>::symmetric(void) const
00583 {
00584    if (!me) return false;
00585    for (int j,i=1; i<nrow; ++i) for (j=0; j<i; ++j) if (me[i][j] != me[j][i]) return false;
00586    return true;
00587 }
00588 
00589 template<class T> inline bool Matrix<T>::save(const std::string &fname,const int io_mode) const
00590 {
00591    std::ofstream ofs(fname.c_str(),(OpenModeType)io_mode);
00592    if (ofs) {
00593       print(ofs);
00594       ofs.close();
00595    } else {
00596       std::cerr << fname << ": cannot open\n";
00597    }
00598    return true;
00599 }
00600 
00601 template<class T> inline T Matrix<T>::trace(T init) const
00602 {
00603    int n = std::min(nrow,ncol);
00604    for (int i=0; i<n; ++i) init += me[i][i];
00605    return init;
00606 }
00607 
00608 template<class T> inline Matrix<T> Matrix<T>::apply(T (*f)(T)) const
00609 {
00610    Matrix<T> temp(nrow,ncol);
00611    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (*f)(me[i][j]);
00612    return temp;
00613 }
00614 
00615 template<class T> inline Matrix<T> Matrix<T>::apply(T (*f)(T,T),const Matrix &b) const
00616 {
00617    if (nrow != b.nrow || ncol != b.ncol) throw exception("Matrix<T>::apply(): size not conformable");
00618    Matrix<T> temp(nrow,ncol);
00619    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (*f)(me[i][j],b[i][j]);
00620    return temp;
00621 }
00622 
00623 template<class T> inline Matrix<T> Matrix<T>::apply(T (*f)(T,T),const T &b) const
00624 {
00625    Matrix<T> temp(nrow,ncol);
00626    for (int j,i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[i][j] = (*f)(me[i][j],b);
00627    return temp;
00628 }
00629 
00630 template<class T> inline Matrix<T> Matrix<T>::submat(const size_type idx1,const size_type idx2, const int len1, const int len2) const
00631 {
00632    int ir,ic,i,j,t,k;
00633    if (len1 == 0) {
00634       ir = nrow - 1;
00635    } else {
00636       ir = idx1 + len1 - 1;
00637    }
00638    if (len2 == 0) {
00639       ic = ncol - 1;
00640    } else {
00641       ic = idx2 + len2 - 1;
00642    }
00643    Matrix<T> temp(len1,len2);
00644    for (i=idx1; i<= ir; ++i) {
00645       t = i - idx1;
00646       for (j=idx2; j<=ic; ++j) {
00647          k = j - idx2;
00648          temp[t][k] = me[i][j];
00649       }
00650    }
00651    return temp;
00652 }
00653 
00654 template<class T> inline Matrix<T> Matrix<T>::submat(const Matrix<bool> &v) const
00655 {
00656    int n = 0;
00657 //   int m = v.size();
00658 //   bool *ve_pt = v.ve;
00659 //   int i;
00660 //   for (i=0; i<m; i++) if (*ve_pt++) n++;
00661 //
00662    Matrix<T> temp(n);
00663 //   T *t_pt = temp.begin();
00664 //   ve_pt = v.ve;
00665 //   for (i=0; i<m; i++) if (*ve_pt++) *t_pt++ = ve[i];
00666    return temp;
00667 }
00668 
00669 template<class T> inline Matrix<T> Matrix<T>::transpose(void) const
00670 {
00671    Matrix<T> temp(ncol,nrow);
00672    for (int j,i=0; i<ncol; ++i) for (j=0; j<nrow; ++j) temp[i][j] = me[j][i];
00673    return temp;
00674 }
00675 
00676 template<class T> inline Matrix<T> Matrix<T>::kron(const Matrix<T> &b) const
00677 {
00678    Matrix<T> temp(nrow*b.nrow,ncol*b.ncol);
00679    int i,j,k,t,ii,iii,jj,jjj;
00680    for (i=0; i<nrow; ++i) {
00681       ii = i*b.nrow;
00682       for (j=0; j<ncol; ++j) {
00683          jj = j*b.ncol;
00684          iii = ii;
00685          for (k=0; k<b.nrow; ++k) {
00686             jjj = jj;
00687             for (t=0; t<b.ncol; ++t) temp[iii][jjj++] = me[i][j]*b[k][t];
00688             iii++;
00689          }
00690       }
00691    }
00692    return temp;
00693 }
00694 
00695 template<class T> inline Matrix<T> Matrix<T>::reshape(const size_type m,const size_type n,orientation orient) const
00696 {
00697    Matrix<T> temp(m,n);
00698    int i,j,t,k;
00699    if (orient == ROW) {
00700       for (t=0,k=0,i=0; i<m; ++i) for (j=0; j<n; ++j) {
00701          if (k >= ncol) {
00702             t++;
00703             if (t >= nrow) return temp;
00704             k = 0;
00705          }
00706          temp[i][j] = me[t][k++];
00707       }
00708    } else if (orient == COLUMN) {
00709       for (t=0,k=0,i=0; i<m; ++i) for (j=0; j<n; ++j) {
00710          if (t >= nrow) {
00711             k++;
00712             if (k >= ncol) return temp;
00713             t = 0;
00714          }
00715          temp[i][j] = me[t++][k];
00716       }
00717    } else {
00718       std::cerr << "unknow orientation\n";
00719       exit(1);
00720    }
00721    return temp;
00722 }
00723 
00724 template<class T> inline Matrix<T> Matrix<T>::diag(void) const
00725 {
00726    int n = std::min(nrow,ncol);
00727    Matrix<T> temp(n,n);
00728    for (int i=0; i<n; ++i) temp[i][i] = me[i][i];
00729    return temp;
00730 }
00731 
00732 template<class T> inline Vector<T> Matrix<T>::diag(const size_type k) const
00733 {
00734    int i,n = std::min(nrow,ncol) - std::abs(k);
00735    Vector<T> temp(n);
00736    if (k >= 0) {
00737       for (i=0; i<n; i++) temp[i] = me[i][i+k];
00738    } else {
00739       for (i=0; i<n; i++) temp[i] = me[i-k][i];
00740    }
00741    return temp;
00742 }
00743 
00744 template<class T> inline Vector<T> Matrix<T>::vec(orientation orient) const
00745 {
00746    Vector<T> temp;
00747    if (!me) return temp;
00748    temp.reserve(nrow*ncol);
00749    int i,j,t=0;
00750    if (orient == ROW) {
00751       for (i=0; i<nrow; ++i) for (j=0; j<ncol; ++j) temp[t++] = me[i][j];
00752    } else if (orient == COLUMN)  {
00753       for (j=0; j<ncol; ++j) for (i=0; i<nrow; ++i) temp[t++] = me[i][j];
00754    } else {
00755       std::cerr << "unknow orientation\n";
00756       exit(1);
00757    }
00758    return temp;
00759 }
00760 
00761 template<class T> inline Vector<T> Matrix<T>::sum(orientation orient) const
00762 {
00763    Vector<T> temp;
00764    if (!me) return temp;
00765    int i,j;
00766    T init;
00767    if (orient == ROW) {
00768       temp.reserve(nrow);
00769       for (i=0; i<nrow; ++i) {
00770          init = T();
00771          for (j=0; j<ncol; ++j) init += me[i][j];
00772          temp[i] = init;
00773       }
00774    } else if (orient == COLUMN)  {
00775       temp.reserve(ncol);
00776       for (j=0; j<ncol; ++j) {
00777          init = T();
00778          for (i=0; i<nrow; ++i) init += me[i][j];
00779          temp[j] = init;
00780       }
00781    } else {
00782       std::cerr << "unknow orientation\n";
00783       exit(1);
00784    }
00785    return temp;
00786 }
00787 
00788 template<class T> inline Vector<T> Matrix<T>::sumsq(orientation orient) const
00789 {
00790    Vector<T> temp;
00791    if (!me) return temp;
00792    int i,j;
00793    T init;
00794    if (orient == ROW) {
00795       temp.reserve(nrow);
00796       for (i=0; i<nrow; ++i) {
00797          init = T();
00798          for (j=0; j<ncol; ++j) init += me[i][j]*me[i][j];
00799          temp[i] = init;
00800       }
00801    } else if (orient == COLUMN)  {
00802       temp.reserve(ncol);
00803       for (j=0; j<ncol; ++j) {
00804          init = T();
00805          for (i=0; i<nrow; ++i) init += me[i][j]*me[i][j];
00806          temp[j] = init;
00807       }
00808    } else {
00809       std::cerr << "unknow orientation\n";
00810       exit(1);
00811    }
00812    return temp;
00813 }
00814 
00815 template<class T> inline Vector<T> Matrix<T>::max(orientation orient) const
00816 {
00817    Vector<T> temp;
00818    if (!me) return temp;
00819    int i,j;
00820    if (orient == ROW) {
00821       temp.reserve(nrow);
00822       for (i=0; i<nrow; ++i) {
00823          temp[i] = me[i][0];
00824          for (j=0; j<ncol; ++j) if (me[i][j] > temp[i]) temp[i] = me[i][j];
00825       }
00826    } else if (orient == COLUMN)  {
00827       temp.reserve(ncol);
00828       for (j=0; j<ncol; ++j) {
00829          temp[j] = me[0][j];
00830          for (i=0; i<nrow; ++i) if (me[i][j] > temp[j]) temp[j] = me[i][j];
00831       }
00832    } else {
00833       std::cerr << "unknow orientation\n";
00834       exit(1);
00835    }
00836    return temp;
00837 }
00838 
00839 template<class T> inline Vector<T> Matrix<T>::min(orientation orient) const
00840 {
00841    Vector<T> temp;
00842    if (!me) return temp;
00843    int i,j;
00844    if (orient == ROW) {
00845       temp.reserve(nrow);
00846       for (i=0; i<nrow; ++i) {
00847          temp[i] = me[i][0];
00848          for (j=1; j<ncol; ++j) if (me[i][j] < temp[i]) temp[i] = me[i][j];
00849       }
00850    } else if (orient == COLUMN)  {
00851       temp.reserve(ncol);
00852       for (j=0; j<ncol; ++j) {
00853          temp[j] = me[0][j];
00854          for (i=1; i<nrow; ++i) if (me[i][j] < temp[j]) temp[j] = me[i][j];
00855       }
00856    } else {
00857       std::cerr << "unknow orientation\n";
00858       exit(1);
00859    }
00860    return temp;
00861 }
00862 
00863 template<class T> inline std::ostream& Matrix<T>::print(std::ostream &os) const
00864 {
00865    int i,j;
00866    for (i=0; i<nrow; ++i) {
00867      for (j=0; j<ncol; ++j)  {
00868         os << ' ' ;
00869         os.width(8) ;
00870         os.precision(SESSION.output_precision) ;
00871         os << me[i][j];
00872      }
00873       os <<  "\n";
00874    }
00875    return os;
00876 }
00877 
00878 template<class T> inline Matrix<T>& Matrix<T>::sortby(orientation orient,const size_type t)
00879 {
00880     int n = 1;
00881     Vector<int> by(n);
00882     by[0] = t;
00883 
00884     int nstack = 100;
00885     int l,r,i,j,k,j1;
00886     T a1,a2;
00887     Vector<T> x(n);                         // allocating for x
00888     Matrix<int> stack(2,nstack);              // allocating for stack
00889     int s = 0;
00890     stack[s][s] = 0;
00891 
00892    if (orient == COLUMN) {
00893       stack[1][0] = nrow-1;
00894       do {
00895          l = stack[0][s]; r = stack[1][s]; s -= 1;
00896          do {
00897             i = l; j = r; j1 = (l+r)/2;
00898             for (k=0; k<n; k++)  x[k] = me[j1][by[k]];
00899             do {
00900                k = 0;
00901                while (k < n) {
00902                   a1 = me[i][by[k]]; a2 = x[k];
00903                   if (a1 < a2) {
00904                      i += 1; k = 0;
00905                   }
00906                   else if (a1 == a2) {
00907                      k += 1;
00908                   }
00909                   else if (a1 > a2) break;
00910                }
00911                k = 0;
00912                while (k < n) {
00913                   a1 = me[j][by[k]]; a2 = x[k];
00914                   if (a1 > a2) {
00915                      j -= 1; k = 0;
00916                   }
00917                   else if (a1 == a2) {
00918                      k += 1;
00919                   }
00920                   else if (a1 < a2) break;
00921                }
00922 
00923                if (i <= j) {
00924                   for (k=0; k<ncol; k++) {
00925                      a1 = me[i][k];
00926                      me[i][k] = me[j][k];
00927                      me[j][k] = a1;
00928                   }
00929                   i += 1;  j -= 1;
00930                }
00931             } while (i <= j);
00932             if (i < r) {
00933                s += 1;
00934                if (s >= nstack-1) {
00935                   std::cerr << " NSTACK " << nstack << " too small in SORTQR\n";
00936                   s = -1;
00937                   break;
00938                }
00939                stack[0][s] = i;  stack[1][s] = r;
00940             }
00941             r = j;
00942          } while (l < r);
00943       } while (s >= 0);
00944    } else if (orient == ROW) {
00945       stack[1][0] = ncol - 1;
00946       do {
00947          l = stack[0][s]; r = stack[1][s]; s -= 1;
00948          do {
00949             i = l; j = r; j1 = (l+r)/2;
00950             for (k=0; k<n; k++)  x[k] = me[by[k]][j1];
00951             do {
00952                k = 0;
00953                while (k < n) {
00954                   a1 = me[by[k]][i]; a2 = x[k];
00955                   if (a1 < a2) {
00956                      i += 1; k = 0;
00957                   }
00958                   else if (a1 == a2) {
00959                      k += 1;
00960                   }
00961                   else if (a1 > a2) break;
00962                }
00963                k = 0;
00964                while (k < n) {
00965                   a1 = me[by[k]][j]; a2 = x[k];
00966                   if (a1 > a2) {
00967                      j -= 1; k = 0;
00968                   }
00969                   else if (a1 == a2) {
00970                      k += 1;
00971                   }
00972                   else if (a1 < a2) break;
00973                }
00974                if (i <= j) {
00975                   for (k=0; k<nrow; k++) {
00976                      a1 = me[k][i];
00977                      me[k][i] = me[k][j];
00978                      me[k][j] = a1;
00979                   }
00980                   i += 1;  j -= 1;
00981                }
00982             } while (i <= j);
00983             if (i < r) {
00984                s += 1;
00985                if (s >= nstack-1) {
00986                   std::cerr << " NSTACK " << nstack << " too small in SORTQR\n";
00987                   s = -1;
00988                   break;
00989                }
00990                stack[0][s] = i;  stack[1][s] = r;
00991             }
00992             r = j;
00993          } while (l < r);
00994       } while (s >= 0);
00995    } else {
00996       std::cerr << "unknow orientation\n";
00997       exit(1);
00998    }
00999    return *this;
01000 }
01001 
01002 /////////// the following are friend functions/operator /////////
01003 
01004 /////////// the following are template functions/operator ///////////////
01005 template<class T> inline Matrix<T> operator / (const T &a,const Matrix<T> &b)
01006 {
01007    Matrix<T> temp(b.num_rows(),b.num_cols());
01008    for (int j,i=0; i<b.num_rows(); ++i) for (j=0; j<b.num_cols(); ++j) temp[i][j] = a/b[i][j];
01009    return temp;
01010 }
01011 
01012 template<class T> inline Vector<T> operator * (const Vector<T> &a,const Matrix<T> &b)
01013 {
01014    if (a.size() != b.num_rows()) throw exception("Matrix<T>::operator*: size not conformable");
01015    Vector<T> temp(b.num_cols());
01016    T** me = b.begin();
01017    T x;
01018    for (int i,j=0; j<b.num_cols(); ++j) {
01019       x = T();
01020       for (i=0; i<b.num_rows(); ++i)  x += a[i] * me[i][j];
01021       temp[j] = x;
01022    }
01023    return temp;
01024 }
01025 
01026 template<class T> inline Matrix<T> hadjoin (const Matrix<T> &a,const Matrix<T> &b)
01027 {
01028    if (a.num_rows() != b.num_rows()) throw exception("Matrix<T>::hadjoin(): size not conformable");
01029    Matrix<T> temp(a.num_rows(),a.num_cols() + b.num_cols());
01030    for (int i=0; i<a.num_rows(); ++i) {
01031       memcpy(temp[i],a[i],sizeof(T)*a.num_cols());
01032       memcpy(&(temp[i][a.num_cols()]),b[i],sizeof(T)*b.num_cols());
01033    }
01034    return temp;
01035 }
01036 
01037 template<class T> inline Matrix<T> hadjoin (const Matrix<T> &a,const Vector<T> &b)
01038 {
01039    if (a.num_rows() != b.size()) throw exception("Matrix<T>::hadjoin(): size not conformable");
01040    Matrix<T> temp(a.num_rows(),a.num_cols() + 1);
01041    for (int i=0; i<a.num_rows(); ++i) {
01042       memcpy(temp[i],a[i],sizeof(T)*a.num_cols());
01043       temp[i][a.num_cols()] = b[i];
01044    }
01045    return temp;
01046 }
01047 
01048 template<class T> inline Matrix<T> hadjoin (const Vector<T> &a,const Matrix<T> &b)
01049 {
01050    if (a.size() != b.num_rows()) throw exception("Matrix<T>::hadjoin(): size not conformable");
01051    Matrix<T> temp(a.size(),1 + b.num_cols());
01052    for (int i=0; i<a.size(); ++i) {
01053       temp[i][0] = a[i];
01054       memcpy(&(temp[i][1]),b[i],sizeof(T)*b.num_cols());
01055    }
01056    return temp;
01057 }
01058 
01059 template<class T> inline Matrix<T> vadjoin (const Matrix<T> &a,const Matrix<T> &b)
01060 {
01061    if (a.num_cols() != b.num_cols()) throw exception("Matrix<T>::vadjoin(): size not conformable");
01062    Matrix<T> temp(a.num_rows() + b.num_rows(),a.num_cols());
01063    for (int i,j=0; j<a.num_cols(); ++j) {
01064       for (i=0; i<a.num_rows(); ++i) temp[i][j] = a[i][j];
01065       for (i=0; i<b.num_rows(); ++i) temp[a.num_rows() + i][j] = b[i][j];
01066    }
01067    return temp;
01068 }
01069 
01070 template<class T> inline Matrix<T> vadjoin (const Matrix<T> &a,const Vector<T> &b)
01071 {
01072    if (a.num_cols() != b.size())  throw exception("Matrix<T>::vadjoin(): size not conformable");
01073    Matrix<T> temp(a.num_rows() + 1,a.num_cols());
01074    for (int i,j=0; j<a.num_cols(); ++j) {
01075       for (i=0; i<a.num_rows(); ++i) temp[i][j] = a[i][j];
01076       temp[a.num_rows()][j] = b[j];
01077    }
01078    return temp;
01079 }
01080 
01081 template<class T> inline Matrix<T> vadjoin (const Vector<T> &a,const Matrix<T> &b)
01082 {
01083    if (a.size() != b.num_cols())  throw exception("Matrix<T>::vadjoin(): size not conformable");
01084    Matrix<T> temp(1 + b.num_rows(),b.num_cols());
01085    for (int i,j=0; j<b.num_cols(); ++j) {
01086       temp[0][j] = a[j];
01087       for (i=0; i<b.num_rows(); ++i) temp[1 + i][j] = b[i][j];
01088    }
01089    return temp;
01090 }
01091 
01092 template<class T> inline Matrix<T> diag (const Vector<T> &a)
01093 {
01094    Matrix<T> temp(a.size(),a.size());
01095    for (int i=0; i<a.size(); ++i) temp[i][i] = a[i];
01096    return temp;
01097 }
01098 
01099 template<class T> inline Matrix<T> diag (const Matrix<T> &a) { return a.diag(); }
01100 
01101 
01102 template<class T> Matrix<T> sin  (const Matrix<T> &a) { return a.apply(std::sin); }
01103 template<class T> Matrix<T> asin (const Matrix<T> &a) { return a.apply(std::asin); }
01104 template<class T> Matrix<T> cos  (const Matrix<T> &a) { return a.apply(std::cos); }
01105 template<class T> Matrix<T> acos (const Matrix<T> &a) { return a.apply(std::acos); }
01106 template<class T> Matrix<T> tan  (const Matrix<T> &a) { return a.apply(std::tan); }
01107 template<class T> Matrix<T> atan (const Matrix<T> &a) { return a.apply(std::atan); }
01108 template<class T> Matrix<T> ceil (const Matrix<T> &a) { return a.apply(std::ceil); }
01109 template<class T> Matrix<T> floor(const Matrix<T> &a) { return a.apply(std::floor); }
01110 template<class T> Matrix<T> log  (const Matrix<T> &a) { return a.apply(std::log); }
01111 template<class T> Matrix<T> log10(const Matrix<T> &a) { return a.apply(std::log10); }
01112 template<class T> Matrix<T> exp  (const Matrix<T> &a) { return a.apply(std::exp); }
01113 template<class T> Matrix<T> sqrt (const Matrix<T> &a) { return a.apply(std::sqrt); }
01114 template<class T> Matrix<T> abs  (const Matrix<T> &a) { return a.apply(std::abs); }
01115 template<class T> Matrix<T> erf  (const Matrix<T> &a) { return a.apply(erf); }
01116 template<class T> Matrix<T> erfc (const Matrix<T> &a) { return a.apply(erfc); }
01117 
01118 template<class T> bool all (const Matrix<T> &a)       { return a.all();}
01119 template<class T> bool any (const Matrix<T> &a)       { return a.any();}
01120 
01121 template<class T> Matrix<T> operator + (const T &a,const Matrix<T> &b) { return b + a; }
01122 template<class T> Matrix<T> operator - (const T &a,const Matrix<T> &b) { return -b + a; }
01123 template<class T> Matrix<T> operator * (const T &a,const Matrix<T> &b) { return b * a; }
01124 template<class T> Matrix<T> operator / (const T &a,const Matrix<T> &b);
01125 template<class T> std::ostream&  operator << (std::ostream &os, const Matrix<T> &a) { return a.print(os); }
01126 
01127 } ////// end of namespace matvec
01128 
01129 
01130 #endif

Generated on Thu Jun 16 17:13:46 2005 for Matvec by doxygen1.2.16