Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

mat.hpp

Go to the documentation of this file.
00001 // Yo Emacs, this -*- C++ -*-
00002 #ifndef MAT_H
00003 #define MAT_H
00004 
00005 #include "vec.hpp"
00006 //#include "misc.h"
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  * Matrix of primitive numeric values.
00020  *
00021  * This implementation is built for speed.
00022  * It does not work with non-primitive types!
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 //              IMPLEMENTATION
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   // this shortcut may not work with non-primitive types
00105   memcpy(_v, m._v, _size * sizeof(T));
00106   //for(int i = 0; i < _size; i++)
00107   //  _v[i] = m._v[i];
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   // this shortcut may not work with non-primitive types
00207   memcpy(_v, m._v, _size * sizeof(T));
00208   //for(int i = 0; i < _size; i++)
00209   //  _v[i] = m._v[i];
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


6 Jan 2011 Doxygen 1.6.3