Main Page | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

fmat.h

Go to the documentation of this file.
00001 
00015 #ifndef FMAT_H
00016 #define FMAT_H
00017 
00018 #include "vec.h"
00019 #include <stdlib.h>
00020 #include <assert.h>
00021 
00022 #ifdef TNT_USE_REGIONS
00023 #include "region2d.h"
00024 #endif
00025 
00027 template <class T>
00028 class Fortran_matrix 
00029 {
00030   public:
00031 
00032     typedef         T   value_type;
00033     typedef         T   element_type;
00034     typedef         T*  pointer;
00035     typedef         T*  iterator;
00036     typedef         T&  reference;
00037     typedef const   T*  const_iterator;
00038     typedef const   T&  const_reference;
00039 
00040     Subscript lbound() const { return 1;}
00041  
00042         enum AllocMode {INTERNAL_ALLOC, EXTERNAL_ALLOC} amode; 
00043         // determine if Storage for v_ is allocated when matrix is 
00044         // created and is destroyed when matrix is destroyed or   
00045     // v points to externally allocated memory region assumed 
00046         // to be of the sufficient size (m_*n_)
00047 
00048   protected:
00049     T* v_;               
00050     Subscript m_;
00051     Subscript n_;
00052     T** col_;           
00053 
00054         int MaxSize; 
00055 
00056  
00057         // internal helper function to create the array
00058     // of row pointers
00059 
00061     void initialize(Subscript M, Subscript N)
00062     {
00063         // adjust col_[] pointers so that they are 1-offset:
00064         //   col_[j][i] is really col_[j-1][i-1];
00065         //
00066         // v_[] is the internal contiguous array, it is still 0-offset
00067         //
00068        if(M == 0 || N == 0)
00069          {
00070             m_ =  0;
00071             n_ =  0;
00072             v_ =  NULL;
00073             col_= NULL;
00074             return ;
00075          }
00076 
00077                 if(amode == INTERNAL_ALLOC) v_ = new T[M*N];
00078                 if(amode == EXTERNAL_ALLOC) assert( (M*N) <= this->MaxSize);
00079 
00080         col_ = new T*[N];
00081 
00082         assert(v_  != NULL);
00083         assert(col_ != NULL);
00084 
00085 
00086         m_ = M;
00087         n_ = N;  
00088         T* p = v_ - 1;              
00089         for (Subscript i=0; i<N; i++)
00090         {
00091             col_[i] = p;
00092             p += M ;
00093             
00094         }
00095         col_ --; 
00096     }
00097    
00098     void copy(const T*  v)
00099     {
00100         Subscript N = m_ * n_;
00101         Subscript i;
00102 
00103 #ifdef TNT_UNROLL_LOOPS
00104         Subscript Nmod4 = N & 4;
00105         Subscript N4 = N - Nmod4;
00106 
00107         for (i=0; i<N4; i+=4)
00108         {
00109             v_[i] = v[i];
00110             v_[i+1] = v[i+1];
00111             v_[i+2] = v[i+2];
00112             v_[i+3] = v[i+3];
00113         }
00114 
00115         for (i=N4; i< N; i++)
00116             v_[i] = v[i];
00117 #else
00118 
00119         for (i=0; i< N; i++)
00120             v_[i] = v[i];
00121 #endif      
00122     }
00123 
00125     void set(const T& val)
00126     {
00127         Subscript N = m_ * n_;
00128         Subscript i;
00129 
00130 #ifdef TNT_UNROLL_LOOPS
00131         Subscript Nmod4 = N & 4;
00132         Subscript N4 = N - Nmod4;
00133 
00134         for (i=0; i<N4; i+=4)
00135         {
00136             v_[i] = val;
00137             v_[i+1] = val;
00138             v_[i+2] = val;
00139             v_[i+3] = val; 
00140         }
00141 
00142         for (i=N4; i< N; i++)
00143             v_[i] = val;
00144 #else
00145 
00146         for (i=0; i< N; i++)
00147             v_[i] = val;
00148         
00149 #endif      
00150     }
00151     
00152 
00153 
00154     void destroy()
00155     {     
00156         /* do nothing, if no memory has been previously allocated */
00157         if (v_ == NULL) return ;
00158 
00159         /* if we are here, then matrix was previously allocated */
00160                 if(amode == INTERNAL_ALLOC)
00161                 {
00162                         delete [] (v_); // do not delete if externally allocated 
00163                 }
00164         col_ ++;                // changed back to 0-offset
00165         delete [] (col_);
00166     }
00167 
00168 
00169   public:
00170 
00171     T* begin() { return v_; }
00172     const T* begin() const { return v_;}
00173 
00174     T* end() { return v_ + m_*n_; }
00175     const T* end() const { return v_ + m_*n_; }
00176 
00177 
00178     // constructors
00179 
00180     Fortran_matrix() : v_(0), m_(0), n_(0), col_(0),
00181                                amode(INTERNAL_ALLOC), MaxSize(0) {}
00182 
00183     Fortran_matrix(const Fortran_matrix<T> & A)
00184     {
00185                 amode=INTERNAL_ALLOC; 
00186                 MaxSize = 0;
00187         initialize(A.m_, A.n_);
00188         copy(A.v_);
00189     }
00190 
00191     Fortran_matrix(Subscript M, Subscript N, const T& value = T(0))
00192     {
00193                 amode=INTERNAL_ALLOC; MaxSize=0;
00194         initialize(M,N);
00195         set(value);
00196     }
00197 
00198    Fortran_matrix(Subscript M, Subscript N,  T* v, 
00199                 const int New_amode=0)
00200     {
00201                 Set_amode(New_amode);
00202                 if(amode == EXTERNAL_ALLOC)
00203                 {
00204                         MaxSize=M*N;
00205                         v_= v;
00206                 }
00207         initialize(M,N);
00208         if(amode == INTERNAL_ALLOC) copy(v);
00209     }
00210 
00211 
00212 //    Fortran_matrix(Subscript M, Subscript N, const T* v, 
00213 //              const int New_amode=0)
00214 //    {
00215 //              Set_amode(New_amode);
00216 //              if(amode == EXTERNAL_ALLOC)
00217 //              {
00218 //                      MaxSize=M*N;
00219 //                      v_= v;
00220 //              }
00221 //       initialize(M,N);
00222 //        if(amode == INTERNAL_ALLOC) copy(v);
00223 //    }
00224 
00225 
00226     Fortran_matrix(Subscript M, Subscript N, char *s)
00227     {
00228                 amode=INTERNAL_ALLOC;
00229         initialize(M,N);
00230         istrstream ins(s);
00231 
00232         Subscript i, j;
00233 
00234         for (i=1; i<=M; i++)
00235             for (j=1; j<=N; j++)
00236                 ins >> (*this)(i,j);
00237     }
00238 
00239     // destructor
00240     ~Fortran_matrix()
00241     {
00242         destroy();
00243     }
00244 
00245 
00246     // assignments
00247     //
00248     Fortran_matrix<T>& operator=(const Fortran_matrix<T> &A)
00249     {
00250         if (v_ == A.v_)
00251             return *this;
00252 
00253         if (m_ == A.m_  && n_ == A.n_)      // no need to re-alloc
00254             copy(A.v_);
00255 
00256         else
00257         {
00258             destroy();
00259             initialize(A.m_, A.n_);
00260             copy(A.v_);
00261         }
00262 
00263         return *this;
00264     }
00265         
00266     Fortran_matrix<T>& operator=(const T& scalar)
00267     { 
00268         set(scalar); 
00269         return *this;
00270     }
00271 
00272 
00273     Subscript dim(Subscript d) const 
00274     {
00275 #ifdef TNT_BOUNDS_CHECK
00276        assert( d >= 1);
00277         assert( d <= 2);
00278 #endif
00279         return (d==1) ? m_ : ((d==2) ? n_ : 0); 
00280     }
00281 
00282     Subscript num_rows() const { return m_; }
00283     Subscript num_cols() const { return n_; }
00284 
00286     void newsize(Subscript M, Subscript N)
00287     {
00288         if (num_rows() == M && num_cols() == N)
00289             return;
00290 
00291         destroy();
00292         initialize(M,N);
00293 
00294         return;
00295     }
00296 
00298    void Set_amode(int mode) 
00299         { 
00300                 assert(mode == 0 || mode == 1);
00301                 if(mode == 0) amode=INTERNAL_ALLOC; 
00302                 if(mode == 1) amode=EXTERNAL_ALLOC;  
00303         }
00304 
00305         void SetMaxSize(const int NewMaxSize)
00306         {
00307                 MaxSize=NewMaxSize;
00308         }
00309 
00310 
00312     inline reference operator()(Subscript i, Subscript j)
00313     { 
00314 #ifdef TNT_BOUNDS_CHECK
00315         assert(1<=i);
00316         assert(i <= m_) ;
00317         assert(1<=j);
00318         assert(j <= n_);
00319 #endif
00320         return col_[j][i]; 
00321     }
00322 
00323     inline const_reference operator() (Subscript i, Subscript j) const
00324     {
00325 #ifdef TNT_BOUNDS_CHECK
00326         assert(1<=i);
00327         assert(i <= m_) ;
00328         assert(1<=j);
00329         assert(j <= n_);
00330 #endif
00331         return col_[j][i]; 
00332     }
00333 
00335     inline reference operator[](Subscript i)
00336     { 
00337 #ifdef TNT_BOUNDS_CHECK
00338         assert(0 <= i);
00339         assert(i <  m_*n_) ;
00340 #endif
00341         return v_[i]; 
00342     }
00343 
00344     inline const_reference operator[] (Subscript i) const
00345     {
00346 #ifdef TNT_BOUNDS_CHECK
00347         assert(0 <= i);
00348         assert(i <  m_*n_) ;
00349 #endif
00350         return v_[i]; 
00351     }
00352 
00353         inline value_type GetVal(Subscript i, Subscript j) const    
00354     {
00355 #ifdef TNT_BOUNDS_CHECK
00356         assert(1<=i);
00357         assert(i <= m_) ;
00358         assert(1<=j);
00359         assert(j <= n_);
00360 #endif
00361         return col_[j][i]; 
00362         }
00363 
00364         inline void SetVal(Subscript i, Subscript j, const value_type new_val)
00365         {
00366 #ifdef TNT_BOUNDS_CHECK
00367         assert(1<=i);
00368         assert(i <= m_) ;
00369         assert(1<=j);
00370         assert(j <= n_);
00371 #endif
00372         col_[j][i] = new_val; 
00373         }
00374 
00375         inline value_type GetVal_lidx(Subscript i) const    
00376     {
00377 #ifdef TNT_BOUNDS_CHECK
00378         assert(1<=i);
00379         assert(i <= m_*n_) ;
00380 #endif
00381         return v_[i]; 
00382         }
00383 
00384         inline void SetVal_lidx(Subscript i, const value_type new_val)
00385         {
00386 #ifdef TNT_BOUNDS_CHECK
00387         assert(1<=i);
00388         assert(i <= m_*n_) ;
00389 #endif
00390         v_[i] = new_val; 
00391         }
00392 
00393  
00394     //#ifdef __GNUC__
00395     //template <class T>   
00396     //#endif  
00397 #if defined(_MSC_VER) || defined(__xlC__)
00398 friend istream& operator>>(istream &s, Fortran_matrix<T> &A);  
00399 #else
00400 
00401 friend istream& operator>><>(istream &s, Fortran_matrix<T> &A); 
00402 #endif
00403         
00404 #ifdef TNT_USE_REGIONS
00405 
00406     typedef Region2D<Fortran_matrix<T> > Region;
00407     typedef const_Region2D<Fortran_matrix<T>,T > const_Region;
00408 
00409     Region operator()(const Index1D &I, const Index1D &J)
00410     {
00411         return Region(*this, I,J);
00412     }
00413 
00414     const_Region operator()(const Index1D &I, const Index1D &J) const
00415     {
00416         return const_Region(*this, I,J);
00417     }
00418 
00419 #endif
00420 
00421 
00422         int Print_format(ostream &sout, const char* format) const
00423         {
00424                 
00425                 char buf[120]; // set max 20 characters per number
00426                 
00427                 sout << m_ << " " << n_ << endl;
00428                 
00429                 for (Subscript i=1; i<= m_; i++)
00430                 {
00431                         for (Subscript j=1; j<= n_; j++)
00432                         {
00433                                 sprintf(buf, format, (*this)(i,j) );
00434                                 sout << buf;
00435                         }
00436                         sout << endl;
00437                 }
00438                 
00439                 return 0;
00440         }
00441 
00442     int GetSymmPart(pointer dsymm)
00443                 // get Symmetrical part of the square matrix in low-diagonal form:
00444         {
00445                 assert(dsymm != NULL);
00446                 assert(m_ == n_);
00447                 
00448                 for (Subscript i=1; i<= m_; i++)
00449                 {
00450                         for (Subscript j=1; j<= i; j++)
00451                         {
00452                                 (*dsymm)= ((*this)(i,j) + (*this)(j,i))/2;
00453                                 dsymm++;
00454                         }
00455                 }
00456                 return 1;               
00457         }
00458 
00459     int GetASymmPart(pointer dasymm)
00460     // get AntiSymmetrical part of the square matrix in lower triangular form
00461         // (diagonal inlcuded)
00462         {
00463                 assert(dasymm != NULL);
00464                 assert(m_ == n_);
00465                 
00466                 for (Subscript i=1; i<= m_; i++)
00467                 {
00468                         for (Subscript j=1; j<= i; j++)
00469                         {
00470                                 (*dasymm)= ((*this)(i,j) - (*this)(j,i))/2;
00471                                 dasymm++;
00472                         }
00473                 }
00474                 return 1;               
00475         }
00476 
00477     int AddSymmPart(pointer dsymm)
00478         // add Symmetrical matrix in low triangular form 
00479         // to the current square matrix 
00480         {
00481                 assert(dsymm != NULL);
00482                 assert(m_ == n_);
00483                 
00484                 for (Subscript i=1; i<= m_; i++)
00485                 {
00486                         for (Subscript j=1; j<= i; j++)
00487                         {
00488                                 (*this)(i,j)+= (*dsymm);
00489                                 if(i != j) (*this)(j,i)+= (*dsymm);
00490                                 dsymm++;
00491                         }
00492                 }
00493                 return 1;               
00494         }
00495 
00496     int AddASymmPart(pointer dasymm)
00497         // add AntiSymmetrical matrix in low triangular form (diagonal included)
00498         // to the current square matrix 
00499         {
00500                 assert(dasymm != NULL);
00501                 assert(m_ == n_);
00502                 
00503                 for (Subscript i=1; i<= m_; i++)
00504                 {
00505                         for (Subscript j=1; j<= i; j++)
00506                         {
00507                                 (*this)(i,j)-= (*dasymm);
00508                                 (*this)(j,i)+= (*dasymm);
00509                                 dasymm++;
00510                         }
00511                 }
00512                 return 1;               
00513         }
00514 
00515         int Symmetrize()
00516         // A= 1/2(A+A^T)
00517         {
00518                 assert(m_ == n_);
00519                 if(m_ == 0)
00520                         return 1;
00521                 for(Subscript i=1; i <= m_; i++)
00522                 {
00523                         for (Subscript j=1; j< i; j++)
00524                         {
00525                                 (*this)(i,j)= 0.5*((*this)(i,j)+ (*this)(j,i));
00526                         }
00527 
00528                 }
00529                 return 1;
00530         }
00531 
00532         int ASymmetrize()
00533         // A= 1/2(A-A^T)
00534         {
00535                 assert(m_ == n_);
00536                 if(m_ == 0)
00537                         return 1;
00538                 for(Subscript i=1; i <= m_; i++)
00539                 {
00540                         for (Subscript j=1; j< i; j++)
00541                         {
00542                                 (*this)(i,j)= 0.5*((*this)(i,j) - (*this)(j,i));
00543                                 (*this)(j,i)=-(*this)(i,j);
00544                         }
00545 
00546                 }
00547                 return 1;
00548         }
00549 
00550 };
00551 
00552 
00553 /* ***************************  I/O  ********************************/
00554 
00555 template <class T>
00556 ostream& operator<<(ostream &s, const Fortran_matrix<T> &A)
00557 {
00558     Subscript M=A.num_rows();
00559     Subscript N=A.num_cols();
00560 
00561     s << M << " " << N << endl;
00562 
00563     for (Subscript i=1; i<=M; i++)
00564     {
00565         for (Subscript j=1; j<=N; j++)
00566         {
00567             s << A(i,j) << " ";
00568         }
00569         s << endl;
00570     }
00571 
00572 
00573     return s;
00574 }
00575 
00576 
00577 
00578 template <class T>
00579 istream& operator>>(istream &s, Fortran_matrix<T> &A)
00580 {
00581 
00582     Subscript M, N;
00583 
00584     s >> M >> N;
00585 
00586     if ( !(M == A.m_ && N == A.n_) )
00587     {
00588         A.destroy();
00589         A.initialize(M,N);
00590     }
00591 
00592 
00593     for (Subscript i=1; i<=M; i++)
00594         for (Subscript j=1; j<=N; j++)
00595         {
00596             s >>  A(i,j);
00597         }
00598 
00599     return s;
00600 }
00601 
00602 //*******************[ basic matrix algorithms ]***************************
00603 
00604 
00605 template <class T>
00606 Fortran_matrix<T> operator+(const Fortran_matrix<T> &A, 
00607     const Fortran_matrix<T> &B)
00608 {
00609     Subscript M = A.num_rows();
00610     Subscript N = A.num_cols();
00611 
00612     assert(M==B.num_rows());
00613     assert(N==B.num_cols());
00614 
00615     Fortran_matrix<T> tmp(M,N);
00616     Subscript i,j;
00617 
00618     for (i=1; i<=M; i++)
00619         for (j=1; j<=N; j++)
00620             tmp(i,j) = A(i,j) + B(i,j);
00621 
00622     return tmp;
00623 }
00624 
00625 template <class T>
00626 Fortran_matrix<T> operator-(const Fortran_matrix<T> &A, 
00627     const Fortran_matrix<T> &B)
00628 {
00629     Subscript M = A.num_rows();
00630     Subscript N = A.num_cols();
00631 
00632     assert(M==B.num_rows());
00633     assert(N==B.num_cols());
00634 
00635     Fortran_matrix<T> tmp(M,N);
00636     Subscript i,j;
00637 
00638     for (i=1; i<=M; i++)
00639         for (j=1; j<=N; j++)
00640             tmp(i,j) = A(i,j) - B(i,j);
00641 
00642     return tmp;
00643 }
00644 
00645 // element-wise multiplication  (use matmult() below for matrix
00646 // multiplication in the linear algebra sense.)
00647 //
00648 //
00649 template <class T>
00650 Fortran_matrix<T> mult_element(const Fortran_matrix<T> &A, 
00651     const Fortran_matrix<T> &B)
00652 {
00653     Subscript M = A.num_rows();
00654     Subscript N = A.num_cols();
00655 
00656     assert(M==B.num_rows());
00657     assert(N==B.num_cols());
00658 
00659     Fortran_matrix<T> tmp(M,N);
00660     Subscript i,j;
00661 
00662     for (i=1; i<=M; i++)
00663         for (j=1; j<=N; j++)
00664             tmp(i,j) = A(i,j) * B(i,j);
00665 
00666     return tmp;
00667 }
00668 
00669 
00670 template <class T>
00671 Fortran_matrix<T> transpose(const Fortran_matrix<T> &A)
00672 {
00673     Subscript M = A.num_rows();
00674     Subscript N = A.num_cols();
00675 
00676     Fortran_matrix<T> S(N,M);
00677     Subscript i, j;
00678 
00679     for (i=1; i<=M; i++)
00680         for (j=1; j<=N; j++)
00681             S(j,i) = A(i,j);
00682 
00683     return S;
00684 }
00685 
00686 
00687     
00688 template <class T>
00689 inline Fortran_matrix<T> matmult(const Fortran_matrix<T>  &A, 
00690     const Fortran_matrix<T> &B)
00691 {
00692 
00693 #ifdef TNT_BOUNDS_CHECK
00694     assert(A.num_cols() == B.num_rows());
00695 #endif
00696 
00697     Subscript M = A.num_rows();
00698     Subscript N = A.num_cols();
00699     Subscript K = B.num_cols();
00700 
00701     Fortran_matrix<T> tmp(M,K);
00702     T sum;
00703 
00704     for (Subscript i=1; i<=M; i++)
00705     for (Subscript k=1; k<=K; k++)
00706     {
00707         sum = 0;
00708         for (Subscript j=1; j<=N; j++)
00709             sum = sum +  A(i,j) * B(j,k);
00710 
00711         tmp(i,k) = sum; 
00712     }
00713 
00714     return tmp;
00715 }
00716 
00717 template <class T>
00718 inline Fortran_matrix<T> operator*(const Fortran_matrix<T> &A, 
00719     const Fortran_matrix<T> &B)
00720 {
00721     return matmult(A,B);
00722 }
00723 
00724 template <class T>
00725 inline int mat_diff(Fortran_matrix<T>& C, Fortran_matrix<T>  &A, 
00726     Fortran_matrix<T> &B)
00727 // C= A-B
00728 // C may coincide with A and B
00729 {
00730 
00731     assert(A.num_cols() == B.num_cols());
00732         assert(A.num_rows() == B.num_rows());
00733 
00734     Subscript M = A.num_rows();
00735     Subscript N = A.num_cols();
00736 
00737     C.newsize(M,N);         // adjust shape of C, if necessary
00738 
00739     for(Subscript i=1; i <= M; i++)
00740         {
00741                 for(Subscript j=1; j <= N; j++)
00742                 {
00743                         C(i,j)=A(i,j)-B(i,j);
00744                 }
00745         }
00746         return 0;
00747 }
00748 
00749 template <class T>
00750 inline int mat_add(Fortran_matrix<T>& C, Fortran_matrix<T>  &A, 
00751     Fortran_matrix<T> &B)
00752 // C= A+B
00753 // C may coincide with A and B
00754 {
00755 
00756     assert(A.num_cols() == B.num_cols());
00757         assert(A.num_rows() == B.num_rows());
00758 
00759     Subscript M = A.num_rows();
00760     Subscript N = A.num_cols();
00761 
00762     C.newsize(M,N);         // adjust shape of C, if necessary
00763 
00764     for(Subscript i=1; i <= M; i++)
00765         {
00766                 for(Subscript j=1; j <= N; j++)
00767                 {
00768                         C(i,j)=A(i,j)+B(i,j);
00769                 }
00770         }
00771         return 0;
00772 }
00773 
00774 
00775 
00776 template <class T>
00777 inline int mat_add_unit(Fortran_matrix<T>& C, Fortran_matrix<T>  &A, 
00778     const T& factor)
00779 // C= A + factor*I , where I is a unit matrix
00780 // C may coincide with A 
00781 {
00782         Subscript N=A.num_rows();
00783         assert(A.num_rows() == A.num_cols());
00784     C.newsize(N,N);    // adjust shape of C, if necessary
00785         C=A;
00786         for(Subscript i=1; i<=N; i++)
00787         {
00788                 C(i,i)=C(i,i)+factor;
00789         }
00790         return 0;
00791 }
00792 
00793 template <class T>
00794 T SProd(const Fortran_matrix<T>  &A, 
00795     const Fortran_matrix<T> &B)
00796 // Scalar Product (sum of element pair product of two matricies
00797 {
00798 
00799     assert(A.num_cols() == B.num_cols());
00800         assert(A.num_rows() == B.num_rows());
00801 
00802     Subscript M = A.num_rows();
00803     Subscript N = A.num_cols();
00804         
00805         T ss;
00806     
00807     ss=0;
00808     for(Subscript i=1; i <= M; i++)
00809         {
00810                 for(Subscript j=1; j <= N; j++)
00811                 {
00812                         ss+=A(i,j)*B(i,j);
00813                 }
00814         }
00815         return ss;
00816 }
00817 
00818 
00819 template <class T>
00820 inline int mat_scale(Fortran_matrix<T>& C, Fortran_matrix<T>  &A, 
00821     const T& factor)
00822 // C= factor*A  , where I is a unit matrix
00823 // C may coincide with A 
00824 {
00825     Subscript M = A.num_rows();
00826     Subscript N = A.num_cols();
00827 
00828     Subscript MN = M*N; 
00829 
00830     C.newsize(M,N);    // adjust shape of C, if necessary
00831 
00832     const T* a = A.begin();
00833     T* t = C.begin();
00834     T* tend = C.end();
00835 
00836     for (; t < tend; t++, a++)
00837         *t = *a * factor;
00838 
00839         return 0;
00840 }
00841 
00842 template <class T>
00843 inline int mat_copy_scale(Fortran_matrix<T>& C, const Fortran_matrix<T>  &A, 
00844     const T& factor)
00845 // C= factor*A  , where I is a unit matrix
00846 // C may coincide with A 
00847 {
00848     Subscript M = A.num_rows();
00849     Subscript N = A.num_cols();
00850 
00851     Subscript MN = M*N; 
00852 
00853     C.newsize(M,N);    // adjust shape of C, if necessary
00854 
00855     const T* a = A.begin();
00856     T* t = C.begin();
00857     T* tend = C.end();
00858 
00859     for (; t < tend; t++, a++)
00860         *t = *a * factor;
00861 
00862         return 0;
00863 }
00864 
00865 template <class T>
00866 inline int matmult(Fortran_matrix<T>& C, const Fortran_matrix<T>  &A, 
00867     const Fortran_matrix<T> &B)
00868 {
00869     assert(A.num_cols() == B.num_rows());
00870 
00871     Subscript M = A.num_rows();
00872     Subscript N = A.num_cols();
00873     Subscript K = B.num_cols();
00874 
00875     C.newsize(M,K);         // adjust shape of C, if necessary
00876 
00877     T sum; 
00878 
00879     const T* row_i;
00880     const T* col_k;
00881 
00882     for (Subscript i=1; i<=M; i++)
00883     {
00884         for (Subscript k=1; k<=K; k++)
00885         {
00886             row_i = &A(i,1);
00887             col_k = &B(1,k);
00888             sum = 0;
00889             for (Subscript j=1; j<=N; j++)
00890             {
00891                 sum +=  *row_i * *col_k;
00892                 row_i += M;
00893                 col_k ++;
00894             }
00895             C(i,k) = sum; 
00896         }
00897     }
00898     return 0;
00899 }
00900 
00901 
00902 template <class T>
00903 NumVector<T> matmult(const Fortran_matrix<T>  &A, const NumVector<T> &x)
00904 {
00905 
00906 #ifdef TNT_BOUNDS_CHECK
00907     assert(A.num_cols() == x.dim());
00908 #endif
00909 
00910     Subscript M = A.num_rows();
00911     Subscript N = A.num_cols();
00912 
00913     NumVector<T> tmp(M);
00914     T sum;
00915 
00916     for (Subscript i=1; i<=M; i++)
00917     {
00918         sum = 0;
00919         for (Subscript j=1; j<=N; j++)
00920             sum = sum +  A(i,j) * x(j);
00921 
00922         tmp(i) = sum; 
00923     }
00924 
00925     return tmp;
00926 }
00927 
00928 template <class T>
00929 inline NumVector<T> operator*(const Fortran_matrix<T>  &A, const NumVector<T> &x)
00930 {
00931     return matmult(A,x);
00932 }
00933 
00934 template <class T>
00935 inline Fortran_matrix<T> operator*(const Fortran_matrix<T>  &A, const T &x)
00936 {
00937     Subscript M = A.num_rows();
00938     Subscript N = A.num_cols();
00939 
00940     Subscript MN = M*N; 
00941 
00942     Fortran_matrix<T> res(M,N);
00943     const T* a = A.begin();
00944     T* t = res.begin();
00945     T* tend = res.end();
00946 
00947     for (t=res.begin(); t < tend; t++, a++)
00948         *t = *a * x;
00949 
00950     return res;
00951 } 
00952 
00953 // my functions
00954 
00955 template <class T>
00956 void raw_copy(T* to, const T* from, const int nelem)
00957 // copy elements from the source to destination
00958 {
00959         assert(nelem > 0);
00960         assert(to != NULL); 
00961         assert(from != NULL);
00962 
00963         const T* ref=from;
00964         T* dest=to;
00965         int i=nelem;
00966         for(; i != 0; dest++, ref++, i--)
00967         {
00968                 *dest=*ref;
00969         }
00970 }
00971 
00972 template <class T>
00973 inline int matmult_T1(Fortran_matrix<T>& C, const Fortran_matrix<T>  &A, 
00974     const Fortran_matrix<T> &B)
00975 // C = A^T * B 
00976 {
00977 
00978     assert(A.num_rows() == B.num_rows());
00979 
00980     Subscript M = A.num_cols();
00981     Subscript N = A.num_rows();
00982     Subscript K = B.num_cols();
00983 
00984     C.newsize(M,K);         // adjust shape of C, if necessary
00985 
00986 
00987     T sum; 
00988 
00989     const T* col_i;
00990     const T* col_k;
00991 
00992     for (Subscript i=1; i<=M; i++)
00993     {
00994         for (Subscript k=1; k<=K; k++)
00995         {
00996             col_i = &A(1,i);
00997             col_k = &B(1,k);
00998             sum = 0;
00999             for (Subscript j=1; j<=N; j++)
01000             {
01001                 sum +=  *col_i * *col_k;
01002                 col_i ++;
01003                 col_k ++;
01004             }
01005         
01006             C(i,k) = sum; 
01007         }
01008 
01009     }
01010 
01011     return 0;
01012 }
01013 
01014 template <class T>
01015 inline int matmult_T2(Fortran_matrix<T>& C, const Fortran_matrix<T>  &A, 
01016     const Fortran_matrix<T> &B)
01017 // C = A * B^T
01018 {
01019 
01020     assert(A.num_cols() == B.num_cols());
01021 
01022     Subscript M = A.num_rows();
01023     Subscript N = A.num_cols();
01024     Subscript K = B.num_rows();
01025 
01026     C.newsize(M,K);         // adjust shape of C, if necessary
01027 
01028 
01029     T sum; 
01030 
01031     const T* row_i;
01032     const T* row_k;
01033 
01034     for (Subscript i=1; i<=M; i++)
01035     {
01036         for (Subscript k=1; k<=K; k++)
01037         {
01038             row_i = &A(i,1);
01039             row_k = &B(k,1);
01040             sum = 0;
01041             for (Subscript j=1; j<=N; j++)
01042             {
01043                 sum +=  *row_i * *row_k;
01044                 row_i += M;
01045                 row_k += K;
01046             }
01047         
01048             C(i,k) = sum; 
01049         }
01050 
01051     }
01052 
01053     return 0;
01054 }
01055 
01056 template<class NumMatrix, class NumVector>
01057 int mat_symm_from_lin(NumMatrix & smat, const NumVector & slin, Subscript n)
01058 // convert Symmetrical Matrix from linear storage to Square form
01059 // ( indexation of the matrix and the vector are assumed to be 1-based )
01060 {
01061         smat.newsize(n,n);
01062         for(Subscript i=1; i <= n ; i++)
01063         {
01064                 for(Subscript j=1; j <= n ; j++)
01065                 {
01066               smat(i,j)=((i >= j) ? slin(i*(i-1)/2 + j) : slin(j*(j-1)/2 + i));
01067                 }
01068         }
01069         return 1;
01070 }
01071 
01072 template<class NumMatrix, class NumVector>
01073 int mat_asymm_from_lin(NumMatrix & smat, NumVector & slin, Subscript n)
01074 // convert AntiSymmetrical Matrix from linear storage to Square form
01075 // ( indexation of the matrix and the vector are assumed to be 1-based )
01076 {
01077         smat.newsize(n,n);
01078         for(Subscript i=1; i <= n ; i++)
01079         {
01080                 for(Subscript j=1; j <= n ; j++)
01081                 {
01082               smat(i,j)=((i >= j) ? slin(i*(i-1)/2 + j) : -slin(j*(j-1)/2 + i));
01083                 }
01084         }
01085         return 1;
01086 }
01087 
01088 #endif
01089 // FMAT_H

Generated on Tue Feb 17 02:03:03 2004 for harlem by doxygen 1.3.6