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];
00043
00044 public:
00045 Matrix() {
00046 for (uint32_t i = 0; i < Rows*Cols; ++i) {
00047 mData[i] = 0;
00048 }
00049 }
00050
00051 Matrix(const value_type* data) {
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
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
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
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 };
00307
00308
00309 #endif