00001
00002 #ifndef IG_MATRIX_H
00003 #define IG_MATRIX_H
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <iostream>
00027 #include <iomanip>
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 namespace CwMtx
00043 {
00044 using std::ostream;
00045
00046
00047 enum { N_NOTALLOCATED, N_ALLOCATED, N_MAPPED };
00048
00049
00050
00051
00052 template <class T> class CWTUnity
00053 {
00054 public:
00055 operator T() { return 1; }
00056 };
00057
00058 template <class T> class CWTZero
00059 {
00060 public:
00061 operator T() { return 0; }
00062 };
00063
00064
00065
00066
00067
00068
00069
00070
00071 template < class T = double >
00072 class CWTMatrix
00073 {
00074 public:
00075 typedef T element;
00076
00077
00078 CWTMatrix();
00079
00080 CWTMatrix(unsigned, unsigned);
00081 CWTMatrix(const CWTMatrix &);
00082
00083 CWTMatrix(const CWTMatrix &, unsigned, unsigned, unsigned, unsigned);
00084
00085
00086 ~CWTMatrix() { deallocate(); };
00087
00088
00089 void dimension(unsigned, unsigned);
00090
00091 void mapInto(const CWTMatrix&, unsigned, unsigned, unsigned, unsigned);
00092
00093 void deallocate();
00094
00095 int getStatus() const { return m_nMatStatus; };
00096 unsigned getRows() const { return m_crow; };
00097 unsigned getCols() const { return m_ccol; };
00098
00099
00100
00101
00102 T* operator [](unsigned irow) { return m_rgrow[irow]; };
00103
00104 const T* operator [](unsigned irow) const { return m_rgrow[irow]; };
00105
00106 CWTMatrix operator +(const CWTMatrix &) const;
00107 CWTMatrix operator -(const CWTMatrix &) const;
00108 CWTMatrix operator -() const;
00109 CWTMatrix operator *(const T &) const;
00110 CWTMatrix operator *(const CWTMatrix &) const;
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 CWTMatrix operator /(const T &value) const
00122 {
00123
00124
00125
00126 T tTmp = CWTUnity<T>();
00127 tTmp /= value;
00128 return (*this)*tTmp;
00129 }
00130
00131
00132 CWTMatrix & operator =(const CWTMatrix &);
00133 CWTMatrix & operator +=(const CWTMatrix &);
00134 CWTMatrix & operator -=(const CWTMatrix &);
00135 CWTMatrix & operator *=(const T &);
00136 CWTMatrix & operator /=(const T &value)
00137 {
00138
00139
00140
00141 T tTmp = CWTUnity<T>();
00142 tTmp /= value;
00143 return (*this) *= tTmp;
00144 }
00145
00146 int operator ==(const CWTMatrix &) const;
00147 int operator !=(const CWTMatrix &mat) const { return !( (*this) == mat ); }
00148
00149
00150 void storeSum(const CWTMatrix &, const CWTMatrix &);
00151
00152 void storeProduct(const CWTMatrix &, const CWTMatrix &);
00153
00154 void storeTranspose(const CWTMatrix &);
00155
00156 void storeAtPosition(unsigned, unsigned, const CWTMatrix &);
00157
00158 void fill(const T &);
00159
00160 void interchangeRows(unsigned, unsigned);
00161 void addRowToRow(unsigned, unsigned, const T & = CWTUnity<T>());
00162 void multiplyRow(unsigned, const T &);
00163
00164 private:
00165
00166 void initialize();
00167
00168
00169
00170
00171
00172 unsigned m_crow;
00173
00174 unsigned m_ccol;
00175
00176 T **m_rgrow;
00177
00178 int m_nMatStatus;
00179 };
00180
00181
00182
00183
00184
00185
00186
00187 template <class T, unsigned crow, unsigned ccol>
00188 class CWTMat: public T
00189 {
00190 public:
00191 CWTMat(): T(crow, ccol) {}
00192
00193 T & operator =(const T &mtx) { return T::operator=(mtx); }
00194 };
00195
00196
00197
00198
00199
00200 template <class T, unsigned crow, unsigned ccol>
00201 class CWTZero< CWTMat<CWTMatrix<T>, crow, ccol> >:
00202 public CWTMat<CWTMatrix<T>, crow, ccol>
00203 {
00204 public:
00205 CWTZero() { fill(CWTZero<T>()); }
00206 };
00207
00208
00209
00210
00211
00212 template < class T >
00213 inline CWTMatrix<T>::CWTMatrix()
00214 {
00215 initialize();
00216 };
00217
00218
00219 template < class T >
00220 inline CWTMatrix<T>::CWTMatrix(unsigned crow, unsigned ccol)
00221 {
00222 initialize();
00223 dimension(crow, ccol);
00224 }
00225
00226 template < class T >
00227 inline CWTMatrix<T>::CWTMatrix(const CWTMatrix<T> &mat)
00228 {
00229 initialize();
00230
00231 if (mat.m_nMatStatus == N_NOTALLOCATED)
00232 {
00233
00234 return;
00235 }
00236 else
00237 {
00238
00239 (*this) = mat;
00240 }
00241 }
00242
00243
00244 template < class T >
00245 inline CWTMatrix<T>::CWTMatrix(const CWTMatrix<T> &mat,
00246 unsigned irowStart,
00247 unsigned icolStart,
00248 unsigned irowEnd,
00249 unsigned icolEnd)
00250 {
00251 initialize();
00252 mapInto(mat, irowStart, icolStart, irowEnd, icolEnd);
00253 }
00254
00255
00256
00257
00258
00259
00260 template < class T >
00261 inline void CWTMatrix<T>::initialize()
00262 {
00263 m_crow = 0;
00264 m_ccol = 0;
00265 m_rgrow = NULL;
00266 m_nMatStatus = N_NOTALLOCATED;
00267 }
00268
00269
00270
00271
00272
00273 template < class T >
00274 void CWTMatrix<T>::dimension(unsigned crowInit, unsigned ccolInit)
00275 {
00276 if (m_nMatStatus != N_NOTALLOCATED)
00277 {
00278 deallocate();
00279 }
00280
00281 m_crow = crowInit;
00282 m_ccol = ccolInit;
00283
00284 #ifdef CC_CWTMTX_ASSUME_BASIC_TYPES
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 m_rgrow = reinterpret_cast<T **>(malloc(m_crow*sizeof(T *)
00298 + m_crow*m_ccol*sizeof(T)));
00299 T *ptTmp = reinterpret_cast<T *>(&(m_rgrow[m_crow]));
00300 #else
00301
00302
00303 m_rgrow = new T*[m_crow];
00304 T *ptTmp = new T[m_crow*m_ccol];
00305 #endif
00306
00307
00308 for (unsigned irow = 0; irow < m_crow; ++irow)
00309 {
00310 m_rgrow[irow] = &(ptTmp[irow*m_ccol]);
00311 }
00312
00313 m_nMatStatus = N_ALLOCATED;
00314 }
00315
00316
00317
00318
00319 template < class T >
00320 void CWTMatrix<T>::mapInto(const CWTMatrix<T> &mat,
00321 unsigned irowStart,
00322 unsigned icolStart,
00323 unsigned irowEnd,
00324 unsigned icolEnd )
00325 {
00326 if (m_nMatStatus != N_NOTALLOCATED)
00327 {
00328 deallocate();
00329 }
00330
00331
00332 m_crow = irowEnd - irowStart + 1;
00333
00334
00335 m_ccol = icolEnd - icolStart + 1;
00336
00337
00338 #ifdef CC_CWTMTX_ASSUME_BASIC_TYPES
00339 m_rgrow = reinterpret_cast<T **>(malloc(m_crow*sizeof(T *)));
00340 #else
00341 m_rgrow = new T*[m_crow];
00342 #endif
00343
00344 for (unsigned irow = 0; irow < m_crow; ++irow)
00345 {
00346
00347 m_rgrow[irow] = &mat.m_rgrow[irow + irowStart][icolStart];
00348 }
00349
00350 m_nMatStatus = N_MAPPED;
00351 }
00352
00353
00354 template < class T >
00355 void CWTMatrix<T>::deallocate()
00356 {
00357
00358 switch (m_nMatStatus)
00359 {
00360 case N_NOTALLOCATED:
00361
00362 break;
00363
00364 case N_MAPPED:
00365
00366 #ifdef CC_CWTMTX_ASSUME_BASIC_TYPES
00367 free(m_rgrow);
00368 #else
00369 delete [] m_rgrow;
00370 #endif
00371 break;
00372
00373 case N_ALLOCATED:
00374
00375 #ifdef CC_CWTMTX_ASSUME_BASIC_TYPES
00376
00377
00378 free(m_rgrow);
00379 #else
00380
00381
00382 delete [] *m_rgrow;
00383 delete [] m_rgrow;
00384 #endif
00385 break;
00386 };
00387
00388
00389 initialize();
00390 }
00391
00392 template < class T >
00393 CWTMatrix<T>
00394 CWTMatrix<T>::operator +(const CWTMatrix<T> &mat) const
00395 {
00396
00397 return CWTMatrix( *this ) += mat;
00398 }
00399
00400 template < class T >
00401 CWTMatrix<T>
00402 CWTMatrix<T>::operator -(const CWTMatrix<T> &mat) const
00403 {
00404
00405 return CWTMatrix( *this ) -= mat;
00406 }
00407
00408 template < class T >
00409 CWTMatrix<T> CWTMatrix<T>::operator -() const
00410 {
00411
00412
00413
00414 T tTmp = CWTZero<T>();
00415 tTmp -= CWTUnity<T>();
00416 return (*this)*tTmp;
00417 }
00418
00419 template < class T >
00420 CWTMatrix<T> CWTMatrix<T>::operator *(const T &value) const
00421 {
00422
00423 return CWTMatrix( *this ) *= value;
00424 }
00425
00426 template < class T >
00427 CWTMatrix<T>
00428 CWTMatrix<T>::operator *(const CWTMatrix<T> &mat) const
00429 {
00430
00431 CWTMatrix matResult( m_crow , mat.m_ccol );
00432
00433 matResult.storeProduct( *this , mat );
00434 return matResult;
00435 }
00436
00437
00438 template < class T >
00439 CWTMatrix<T> &
00440 CWTMatrix<T>::operator =(const CWTMatrix<T> &mat)
00441 {
00442 if (m_nMatStatus == N_NOTALLOCATED)
00443 {
00444
00445 dimension(mat.m_crow, mat.m_ccol);
00446 }
00447
00448
00449
00450
00451 for (unsigned irow = 0; irow < m_crow; ++irow)
00452 {
00453 for (unsigned icol = 0; icol < m_ccol; ++icol)
00454 {
00455 m_rgrow[irow][icol] = mat.m_rgrow[irow][icol];
00456 }
00457 }
00458
00459 return *this;
00460 }
00461
00462 template < class T >
00463 CWTMatrix<T> &
00464 CWTMatrix<T>::operator +=(const CWTMatrix<T> &mat)
00465 {
00466 for (unsigned irow = 0; irow < m_crow; ++irow)
00467 {
00468 for (unsigned icol = 0; icol < m_ccol; ++icol)
00469 {
00470 m_rgrow[irow][icol] += mat.m_rgrow[irow][icol];
00471 }
00472 }
00473
00474 return *this;
00475 }
00476
00477 template < class T >
00478 CWTMatrix<T> &
00479 CWTMatrix<T>::operator -=(const CWTMatrix<T> &mat)
00480 {
00481 for (unsigned irow = 0; irow < m_crow; ++irow)
00482 {
00483 for (unsigned icol = 0; icol < m_ccol; ++icol)
00484 {
00485 m_rgrow[irow][icol] -= mat.m_rgrow[irow][icol];
00486 }
00487 }
00488
00489 return *this;
00490 }
00491
00492 template < class T >
00493 CWTMatrix<T> & CWTMatrix<T>::operator *=(const T &value)
00494 {
00495 for (unsigned irow = 0; irow < m_crow; ++irow)
00496 {
00497 for (unsigned icol = 0; icol < m_ccol; ++icol)
00498 {
00499 m_rgrow[irow][icol] *= value;
00500 }
00501 }
00502
00503 return *this;
00504 }
00505
00506 template < class T >
00507 int CWTMatrix<T>::operator ==(const CWTMatrix<T> &mat) const
00508 {
00509 if ((m_crow == mat.m_crow) && (m_ccol == mat.m_ccol))
00510 {
00511 for (unsigned irow = 0; irow < m_crow; ++irow)
00512 {
00513 for (unsigned icol = 0; icol < m_ccol; ++icol)
00514 {
00515 if (m_rgrow[irow][icol] != mat.m_rgrow[irow][icol])
00516 {
00517 return 0;
00518 }
00519 }
00520 }
00521
00522 return 1;
00523 }
00524 else
00525 {
00526 return 0;
00527 }
00528 }
00529
00530
00531 template < class T >
00532 void CWTMatrix<T>::storeSum(const CWTMatrix<T> &mat1,
00533 const CWTMatrix<T> &mat2)
00534 {
00535
00536
00537
00538 for (unsigned irow = 0; irow < m_crow; ++irow)
00539 {
00540 for (unsigned icol = 0; icol < m_ccol; ++icol)
00541 {
00542 m_rgrow[irow][icol] =
00543 mat1.m_rgrow[irow][icol] + mat2.m_rgrow[irow][icol];
00544 }
00545 }
00546 }
00547
00548
00549 template < class T >
00550 void CWTMatrix<T>::storeProduct(const CWTMatrix<T> &mat1,
00551 const CWTMatrix<T> &mat2)
00552 {
00553
00554
00555
00556 for (unsigned irow = 0; irow < m_crow; ++irow)
00557 {
00558 for (unsigned icol = 0; icol < m_ccol; ++icol)
00559 {
00560 m_rgrow[irow][icol] = CWTZero<T>();
00561
00562 for (unsigned icol2 = 0; icol2 < mat1.m_ccol; ++icol2)
00563 {
00564 m_rgrow[irow][icol] +=
00565 mat1.m_rgrow[irow][icol2]*mat2.m_rgrow[icol2][icol];
00566 }
00567 }
00568 }
00569 }
00570
00571
00572 template < class T >
00573 void CWTMatrix<T>::storeAtPosition(unsigned irowStart,
00574 unsigned icolStart,
00575 const CWTMatrix<T> &mat)
00576 {
00577 for (unsigned irow = 0; irow < mat.m_crow; ++irow)
00578 {
00579 for (unsigned icol = 0; icol < mat.m_ccol; ++icol)
00580 {
00581 m_rgrow[irow + irowStart][icol + icolStart] =
00582 mat.m_rgrow[irow][icol];
00583 }
00584 }
00585 }
00586
00587
00588 template < class T >
00589 void CWTMatrix<T>::storeTranspose(const CWTMatrix<T> &mat)
00590 {
00591
00592
00593
00594 for (unsigned irow = 0; irow < m_crow; ++irow)
00595 {
00596 for (unsigned icol = 0; icol < m_ccol; ++icol)
00597 {
00598 m_rgrow[irow][icol] = mat.m_rgrow[icol][irow];
00599 }
00600 }
00601 }
00602
00603 template < class T >
00604 inline void CWTMatrix<T>::fill(const T &elemFill)
00605 {
00606 unsigned iEnd = m_crow*m_ccol;
00607
00608 for (unsigned i = 0; i < iEnd; ++i)
00609 {
00610 (*m_rgrow)[i] = elemFill;
00611 }
00612 }
00613
00614 template < class T >
00615 void CWTMatrix<T>::interchangeRows(unsigned irow1, unsigned irow2)
00616 {
00617 T* rowSav = m_rgrow[irow1];
00618
00619
00620 m_rgrow[irow1] = m_rgrow[irow2];
00621 m_rgrow[irow2] = rowSav;
00622 }
00623
00624 template < class T >
00625 void CWTMatrix<T>::multiplyRow(unsigned irow, const T &value)
00626 {
00627 for (unsigned icol = 0; icol < m_ccol; ++icol)
00628 {
00629 m_rgrow[irow][icol] *= value;
00630 }
00631 }
00632
00633 template < class T >
00634 void CWTMatrix<T>::addRowToRow(unsigned irowSrc,
00635 unsigned irowDest,
00636 const T &value)
00637 {
00638 for (unsigned icol = 0; icol < m_ccol; ++icol)
00639 {
00640 m_rgrow[irowDest][icol] += m_rgrow[irowSrc][icol]*value;
00641 }
00642 }
00643
00644
00645
00646
00647
00648 template < class T >
00649 inline CWTMatrix<T> operator *(const T &value,
00650 const CWTMatrix<T> &mat)
00651 {
00652 return mat*value;
00653 }
00654
00655 template < class T >
00656 CWTMatrix<T> transpose(const CWTMatrix<T> &mat)
00657 {
00658 CWTMatrix<T> matTranspose( mat.getCols(), mat.getRows() );
00659 matTranspose.storeTranspose(mat);
00660 return matTranspose;
00661 }
00662
00663 template < class T >
00664 ostream & operator <<(ostream &os, const CWTMatrix<T>& mtx)
00665 {
00666 os << "[" ;
00667
00668 for (unsigned i = 0; i < mtx.getRows(); i++)
00669 {
00670 if (i > 0)
00671 {
00672 os << "; ";
00673 }
00674
00675 os << mtx[i][0];
00676
00677 for (unsigned j = 1; j < mtx.getCols(); j++)
00678 {
00679 os << ", " << mtx[i][j];
00680 }
00681 }
00682
00683 os << "]";
00684
00685 return os;
00686 }
00687 }
00688
00689 #endif // IG_MATRIX_H
00690