Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

PhxMatrix.h

Go to the documentation of this file.
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       // doesn't initialize!!!!!!!
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     // explicit conversion from value_type
00276     explicit Matrix(value_type a0) : BaseType(false)
00277     { // don't initialize
00278       BaseType::mData[0][0] = a0;
00279     }
00280 
00281     // implicit conversion to value_type
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]; // data in row major order
00477 
00478     // Constructs uninitialized matrix.
00479     BasicMatrix(bool dummy) {}
00480   public:
00481     BasicMatrix()
00482     { // constructs zero matrix
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     { // constructs from array
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       //Set the rest of the diagonal to 1
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       //Set the rest of the diagonal to 1
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       //Set the rest of the diagonal to 1
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       //used more than once.
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       //Set the rest of the diagonal to 1
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       //Set the rest of the diagonal to 1
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   // left-side scalar multiply
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   // input / output operators
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 ; // namespace Phx
01015 
01016 
01017 #endif /* PHX_MATRIX_H */

Generated on Mon Jul 10 19:45:28 2006 for Phoenix OSFS by  doxygen 1.4.2