00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef MTH_MATRIX_H
00012 #define MTH_MATRIX_H
00013
00014 #include "mthVector.h"
00015
00019 namespace mth {
00020
00022 template <class T, unsigned M=0, unsigned N=0>
00023 class Matrix : public can::Array<Vector<T,N>,M>
00024 {
00025 public:
00027 Matrix() {}
00031 Matrix(unsigned m, unsigned n) { (void) m; (void) n; }
00033 unsigned rows() const {return M;}
00035 unsigned cols() const {return N;}
00040 T& operator()(unsigned i, unsigned j) {return (*this)[i][j];}
00043 T const& operator()(unsigned i, unsigned j) const {return (*this)[i][j];}
00045 Matrix<T,M,N> operator+(Matrix<T,M,N> const& b) const
00046 {
00047 Matrix<T,M,N> r;
00048 for (unsigned i=0; i < M; ++i)
00049 r.elems[i] = this->elems[i] + b.elems[i];
00050 return r;
00051 }
00053 Matrix<T,M,N> operator-(Matrix<T,M,N> const& b) const
00054 {
00055 Matrix<T,M,N> r;
00056 for (unsigned i=0; i < M; ++i)
00057 r.elems[i] = this->elems[i] - b.elems[i];
00058 return r;
00059 }
00061 Matrix<T,M,N> operator*(T const& s) const
00062 {
00063 Matrix<T,M,N> r;
00064 for (unsigned i=0; i < M; ++i)
00065 r.elems[i] = this->elems[i] * s;
00066 return r;
00067 }
00069 Matrix<T,M,N> operator/(T const& s) const
00070 {
00071 Matrix<T,M,N> r;
00072 for (unsigned i=0; i < M; ++i)
00073 r.elems[i] = this->elems[i] / s;
00074 return r;
00075 }
00077 Vector<T,M> operator*(Vector<T,N> const& b) const
00078 {
00079 Vector<T,M> r;
00080 for (unsigned i=0; i < M; ++i)
00081 r[i] = this->elems[i] * b;
00082 return r;
00083 }
00087 template <unsigned O>
00088 Matrix<T,M,O> operator*(Matrix<T,N,O> const& b) const
00089 {
00090 Matrix<T,M,O> r;
00091 for (unsigned i=0; i < M; ++i)
00092 for (unsigned j=0; j < O; ++j)
00093 {
00094 r[i][j] = this->elems[i][0]*b[0][j];
00095 for (unsigned k=1; k < N; ++k)
00096 r[i][j] += this->elems[i][k]*b[k][j];
00097 }
00098 return r;
00099 }
00101 void zero()
00102 {
00103 for (unsigned i=0; i < M; ++i)
00104 this->elems[i].zero();
00105 }
00106 void resize(unsigned m, unsigned n)
00107 {
00108 (void) m;
00109 (void) n;
00110 }
00111 };
00112
00123 template <class T>
00124 class Matrix<T,0,0>
00125 {
00126 public:
00128 Matrix() : columns(0) {}
00130 Matrix(unsigned m, unsigned n) : columns(n), elems(m*n) {}
00132 unsigned rows() const {return elems.size()/columns;}
00134 unsigned cols() const {return columns;}
00136 void resize(unsigned m, unsigned n)
00137 {
00138 columns = n;
00139 elems.resize(m*n);
00140 }
00142 T& operator()(unsigned i, unsigned j)
00143 {
00144 return elems[i*columns + j];
00145 }
00147 T const& operator()(unsigned i, unsigned j) const
00148 {
00149 return elems[i*columns + j];
00150 }
00152 Matrix<T>& operator+=(Matrix<T> const& b)
00153 {
00154 for (unsigned i=0; i < this->elems.size(); ++i)
00155 this->elems[i] += b.elems[i];
00156 return *this;
00157 }
00159 Matrix<T>& operator-=(Matrix<T> const& b)
00160 {
00161 for (unsigned i=0; i < this->elems.size(); ++i)
00162 this->elems[i] -= b.elems[i];
00163 return *this;
00164 }
00166 Matrix<T>& operator*=(T const& s)
00167 {
00168 for (unsigned i=0; i < this->elems.size(); ++i)
00169 this->elems[i] *= s;
00170 return *this;
00171 }
00173 Matrix<T>& operator/=(T const& s)
00174 {
00175 for (unsigned i=0; i < this->elems.size(); ++i)
00176 this->elems[i] /= s;
00177 return *this;
00178 }
00180 void zero()
00181 {
00182 for (unsigned i=0; i < cols() * rows(); ++i)
00183 this->elems[i] = (T)0.0;
00184 }
00185 protected:
00186 unsigned columns;
00187 can::Array<T> elems;
00188 };
00189
00193 template <class T>
00194 class Matrix3x3 : public Matrix<T,3,3>
00195 {
00196 public:
00198 Matrix3x3() {}
00200 Matrix3x3(
00201 T const& a11,T const& a12,T const& a13,
00202 T const& a21,T const& a22, T const& a23,
00203 T const& a31,T const& a32, T const& a33)
00204 {
00205 (*this)[0] = Vector3<T>(a11,a12,a13);
00206 (*this)[1] = Vector3<T>(a21,a22,a23);
00207 (*this)[2] = Vector3<T>(a31,a32,a33);
00208 }
00210 Matrix3x3(Matrix<T,3,3> const& other) : Matrix<T,3,3>(other) {}
00212 void toArray(T (*array)[3]) const
00213 {
00214 for (unsigned i=0; i < 3; ++i)
00215 for (unsigned j=0; j < 3; ++j)
00216 array[i][j] = (*this)[i][j];
00217 }
00218 };
00219
00220 }
00221
00222 template <class T, unsigned M, unsigned N>
00223 std::ostream& operator<<(std::ostream& s, mth::Matrix<T,M,N> const& a)
00224 {
00225 for (unsigned i=0; i < a.rows(); ++i) {
00226 for (unsigned j=0; j < a.cols(); ++j)
00227 s << a(i,j) << ' ';
00228 s << '\n';
00229 }
00230 return s;
00231 }
00232
00233 #endif