Main Page | Namespace List | 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 <math.h>
00013 #include <iostream>
00014 
00015 namespace Phx {
00016   
00039   template <uint16_t Rows, uint16_t Cols, typename value_type = double>
00040   class Matrix {
00041     private:
00042     value_type mData[Rows*Cols]; // data in row major order
00043     
00044     public:
00045     Matrix() { // constructs zero matrix
00046       for (uint32_t i = 0; i < Rows*Cols; ++i) {
00047         mData[i] = 0;
00048       }
00049     }
00050 
00051     Matrix(const value_type* data) { // constructs from array
00052       if (!data) {
00053         std::cerr << "Constructing matrix from 0 array." << std::endl;
00054         throw RangeException();
00055       }
00056 
00057       for (uint32_t i = 0; i < Rows*Cols; ++i) {
00058         mData[i] = data[i];
00059       }
00060     }
00061 
00062     uint32_t rows() const { return Rows; }
00063     uint32_t columns() const { return Cols; }
00064 
00065     value_type element(uint16_t row, uint16_t col) const { 
00066       if (row >= rows() || col >= columns()) {
00067         std::cerr << "Illegal read access: " << row << ", " << col
00068                   << " in " << Rows << "x" << Cols << " matrix." << std::endl;
00069         return mData[0];
00070       }
00071       return mData[row*Cols+col];
00072     }
00073 
00074     value_type& element(uint16_t row, uint16_t col) {
00075       if (row >= rows() || col >= columns()) {
00076         std::cerr << "Illegal read access: " << row << ", " << col
00077                   << " in " << Rows << "x" << Cols << " matrix." << std::endl;
00078         return mData[0];
00079       }
00080       return mData[row*Cols+col];
00081     }
00082 
00083     void element(uint16_t row, uint16_t col, value_type value) {
00084       if (row >= rows() || col >= columns()) {
00085         std::cerr << "Illegal write access: " << row << ", " << col
00086                   << " in " << Rows << "x" << Cols << " matrix." << std::endl;
00087         return ;
00088       }
00089       mData[row*Cols+col] = value;
00090     }
00091 
00092     template <uint16_t RowRangeSize, uint16_t ColRangeSize>
00093     Matrix<RowRangeSize, ColRangeSize, value_type> 
00094     subMatrix(const Matrix<1, RowRangeSize, uint16_t>& rowRange, 
00095               const Matrix<1, ColRangeSize, uint16_t>& colRange) {
00096       Matrix<RowRangeSize, ColRangeSize, value_type> result;
00097       for (uint32_t i = 0; i < RowRangeSize; i++) {
00098         for (uint32_t j = 0; j < ColRangeSize; j++) {
00099           result.element(i,j, element(rowRange.element(0, i), colRange.element(0,j)));
00100         }
00101       }
00102       return result;
00103     }
00104 
00105     // Double/single indexing operators.
00106     /*value_type& operator()(uint16_t i, uint16_t j) {
00107       return element(i,j);
00108     }
00109     value_type& operator()(uint16_t i) {
00110       return element(i / Rows, i % Rows);
00111     }
00112     value_type operator()(uint16_t i, uint16_t j) const {
00113       return element(i,j);
00114     }
00115     value_type operator()(uint16_t i) const {
00116       return element(i / Rows, i % Rows);
00117       }*/
00118 
00119     template <uint32_t RowRangeSize, uint32_t ColRangeSize>
00120     Matrix<RowRangeSize, ColRangeSize, value_type> 
00121     operator()(const Matrix<1, RowRangeSize, uint16_t>& rowRange, 
00122                const Matrix<1, ColRangeSize, uint16_t>& colRange) {
00123       return subMatrix(rowRange, colRange);
00124     }
00125 
00131     template <uint16_t RhsCols>
00132     Matrix<Rows, RhsCols, value_type> operator*(const Matrix<Cols, RhsCols, value_type>& rhs) const {
00133       Matrix<Rows, RhsCols, value_type> result;
00134       for (uint32_t i = 0; i < Rows; i++) {
00135         for (uint32_t j = 0; j < RhsCols; j++) {
00136           for (uint32_t k = 0; k < Cols; k++) {
00137             result.element(i,j) += element(i,k)*rhs.element(k,j);
00138           }
00139         }
00140       }
00141       return result;
00142     }
00143 
00148     Matrix<Rows, Cols, value_type> operator+(const Matrix<Rows, Cols, value_type>& rhs) const {
00149       Matrix<Rows, Cols, value_type> result;
00150       for (uint32_t i = 0;  i < Rows*Cols;  i++) {
00151         result.mData[i] = mData[i] + rhs.data()[i];
00152       }
00153       return result;
00154     }
00155 
00160     Matrix<Rows, Cols, value_type> operator-(const Matrix<Rows, Cols, value_type>& rhs) const {
00161       Matrix<Rows, Cols, value_type> result;
00162       for (uint32_t i = 0;  i < Rows*Cols;  i++) {
00163         result.mData[i] = mData[i] - rhs.data()[i];
00164       }
00165       return result;
00166     }
00167 
00172     Matrix<Rows, Cols, value_type> operator*(value_type s) const {
00173       Matrix<Rows, Cols, value_type> result;
00174       for (uint32_t i = 0;  i < Rows*Cols;  i++) {
00175         result.mData[i] = mData[i] * s;
00176       }
00177       return result;      
00178     }
00179 
00184     Matrix<Rows, Cols, value_type> operator/(value_type s) const {
00185       Matrix<Rows, Cols, value_type> result;
00186       for (uint32_t i = 0;  i < Rows*Cols;  i++) {
00187         result.mData[i] = mData[i] / s;
00188       }
00189       return result;      
00190     }
00191 
00196     Matrix<Rows, Cols, value_type> operator-(void) const {
00197       Matrix<Rows, Cols, value_type> result;
00198       for (uint32_t i = 0;  i < Rows*Cols;  i++) {
00199         result.mData[i] = -mData[i];
00200       }
00201       return result;
00202     }
00203 
00210     Matrix<Cols, Rows, value_type> transpose(void) const {
00211       Matrix<Cols, Rows, value_type> result;
00212       for (uint16_t i = 0;  i < Rows;  i++) {
00213         for (uint16_t j = 0;  j < Cols;  j++) {
00214           result.element(j,i, element(i,j));
00215         }
00216       }
00217       return result;
00218     }
00219 
00231     static Matrix<Rows, Cols, value_type> identity() {
00232       Matrix<Rows, Cols, value_type> id;
00233       for (uint16_t i = 0; i < Rows && i < Cols; i++) {
00234         id.element(i,i) = 1;
00235       }
00236       return id;
00237     }
00238 
00245     static Matrix<Rows, Cols, value_type> zero() {
00246       return Matrix<Rows, Cols, value_type>();
00247     }
00248 
00249     value_type* data() { return mData; }
00250     const value_type* data() const { return mData; }
00251 
00252   private:
00253 
00254     void print(std::ostream& os) const {
00255       for (uint16_t i = 0; i < Rows; i++) {
00256         for (uint16_t j = 0; j < Cols; j++) {
00257           os.width(11);
00258           os.precision(11);
00259           os << element(i,j) << " ";
00260         }
00261         os << std::endl;
00262       }
00263     }
00264 
00265     void input(std::istream& is) {
00266       for (uint16_t i = 0; i < Rows; i++) {
00267         for (uint16_t j = 0; j < Cols; j++) {
00268           if (is.good()) {
00269             is >> element(i,j);
00270           } else {
00271             std::cerr << "Unable to read matrix from input stream." << std::endl;
00272             throw IOException();
00273           }
00274         }
00275       }
00276     }
00277 
00278     template <uint16_t Rows2, uint16_t Cols2, typename value_type2>
00279     friend std::ostream& operator<<(std::ostream& os, const Matrix<Rows2, Cols2, value_type2>& rhs);
00280 
00281     template <uint16_t Rows2, uint16_t Cols2, typename value_type2>
00282     friend std::istream& operator>>(std::istream& is, Matrix<Rows2, Cols2, value_type2>& rhs);
00283   };
00284 
00285 
00286   typedef Matrix<2,2>  Matrix2;
00287   typedef Matrix<3,3>  Matrix3;
00288   typedef Matrix<4,4>  Matrix4;
00289   typedef Matrix<2,1>  Vector2;
00290   typedef Matrix<3,1>  Vector3;
00291   typedef Matrix<4,1>  Vector4;
00292 
00293   // input / output operators
00294   template <uint16_t Rows, uint16_t Cols, typename value_type>
00295     std::ostream& operator<<(std::ostream& os, const Matrix<Rows, Cols, value_type>& rhs) {
00296     rhs.print(os);
00297     return os;
00298   }
00299 
00300   template <uint16_t Rows, uint16_t Cols, typename value_type>
00301     std::istream& operator>>(std::istream& is, Matrix<Rows, Cols, value_type>& rhs) {
00302     rhs.input(is);
00303     return is;
00304   }
00305 
00306 }; // namespace Phx
00307 
00308 
00309 #endif /* PHX_MATRIX_H */

Generated on Wed Dec 21 22:05:37 2005 for Phoenix OSFS by  doxygen 1.4.2