00001
00002 #ifndef MAT_H
00003 #define MAT_H
00004
00005 #include "vec.hpp"
00006
00007
00008 #include <cstring>
00009 #include <iostream>
00010 #include <cassert>
00011
00012 #define SWAP(a1, a2, tmp) { (tmp) = (a1); (a1) = (a2); (a2) = (tmp); }
00013
00014 using std::istream;
00015 using std::ostream;
00016 using std::endl;
00017
00018
00019
00020
00021
00022
00023
00024 template <class T>
00025 class Mat
00026 {
00027 public:
00028 Mat();
00029 explicit Mat(int xs,int ys);
00030 Mat(const Mat &);
00031 ~Mat();
00032
00033 void setSize(int xs,int ys);
00034 inline int xs() const;
00035 inline int ys() const;
00036 inline T &operator ()(int x,int y);
00037 inline const T &operator ()(int x,int y) const;
00038
00039 Mat<T> operator ~() const;
00040
00041 inline void swapRows(int r0, int r1);
00042 inline const T *data() const;
00043 inline T *data();
00044
00045 Mat<T> &operator =(const Mat<T> &);
00046 Mat<T> operator +(const Mat<T> &) const;
00047 Mat<T> &operator +=(const Mat<T> &);
00048 Mat<T> operator -(const Mat<T> &) const;
00049 Mat<T> &operator -=(const Mat<T> &);
00050 Mat<T> operator *(const Mat<T> &) const;
00051 Mat<T> &operator *=(const Mat<T> &);
00052 Mat<T> operator -() const;
00053
00054 Mat<T> &operator =(const T &);
00055 Mat<T> operator *(const T &) const;
00056 Mat<T> &operator *=(const T &);
00057
00058 Vec<T> operator *(const Vec<T> &v) const;
00059
00060 bool operator ==(const Mat<T> &) const;
00061 bool operator !=(const Mat<T> &) const;
00062 bool operator <(const Mat<T> &) const;
00063 bool operator <=(const Mat<T> &) const;
00064 bool operator >(const Mat<T> &) const;
00065 bool operator >=(const Mat<T> &) const;
00066
00067 bool operator ==(const T &t) const;
00068 bool operator !=(const T &t) const;
00069 bool operator <(const T &t) const;
00070 bool operator <=(const T &t) const;
00071 bool operator >(const T &t) const;
00072 bool operator >=(const T &t) const;
00073 private:
00074 int _xs,_ys;
00075 int _size;
00076 T *_v;
00077 };
00078
00079 template<class T>
00080 ostream &operator <<(ostream &os, const Mat<T> &m);
00081
00082
00083
00084
00085
00086 template <class T>
00087 Mat<T>::Mat() : _xs(0), _ys(0), _size(0), _v(0)
00088 {
00089 }
00090
00091 template <class T>
00092 Mat<T>::Mat(int xs,int ys) : _xs(xs), _ys(ys), _size(_xs * _ys), _v(0)
00093 {
00094 if(_size > 0)
00095 _v = new T[_size];
00096 }
00097
00098 template <class T>
00099 Mat<T>::Mat(const Mat &m) : _xs(m._xs), _ys(m._ys), _size(_xs * _ys),_v(0)
00100 {
00101 if(_size > 0)
00102 _v = new T[_size];
00103
00104
00105 memcpy(_v, m._v, _size * sizeof(T));
00106
00107
00108 }
00109
00110 template <class T>
00111 Mat<T>::~Mat()
00112 {
00113 if(_v)
00114 delete [] _v;
00115 }
00116
00117 template <class T>
00118 inline void Mat<T>::setSize(int xs,int ys)
00119 {
00120 if(_size != xs * ys) {
00121 if(_v)
00122 delete [] _v;
00123 _xs = xs;
00124 _ys = ys;
00125 _size = _xs * _ys;
00126 if(_size > 0)
00127 _v = new T[_size];
00128 }
00129 }
00130
00131 template <class T>
00132 inline int Mat<T>::xs() const
00133 {
00134 return _xs;
00135 }
00136
00137 template <class T>
00138 inline int Mat<T>::ys() const
00139 {
00140 return _ys;
00141 }
00142
00143 template <class T>
00144 inline T &Mat<T>::operator ()(int x,int y)
00145 {
00146 assert(x >= 0 && x < _xs && y >= 0 && y < _ys);
00147 return _v[y * _xs + x];
00148 }
00149
00150 template <class T>
00151 inline const T &Mat<T>::operator ()(int x,int y) const
00152 {
00153 assert(x >= 0 && x < _xs && y >= 0 && y < _ys);
00154 return _v[y * _xs + x];
00155 }
00156
00157 template <class T>
00158 Mat<T> Mat<T>::operator ~() const
00159 {
00160 Mat<T> r(_ys, _xs);
00161 for(int x = 0; x < _xs; x++) {
00162 for(int y = 0; y < _ys; y++)
00163 r(y, x) = (*this)(x, y);
00164 }
00165 return r;
00166 }
00167
00168 template <class T>
00169 void Mat<T>::swapRows(int r0, int r1)
00170 {
00171 assert(0 <= r0 && r0 < _ys);
00172 assert(0 <= r1 && r1 < _ys);
00173 if(r0 != r1) {
00174 T tmp;
00175 T *v0 = _v + r0 * _xs;
00176 T *v1 = _v + r1 * _xs;
00177 for(int i = 0; i < _xs; i++)
00178 SWAP(v0[i], v1[i], tmp);
00179 }
00180 }
00181
00182 template <class T>
00183 const T *Mat<T>::data() const
00184 {
00185 return _v;
00186 }
00187
00188 template <class T>
00189 T *Mat<T>::data()
00190 {
00191 return _v;
00192 }
00193
00194 template <class T>
00195 Mat<T> &Mat<T>::operator =(const Mat<T> &m)
00196 {
00197 if(_size != m._size) {
00198 if(_v)
00199 delete [] _v;
00200 _xs = m._xs;
00201 _ys = m._ys;
00202 _size = _xs * _ys;
00203 if(_size)
00204 _v = new T[_size];
00205 }
00206
00207 memcpy(_v, m._v, _size * sizeof(T));
00208
00209
00210 return *this;
00211 }
00212
00213 template <class T>
00214 Mat<T> Mat<T>::operator +(const Mat<T> &m) const
00215 {
00216 assert(m._xs == _xs && m._ys == _ys);
00217 Mat<T> r(_xs,_ys);
00218 int x, y;
00219 for(x = 0; x < _xs; x++)
00220 for(y = 0; y < _ys; y++)
00221 r(x, y) -= (*this)(x, y) + m(x, y);
00222 return r;
00223 }
00224
00225 template <class T>
00226 Mat<T> &Mat<T>::operator +=(const Mat<T> &m)
00227 {
00228 assert(m._xs == _xs && m._ys == _ys);
00229 int x, y;
00230 for(x = 0; x < _xs; x++)
00231 for(y = 0; y < _ys; y++)
00232 (*this)(x, y) += m(x, y);
00233 return *this;
00234 }
00235
00236 template <class T>
00237 Mat<T> Mat<T>::operator -(const Mat<T> &m) const
00238 {
00239 assert(m._xs == _xs && m._ys == _ys);
00240 Mat<T> r(_xs,_ys);
00241 int x, y;
00242 for(x = 0; x < _xs; x++)
00243 for(y = 0; y < _ys; y++)
00244 r(x, y) -= (*this)(x, y) - m(x, y);
00245 return r;
00246 }
00247
00248 template <class T>
00249 Mat<T> &Mat<T>::operator -=(const Mat<T> &m)
00250 {
00251 assert(m._xs == _xs && m._ys == _ys);
00252 int x, y;
00253 for(x = 0; x < _xs; x++)
00254 for(y = 0; y < _ys; y++)
00255 (*this)(x, y) -= m(x, y);
00256 return *this;
00257 }
00258
00259 template <class T>
00260 Mat<T> Mat<T>::operator *(const Mat<T> &m) const
00261 {
00262 assert(_xs == m._ys);
00263 Mat<T> r(m._xs, _ys);
00264 int x, y,i;
00265 for(x = 0; x < r._xs; x++) {
00266 for(y = 0; y < r._ys; y++) {
00267 r(x, y) = 0;
00268 for(i = 0; i < _xs; i++)
00269 r(x, y) += (*this)(i, y) * m(x, i);
00270 }
00271 }
00272 return r;
00273 }
00274
00275 template <class T>
00276 Mat<T> &Mat<T>::operator *=(const Mat<T> &m)
00277 {
00278 (*this) = (*this) * m;
00279 return *this;
00280 }
00281
00282 template <class T>
00283 Mat<T> Mat<T>::operator -() const
00284 {
00285 Mat<T> r(_xs,_ys);
00286 for(int i = 0; i < _size; i++)
00287 r._v[i] = -_v[i];
00288 return r;
00289 }
00290
00291 template <class T>
00292 Mat<T> &Mat<T>::operator =(const T &t)
00293 {
00294 for(int i = 0; i < _size; i++)
00295 _v[i] = t;
00296 return *this;
00297 }
00298
00299 template <class T>
00300 Mat<T> Mat<T>::operator *(const T &t) const
00301 {
00302 Mat<T> r(_xs,_ys);
00303 int x, y;
00304 for(x = 0; x < _xs; x++)
00305 for(y = 0; y < _ys; y++)
00306 r(x, y) = (*this)(x, y) * t;
00307 return r;
00308 }
00309
00310 template <class T>
00311 Mat<T> &Mat<T>::operator *=(const T &t)
00312 {
00313 int x, y;
00314 for(x = 0; x < _xs; x++)
00315 for(y = 0; y < _ys; y++)
00316 (*this)(x, y) *= t;
00317 return *this;
00318 }
00319
00320 template <class T>
00321 Vec<T> Mat<T>::operator *(const Vec<T> &v) const
00322 {
00323 assert(_xs == v.size());
00324 Vec<T> r(_ys);
00325 for(int y = 0; y < _ys; y++) {
00326 r(y) = T(0);
00327 for(int x = 0; x < _xs; x++)
00328 r(y) += (*this)(x, y) * v(x);
00329 }
00330 return r;
00331 }
00332
00333 template <class T>
00334 bool Mat<T>::operator ==(const Mat<T> &m) const
00335 {
00336 for(int i = 0; i < _size; i++) {
00337 if(!(_v[i] == m._v[i]))
00338 return false;
00339 }
00340 return true;
00341 }
00342
00343 template <class T>
00344 bool Mat<T>::operator !=(const Mat<T> &m) const
00345 {
00346 for(int i = 0; i < _size; i++) {
00347 if(!(_v[i] != m._v[i]))
00348 return false;
00349 }
00350 return true;
00351 }
00352
00353 template <class T>
00354 bool Mat<T>::operator <(const Mat<T> &m) const
00355 {
00356 assert(_xs == m._xs && _ys == m._ys);
00357 for(int i = 0; i < _size; i++) {
00358 if(!(_v[i] < m._v[i]))
00359 return false;
00360 }
00361 return true;
00362 }
00363
00364 template <class T>
00365 bool Mat<T>::operator <=(const Mat<T> &m) const
00366 {
00367 assert(_xs == m._xs && _ys == m._ys);
00368 for(int i = 0; i < _size; i++) {
00369 if(!(_v[i] <= m._v[i]))
00370 return false;
00371 }
00372 return true;
00373 }
00374
00375 template <class T>
00376 bool Mat<T>::operator >(const Mat<T> &m) const
00377 {
00378 assert(_xs == m._xs && _ys == m._ys);
00379 for(int i = 0; i < _size; i++) {
00380 if(!(_v[i] > m._v[i]))
00381 return false;
00382 }
00383 return true;
00384 }
00385
00386 template <class T>
00387 bool Mat<T>::operator >=(const Mat<T> &m) const
00388 {
00389 assert(_xs == m._xs && _ys == m._ys);
00390 for(int i = 0; i < _size; i++) {
00391 if(!(_v[i] >= m._v[i]))
00392 return false;
00393 }
00394 return true;
00395 }
00396
00397 template <class T>
00398 bool Mat<T>::operator ==(const T &t) const
00399 {
00400 for(int i = 0; i < _size; i++) {
00401 if(!(_v[i] == t))
00402 return false;
00403 }
00404 return true;
00405 }
00406
00407 template <class T>
00408 bool Mat<T>::operator !=(const T &t) const
00409 {
00410 for(int i = 0; i < _size; i++) {
00411 if(!(_v[i] != t))
00412 return false;
00413 }
00414 return true;
00415 }
00416
00417 template <class T>
00418 bool Mat<T>::operator <(const T &t) const
00419 {
00420 for(int i = 0; i < _size; i++) {
00421 if(!(_v[i] < t))
00422 return false;
00423 }
00424 return true;
00425 }
00426
00427 template <class T>
00428 bool Mat<T>::operator <=(const T &t) const
00429 {
00430 for(int i = 0; i < _size; i++) {
00431 if(!(_v[i] <= t))
00432 return false;
00433 }
00434 return true;
00435 }
00436
00437 template <class T>
00438 bool Mat<T>::operator >(const T &t) const
00439 {
00440 for(int i = 0; i< _size; i++) {
00441 if(!(_v[i] > t))
00442 return false;
00443 }
00444 return true;
00445 }
00446
00447 template <class T>
00448 bool Mat<T>::operator >=(const T &t) const
00449 {
00450 for(int i = 0; i < _size; i++) {
00451 if(!(_v[i] >= t))
00452 return false;
00453 }
00454 return true;
00455 }
00456
00457
00458
00459
00460
00461 template <class T>
00462 ostream &operator <<(ostream &os, const Mat<T> &m)
00463 {
00464 os << "[" << endl;
00465 for(int y = 0; y < m.ys(); y++) {
00466 os << "[";
00467 for(int x = 0; x < m.xs(); x++) {
00468 if(x) os << ", ";
00469 os << m(x, y);
00470 }
00471 os << "]" << endl;
00472 }
00473 os << "]";
00474 return os;
00475 }
00476
00477 #endif