00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00035
00036
00037 #ifndef _MBOMATRIX_H_
00038 #define _MBOMATRIX_H_
00039
00040 #include <exception>
00041
00042 #if !defined(__MINMAX_DEFINED) && !defined(max) && !defined(min)
00043 # define max(a,b) (((a) > (b)) ? (a) : (b))
00044 # define min(a,b) (((a) < (b)) ? (a) : (b))
00045 #endif
00046
00047 namespace mbo
00048 {
00049
00050
00054 class MatrixException
00055 : public std::exception
00056 {
00057 MatrixException(_IN const char *szWhat)
00058 : std::exception(szWhat)
00059 {
00060 }
00061 };
00062
00063
00067 template <class _Ty, size_t _Cols, size_t _Rows>
00068 class Matrix
00069 {
00070 public:
00071
00072 Matrix (const Matrix<_Ty, _Cols, _Rows> & m);
00073
00074 size_t numRows () { return numRows; }
00075 size_t numCols () { return numCols; }
00076
00077
00078 _Ty& operator () (size_t row, size_t col) throw(MatrixException);
00079
00080
00081 Matrix<_Ty, _Cols, _Rows> operator + () { return *this; }
00082 Matrix<_Ty, _Cols, _Rows> operator - ();
00083
00084
00085 Matrix<_Ty, _Cols, _Rows> & operator = (const Matrix<_Ty, _Cols, _Rows> & m);
00086
00087
00088 Matrix<_Ty, _Cols, _Rows> & operator += (const Matrix<_Ty, _Cols, _Rows> & m) throw(MatrixException);
00089 Matrix<_Ty, _Cols, _Rows> & operator -= (const Matrix<_Ty, _Cols, _Rows> & m) throw(MatrixException);
00090 Matrix<_Ty, _Cols, _Rows> & operator *= (const Matrix<_Ty, _Cols, _Rows> & m) throw(MatrixException);
00091 Matrix<_Ty, _Cols, _Rows> & operator *= (const _Ty& c);
00092 Matrix<_Ty, _Cols, _Rows> & operator /= (const _Ty& c);
00093 Matrix<_Ty, _Cols, _Rows> & operator ^= (const size_t& pow) throw(MatrixException);
00094
00095
00096 friend bool operator == (const Matrix<_Ty, _Cols, _Rows> & m1, const Matrix<_Ty, _Cols, _Rows> & m2);
00097 friend bool operator != (const Matrix<_Ty, _Cols, _Rows> & m1, const Matrix<_Ty, _Cols, _Rows> & m2);
00098
00099
00100 friend template<class _Ty, _Cols, _Rows> Matrix<_Ty, _Cols, _Rows> operator + (const Matrix<_Ty, _Cols, _Rows> & m1, const Matrix<_Ty, _Cols, _Rows> & m2) throw(MatrixException);
00101 friend template<class _Ty, _Cols, _Rows> Matrix<_Ty, _Cols, _Rows> operator - (const Matrix<_Ty, _Cols, _Rows> & m1, const Matrix<_Ty, _Cols, _Rows> & m2) throw(MatrixException);
00102 friend template<class _Ty, size_t _Cols1Rows2, size_t _Rows1, size_t _Cols2>
00103 Matrix<_Ty, _Cols2, _Rows1> operator * (const Matrix<_Ty, _Cols1Rows2, _Rows1> & lhs, const Matrix<_Ty, _Cols2, _Cols1Rows2> & rhs)
00104 friend template<class _Ty, _Cols, _Rows> Matrix<_Ty, _Cols, _Rows> operator * (const Matrix<_Ty, _Cols, _Rows> & m1, const Matrix<_Ty, _Cols, _Rows> & m2) throw(MatrixException);
00105 friend template<class _Ty, _Cols, _Rows> Matrix<_Ty, _Cols, _Rows> operator * (const Matrix<_Ty, _Cols, _Rows> & m, const T& no);
00106 friend template<class _Ty, _Cols, _Rows> Matrix<_Ty, _Cols, _Rows> operator * (const T& no, const Matrix<_Ty, _Cols, _Rows> & m) { return (m*no); }
00107 friend template<class _Ty, _Cols, _Rows> Matrix<_Ty, _Cols, _Rows> operator / (const Matrix<_Ty, _Cols, _Rows> & m1, const Matrix<_Ty, _Cols, _Rows> & m2) throw(MatrixException) { return (m1 * !m2); }
00108 friend template<class _Ty, _Cols, _Rows> Matrix<_Ty, _Cols, _Rows> operator / (const Matrix<_Ty, _Cols, _Rows> & m, const T& no) { return (m*(1/no)); }
00109 friend template<class _Ty, _Cols, _Rows> Matrix<_Ty, _Cols, _Rows> operator / (const T& no, const Matrix<_Ty, _Cols, _Rows> & m) throw(MatrixException) { return (!m * no); }
00110 friend template<class _Ty, _Cols, _Rows> Matrix<_Ty, _Cols, _Rows> operator ~ (const Matrix<_Ty, _Cols, _Rows> & m);
00111 friend template<class _Ty, _Cols, _Rows> Matrix<_Ty, _Cols, _Rows> operator ! (Matrix<_Ty, _Cols, _Rows> m) throw(MatrixException);
00112 friend template<class _Ty, _Cols, _Rows> Matrix<_Ty, _Cols, _Rows> operator ^ (const Matrix<_Ty, _Cols, _Rows> & m, const size_t& pow) throw(MatrixException);
00113
00114
00115 void Null (const size_t& row, const size_t& col);
00116 void Null ();
00117 void Unit (const size_t& row);
00118 void Unit ();
00119
00120
00121 Matrix<_Ty, _Cols, _Rows> Solve(const Matrix<_Ty, _Cols, _Rows> & v) const throw(MatrixException);
00122 Matrix<_Ty, _Cols, _Rows> Adj() throw(MatrixException);
00123 _Ty Det() throw(MatrixException);
00124 _Ty Norm();
00125 _Ty Cofactor(size_t row, size_t col) throw(MatrixException);
00126 _Ty Cond();
00127
00128
00129 bool IsSquare () { return (Row == Col); }
00130 bool IsSingular ();
00131 bool IsDiagonal ();
00132 bool IsScalar ();
00133 bool IsUnit ();
00134 bool IsNull ();
00135 bool IsSymmetric ();
00136 bool IsSkewSymmetric ();
00137 bool IsUpperTiangular ();
00138 bool IsLowerTiangular ();
00139
00140
00141 friend istream& operator >> (istream& i, Matrix<_Ty, _Cols, _Rows> & m);
00142 friend ostream& operator << (ostream& o, Matrix<_Ty, _Cols, _Rows> & m);
00143
00144 private:
00145 _Ty Val[_Cols][_Rows];
00146
00147 int pivot(size_t row);
00148 };
00149
00150 template<class _Ty, size_t _Cols>
00151 class Vector: Matrix<_Ty, _Cols, 1>
00152 {
00153 };
00154
00155
00156 template<class _Ty, size_t _Cols, size_t _Rows>
00157 inline Matrix<_Ty, _Cols, _Rows>::Matrix ()
00158 {
00159 }
00160
00161
00162 template<class _Ty, size_t _Cols, size_t _Rows>
00163 inline Matrix<_Ty, _Cols, _Rows>::Matrix (const Matrix<_Ty, _Cols, _Rows> & m)
00164 : Val(m.Val)
00165 {
00166 }
00167
00168
00169 template<class _Ty, size_t _Cols, size_t _Rows>
00170 inline _Ty& Matrix<_Ty, _Cols, _Rows>::operator () (size_t nRow, size_t nCol) throw(MatrixException)
00171 {
00172 if (nRow >= _Rows || nCol >= _Cols)
00173 {
00174 throw MatrixException("Matrix<_Ty, _Cols, _Rows>::operator(): Index out of range!");
00175 }
00176 return Val[row][col];
00177 }
00178
00179
00180 template<class _Ty, size_t _Cols, size_t _Rows>
00181 istream& operator >> (istream& in, Matrix<_Ty, _Cols, _Rows> & m)
00182 {
00183 for (size_t i=0; i < m.Row; i++)
00184 {
00185 for (size_t j=0; j < m.Col; j++)
00186 {
00187 in >> m.Val[i][j];
00188 }
00189 }
00190 return in;
00191 }
00192
00193
00194 template<class _Ty, size_t _Cols, size_t _Rows>
00195 ostream& operator << (ostream &out, Matrix<_Ty, _Cols, _Rows> & m)
00196 {
00197 for (size_t i=0; i < m.Row; i++)
00198 {
00199 for (size_t j=0; j < m.Col; j++)
00200 {
00201 out << m.Val[i][j] << '\t';
00202 }
00203 out << endl;
00204 }
00205 return out;
00206 }
00207
00208
00209 template<class _Ty, size_t _Cols, size_t _Rows>
00210 inline Matrix<_Ty, _Cols, _Rows> & Matrix<_Ty, _Cols, _Rows>::operator = (const Matrix<_Ty, _Cols, _Rows> & m)
00211 {
00212 *Val = *m.Val;
00213 return *this;
00214 }
00215
00216
00217 template<class _Ty, size_t _Cols, size_t _Rows>
00218 bool operator == (const Matrix<_Ty, _Cols, _Rows> & lhs, const Matrix<_Ty, _Cols, _Rows> & rhs)
00219 {
00220 for (size_t i=0; i < _Rows; i++)
00221 {
00222 for (size_t j=0; j < _Cols; i++)
00223 {
00224 if (lhs1.Val[i][j] != rhs2.Val[i][j])
00225 return false;
00226 }
00227 }
00228 }
00229 return true;
00230 }
00231
00232
00233 template<class _Ty, size_t _Cols, size_t _Rows>
00234 bool operator != (const Matrix<_Ty, _Cols, _Rows> & lhs, const Matrix<_Ty, _Cols, _Rows> & rhs)
00235 {
00236 return !(lhs == rhs);
00237 }
00238
00239
00240
00241 template<class _Ty, size_t _Cols, size_t _Rows>
00242 inline Matrix<_Ty, _Cols, _Rows> & Matrix<_Ty, _Cols, _Rows>::operator += (const Matrix<_Ty, _Cols, _Rows> & rhs)
00243 {
00244 for (size_t i=0; i < _Rows; i++)
00245 {
00246 for (size_t j=0; j < _Cols; j++)
00247 {
00248 Val[i][j] += rhs.Val[i][j];
00249 }
00250 }
00251 return *this;
00252 }
00253
00254
00255
00256 template<class _Ty, size_t _Cols, size_t _Rows>
00257 inline Matrix<_Ty, _Cols, _Rows> & Matrix<_Ty, _Cols, _Rows>::operator -= (const Matrix<_Ty, _Cols, _Rows> & m)
00258 {
00259 for (size_t i=0; i < _Rows; i++)
00260 {
00261 for (size_t j=0; j < _Cols; j++)
00262 {
00263 Val[i][j] -= rhs.Val[i][j];
00264 }
00265 }
00266 return *this;
00267 }
00268
00269
00270 template<class _Ty, size_t _Cols, size_t _Rows>
00271 inline Matrix<_Ty, _Cols, _Rows> & Matrix<_Ty, _Cols, _Rows>::operator *= (const _Ty& c)
00272 {
00273 for (size_t i=0; i < _Rows; i++)
00274 {
00275 for (size_t j=0; j < _Cols; j++)
00276 {
00277 Val[i][j] *= c;
00278 }
00279 }
00280 return *this;
00281 }
00282
00283
00284
00285 template<class _Ty, size_t _Cols, size_t _Rows>
00286 inline Matrix<_Ty, _Cols, _Rows> & Matrix<_Ty, _Cols, _Rows>::operator *= (const Matrix<_Ty, _Cols, _Rows> & m)
00287 {
00288 for (size_t i=0; i < _Rows; i++)
00289 {
00290 for (size_t j=0; j < _Cols; j++)
00291 {
00292 Val[i][j] *= rhs.Val[i][j];
00293 }
00294 }
00295 return *this;
00296 }
00297
00298
00299
00300 template<class _Ty, size_t _Cols, size_t _Rows>
00301 inline Matrix<_Ty, _Cols, _Rows> & Matrix<_Ty, _Cols, _Rows>::operator /= (const T& c)
00302 {
00303 for (size_t i=0; i < _Rows; i++)
00304 {
00305 for (size_t j=0; j < _Cols; j++)
00306 {
00307 Val[i][j] /= c;
00308 }
00309 }
00310 return *this;
00311 }
00312
00313
00314 template<class _Ty, size_t _Cols, size_t _Rows>
00315 inline Matrix<_Ty, _Cols, _Rows> & Matrix<_Ty, _Cols, _Rows>::operator ^= (const size_t& c) throw(MatrixException)
00316 {
00317 for (size_t i=0; i < _Rows; i++)
00318 {
00319 for (size_t j=0; j < _Cols; j++)
00320 {
00321 Val[i][j] ^= c;
00322 }
00323 }
00324 return *this;
00325 }
00326
00327
00328 template<class _Ty, size_t _Cols, size_t _Rows>
00329 inline Matrix<_Ty, _Cols, _Rows> Matrix<_Ty, _Cols, _Rows>::operator - ()
00330 {
00331 Matrix<_Ty, _Cols, _Rows> ret();
00332
00333 for (size_t i=0; i < _Rows; i++)
00334 {
00335 for (size_t j=0; j < _Cols; j++)
00336 {
00337 ret.Val[i][j] = - Val[i][j];
00338 }
00339 }
00340 return ret;
00341 }
00342
00343
00344 template<class _Ty, size_t _Cols, size_t _Rows>
00345 Matrix<_Ty, _Cols, _Rows> operator + (const Matrix<_Ty, _Cols, _Rows> & lhs, const Matrix<_Ty, _Cols, _Rows> & rhs)
00346 {
00347 Matrix<_Ty, _Cols, _Rows> ret();
00348
00349 for (size_t i=0; i < _Rows; i++)
00350 {
00351 for (size_t j=0; j < _Cols; j++)
00352 {
00353 ret.Val[i][j] = lhs.Val[i][j] + rhs.Val[i][j];
00354 }
00355 }
00356 return ret;
00357 }
00358
00359
00360 template<class _Ty, size_t _Cols, size_t _Rows>
00361 Matrix<_Ty, _Cols, _Rows> operator - (const Matrix<_Ty, _Cols, _Rows> & lhs, const Matrix<_Ty, _Cols, _Rows> & rhs)
00362 {
00363 Matrix<_Ty, _Cols, _Rows> ret();
00364
00365 for (size_t i=0; i < _Rows; i++)
00366 {
00367 for (size_t j=0; j < _Cols; j++)
00368 {
00369 ret.Val[i][j] = lhs.Val[i][j] - rhs.Val[i][j];
00370 }
00371 }
00372 return ret;
00373 }
00374
00375
00376
00377 template<class _Ty, size_t _Cols, size_t _Rows>
00378 Matrix<_Ty, _Cols, _Rows> operator * (const Matrix<_Ty, _Cols, _Rows> & lhs, const _Ty& c)
00379 {
00380 Matrix<_Ty, _Cols, _Rows> ret();
00381
00382 for (size_t i=0; i < m.Row; i++)
00383 {
00384 for (size_t j=0; j < m.Col; j++)
00385 {
00386 ret.Val[i][j] = lhs.Val[i][j] * c;
00387 }
00388 }
00389 return ret;
00390 }
00391
00392
00393
00394 template<class _Ty, size_t _Cols1Rows2, size_t _Rows1, size_t _Cols2>
00395 Matrix<_Ty, _Cols, _Rows> operator * (const Matrix<_Ty, _Cols1Rows2, _Rows1> & lhs, const Matrix<_Ty, _Cols2, _Cols1Rows2> & rhs)
00396 {
00397 Matrix<_Ty, _Cols2, _Rows1> ret();
00398
00399 for (size_t i=0; i < _Rows1; i++)
00400 {
00401 for (size_t j=0; j < _Cols2; j++)
00402 {
00403 ret.Val[i][j] = _Ty(0);
00404 for (size_t k=0; k < _Cols1Rows2; k++)
00405 {
00406 ret.Val[i][j] += lhs.Val[i][k] * rhs[k][j];
00407 }
00408 }
00409 }
00410 return ret;
00411 }
00412
00413
00414 template<class _Ty, size_t _Cols, size_t _Rows>
00415 Matrix<_Ty, _Cols, _Rows> operator ^ (const Matrix<_Ty, _Cols, _Rows> & lhs, const size_t & rhs)
00416 {
00417 assert(rhs > 0);
00418
00419 Matrix<_Ty, _Cols, _Rows> temp(m);
00420
00421 for (size_t i=2; i <= pow; i++)
00422 {
00423 ret = ret * lhs;
00424 }
00425
00426 return ret;
00427 }
00428
00429
00430
00431 template<class _Ty, size_t _Cols, size_t _Rows>
00432 Matrix<_Ty, _Cols, _Rows> operator ~ (const Matrix<_Ty, _Cols, _Rows> & rhs)
00433 {
00434 Matrix<_Ty, _Cols, _Rows> ret();
00435
00436 for (size_t i=0; i < _Rows; i++)
00437 {
00438 for (size_t j=0; j < _Cols; j++)
00439 {
00440 ret.Val[i][j] = rhs.Val[j][i];
00441 }
00442 }
00443 return ret;
00444 }
00445
00446
00447
00448 template<class _Ty, size_t _Cols, size_t _Rows>
00449 Matrix<_Ty, _Cols, _Rows> operator ! (Matrix<_Ty, _Cols, _Rows> rhs)
00450 {xxx
00451 size_t i,j,k;
00452 T a1,a2,*rowptr;
00453
00454 Matrix<_Ty, _Cols, _Rows> temp(m.Row,m.Col);
00455
00456 temp.Unit();
00457 for (k=0; k < m.Row; k++)
00458 {
00459 int indx = m.pivot(k);
00460 if (indx == -1)
00461 throw MatrixException("Matrix<_Ty, _Cols, _Rows>::operator!: Inversion of a singular Matrix");
00462
00463 if (indx != 0)
00464 {
00465 rowptr = temp.Val[k];
00466 temp.Val[k] = temp.Val[indx];
00467 temp.Val[indx] = rowptr;
00468 }
00469 a1 = m.Val[k][k];
00470 for (j=0; j < m.Row; j++)
00471 {
00472 m.Val[k][j] /= a1;
00473 temp.Val[k][j] /= a1;
00474 }
00475 for (i=0; i < m.Row; i++)
00476 if (i != k)
00477 {
00478 a2 = m.Val[i][k];
00479 for (j=0; j < m.Row; j++)
00480 {
00481 m.Val[i][j] -= a2 * m.Val[k][j];
00482 temp.Val[i][j] -= a2 * temp.Val[k][j];
00483 }
00484 }
00485 }
00486 return temp;
00487 }
00488
00489
00490
00491 template<class _Ty, size_t _Cols, size_t _Rows>
00492 inline Matrix<_Ty, _Cols, _Rows> Matrix<_Ty, _Cols, _Rows>::Solve(const Matrix<_Ty, _Cols, _Rows> & v) const throw(MatrixException)
00493 {xxx
00494 size_t i, j, k;
00495 _Ty a1;
00496
00497 Matrix<_Ty, _Cols, _Rows> temp(Row, Col + v.Col);
00498 for (i=0; i < Row; i++)
00499 {
00500 for (j=0; j < Col; j++)
00501 temp.Val[i][j] = Val[i][j];
00502 for (k=0; k < v.Col; k++)
00503 temp.Val[i][Col+k] = v.Val[i][k];
00504 }
00505 for (k=0; k < Row; k++)
00506 {
00507 int indx = temp.pivot(k);
00508 if (indx == -1)
00509 throw MatrixException("Matrix<_Ty, _Cols, _Rows>::Solve(): Singular Matrix!");
00510
00511 a1 = temp.Val[k][k];
00512 for (j=k; j < temp.Col; j++)
00513 temp.Val[k][j] /= a1;
00514
00515 for (i=k+1; i < Row; i++)
00516 {
00517 a1 = temp.Val[i][k];
00518 for (j=k; j < temp.Col; j++)
00519 temp.Val[i][j] -= a1 * temp.Val[k][j];
00520 }
00521 }
00522 Matrix<_Ty, _Cols, _Rows> s(v.Row,v.Col);
00523 for (k=0; k < v.Col; k++)
00524 for (int m=int(Row)-1; m >= 0; m--)
00525 {
00526 s.Val[m][k] = temp.Val[m][Col+k];
00527 for (j=m+1; j < Col; j++)
00528 s.Val[m][k] -= temp.Val[m][j] * s.Val[j][k];
00529 }
00530 return s;
00531 }
00532
00533
00534
00535 template<class _Ty, size_t _Cols, size_t _Rows>
00536 inline Matrix<_Ty, _Cols, _Rows> & Matrix<_Ty, _Cols, _Rows>::Null()
00537 {
00538 for (size_t i=0; i < Row; i++)
00539 {
00540 for (size_t j=0; j < Col; j++)
00541 {
00542 Val[i][j] = _Ty(0);
00543 }
00544 }
00545 return *this;
00546 }
00547
00548
00549 template<class _Ty, size_t _Cols, size_t _Rows>
00550 inline void Matrix<_Ty, _Cols, _Rows>::Unity()
00551 {
00552 for (size_t i=0; i < Row; i++)
00553 {
00554 for (size_t j=0; j < Col; j++)
00555 {
00556 Val[i][j] = i == j ? _Ty(1) : _Ty(0);
00557 }
00558 }
00559 return;
00560 }
00561
00562
00563 template<class _Ty, size_t _Cols, size_t _Rows>
00564 inline int Matrix<_Ty, _Cols, _Rows>::pivot(size_t row)
00565 {
00566 size_t k = row;
00567 double amax = -1.0, temp;
00568
00569 for (size_t i=row; i < _Rows; i++)
00570 {
00571 if ((temp = abs(Val[i][row])) > amax && temp != 0.0)
00572 {
00573 amax = temp;
00574 k = i;
00575 }
00576 }
00577 if (Val[k][row] == _Ty(0))
00578 {
00579 return -1;
00580 }
00581 if (k != row)
00582 {
00583 _Ty* rowptr = Val[k];
00584 Val[k] = Val[row];
00585 Val[row] = rowptr;
00586 int ret = static_cast<int>(k);
00587 if (ret == -1)
00588 {
00589 throw MatrixException("Matrix<_Ty, _Cols, _Rows::pivot(row): return value == -1");
00590 }
00591 return ret;
00592 }
00593 return 0;
00594 }
00595
00596
00597
00598 template<class _Ty, size_t _Cols, size_t _Rows>
00599 inline _Ty Matrix<_Ty, _Cols, _Rows>::Det()
00600 {
00601 size_t i, j, k;
00602 T piv, detVal = T(1);
00603
00604 Matrix<_Ty, _Cols, _Rows> temp(*this);
00605
00606 for (k = 0; k < Row; k++)
00607 {
00608 int indx = temp.pivot(k);
00609 if (indx == -1)
00610 {
00611 return 0;
00612 }
00613 if (indx != 0)
00614 {
00615 detVal = - detVal;
00616 }
00617 detVal = detVal * temp.Val[k][k];
00618 for (i=k+1; i < Row; i++)
00619 {
00620 piv = temp.Val[i][k] / temp.Val[k][k];
00621 for (j=k+1; j < Row; j++)
00622 {
00623 temp.Val[i][j] -= piv * temp.Val[k][j];
00624 }
00625 }
00626 }
00627 return detVal;
00628 }
00629
00630
00631 template<class _Ty, size_t _Cols, size_t _Rows>
00632 inline _Ty Matrix<_Ty, _Cols, _Rows>::Norm()
00633 {
00634 _Ty ret = _Ty(0);
00635
00636 for (size_t i=0; i < _Rows; i++)
00637 {
00638 for (size_t j=0; j < _Cols; j++)
00639 {
00640 ret += Val[i][j] * Val[i][j];
00641 }
00642 }
00643 ret = sqrt(ret);
00644 return ret;
00645 }
00646
00647
00648
00649 template<class _Ty, size_t _Cols, size_t _Rows> T
00650 inline Matrix<_Ty, _Cols, _Rows>::Cond()
00651 {
00652 Matrix<_Ty, _Cols, _Rows> inv();
00653
00654 inv = ! (*this);
00655 _Ty ret = Norm() * inv.Norm();
00656
00657 return retVal;
00658 }
00659
00660
00661
00662 template<class _Ty, size_t _Cols, size_t _Rows>
00663 inline _Ty Matrix<_Ty, _Cols, _Rows>::Cofactor(size_t row, size_t col) throw(MatrixException)
00664 {xxx
00665 size_t i, i1, j, j1;
00666
00667 if (Row != Col)
00668 {
00669 throw MatrixException("Matrix<_Ty, _Cols, _Rows>::Cofactor(): Cofactor of a non-square Matrix!");
00670 }
00671
00672 if (row > _Rows || col > _Cols)
00673 {
00674 throw MatrixException("Matrix<_Ty, _Cols, _Rows>::Cofactor(): Index out of range!");
00675 }
00676
00677 Matrix<_Ty, _Cols-1, _Rows-1> temp();
00678
00679 for (i=i1=0; i < Row; i++)
00680 {
00681 if (i == row)
00682 {
00683 continue;
00684 }
00685 for (j=j1=0; j < Col; j++)
00686 {
00687 if (j == col)
00688 {
00689 continue;
00690 }
00691 temp.Val[i1][j1] = Val[i][j];
00692 j1++;
00693 }
00694 i1++;
00695 }
00696 return ((row+col)%2 == 1) ? -temp.Det() : temp.Det();
00697 }
00698
00699
00700
00701 template<class _Ty, size_t _Cols, size_t _Rows>
00702 inline Matrix<_Ty, _Cols, _Rows> Matrix<_Ty, _Cols, _Rows>::Adjoin()
00703 {xxx
00704 if (Row != Col)
00705 {
00706 throw MatrixException("Matrix<_Ty, _Cols, _Rows>::Adjoin(): Adjoin of a non-square Matrix.");
00707 }
00708
00709 Matrix<_Ty, _Cols, _Rows> ret();
00710
00711 for (size_t i=0; i < Row; i++)
00712 {
00713 for (size_t j=0; j < Col; j++)
00714 {
00715 ret.Val[i][j] = Cofact(i,j);
00716 }
00717 }
00718 ret = ~ret;
00719 return ret;
00720 }
00721
00722
00723 template<class _Ty, size_t _Cols, size_t _Rows>
00724 inline bool Matrix<_Ty, _Cols, _Rows>::IsSingular()
00725 {
00726 if (Row != Col)
00727 {
00728 return false;
00729 }
00730 return (Det() == T(0));
00731 }
00732
00733
00734 template<class _Ty, size_t _Cols, size_t _Rows>
00735 inline bool Matrix<_Ty, _Cols, _Rows>::IsDiagonal()
00736 {
00737 if (Row != Col)
00738 {
00739 return false;
00740 }
00741 for (size_t i=0; i < Row; i++)
00742 {
00743 for (size_t j=0; j < Col; j++)
00744 {
00745 if (i != j && Val[i][j] != T(0))
00746 {
00747 return false;
00748 }
00749 }
00750 }
00751 return true;
00752 }
00753
00754
00755 template<class _Ty, size_t _Cols, size_t _Rows>
00756 inline bool Matrix<_Ty, _Cols, _Rows>::IsScalar()
00757 {
00758 if (!IsDiagonal())
00759 {
00760 return false;
00761 }
00762 _Ty v = Val[0][0];
00763 for (size_t i=1; i < Row; i++)
00764 {
00765 if (Val[i][i] != v)
00766 {
00767 return false;
00768 }
00769 }
00770 return true;
00771 }
00772
00773
00774 template<class _Ty, size_t _Cols, size_t _Rows>
00775 inline bool Matrix<_Ty, _Cols, _Rows>::IsUnit ()
00776 {
00777 return (IsScalar() && Val[0][0] == T(1)) ? true : false;
00778 }
00779
00780
00781 template<class _Ty, size_t _Cols, size_t _Rows>
00782 inline bool Matrix<_Ty, _Cols, _Rows>::IsNull()
00783 {
00784 for (size_t i=0; i < Row; i++)
00785 {
00786 for (size_t j=0; j < Col; j++)
00787 {
00788 if (Val[i][j] != T(0))
00789 {
00790 return false;
00791 }
00792 }
00793 }
00794 return true;
00795 }
00796
00797
00798 template<class _Ty, size_t _Cols, size_t _Rows>
00799 inline bool Matrix<_Ty, _Cols, _Rows>::IsSymmetric()
00800 {
00801 if (_Rows != _Cols)
00802 {
00803 return false;
00804 }
00805 for (size_t i=0; i < Row; i++)
00806 {
00807 for (size_t j=0; j < Col; j++)
00808 {
00809 if (Val[i][j] != Val[j][i])
00810 {
00811 return false;
00812 }
00813 }
00814 }
00815 return true;
00816 }
00817
00818
00819 template<class _Ty, size_t _Cols, size_t _Rows>
00820 inline bool Matrix<_Ty, _Cols, _Rows>::IsSkewSymmetric()
00821 {
00822 if (Row != Col)
00823 {
00824 return false;
00825 }
00826 for (size_t i=0; i < Row; i++)
00827 {
00828 for (size_t j=0; j < Col; j++)
00829 {
00830 if (Val[i][j] != -Val[j][i])
00831 {
00832 return false;
00833 }
00834 }
00835 }
00836 return true;
00837 }
00838
00839
00840 template<class _Ty, size_t _Cols, size_t _Rows>
00841 inline bool Matrix<_Ty, _Cols, _Rows>::IsUpperTiangular()
00842 {
00843 if (Row != Col)
00844 {
00845 return false;
00846 }
00847 for (size_t i=1; i < Row; i++)
00848 {
00849 for (size_t j=0; j < i-1; j++)
00850 {
00851 if (Val[i][j] != T(0))
00852 {
00853 return false;
00854 }
00855 }
00856 }
00857 return true;
00858 }
00859
00860
00861 template<class _Ty, size_t _Cols, size_t _Rows>
00862 inline bool Matrix<_Ty, _Cols, _Rows>::IsLowerTiangular ()
00863 {
00864 if (Row != Col)
00865 {
00866 return false;
00867 }
00868 for (size_t j=1; j < Col; j++)
00869 {
00870 for (size_t i=0; i < j-1; i++)
00871 {
00872 if (Val[i][j] != T(0))
00873 {
00874 return false;
00875 }
00876 }
00877 }
00878 return true;
00879 }
00880
00881 }
00882
00883 #endif // _MBOMATRIX_H_