GEL  2
GEL is a library for Geometry and Linear Algebra
/Users/jab/Documents/Teaching/02585/GEL2_and_demos/GEL/src/LinAlg/Matrix.h
Go to the documentation of this file.
00001 #if !defined(MATRIX_H_HAA_AGUST_2001)
00002 #define MATRIX_H_HAA_AGUST_2001
00003 
00004 #include <cassert>
00005 #include <iostream>
00006 #include <cmath>
00007 #include "Vector.h"
00008 #include "CGLA/ArithMatFloat.h"
00009 
00010 namespace LinAlg
00011 {
00012 
00064         template <class T>
00065         class CMatrixType 
00066         {
00067                 friend class CVectorType<T>;
00068 
00069         private:
00071                 int nRows;
00073                 int nCols;
00075                 int nElems;
00077                 T* Data;
00079                 T** Ilife;
00080         
00082                 void SetScalar(const T& Scalar) 
00083                 {
00084                         T* Itt=Data;
00085                         T* Stop=&(Data[nElems]);
00086                         while(Itt!=Stop)
00087                                 {
00088                                         *Itt=Scalar;
00089                                         ++Itt;
00090                                 }
00091                 } 
00092         
00094                 void CleanUp(void)
00095                 {
00096                         if(Data!=NULL) 
00097                                 delete [] Data; 
00098                         if(Ilife!=NULL) 
00099                                 delete [] Ilife;
00100                 };
00101         
00103                 void Allocate(void)
00104                 { 
00105                         Data= new T[nElems]; 
00106                         Ilife=new T*[nRows];    
00107                         for(int cRow=0;cRow<nRows;cRow++) 
00108                                 Ilife[cRow]=&Data[cRow*nCols];
00109                 };
00110         
00111         public:
00113 
00114                 CMatrixType<T>() : nRows(0),nCols(0),nElems(0),Data(NULL),Ilife(NULL) {};
00115 
00116                 CMatrixType<T>(const int Row,const int Col) : nRows(Row),nCols(Col),nElems(Row*Col) {Allocate();}
00117 
00118                 CMatrixType<T>(const int Row,const int Col,const T& Scalar) : nRows(Row),nCols(Col),nElems(Row*Col) {Allocate(); SetScalar(Scalar);};
00119 
00120                 CMatrixType<T>(const CMatrixType<T>& Rhs) : nRows(Rhs.nRows),nCols(Rhs.nCols),nElems(Rhs.nRows*Rhs.nCols) 
00121                 { 
00122                         Allocate();
00123                         memcpy(Data,Rhs.Data,nElems*sizeof(T));
00124                 }
00125 
00126                 template <class VVT, class HVT, class MT, unsigned int ROWS>
00127                 CMatrixType<T>(const CGLA::ArithMatFloat<VVT,HVT,MT,ROWS>& Rhs): 
00128                         nRows(Rhs.get_v_dim()),nCols(Rhs.get_h_dim()),
00129                         nElems(nRows*nCols) 
00130                 { 
00131                         Allocate();
00132                         for(int i=0;i<nElems;++i)
00133                                 Data[i] = Rhs.get()[i];
00134                 }
00135 
00136                 CMatrixType<T>(const CVectorType<T>& Rhs) : nRows(Rhs.Length()),nCols(1),nElems(Rhs.Length()) 
00137                 { 
00138                         Allocate();
00139                         memcpy(Data,Rhs.Data,nElems*sizeof(T));
00140                 }
00141                 virtual ~CMatrixType<T>(){CleanUp();};
00143 
00150                 CMatrixType<T>& operator=(const T& Rhs){ SetScalar(Rhs);return *this;}
00151 
00152     CMatrixType<T>& operator=(const CMatrixType<T>& Rhs)
00153                 { 
00154                         Resize(Rhs.nRows,Rhs.nCols); 
00155                         memcpy(Data,Rhs.Data,nElems*sizeof(T));
00156                         return *this;
00157                 }
00158 
00159                 template <class VVT, class HVT, class MT, unsigned int ROWS>
00160                 CMatrixType<T>& operator=(const CGLA::ArithMatFloat<VVT,HVT,MT,ROWS>& Rhs)
00161                 { 
00162                         Resize(Rhs.get_v_dim(),Rhs.get_h_dim()); 
00163                         for(int i=0;i<nElems;++i)
00164                                 Data[i] = Rhs.get()[i];
00165                         return *this;
00166                 }
00167 
00168                 CMatrixType<T>& operator=(const CVectorType<T>&Rhs)
00169                 {
00170                         Resize(Rhs.Lenght(),1);
00171                         memcpy(Data,Rhs.Dat,nElems*sizeof(T));
00172                         return *this;
00173                 }
00175 
00176 
00182 
00183                 const int Rows(void) const {return nRows;};
00185                 const int Cols(void) const {return nCols;};
00187                 void Resize(const int Row,const int Col)
00188                 {
00189                         if(Row!=nRows || Col!=nCols)
00190                                 {
00191                                         CleanUp();
00192                                         nRows=Row;
00193                                         nCols=Col;
00194                                         nElems=Row*Col;
00195                                         Data= new T[nElems];
00196                                         Ilife=new T*[nRows];
00197                                         for(int cRow=0;cRow<nRows;cRow++)
00198                                                 {
00199                                                         Ilife[cRow]=&Data[cRow*nCols];
00200                                                 }
00201                                 }
00202                 }
00204         
00212                 T* operator[](const int Row) 
00213                 {
00214                         assert(Row>=0);
00215                         assert(Row<nRows);
00216                 
00217                         return Ilife[Row];
00218                 }
00219         
00220                 const T* operator[](const int Row) const 
00221                 {
00222                         assert(Row>=0);
00223                         assert(Row<nRows);
00224                 
00225                         return Ilife[Row];
00226                 }
00227 
00228                 const T& get(const int Row,const int Col) const
00229                 {
00230                         assert(Row>=0 && Row<nRows);
00231                         assert(Col>=0 && Col<nCols);
00232                         return Ilife[Row][Col];
00233                 }
00234 
00235                 void set(const int Row,const int Col,const T val) 
00236                 {
00237                         assert(Row>=0 && Row<nRows);
00238                         assert(Col>=0 && Col<nCols);
00239                         Ilife[Row][Col]=val;
00240                 }
00242         
00248                 CMatrixType<T> operator+(const T& Rhs) const {CMatrixType<T>Ret(*this); return Ret+=Rhs;};
00249                 CMatrixType<T> operator-(const T& Rhs) const {CMatrixType<T>Ret(*this); return Ret-=Rhs;};
00250                 CMatrixType<T> operator*(const T& Rhs) const {CMatrixType<T>Ret(*this); return Ret*=Rhs;};
00251                 CMatrixType<T> operator/(const T& Rhs) const {CMatrixType<T>Ret(*this); return Ret/=Rhs;};
00252                 CMatrixType<T>& operator+=(const T& Rhs)
00253                 {
00254 
00255                         T* Itt=Data;
00256                         T* Stop=&(Data[nElems]);
00257                         while(Itt!=Stop)
00258                                 {
00259                                         (*Itt)+=Rhs;
00260                                         ++Itt;
00261                                 }
00262                 
00263                         return *this; 
00264                 }
00265         
00266                 CMatrixType<T>& operator-=(const T& Rhs)
00267                 {
00268                         T* Itt=Data;
00269                         T* Stop=&(Data[nElems]);
00270                         while(Itt!=Stop)
00271                                 {
00272                                         (*Itt)-=Rhs;
00273                                         ++Itt;
00274                                 }
00275                 
00276                         return *this; 
00277                 }
00278         
00279                 CMatrixType<T>& operator*=(const T& Rhs)
00280                 {
00281                         T* Itt=Data;
00282                         T* Stop=&(Data[nElems]);
00283                         while(Itt!=Stop)
00284                                 {
00285                                         (*Itt)*=Rhs;
00286                                         ++Itt;
00287                                 }
00288                 
00289                         return *this; 
00290                 }
00291         
00292                 CMatrixType<T>& operator/=(const T& Rhs)
00293                 {
00294                         T* Itt=Data;
00295                         T* Stop=&(Data[nElems]);
00296                         while(Itt!=Stop)
00297                                 {
00298                                         (*Itt)/=Rhs;
00299                                         ++Itt;
00300                                 }
00301                 
00302                         return *this; 
00303                 }
00304 
00305                 CMatrixType<T> operator+(const CMatrixType<T>& Rhs) const {CMatrixType<T>Ret(*this); return Ret+=Rhs;};
00306                 CMatrixType<T> operator-(const CMatrixType<T>& Rhs) const {CMatrixType<T>Ret(*this); return Ret-=Rhs;};
00307 
00308                 CMatrixType<T>& operator+=(const CMatrixType<T>& Rhs)
00309                 {
00310                         assert(nRows==Rhs.nRows);
00311                         assert(nCols==Rhs.nCols);
00312 
00313                         T* IttRhs=Rhs.Data;
00314                         T* Itt=Data;
00315                         T* Stop=&(Data[nElems]);
00316                         while(Itt!=Stop)
00317                                 {
00318                                         (*Itt)+=(*IttRhs);
00319                                         ++Itt;
00320                                         ++IttRhs;
00321                                 }
00322 
00323                         return *this; 
00324                 }
00325         
00326                 CMatrixType<T>& operator-=(const CMatrixType<T>& Rhs)
00327                 {
00328                         assert(nRows==Rhs.nRows);
00329                         assert(nCols==Rhs.nCols);
00330                         T* IttRhs=Rhs.Data;
00331                         T* Itt=Data;
00332                         T* Stop=&(Data[nElems]);
00333                         while(Itt!=Stop)
00334                                 {
00335                                         (*Itt)-=(*IttRhs);
00336                                         ++Itt;
00337                                         ++IttRhs;
00338                                 }
00339                         return *this; 
00340                 }
00341 
00342                 CMatrixType<T> operator* (const CMatrixType<T>& Rhs) const
00343                 {
00344                         assert(nCols==Rhs.nRows);
00345                         CMatrixType<T> Ret(nRows,Rhs.nCols);
00346 
00347                         for(int cRow=0;cRow<nRows;cRow++)
00348                                 {
00349                                         for(int cCol=0;cCol<Rhs.nCols;cCol++)
00350                                                 {
00351                                                         T* Ret_ij=&(Ret[cRow][cCol]);
00352                                                         *Ret_ij=0;
00353                                                         for(int cI=0;cI<nCols;cI++)
00354                                                                 {
00355                                                                         (*Ret_ij)+=(Ilife[cRow])[cI]*Rhs[cI][cCol];
00356                                                                 }
00357                                                 }
00358                                 }
00359                         return Ret;
00360                 }
00361 
00362                 CVectorType<T> operator* (const CVectorType<T>& Rhs) const 
00363                 {
00364                         assert(nCols==Rhs.nElems);
00365                         CVectorType<T> Ret(nRows,0);
00366 
00367                         T* ThisItt=Data;
00368                         T* Stop=&(Data[nElems]);
00369                         T* RhsItt;
00370                         T* RetItt=Ret.Data;
00371                         while(ThisItt!=Stop)
00372                                 {
00373                                         RhsItt=Rhs.Data;
00374                                         for(int cCol=nCols;cCol>0;--cCol)
00375                                                 {
00376                                                         (*RetItt)+=(*RhsItt)*(*ThisItt);
00377                                                         ++ThisItt;
00378                                                         ++RhsItt;
00379                                                 }
00380                                         ++RetItt;
00381                                 }
00382                         return Ret;
00383                 }
00385         
00391 
00392                 CMatrixType<T>& Transpose(void)
00393                 {
00394                         T* NewData =new T[nElems];
00395                         T*RowP;
00396                         int cRow;
00397                         for(cRow=0;cRow<nRows;cRow++)
00398                                 {
00399                                         RowP=Ilife[cRow];
00400                                         for(int cCol=0;cCol<nCols;cCol++)
00401                                                 {
00402                                                         NewData[cCol*nRows+cRow]=RowP[cCol];
00403                                                 }
00404                                 }
00405                 
00406                         CleanUp();
00407                 
00408                         Data=NewData;
00409                         int temp=nRows;
00410                         nRows=nCols;
00411                         nCols=temp;
00412                         Ilife=new T*[nRows];    
00413                         for(cRow=0;cRow<nRows;cRow++) 
00414                                 {
00415                                         Ilife[cRow]=&Data[cRow*nCols];
00416                                 }
00417                 
00418                         return *this;
00419                 }
00420 
00422                 void Transposed(CMatrixType<T>& AT) const
00423                 {
00424                         AT.Resize(nCols,nRows);
00425                         for(int cRow=nRows-1;cRow>=0;--cRow)
00426                                 {
00427                                         for(int cCol=nCols-1;cCol>=0;--cCol)
00428                                                 {
00429                                                         AT[cCol][cRow]=Ilife[cRow][cCol];
00430                                                 }
00431                                 }
00432                 }
00433 
00435                 CMatrixType<T> Transposed(void) const
00436                 {
00437                         CMatrixType<T> Ret(nCols,nRows);
00438                         Transposed(Ret);
00439                         return Ret;
00440                 }
00442 
00443 
00450 
00451                 void ElemMult(const CMatrixType<T>& Rhs)
00452                 {
00453                         T*Itt=Data;
00454                         T*Stop=&(Data[nElems]);
00455                         T*RhsItt=Rhs.Data;
00456                         while(Itt!=Stop)
00457                                 {
00458                                         (*Itt)*=(*RhsItt);
00459                                         ++Itt;
00460                                         ++RhsItt;
00461                                 }
00462                 }
00463 
00465                 void ElemDiv(const CMatrixType<T>& Rhs)
00466                 {
00467                         T*Itt=Data;
00468                         T*Stop=&(Data[nElems]);
00469                         T*RhsItt=Rhs.Data;
00470                         while(Itt!=Stop)
00471                                 {
00472                                         (*Itt)/=(*RhsItt);
00473                                         ++Itt;
00474                                         ++RhsItt;
00475                                 }
00476                 }
00477 
00479                 void ElemSqr(void)
00480                 {
00481                         T*Itt=Data;
00482                         T*Stop=&(Data[nElems]);
00483                         while(Itt!=Stop)
00484                                 {
00485                                         (*Itt)*=(*Itt);
00486                                         ++Itt;
00487                                 }
00488                 }
00489 
00491                 void ElemSqrt(void)
00492                 {
00493                         T*Itt=Data;
00494                         T*Stop=&(Data[nElems]);
00495                         while(Itt!=Stop)
00496                                 {
00497                                         (*Itt)=sqrt(*Itt);
00498                                         ++Itt;
00499                                 }
00500                 }
00502 
00508 
00509                 const T NormMax(void) const
00510                 {
00511                         T Ret=0;
00512                         T Abs;
00513                         const T*Itt=Data;
00514                         const T*Stop=&(Data[nElems]);
00515                         while(Itt!=Stop)
00516                                 {
00517                                         Abs=(*Itt)>0?(*Itt):-(*Itt);
00518                                         if(Ret<Abs)
00519                                                 Ret=Abs;
00520 
00521                                         ++Itt;
00522                                 }
00523                         return Ret;
00524                 }
00525 
00527                 const T NormFrobenius(void) const
00528                 {
00529                         T Ret=0;
00530                         const T*Itt=Data;
00531                         const T*Stop=&(Data[nElems]);
00532                         while(Itt!=Stop)
00533                                 {
00534                                         Ret+=(*Itt)*(*Itt);
00535                                         ++Itt;
00536                                 }
00537                         return sqrt(Ret);
00538                 }
00540 
00541 
00547 
00548                 void GetRow(CVectorType<T>& Row,const int cRow) const
00549                 {
00550                         Row.Resize(nCols);
00551                         memcpy(Row.Data,Ilife[cRow],nCols*sizeof(T));
00552                 }
00553 
00555                 void SetRow(CVectorType<T>& Row,const int cRow)
00556                 {
00557                         assert(Row.Length()==nCols);
00558                         memcpy(Ilife[cRow],Row.Data,nCols*sizeof(T));
00559                 }
00560 
00562                 void RowTransfere(CMatrixType<T>& A, const int from,const int to) const
00563                 {
00564                         assert(A.Cols()==nCols);
00565                         memcpy(A.Ilife[to],Ilife[from],nCols*sizeof(T));
00566                 }
00567 
00568                 void GetCol(CVectorType<T>&Col, const int nCol) const
00569                 {
00570                         Col.Resize(nRows);
00571                         const T* Itt=&Data[nCol];
00572                         T* VecItt=&Col[0];
00573                         for(int cRow=0;cRow<nRows;cRow++)
00574                                 {
00575                                         *VecItt=*Itt;
00576                                         ++VecItt;
00577                                         Itt+=nCols;
00578                                 }
00579                 }
00580 
00581                 void SetCol(CVectorType<T>&Col, const int nCol)
00582                 {
00583                         assert(nRows==Col.Length());
00584                         assert(nCol<nCols);
00585 
00586                         T* Itt=&Data[nCol];
00587                         T* VecItt=&Col[0];
00588                         for(int cRow=0;cRow<nRows;cRow++)
00589                                 {
00590                                         *Itt=*VecItt;
00591                                         ++VecItt;
00592                                         Itt+=nCols;
00593                                 }
00594                 }
00595 
00596                 void GetSubMatrix(CMatrixType<T>& A, const int StartRow, const int StartCol, const int RowDim, const int ColDim) const
00597                 {
00598                         assert(StartRow+RowDim<=nRows);
00599                         assert(StartCol+ColDim<=nCols);
00600                         A.Resize(RowDim,ColDim);
00601                         const T* Itt=&(Ilife[StartRow][StartCol]);
00602 
00603                         for(int cRow=0;cRow<A.Rows();cRow++)
00604                                 {
00605                                         memcpy(A[cRow],Itt,A.Cols()*sizeof(T));
00606                                         Itt+=nCols;
00607                                 }
00608                 }
00609 
00610                 void SetSubMatrix(CMatrixType<T>& A, const int StartRow, const int StartCol)
00611                 {
00612                         assert(A.Rows()+StartRow<=nRows);
00613                         assert(A.Cols()+StartCol<=nCols);
00614                         T* Itt=&(Ilife[StartRow][StartCol]);
00615 
00616                         for(int cRow=0;cRow<A.Rows();cRow++)
00617                                 {
00618                                         memcpy(Itt,A[cRow],A.Cols()*sizeof(T));
00619                                         Itt+=nCols;
00620                                 }
00621                 }
00622 
00624 
00625 
00626 
00627         };
00628 
00635         template<class T>
00636         inline CMatrixType<T> operator+(const T& Lhs,const CMatrixType<T>&Rhs ) 
00637         {
00638                 return Rhs+Lhs;
00639         }
00640 
00641         template<class T>
00642         inline CMatrixType<T> operator*(const T& Lhs,const CMatrixType<T>&Rhs ) 
00643         {
00644                 return Rhs*Lhs;
00645         }
00646 
00647         template <class T>
00648         std::ostream& operator<<(std::ostream &s, const CMatrixType<T> &A)
00649         {
00650     int nRows=A.Rows();
00651     int nCols=A.Cols();
00652         
00653     for (int cRow=0; cRow<nRows; cRow++)
00654                         {
00655         for (int cCol=0; cCol<nCols; cCol++)
00656                                         {
00657             s << A[cRow][cCol] << " ";
00658                                         }
00659         s << "\n";
00660                         }
00661     return s;
00662         }
00663 
00664         template <class T>
00665         std::istream& operator>>(std::istream &s, CMatrixType<T> &A)
00666         {
00667     int nRows;
00668                 int nCols;
00669 
00670     s >> nRows >> nCols;
00671 
00672     if ( nRows!=A.Rows() || nCols!=A.Cols() )
00673                         A.Resize(nRows,nCols);
00674 
00675                 T* RowP;
00676 
00677 
00678     for (int cRow=0; cRow<nRows;cRow++)
00679                         {
00680                                 RowP=A[cRow];
00681         for (int cCol=0;cCol<nCols;cCol++)
00682                                         {
00683             s >>  RowP[cCol];
00684                                         }
00685                         }
00686 
00687     return s;
00688         }
00690 
00692         typedef CMatrixType<double> CMatrix;
00693 }
00694 #endif // !defined(MATRIX_H_HAA_AGUST_2001)
00695 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations