00001 #ifndef NMWR_GB_MATRIX_NM_H
00002 #define NMWR_GB_MATRIX_NM_H
00003
00004
00005
00006
00007 #include <iostream.h>
00008 #include "Utility/pre-post-conditions.h"
00009 #include "Geometry/coords.h"
00010
00011 template<unsigned M, unsigned N, unsigned offset>
00012 struct fixed_row_mjr_subcriptor {
00013 static int index(unsigned i, unsigned j) {
00014 REQUIRE( (offset <= i && i <= M + offset -1
00015 && offset <= i && i <= N + offset -1),
00016 "fixed_row_mjr_subcriptor<" << M << ',' << N << ',' << offset << '>'
00017 << " : index (" << i << ',' << j << ") out of range!",1);
00018 return (i-offset)*N + j;
00019 }
00020 };
00021
00022
00023 template<unsigned M, unsigned N>
00024 class matrix : public coordN<N*M> {
00025 public:
00026 typedef coordN<N*M> base_vec;
00027 typedef fixed_row_mjr_subcriptor<M,N,1> subscriptor;
00028
00029 matrix() {}
00030 matrix(component c) : base_vec(c) {}
00031
00032 component& operator()(unsigned i, unsigned j)
00033 { return base_vec::operator[](subscriptor::index(i,j));}
00034
00035 const component& operator()(unsigned i, unsigned j) const
00036 { return base_vec::operator[](subscriptor::index(i,j));}
00037
00038 matrix<M,N>& operator +=(const matrix<M,N>& rs)
00039 { base_vec::operator+=(rs); return *this;}
00040
00041 matrix<M,N>& operator -=(const matrix<M,N>& rs)
00042 { base_vec::operator-=(rs); return *this;}
00043
00044 matrix<M,N>& operator *=(const component& rs)
00045 { base_vec::operator*=(rs); return *this;}
00046
00047 };
00048
00049
00050 template<unsigned N, unsigned M>
00051 inline matrix<M,N> operator+(const matrix<M,N>& ls, const matrix<M,N> rs)
00052 { matrix<M,N> tmp(ls); return (tmp += rs);}
00053
00054
00055 template<unsigned N, unsigned M>
00056 inline matrix<M,N> operator-(const matrix<M,N>& ls, const matrix<M,N> rs)
00057 { matrix<M,N> tmp(ls); return (tmp -= rs);}
00058
00059 template<unsigned N, unsigned M>
00060 inline matrix<M,N> operator*(const matrix<M,N>& ls, coord_N_component rs)
00061 { matrix<M,N> tmp(ls); return (tmp *= rs);}
00062
00063
00064 template<unsigned N, unsigned M>
00065 inline matrix<M,N> operator*( coord_N_component ls, const matrix<M,N>& rs)
00066 { matrix<M,N> tmp(rs); return (tmp *= ls);}
00067
00068
00069
00070
00071 template<unsigned K, unsigned L, unsigned M>
00072 inline void mul(matrix<K,M>& res,
00073 const matrix<K,L>& ls, const matrix<L,M>& rs)
00074 {
00075 for(unsigned k = 1; k <= K; k++)
00076 for(unsigned m = 1; m <= M; m++) {
00077 res(k,m) = 0.0;
00078 for(unsigned l = 1; l <= L; l++)
00079 res(k,m) += ls(k,l) * rs(l,m);
00080 }
00081 }
00082
00083 template<unsigned K, unsigned L, unsigned M>
00084 inline matrix<K,M> operator*(const matrix<K,L>& ls, const matrix<L,M>& rs)
00085 {
00086 matrix<K,M> res;
00087 mul(res,ls,rs);
00088 return res;
00089 }
00090
00091
00092 template<unsigned N, unsigned M>
00093 inline void mul(coordN<N> & res,
00094 const matrix<M,N>& ls, const coordN<N>& rs)
00095 {
00096 for(unsigned i = 1; i <= M; i++) {
00097 res[i] = 0.0;
00098 for(unsigned j = 1; j <= M; j++)
00099 res[i] += ls(i,j) * rs[j];
00100 }
00101 }
00102
00103 template<unsigned N, unsigned M>
00104 inline coordN<M> operator*(const matrix<M,N>& ls, const coordN<N>& rs)
00105 {
00106 coordN<M> res;
00107 mul(res,ls,rs);
00108 return res;
00109 }
00110
00111
00112
00113
00114 template<unsigned N, unsigned M>
00115 inline ostream& operator<<(ostream& out, const matrix<M,N>& rs)
00116 {
00117 for(unsigned i = 1; i<= M; i++) {
00118 for(unsigned j = 1; j <= N; j++)
00119 out << rs(i,j) << ' ';
00120 out << '\n';
00121 }
00122 return out;
00123 }
00124
00125 template<unsigned N, unsigned M>
00126 inline istream& operator>>(istream& in, matrix<M,N>& rs)
00127 {
00128 for(unsigned i = 1; i<= M; i++) {
00129 for(unsigned j = 1; j <= N; j++)
00130 in >> rs(i,j);
00131 }
00132 return in;
00133 }
00134
00135
00136
00137
00138 #endif