GEL
2
GEL is a library for Geometry and Linear Algebra
|
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