00001 #ifndef GSGL_MATH_MATRIX_H
00002 #define GSGL_MATH_MATRIX_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "math/math.hpp"
00038
00039 #include "data/exception.hpp"
00040 #include "data/string.hpp"
00041 #include "data/stream.hpp"
00042
00043 #include <cstring>
00044
00045 namespace gsgl
00046 {
00047
00048 namespace math
00049 {
00050
00051
00052
00053 template <int R, int C, typename T = gsgl::real_t>
00054 class matrix
00055 : public math_object
00056 {
00057 protected:
00058 T data[R*C];
00059 public:
00060 matrix();
00061 explicit matrix(const T *);
00062 matrix(const matrix<R,C,T> &);
00063 matrix & operator= (const matrix<R,C,T> &);
00064 virtual ~matrix();
00065
00066 const T & item (int i, int j) const { return data[j*R+i]; }
00067 T & item (int i, int j) { return data[j*R+i]; }
00068
00069
00070 const T *ptr() const { return data; }
00071 T * ptr() { return data; }
00072
00073 void to_stream(io::text_stream & s) const;
00074 void from_stream(io::text_stream & s);
00075
00076 bool operator== (const matrix<R,C,T> & m) const;
00077 };
00078
00079
00080
00081
00082 template <int R, int C, typename T>
00083 matrix<R,C,T>::matrix()
00084 : math_object()
00085 {
00086 ::memset(data, 0, sizeof(T) * R*C);
00087 }
00088
00089 template <int R, int C, typename T>
00090 matrix<R,C,T>::matrix(const T *ptr)
00091 : math_object()
00092 {
00093 ::memcpy(data, ptr, sizeof(T) * R*C);
00094 }
00095
00096 template <int R, int C, typename T>
00097 matrix<R,C,T>::matrix(const matrix<R,C,T> & m)
00098 : math_object()
00099 {
00100 ::memcpy(data, m.data, sizeof(T) * R*C);
00101 }
00102
00103 template <int R, int C, typename T>
00104 matrix<R,C,T> & matrix<R,C,T>::operator= (const matrix<R,C,T> & m)
00105 {
00106 ::memcpy(data, m.data, sizeof(T) * R*C);
00107 return *this;
00108 }
00109
00110 template <int R, int C, typename T>
00111 matrix<R,C,T>::~matrix()
00112 {
00113 }
00114
00115
00116
00117 template <int R, int C, typename T>
00118 bool matrix<R,C,T>::operator== (const matrix<R,C,T> & m) const
00119 {
00120 for (int i = 0; i < R*C; ++i)
00121 if (data[i] != m.data[i])
00122 return false;
00123 return true;
00124 }
00125
00126
00127
00128
00129 template <int R, int C, typename T>
00130 void matrix<R,C,T>::to_stream(io::text_stream & s) const
00131 {
00132 for (int i = 0; i < R; ++i)
00133 {
00134 for (int j = 0; j < C; ++j)
00135 {
00136 if (j > 0)
00137 s << L' ';
00138 s << item(i, j);
00139 }
00140 s << L'\n';
00141 }
00142 }
00143
00144 template <int R, int C, typename T>
00145 void matrix<R,C,T>::from_stream(io::text_stream & s)
00146 {
00147 for (int i = 0; i < R; ++i)
00148 {
00149 for (int j = 0; j < C; ++j)
00150 {
00151 s >> item(i, j);
00152 }
00153 }
00154 }
00155
00156
00157
00158
00159
00160
00161 namespace matrix_utils
00162 {
00163
00164
00165 template <int RA, int CA, int RB, int CB, typename T>
00166 void multiply(const matrix<RA,CA,T> & a, const matrix<RB,CB,T> & b, matrix<RA,CB,T> & result)
00167 {
00168 assert(CA == RB);
00169
00170 gsgl::real_t *pa = const_cast<gsgl::real_t *>(a.ptr());
00171 gsgl::real_t *pb = const_cast<gsgl::real_t *>(b.ptr());
00172 gsgl::real_t *pr = const_cast<gsgl::real_t *>(result.ptr());
00173
00174 for (int i = 0; i < RA; ++i)
00175 {
00176 for (int j = 0; j < CB; ++j)
00177 {
00178 pr[j*RA+i] = 0;
00179
00180 for (int r = 0; r < CA; ++r)
00181 {
00182 pr[j*RA+i] += pa[r*RA+i] * pb[j*RB+r];
00183 }
00184 }
00185 }
00186 }
00187
00188 }
00189
00190
00191 }
00192
00193
00194 }
00195
00196 #endif