00001 #ifndef PHX_MATRIX_H
00002 #define PHX_MATRIX_H
00003
00010 #include <Phx/PhxConfig.h>
00011 #include <Phx/PhxTypes.h>
00012 #include <Phx/Core/PhxCore.h>
00013 #include <Phx/Util/PhxLog.h>
00014 #include <math.h>
00015 #include <iostream>
00016 #include <sstream>
00017
00018 namespace Phx
00019 {
00020
00021 template <uint16_t, uint16_t, typename> class BasicMatrix;
00022
00029 template <uint16_t Rows, uint16_t Cols, typename value_type>
00030 class MatrixRow
00031 {
00032 private:
00033 MatrixRow()
00034 {
00035
00036 }
00037 public:
00038 value_type operator[](uint16_t col) const
00039 {
00040 if (col < Cols) { return mData[col]; }
00041 std::ostringstream oss;
00042 oss << "Invalid column index " << col;
00043 Core::systemLog()->newMessage("MatrixRow", PHX_ERROR, oss.str());
00044 return mData[0];
00045 }
00046 value_type& operator[](uint16_t col)
00047 {
00048 if (col < Cols) { return mData[col]; }
00049 std::ostringstream oss;
00050 oss << "Invalid column index " << col;
00051 Core::systemLog()->newMessage("MatrixRow", PHX_ERROR, oss.str());
00052 return mData[0];
00053 }
00054 private:
00055 value_type mData[Cols];
00056
00057 template <uint16_t Rows2, uint16_t Cols2, typename value_type2>
00058 friend class BasicMatrix;
00059 };
00060
00065 template <uint16_t Rows, uint16_t Cols, typename value_type>
00066 class BasicIndexMatrix : public BasicMatrix<Rows,Cols,value_type>
00067 {
00068 typedef BasicMatrix<Rows,Cols,value_type> BaseType;
00069 protected:
00070 BasicIndexMatrix(bool dummy) : BaseType(dummy) { }
00071 public:
00072 BasicIndexMatrix() { }
00073 BasicIndexMatrix(const value_type* data) : BaseType(data) {}
00074
00075 const MatrixRow<Rows,Cols,value_type>& operator[](uint16_t r) const
00076 {
00077 if (r < Rows)
00078 {
00079 return BaseType::mData[r];
00080 }
00081 std::ostringstream oss;
00082 oss << "Invalid row index " << r;
00083 Core::systemLog()->newMessage("BasicIndexMatrix", PHX_ERROR, oss.str());
00084 return BaseType::mData[0];
00085 }
00086 MatrixRow<Rows,Cols,value_type>& operator[](uint16_t r)
00087 {
00088 if (r < Rows)
00089 {
00090 return BaseType::mData[r];
00091 }
00092 std::ostringstream oss;
00093 oss << "Invalid row index " << r;
00094 Core::systemLog()->newMessage("BasicIndexMatrix", PHX_ERROR, oss.str());
00095 return BaseType::mData[0];
00096 }
00097 };
00098
00103 template <uint16_t Rows, typename value_type>
00104 class BasicIndexMatrix<Rows,1,value_type> :
00105 public BasicMatrix<Rows,1,value_type>
00106 {
00107 typedef BasicMatrix<Rows,1,value_type> BaseType;
00108 protected:
00109 BasicIndexMatrix(bool dummy) : BaseType(dummy) {}
00110 public:
00111 BasicIndexMatrix() { }
00112 BasicIndexMatrix(const value_type* data) : BaseType(data) {}
00113
00114 value_type operator[](uint16_t r) const
00115 {
00116 if (r < Rows)
00117 {
00118 return BaseType::mData[r][0];
00119 }
00120 std::ostringstream oss;
00121 oss << "Invalid vector index " << r;
00122 Core::systemLog()->newMessage("BasicIndexMatrix", PHX_ERROR, oss.str());
00123 return BaseType::mData[0][0];
00124 }
00125 value_type& operator[](uint16_t r)
00126 {
00127 if (r < Rows)
00128 {
00129 return BaseType::mData[r][0];
00130 }
00131 std::ostringstream oss;
00132 oss << "Invalid vector index " << r;
00133 Core::systemLog()->newMessage("BasicIndexMatrix", PHX_ERROR, oss.str());
00134 return BaseType::mData[0][0];
00135 }
00136
00137 value_type norm(void) const {
00138 return sqrt(norm2());
00139 }
00140
00141 value_type norm2(void) const {
00142 double sum = 0;
00143 for (uint16_t i = 0; i < Rows; i++) {
00144 sum += BaseType::mData[i][0]*BaseType::mData[i][0];
00145 }
00146 return sum;
00147 }
00148 };
00149
00172 template <uint16_t Rows, uint16_t Cols, typename value_type = double>
00173 class Matrix : public BasicIndexMatrix<Rows, Cols, value_type>
00174 {
00175 typedef BasicIndexMatrix<Rows, Cols, value_type> BaseType;
00176 public:
00177 Matrix() : BaseType() { }
00178 Matrix(const value_type* data) : BaseType(data) {}}
00179 ;
00180
00184 template <typename value_type>
00185 class Matrix<4,1, value_type> : public BasicIndexMatrix<4,1, value_type>
00186 {
00187 typedef BasicIndexMatrix<4, 1, value_type> BaseType;
00188 public:
00189 Matrix() { }
00190 Matrix(const value_type* data) : BaseType(data) {}
00191 Matrix(value_type a0, value_type a1, value_type a2, value_type a3) : BaseType(false)
00192 {
00193 BaseType::mData[0][0] = a0;
00194 BaseType::mData[1][0] = a1;
00195 BaseType::mData[2][0] = a2;
00196 BaseType::mData[3][0] = a3;
00197 }
00198
00199 void normalize()
00200 {
00201 double t = sqrt(BaseType::mData[0][0]*BaseType::mData[0][0] + BaseType::mData[1][0]*BaseType::mData[1][0] + BaseType::mData[2][0]*BaseType::mData[2][0] + BaseType::mData[3][0]*BaseType::mData[3][0]);
00202
00203 BaseType::mData[0][0] = BaseType::mData[0][0]/t;
00204 BaseType::mData[1][0] = BaseType::mData[1][0]/t;
00205 BaseType::mData[2][0] = BaseType::mData[2][0]/t;
00206 BaseType::mData[3][0] = BaseType::mData[3][0]/t;
00207 }
00208 };
00209
00213 template <typename value_type>
00214 class Matrix<3,1, value_type> : public BasicIndexMatrix<3,1, value_type>
00215 {
00216 typedef BasicIndexMatrix<3, 1, value_type> BaseType;
00217 public:
00218 Matrix() { }
00219 Matrix(const value_type* data) : BaseType(data) {}
00220 Matrix(value_type a0, value_type a1, value_type a2) : BaseType(false)
00221 {
00222 BaseType::mData[0][0] = a0;
00223 BaseType::mData[1][0] = a1;
00224 BaseType::mData[2][0] = a2;
00225 }
00226
00227 void normalize()
00228 {
00229 double t = sqrt(BaseType::mData[0][0]*BaseType::mData[0][0] + BaseType::mData[1][0]*BaseType::mData[1][0] + BaseType::mData[2][0]*BaseType::mData[2][0]);
00230 BaseType::mData[0][0] = BaseType::mData[0][0]/t;
00231 BaseType::mData[1][0] = BaseType::mData[1][0]/t;
00232 BaseType::mData[2][0] = BaseType::mData[2][0]/t;
00233 }
00234
00235 value_type x(){return BaseType::mData[0][0];}
00236 value_type y(){return BaseType::mData[1][0];}
00237 value_type z(){return BaseType::mData[2][0];}
00238 };
00239
00243 template <typename value_type>
00244 class Matrix<2,1, value_type> : public BasicIndexMatrix<2,1, value_type>
00245 {
00246 typedef BasicIndexMatrix<2, 1, value_type> BaseType;
00247 public:
00248 Matrix() { }
00249 Matrix(const value_type* data) : BaseType(data) {}
00250 Matrix(value_type a0, value_type a1) : BaseType(false)
00251 {
00252 BaseType::mData[0][0] = a0;
00253 BaseType::mData[1][0] = a1;
00254 }
00255
00256 void normalize()
00257 {
00258 double t = sqrt(BaseType::mData[0][0]*BaseType::mData[0][0] + BaseType::mData[1][0]*BaseType::mData[1][0]);
00259 BaseType::mData[0][0] = BaseType::mData[0][0]/t;
00260 BaseType::mData[1][0] = BaseType::mData[1][0]/t;
00261 }
00262 };
00263
00267 template <typename value_type>
00268 class Matrix<1,1, value_type> : public BasicIndexMatrix<1,1, value_type>
00269 {
00270 typedef BasicIndexMatrix<1, 1, value_type> BaseType;
00271 public:
00272 Matrix() { }
00273 Matrix(const value_type* data) : BaseType(data) {}
00274
00275
00276 explicit Matrix(value_type a0) : BaseType(false)
00277 {
00278 BaseType::mData[0][0] = a0;
00279 }
00280
00281
00282 operator value_type() const
00283 {
00284 return BaseType::mData[0][0];
00285 }
00286
00287 const Matrix<1,1, value_type>&
00288 operator=(const Matrix<1,1, value_type>& m)
00289 {
00290 BaseType::operator=(m);
00291 return *this;
00292 }
00293
00294 double operator=(double a0)
00295 {
00296 BaseType::mData[0][0] = a0;
00297 return BaseType::mData[0][0];
00298 }
00299 };
00300
00304 template <typename value_type>
00305 class Matrix<2,2, value_type> : public BasicIndexMatrix<2,2, value_type>
00306 {
00307 typedef BasicIndexMatrix<2, 2, value_type> BaseType;
00308 public:
00309 Matrix() { }
00310 Matrix(const value_type* data) : BaseType(data) {}
00311 Matrix(value_type a0, value_type a1,
00312 value_type b0, value_type b1) : BaseType(false)
00313 {
00314 BaseType::mData[0][0]=a0; BaseType::mData[0][1]=a1;
00315 BaseType::mData[1][0]=b0; BaseType::mData[1][1]=b1;
00316 }
00317
00318 value_type determinant()
00319 {
00320 return BaseType::mData[0][0]*BaseType::mData[1][1]-BaseType::mData[0][1]*BaseType::mData[1][0];
00321 }
00322
00323 Matrix<2,2,value_type> inverse(double tolerance=0.0005)
00324 {
00325 Matrix<2,2,value_type> mr;
00326 value_type det = determinant();
00327 if(fabs(det)>tolerance)
00328 {
00329 mr[0][0] = BaseType::mData[1][1]/det;
00330 mr[0][1] = -BaseType::mData[0][1]/det;
00331 mr[1][0] = -BaseType::mData[1][0]/det;
00332 mr[1][1] = BaseType::mData[0][0]/det;
00333 }else{
00334 Core::systemLog()->newMessage("BasicIndexMatrix", PHX_ERROR,
00335 "Unable to compute inverse.");
00336 }
00337 return mr;
00338 }
00339 };
00340
00344 template <typename value_type>
00345 class Matrix<3,3, value_type> : public BasicIndexMatrix<3,3, value_type>
00346 {
00347 typedef BasicIndexMatrix<3, 3, value_type> BaseType;
00348 public:
00349 Matrix() { }
00350 Matrix(const value_type* data) : BaseType(data) {}
00351 Matrix(value_type a0, value_type a1, value_type a2,
00352 value_type b0, value_type b1, value_type b2,
00353 value_type c0, value_type c1, value_type c2) : BaseType(false)
00354 {
00355 BaseType::mData[0][0]=a0; BaseType::mData[0][1]=a1; BaseType::mData[0][2]=a2;
00356 BaseType::mData[1][0]=b0; BaseType::mData[1][1]=b1; BaseType::mData[1][2]=b2;
00357 BaseType::mData[2][0]=c0; BaseType::mData[2][1]=c1; BaseType::mData[2][2]=c2;
00358 }
00359
00360 value_type determinant()
00361 {
00362 return
00363 BaseType::mData[0][0] * BaseType::mData[1][1] * BaseType::mData[2][2] + BaseType::mData[0][1] * BaseType::mData[1][2] * BaseType::mData[2][0] + BaseType::mData[0][2] * BaseType::mData[1][0] * BaseType::mData[2][1] - BaseType::mData[0][0] * BaseType::mData[1][2] * BaseType::mData[2][1] -
00364 BaseType::mData[0][1] * BaseType::mData[1][0] * BaseType::mData[2][2] -
00365 BaseType::mData[0][2] * BaseType::mData[1][1] * BaseType::mData[2][0];
00366 }
00367
00368 Matrix<3,3,value_type> inverse(double tolerance=0.0005)
00369 {
00370 Matrix<3,3,value_type> mr;
00371 value_type det = determinant();
00372 if(fabs(det)>tolerance)
00373 {
00374 mr[0][0] = ( BaseType::mData[1][1]*BaseType::mData[2][2] - BaseType::mData[1][2]*BaseType::mData[2][1] ) / det;
00375 mr[0][1] = ( BaseType::mData[2][1]*BaseType::mData[0][2] - BaseType::mData[0][1]*BaseType::mData[2][2] ) / det;
00376 mr[0][2] = ( BaseType::mData[0][1]*BaseType::mData[1][2] - BaseType::mData[1][1]*BaseType::mData[0][2] ) / det;
00377 mr[1][0] = ( BaseType::mData[1][2]*BaseType::mData[2][0] - BaseType::mData[1][0]*BaseType::mData[2][2] ) / det;
00378 mr[1][1] = ( BaseType::mData[0][0]*BaseType::mData[2][2] - BaseType::mData[2][0]*BaseType::mData[0][2] ) / det;
00379 mr[1][2] = ( BaseType::mData[1][0]*BaseType::mData[0][2] - BaseType::mData[0][0]*BaseType::mData[1][2] ) / det;
00380 mr[2][0] = ( BaseType::mData[1][0]*BaseType::mData[2][1] - BaseType::mData[2][0]*BaseType::mData[1][1] ) / det;
00381 mr[2][1] = ( BaseType::mData[2][0]*BaseType::mData[0][1] - BaseType::mData[0][0]*BaseType::mData[2][1] ) / det;
00382 mr[2][2] = ( BaseType::mData[0][0]*BaseType::mData[1][1] - BaseType::mData[0][1]*BaseType::mData[1][0] ) / det;
00383 }else{
00384 Core::systemLog()->newMessage("BasicIndexMatrix", PHX_ERROR,
00385 "Unable to create inverse.");
00386 }
00387 return mr;
00388 }
00389 };
00390
00394 template <typename value_type>
00395 class Matrix<4,4, value_type> : public BasicIndexMatrix<4,4, value_type>
00396 {
00397 typedef BasicIndexMatrix<4, 4, value_type> BaseType;
00398 private:
00399 Matrix<3,3,value_type> submat(int i, int j)
00400 {
00401 Matrix<3,3,value_type> sm;
00402 int si, sj;
00403 for(int di=0;di<3;di++)
00404 {
00405 for(int dj=0; dj<3; dj++)
00406 {
00407 si = di + ( ( di >= i ) ? 1 : 0 );
00408 sj = dj + ( ( dj >= j ) ? 1 : 0 );
00409
00410 sm[di][dj] = BaseType::mData[si][sj];
00411 }
00412 }
00413 return sm;
00414 }
00415
00416 public:
00417 Matrix() { }
00418 Matrix(const value_type* data) : BaseType(data) {}
00419 Matrix(value_type a0, value_type a1, value_type a2, value_type a3,
00420 value_type b0, value_type b1, value_type b2, value_type b3,
00421 value_type c0, value_type c1, value_type c2, value_type c3,
00422 value_type d0, value_type d1, value_type d2, value_type d3) : BaseType(false)
00423 {
00424 BaseType::mData[0][0]=a0; BaseType::mData[0][1]=a1; BaseType::mData[0][2]=a2; BaseType::mData[0][3]=a3;
00425 BaseType::mData[1][0]=b0; BaseType::mData[1][1]=b1; BaseType::mData[1][2]=b2; BaseType::mData[1][3]=b3;
00426 BaseType::mData[2][0]=c0; BaseType::mData[2][1]=c1; BaseType::mData[2][2]=c2; BaseType::mData[2][3]=c3;
00427 BaseType::mData[3][0]=d0; BaseType::mData[3][1]=d1; BaseType::mData[3][2]=d2; BaseType::mData[3][3]=d3;
00428 }
00429
00430 value_type determinant()
00431 {
00432 Matrix<3,3,value_type> msub3;
00433 value_type result=0,det;
00434 int i=1;
00435 for ( int n = 0; n < 4; n++, i *= -1 )
00436 {
00437
00438 msub3 = submat( 0, n );
00439 det = msub3.determinant();
00440 result += BaseType::mData[0][n] * det * i;
00441 }
00442 return result;
00443 }
00444
00445 Matrix<4,4,value_type> inverse(double tolerance=0.0005)
00446 {
00447 value_type det=determinant();
00448 Matrix<3,3,value_type> mtemp;
00449 Matrix<4,4,value_type> mr;
00450 if(fabs(det)>tolerance)
00451 {
00452 int sign;
00453 for ( int i = 0; i < 4; i++ )
00454 for ( int j = 0; j < 4; j++ )
00455 {
00456 sign = 1 - ( (i +j) % 2 ) * 2;
00457 mtemp = submat( i, j );
00458 mr[(i+j*4)/4][(i+j*4)%4] = ( mtemp.determinant() * sign ) / det;
00459 }
00460 }else{
00461 Core::systemLog()->newMessage("BasicIndexMatrix", PHX_ERROR,
00462 "Unable to compute inverse.");
00463 }
00464 return mr;
00465 }
00466 };
00467
00468
00472 template <uint16_t Rows, uint16_t Cols, typename value_type = double>
00473 class BasicMatrix
00474 {
00475 protected:
00476 MatrixRow<Rows,Cols,value_type> mData[Rows];
00477
00478
00479 BasicMatrix(bool dummy) {}
00480 public:
00481 BasicMatrix()
00482 {
00483 for (uint16_t i = 0; i < Rows; ++i)
00484 {
00485 for (uint16_t j = 0; j < Cols; ++j)
00486 {
00487 mData[i][j] = 0;
00488 }
00489 }
00490 }
00491 BasicMatrix(const value_type* data)
00492 {
00493 if (!data)
00494 {
00495 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR,
00496 "Constructing matrix from 0 array.");
00497 throw RangeException();
00498 }
00499
00500 for (uint16_t i = 0; i < Rows; ++i)
00501 {
00502 for (uint16_t j = 0; j < Cols; ++j)
00503 {
00504 mData[i][j] = data[i*Cols + j];
00505 }
00506 }
00507 }
00508
00509 uint32_t rows() const { return Rows; }
00510 uint32_t columns() const { return Cols; }
00511
00512 value_type element(uint16_t row, uint16_t col) const
00513 {
00514 if (row >= rows() || col >= columns())
00515 {
00516 std::ostringstream oss;
00517 oss << "Illegal read access: " << row << ", " << col
00518 << " in " << Rows << "x" << Cols << " matrix.";
00519 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR, oss.str());
00520 return mData[0][0];
00521 }
00522 return mData[row][col];
00523 }
00524
00525 value_type& element(uint16_t row, uint16_t col)
00526 {
00527 if (row >= rows() || col >= columns())
00528 {
00529 std::ostringstream oss;
00530 oss << "Illegal read access: " << row << ", " << col << " in "
00531 << Rows << "x" << Cols << " matrix.";
00532 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR, oss.str());
00533 return mData[0][0];
00534 }
00535 return mData[row][col];
00536 }
00537
00538 void element(uint16_t row, uint16_t col, value_type value)
00539 {
00540 if (row >= rows() || col >= columns())
00541 {
00542 std::ostringstream oss;
00543 oss << "Illegal write access: " << row << ", " << col
00544 << " in " << Rows << "x" << Cols << " matrix.";
00545 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR, oss.str());
00546 return ;
00547 }
00548 mData[row][col] = value;
00549 }
00550
00551 template <uint16_t RowRangeSize, uint16_t ColRangeSize>
00552 Matrix<RowRangeSize, ColRangeSize, value_type>
00553 subMatrix(const Matrix<1, RowRangeSize, uint16_t>& rowRange,
00554 const Matrix<1, ColRangeSize, uint16_t>& colRange)
00555 {
00556 Matrix<RowRangeSize, ColRangeSize, value_type> result;
00557 for (uint32_t i = 0; i < RowRangeSize; i++)
00558 {
00559 for (uint32_t j = 0; j < ColRangeSize; j++)
00560 {
00561 result.element(i,j, element(rowRange.element(0, i), colRange.element(0,j)));
00562 }
00563 }
00564 return result;
00565 }
00566
00567 template <uint32_t RowRangeSize, uint32_t ColRangeSize>
00568 Matrix<RowRangeSize, ColRangeSize, value_type>
00569 operator()(const Matrix<1, RowRangeSize, uint16_t>& rowRange,
00570 const Matrix<1, ColRangeSize, uint16_t>& colRange)
00571 {
00572 return subMatrix(rowRange, colRange);
00573 }
00574
00580 template <uint16_t RhsCols>
00581 Matrix<Rows, RhsCols, value_type> operator*(const Matrix<Cols, RhsCols, value_type>& rhs) const
00582 {
00583 Matrix<Rows, RhsCols, value_type> result;
00584 for (uint32_t i = 0; i < Rows; i++)
00585 {
00586 for (uint32_t j = 0; j < RhsCols; j++)
00587 {
00588 for (uint32_t k = 0; k < Cols; k++)
00589 {
00590 result.element(i,j) += element(i,k)*rhs.element(k,j);
00591 }
00592 }
00593 }
00594 return result;
00595 }
00596
00601 Matrix<Rows, Cols, value_type> operator+(const Matrix<Rows, Cols, value_type>& rhs) const
00602 {
00603 Matrix<Rows, Cols, value_type> result;
00604 for (uint32_t i = 0; i < Rows; i++)
00605 {
00606 for (uint32_t j = 0; j < Cols; j++)
00607 {
00608 result.mData[i][j] = mData[i][j] + rhs.data()[i][j];
00609 }
00610 }
00611 return result;
00612 }
00613
00618 Matrix<Rows, Cols, value_type> operator-(const Matrix<Rows, Cols, value_type>& rhs) const
00619 {
00620 Matrix<Rows, Cols, value_type> result;
00621 for (uint32_t i = 0; i < Rows; i++)
00622 {
00623 for (uint32_t j = 0; j < Cols; j++)
00624 {
00625 result.mData[i][j] = mData[i][j] - rhs.data()[i][j];
00626 }
00627 }
00628 return result;
00629 }
00630
00635 Matrix<Rows, Cols, value_type> operator*(value_type s) const
00636 {
00637 Matrix<Rows, Cols, value_type> result;
00638 for (uint16_t i = 0; i < Rows; i++)
00639 {
00640 for (uint16_t j = 0; j < Cols; j++)
00641 {
00642 result.mData[i][j] = mData[i][j] * s;
00643 }
00644 }
00645 return result;
00646 }
00647
00652 Matrix<Rows, Cols, value_type> operator/(value_type s) const
00653 {
00654 Matrix<Rows, Cols, value_type> result;
00655 for (uint16_t i = 0; i < Rows; i++)
00656 {
00657 for (uint16_t j = 0; j < Cols; j++)
00658 {
00659 result.mData[i][j] = mData[i][j] / s;
00660 }
00661 }
00662 return result;
00663 }
00664
00669 Matrix<Rows, Cols, value_type> operator-(void) const
00670 {
00671 Matrix<Rows, Cols, value_type> result;
00672 for (uint16_t i = 0; i < Rows; i++)
00673 {
00674 for (uint16_t j = 0; j < Cols; j++)
00675 {
00676 result.mData[i][j] = -mData[i][j];
00677 }
00678 }
00679 return result;
00680 }
00681
00688 Matrix<Cols, Rows, value_type> transpose(void) const
00689 {
00690 Matrix<Cols, Rows, value_type> result;
00691 for (uint16_t i = 0; i < Rows; i++)
00692 {
00693 for (uint16_t j = 0; j < Cols; j++)
00694 {
00695 result.element(j,i, element(i,j));
00696 }
00697 }
00698 return result;
00699 }
00700
00712 static Matrix<Rows, Cols, value_type> identity()
00713 {
00714 Matrix<Rows, Cols, value_type> id;
00715 for (uint16_t i = 0; i < Rows && i < Cols; i++)
00716 {
00717 id.element(i,i) = 1;
00718 }
00719 return id;
00720 }
00721
00728 static Matrix<Rows, Cols, value_type> zero()
00729 {
00730 return Matrix<Rows, Cols, value_type>();
00731 }
00732
00733 MatrixRow<Rows,Cols,value_type>* data() { return mData; }
00734 const MatrixRow<Rows,Cols,value_type>* data() const { return mData; }
00735
00743 static Matrix<Rows, Cols, value_type> rotationMatrixX(double rad)
00744 {
00745 Matrix<Rows, Cols, value_type> rotMatrix;
00746 if(Rows != Cols)
00747 {
00748 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR,
00749 "Can't create rotation matrix for non-square matrix.");
00750 return rotMatrix;
00751 }
00752 if(Rows<3)
00753 {
00754 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR,
00755 "Matrix is too small for rotation.");
00756 return rotMatrix;
00757 }
00758 rotMatrix[0][0]=1; rotMatrix[0][1]=0; rotMatrix[0][2]=0;
00759 rotMatrix[1][0]=0; rotMatrix[1][1]=cos(rad); rotMatrix[1][2]=-sin(rad);
00760 rotMatrix[2][0]=0; rotMatrix[2][1]=sin(rad); rotMatrix[2][2]=cos(rad);
00761
00762
00763 for(int i=3;i<Rows;i++)
00764 {
00765 rotMatrix[i][i]=1;
00766 }
00767 return rotMatrix;
00768 }
00769
00777 static Matrix<Rows, Cols, value_type> rotationMatixY(double rad)
00778 {
00779 Matrix<Rows, Cols, value_type> rotMatrix;
00780 if(Rows != Cols)
00781 {
00782 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR,
00783 "Can't create rotation matrix from non-square matrix.");
00784 return rotMatrix;
00785 }
00786 if(Rows<3)
00787 {
00788 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR, "Matrix is too small for rotation.");
00789 return rotMatrix;
00790 }
00791 rotMatrix[0][0]=cos(rad); rotMatrix[0][1]=0; rotMatrix[0][2]=sin(rad);
00792 rotMatrix[1][0]=0; rotMatrix[1][1]=1; rotMatrix[1][2]=0;
00793 rotMatrix[2][0]=-sin(rad); rotMatrix[2][1]=0; rotMatrix[2][2]=cos(rad);
00794
00795
00796 for(int i=3;i<Rows;i++)
00797 {
00798 rotMatrix[i][i]=1;
00799 }
00800 return rotMatrix;
00801 }
00802
00810 static Matrix<Rows, Cols, value_type> rotationMatixZ(double rad)
00811 {
00812 Matrix<Rows, Cols, value_type> rotMatrix;
00813 if(Rows != Cols)
00814 {
00815 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR,
00816 "Can't create rotation matrix for non-square matrix");
00817 return rotMatrix;
00818 }
00819 if(Rows<2)
00820 {
00821 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR,
00822 "Matrix is too small for rotation.");
00823 return rotMatrix;
00824 }
00825 rotMatrix[0][0]=cos(rad); rotMatrix[0][1]=-sin(rad);
00826 rotMatrix[1][0]=sin(rad); rotMatrix[1][1]=cos(rad);
00827
00828
00829 for(int i=2;i<Rows;i++)
00830 {
00831 rotMatrix[i][i]=1;
00832 }
00833 return rotMatrix;
00834 }
00835
00845 static Matrix<Rows, Cols, value_type> rotationMatix(double roll, double pitch, double yaw)
00846 {
00847 Matrix<Rows, Cols, value_type> rotMatrix;
00848
00849 if(Rows != Cols)
00850 {
00851 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR,
00852 "Can't create rotation matrix for non-square matrix");
00853 return rotMatrix;
00854 }
00855 if(Rows<3)
00856 {
00857 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR,
00858 "Matrix is too small for rotation.");
00859 return rotMatrix;
00860 }
00861
00862 double cr = cos(roll);
00863 double sr = sin(roll);
00864
00865 double cp = cos(pitch);
00866 double sp = sin(pitch);
00867
00868 double cy = cos(yaw);
00869 double sy = sin(yaw);
00870
00871
00872 double srsp = sr*sp;
00873 double crsp = cr*sp;
00874
00875 rotMatrix[0][0]=cp*cy;
00876 rotMatrix[0][1]=-cp*sy;
00877 rotMatrix[0][2]=sp;
00878 rotMatrix[1][0]=srsp*cy+cr*sy;
00879 rotMatrix[1][1]=-srsp*sy+cr*cy;
00880 rotMatrix[1][2]=-sr*cp;
00881 rotMatrix[2][0]=-crsp*cy+sr*sy;
00882 rotMatrix[2][1]=crsp*sy+sr*cy;
00883 rotMatrix[2][2]=cr*cp;
00884
00885
00886 for(int i=3;i<Rows;i++)
00887 {
00888 rotMatrix[i][i]=1;
00889 }
00890 return rotMatrix;
00891 }
00892
00901 static Matrix<Rows, Cols, value_type> rotationMatix(Matrix<3,1> axis, double rad)
00902 {
00903 Matrix<Rows, Cols, value_type> rotMatrix;
00904
00905 if(Rows != Cols)
00906 {
00907 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR,
00908 "Can't create rotation matrix for non-square matrix.");
00909 return rotMatrix;
00910 }
00911 if(Rows<3)
00912 {
00913 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR,
00914 "Matrix is too small for rotation.");
00915 return rotMatrix;
00916 }
00917
00918 axis.normalize();
00919 double s = sin( rad/2 );
00920 double w = cos( rad/2 );
00921
00922 double x = axis[0]*s;
00923 double y = axis[1]*s;
00924 double z = axis[2]*s;
00925
00926 rotMatrix[0][0]=1-2*y*y-2*z*z;rotMatrix[0][1]=2*x*y - 2*z*w ;rotMatrix[0][2]=2*x*z + 2*y*w;
00927 rotMatrix[1][0]=2*x*y + 2*z*w;rotMatrix[1][1]= 1-2*x*x-2*z*z;rotMatrix[1][2]=2*y*z - 2*x*w;
00928 rotMatrix[2][0]=2*x*z - 2*y*w;rotMatrix[2][1]= 2*y*z + 2*x*w;rotMatrix[2][2]=1-2*x*x-2*y*y;
00929
00930
00931 for(int i=3;i<Rows;i++)
00932 {
00933 rotMatrix[i][i]=1;
00934 }
00935 return rotMatrix;
00936 }
00937
00938 private:
00939
00940 void print(std::ostream& os) const
00941 {
00942 for (uint16_t i = 0; i < Rows; i++)
00943 {
00944 for (uint16_t j = 0; j < Cols; j++)
00945 {
00946 os.width(11);
00947 os.precision(11);
00948 os << element(i,j) << " ";
00949 }
00950 os << std::endl;
00951 }
00952 }
00953
00954 void input(std::istream& is)
00955 {
00956 for (uint16_t i = 0; i < Rows; i++)
00957 {
00958 for (uint16_t j = 0; j < Cols; j++)
00959 {
00960 if (is.good())
00961 {
00962 is >> element(i,j);
00963 }
00964 else
00965 {
00966 Core::systemLog()->newMessage("BasicMatrix", PHX_ERROR,
00967 "Unable to read matrix from input stream.");
00968 throw IOException();
00969 }
00970 }
00971 }
00972 }
00973
00974 template <uint16_t Rows2, uint16_t Cols2, typename value_type2>
00975 friend Matrix<Rows2,Cols2,value_type2> operator*(double s, const Matrix<Rows2, Cols2, value_type2>& m);
00976
00977 template <uint16_t Rows2, uint16_t Cols2, typename value_type2>
00978 friend std::ostream& operator<<(std::ostream& os, const Matrix<Rows2, Cols2, value_type2>& rhs);
00979
00980 template <uint16_t Rows2, uint16_t Cols2, typename value_type2>
00981 friend std::istream& operator>>(std::istream& is, Matrix<Rows2, Cols2, value_type2>& rhs);
00982 };
00983
00984 typedef Matrix<2,2> Matrix2;
00985 typedef Matrix<3,3> Matrix3;
00986 typedef Matrix<4,4> Matrix4;
00987 typedef Matrix<2,1> Vector2;
00988 typedef Matrix<3,1> Vector3;
00989 typedef Matrix<4,1> Vector4;
00990
00991
00992 template <uint16_t Rows, uint16_t Cols, typename value_type>
00993 Matrix<Rows,Cols,value_type> operator*(double s, const Matrix<Rows, Cols, value_type>& m)
00994 {
00995 return m * s;
00996 }
00997
00998
00999 template <uint16_t Rows, uint16_t Cols, typename value_type>
01000 std::ostream& operator<<(std::ostream& os, const Matrix<Rows, Cols, value_type>& rhs)
01001 {
01002 rhs.print(os);
01003 return os;
01004 }
01005
01006 template <uint16_t Rows, uint16_t Cols, typename value_type>
01007 std::istream& operator>>(std::istream& is, Matrix<Rows, Cols, value_type>& rhs)
01008 {
01009 rhs.input(is);
01010 return is;
01011 }
01012
01013 }
01014 ;
01015
01016
01017 #endif