00001
00002 #ifndef IG_STAT_MATRIX_H
00003 #define IG_STAT_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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 namespace CwMtx
00042 {
00043 using std::ostream;
00044
00045
00046
00047 template <unsigned r, unsigned c, class T>
00048 class CWTSMatrix;
00049
00050 template <unsigned r, class T>
00051 class CWTSSquareMatrix;
00052
00053 template <unsigned r, class T>
00054 class CWTSVector;
00055
00056 template <class T>
00057 class CWTSSpaceVector;
00058
00059 template <class T>
00060 class CWTSQuaternion;
00061
00062
00063
00064 template <class T>
00065 class CWTSZero
00066 {
00067 public:
00068 operator T() { return 0; }
00069 };
00070
00071 template <unsigned r, unsigned c, class T>
00072 class CWTSZero< CWTSMatrix<r, c, T> >:
00073 public CWTSMatrix<r, c, T>
00074 {
00075 public:
00076 CWTSZero() { fill(CWTSZero<T>()); }
00077 };
00078
00079 template <unsigned r, class T>
00080 class CWTSZero< CWTSSquareMatrix<r, T> >:
00081 public CWTSSquareMatrix<r, T>
00082 {
00083 public:
00084 CWTSZero() { fill(CWTSZero<T>()); }
00085 };
00086
00087 template <unsigned r, class T>
00088 class CWTSZero< CWTSVector<r, T> >:
00089 public CWTSVector<r, T>
00090 {
00091 public:
00092 CWTSZero() { fill(CWTSZero<T>()); }
00093 };
00094
00095 template <class T>
00096 class CWTSZero< CWTSSpaceVector<T> >:
00097 public CWTSSpaceVector<T>
00098 {
00099 public:
00100 CWTSZero() { fill(CWTSZero<T>()); }
00101 };
00102
00103 template <class T>
00104 class CWTSZero< CWTSQuaternion<T> >:
00105 public CWTSQuaternion<T>
00106 {
00107 public:
00108 CWTSZero() { fill(CWTSZero<T>()); }
00109 };
00110
00111
00112
00113 template <class T>
00114 class CWTSUnity
00115 {
00116 public:
00117 operator T() { return 1; }
00118 };
00119
00120
00121
00122 template <unsigned r, class T>
00123 class CWTSUnity< CWTSMatrix<r, r, T> >:
00124 public CWTSSquareMatrix<r, T>
00125 {
00126 public:
00127 CWTSUnity() { this->makeUnity(); }
00128 };
00129
00130 template <unsigned r, class T>
00131 class CWTSUnity< CWTSSquareMatrix<r, T> >:
00132 public CWTSSquareMatrix<r, T>
00133 {
00134 public:
00135 CWTSUnity() { this->makeUnity(); }
00136 };
00137
00138 template <class T>
00139 class CWTSUnity< CWTSQuaternion<T> >:
00140 public CWTSQuaternion<T>
00141 {
00142 public:
00143 CWTSUnity()
00144 {
00145 (*this)[0] = (*this)[1] = (*this)[2] = CWTSZero<T>();
00146 (*this)[3] = CWTSUnity<T>();
00147 }
00148 };
00149
00150
00151
00152
00153
00154
00155
00156
00157 template <unsigned r, unsigned c, class T = double>
00158 class CWTSMatrix
00159 {
00160 public:
00161 typedef T element;
00162
00163 CWTSMatrix() {}
00164 CWTSMatrix(const CWTSMatrix &);
00165
00166 ~CWTSMatrix() {}
00167
00168 unsigned getRows() const { return r; }
00169 unsigned getCols() const { return c; }
00170
00171
00172
00173
00174 T* operator [](unsigned irow) { return m_rgrow[irow]; }
00175
00176 const T* operator [](unsigned irow) const { return m_rgrow[irow]; }
00177
00178 CWTSMatrix operator +(const CWTSMatrix &) const;
00179 CWTSMatrix operator -(const CWTSMatrix &) const;
00180 CWTSMatrix operator -() const;
00181 CWTSMatrix operator *(const T &) const;
00182 CWTSMatrix operator /(const T &value) const;
00183
00184
00185 CWTSMatrix & operator =(const CWTSMatrix &);
00186 CWTSMatrix & operator +=(const CWTSMatrix &);
00187 CWTSMatrix & operator -=(const CWTSMatrix &);
00188 CWTSMatrix & operator *=(const T &);
00189 CWTSMatrix & operator /=(const T &value);
00190
00191 bool operator ==(const CWTSMatrix &) const;
00192 bool operator !=(const CWTSMatrix &mat) const;
00193
00194 void interchangeRows(unsigned, unsigned);
00195 void addRowToRow(unsigned, unsigned, const T & = CWTSUnity<T>());
00196 void multiplyRow(unsigned, const T &);
00197
00198
00199 void fill(const T &);
00200
00201 void storeSum(const CWTSMatrix &, const CWTSMatrix &);
00202
00203 template <unsigned r2, unsigned c2>
00204 void storeAtPosition(unsigned, unsigned, const CWTSMatrix<r2, c2, T> &);
00205
00206 private:
00207
00208 T m_rgrow[r][c];
00209 };
00210
00211 template <unsigned r, unsigned c, class T >
00212 inline CWTSMatrix<r, c, T>::CWTSMatrix(const CWTSMatrix<r, c, T> &mat)
00213 {
00214
00215 (*this) = mat;
00216 }
00217
00218 template <unsigned r, unsigned c, class T>
00219 CWTSMatrix<r, c, T>
00220 CWTSMatrix<r, c, T>::operator +(const CWTSMatrix<r, c, T> &mat) const
00221 {
00222
00223 return CWTSMatrix(*this) += mat;
00224 }
00225
00226 template <unsigned r, unsigned c, class T>
00227 CWTSMatrix<r, c, T>
00228 CWTSMatrix<r, c, T>::operator -(const CWTSMatrix<r, c, T> &mat) const
00229 {
00230
00231 return CWTSMatrix(*this) -= mat;
00232 }
00233
00234 template <unsigned r, unsigned c, class T>
00235 CWTSMatrix<r, c, T>
00236 CWTSMatrix<r, c, T>::operator -() const
00237 {
00238 return (*this)*(CWTSZero<T>() - CWTSUnity<T>());
00239 }
00240
00241 template <unsigned r, unsigned c, class T>
00242 CWTSMatrix<r, c, T>
00243 CWTSMatrix<r, c, T>::operator *(const T &value) const
00244 {
00245
00246 return CWTSMatrix(*this) *= value;
00247 }
00248
00249 template <unsigned r, unsigned c, class T>
00250 inline CWTSMatrix<r, c, T>
00251 CWTSMatrix<r, c, T>::operator /(const T &value) const
00252 {
00253 return (*this)*(CWTSUnity<T>()/value);
00254 }
00255
00256
00257 template <unsigned r, unsigned c, class T>
00258 CWTSMatrix<r, c, T> &
00259 CWTSMatrix<r, c, T>::operator =(const CWTSMatrix<r, c, T> &mat)
00260 {
00261 for (unsigned irow = 0; irow < r; ++irow)
00262 {
00263 for (unsigned icol = 0; icol < c; ++icol)
00264 {
00265 m_rgrow[irow][icol] = mat.m_rgrow[irow][icol];
00266 }
00267 }
00268
00269 return (*this);
00270 }
00271
00272 template <unsigned r, unsigned c, class T>
00273 CWTSMatrix<r, c, T> &
00274 CWTSMatrix<r, c, T>::operator +=(const CWTSMatrix<r, c, T> &mat)
00275 {
00276 for (unsigned irow = 0; irow < r; ++irow)
00277 {
00278 for (unsigned icol = 0; icol < c; ++icol)
00279 {
00280 m_rgrow[irow][icol] += mat.m_rgrow[irow][icol];
00281 }
00282 }
00283
00284 return (*this);
00285 }
00286
00287 template <unsigned r, unsigned c, class T>
00288 CWTSMatrix<r, c, T> &
00289 CWTSMatrix<r, c, T>::operator -=(const CWTSMatrix<r, c, T> &mat)
00290 {
00291 for (unsigned irow = 0; irow < r; ++irow)
00292 {
00293 for (unsigned icol = 0; icol < c; ++icol)
00294 {
00295 m_rgrow[irow][icol] -= mat.m_rgrow[irow][icol];
00296 }
00297 }
00298
00299 return (*this);
00300 }
00301
00302 template <unsigned r, unsigned c, class T>
00303 CWTSMatrix<r, c, T> &
00304 CWTSMatrix<r, c, T>::operator *=(const T &value)
00305 {
00306 for (unsigned irow = 0; irow < r; ++irow)
00307 {
00308 for (unsigned icol = 0; icol < c; ++icol)
00309 {
00310 m_rgrow[irow][icol] *= value;
00311 }
00312 }
00313
00314 return (*this);
00315 }
00316
00317 template <unsigned r, unsigned c, class T>
00318 inline CWTSMatrix<r, c, T> &
00319 CWTSMatrix<r, c, T>::operator /=(const T &value)
00320 {
00321 return (*this) *= CWTSUnity<T>()/value;
00322 }
00323
00324 template <unsigned r, unsigned c, class T>
00325 bool
00326 CWTSMatrix<r, c, T>::operator ==(const CWTSMatrix<r, c, T> &mat) const
00327 {
00328 for (unsigned irow = 0; irow < r; ++irow)
00329 {
00330 for (unsigned icol = 0; icol < c; ++icol)
00331 {
00332 if (m_rgrow[irow][icol] != mat.m_rgrow[irow][icol])
00333 {
00334 return false;
00335 }
00336 }
00337 }
00338
00339 return true;
00340 }
00341
00342 template <unsigned r, unsigned c, class T>
00343 inline bool
00344 CWTSMatrix<r, c, T>::operator !=(const CWTSMatrix &mat) const
00345 {
00346 return !( (*this) == mat );
00347 }
00348
00349 template <unsigned r, unsigned c, class T>
00350 void
00351 CWTSMatrix<r, c, T>::fill(const T &elemFill)
00352 {
00353 for (unsigned irow = 0; irow < r; ++irow)
00354 {
00355 for (unsigned icol = 0; icol < c; ++icol)
00356 {
00357 m_rgrow[irow][icol] = elemFill;
00358 }
00359 }
00360 }
00361
00362
00363 template <unsigned r, unsigned c, class T>
00364 void
00365 CWTSMatrix<r, c, T>::storeSum(const CWTSMatrix<r, c, T> &mat1,
00366 const CWTSMatrix<r, c, T> &mat2)
00367 {
00368 for (unsigned irow = 0; irow < r; ++irow)
00369 {
00370 for (unsigned icol = 0; icol < c; ++icol)
00371 {
00372 m_rgrow[irow][icol] =
00373 mat1.m_rgrow[irow][icol] + mat2.m_rgrow[irow][icol];
00374 }
00375 }
00376 }
00377
00378 template <unsigned r, unsigned c, class T>
00379 template <unsigned r2, unsigned c2>
00380 void
00381 CWTSMatrix<r, c, T>::storeAtPosition(unsigned irowStart,
00382 unsigned icolStart,
00383 const CWTSMatrix<r2, c2, T> &mat)
00384 {
00385 for (unsigned irow = 0; irow < r2; ++irow)
00386 {
00387 for (unsigned icol = 0; icol < c2; ++icol)
00388 {
00389 m_rgrow[irow + irowStart][icol + icolStart] = mat[irow][icol];
00390 }
00391 }
00392 }
00393
00394 template <unsigned r, unsigned c, class T>
00395 void
00396 CWTSMatrix<r, c, T>::interchangeRows(unsigned irow1, unsigned irow2)
00397 {
00398 T elemTmp;
00399
00400 for (unsigned icol = 0; icol < c; ++icol)
00401 {
00402 elemTmp = m_rgrow[irow1][icol];
00403 m_rgrow[irow1][icol] = m_rgrow[irow2][icol];
00404 m_rgrow[irow2][icol] = elemTmp;
00405 }
00406 }
00407
00408 template <unsigned r, unsigned c, class T>
00409 void
00410 CWTSMatrix<r, c, T>::multiplyRow(unsigned irow, const T &value)
00411 {
00412 for (unsigned icol = 0; icol < c; ++icol)
00413 {
00414 m_rgrow[irow][icol] *= value;
00415 }
00416 }
00417
00418 template <unsigned r, unsigned c, class T>
00419 void
00420 CWTSMatrix<r, c, T>::addRowToRow(unsigned irowSrc,
00421 unsigned irowDest,
00422 const T &value)
00423 {
00424 for (unsigned icol = 0; icol < c; ++icol)
00425 {
00426 m_rgrow[irowDest][icol] += m_rgrow[irowSrc][icol]*value;
00427 }
00428 }
00429
00430
00431
00432 template <unsigned r, unsigned c, class T>
00433 inline CWTSMatrix<r, c, T>
00434 operator *(const T &value, const CWTSMatrix<r, c, T> &mat)
00435 {
00436 return (mat*value);
00437 }
00438
00439 template <unsigned r, unsigned c, unsigned c2, class T>
00440 CWTSMatrix<r, c2, T>
00441 operator *(CWTSMatrix<r, c, T> mat1, const CWTSMatrix<c, c2, T> &mat2)
00442 {
00443 CWTSMatrix<r, c2, T> matResult;
00444
00445 for (unsigned irow = 0; irow < r; ++irow)
00446 {
00447 for (unsigned icol = 0; icol < c2; ++icol)
00448 {
00449 matResult[irow][icol] = CWTSZero<T>();
00450
00451 for (unsigned icol2 = 0; icol2 < c; ++icol2)
00452 {
00453 matResult[irow][icol] += mat1[irow][icol2]*mat2[icol2][icol];
00454 }
00455 }
00456 }
00457
00458 return matResult;
00459 }
00460
00461 template <unsigned r, unsigned c, class T>
00462 CWTSMatrix<r, c, T>
00463 transpose(const CWTSMatrix<c, r, T> &mat)
00464 {
00465 CWTSMatrix<r, c, T> matTranspose;
00466
00467 for (unsigned irow = 0; irow < r; ++irow)
00468 {
00469 for (unsigned icol = 0; icol < c; ++icol)
00470 {
00471 matTranspose[irow][icol] = mat[icol][irow];
00472 }
00473 }
00474
00475 return matTranspose;
00476 }
00477
00478 template <unsigned r, unsigned c, class T>
00479 ostream &
00480 operator <<(ostream &os, const CWTSMatrix<r, c, T> &mtx)
00481 {
00482 os << "[" ;
00483
00484 for (unsigned i = 0; i < r; i++)
00485 {
00486 if (i > 0)
00487 {
00488 os << "; ";
00489 }
00490
00491 os << mtx[i][0];
00492
00493 for (unsigned j = 1; j < c; j++)
00494 {
00495 os << ", " << mtx[i][j];
00496 }
00497 }
00498
00499 os << "]";
00500
00501 return os;
00502 }
00503
00504 }
00505
00506 #endif // IG_STAT_MATRIX_H
00507