00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _BASE_MATRIX_
00026 #define _BASE_MATRIX_
00027
00028 #include <base/base>
00029
00030 #include <iomanip>
00031
00032 #include <base/Vector>
00033 #include <base/Matrix3>
00034 #include <base/Matrix4>
00035
00036 #ifndef USE_BOOST_UBLAS
00037
00038
00039
00040
00041
00042 namespace base {
00043
00044
00045 #include <base/array>
00046
00047
00048 template<typename T>
00049 class matrix
00050 {
00051 public:
00052 typedef T value_type;
00053 typedef value_type& reference;
00054 typedef value_type* pointer;
00055 typedef const value_type& const_reference;
00056 typedef const value_type* const_pointer;
00057 typedef SInt difference_type;
00058 typedef Int size_type;
00059
00060 matrix() : _rows(0), _cols(0) {}
00061 matrix(size_type rows, size_type cols) : _rows(rows), _cols(cols), a(rows*cols) {}
00062 matrix(const matrix& m) : _rows(m._rows), _cols(m._cols), a(m.a) {}
00063 explicit matrix(const vector<value_type>& v) : _rows(v.size()), _cols(1), a(v.size())
00064 { for(size_type i=0; i<a.size(); i++) a[i]=v[i]; }
00065 matrix(size_type rows, size_type cols, const_reference p)
00066 : _rows(rows), _cols(cols), a(rows*cols)
00067 {
00068 for(size_type r=0; r<rows; r++)
00069 for(size_type c=0; c<cols; c++)
00070 _m(r,c) = (r!=c)?value_type(0):p;
00071 }
00072 ~matrix() {}
00073
00074 size_type rows() const { return _rows; }
00075 size_type cols() const { return _cols; }
00076 size_type size1() const { return _rows; }
00077 size_type size2() const { return _cols; }
00078
00079 bool operator==(const matrix& m) const
00080 { Assert(_rows == m._rows); Assert(_cols == m._cols); return (a == m.a); }
00081 bool operator!=(const matrix& m) const
00082 { Assert(_rows == m._rows); Assert(cols == m._cols); return (a != m.a); }
00083
00084 bool equals(const matrix& m, value_type eps = value_type(consts::epsilon) ) const
00085 {
00086 if (&m != this) {
00087 Assert(_rows == m._rows);
00088 Assert(_cols == m._cols);
00089 for(Int i=0; i<a.size(); i++)
00090 if (!base::equals(a[i],m.a[i],eps)) return false;
00091 }
00092 return true;
00093 }
00094
00095 reference operator()(size_type r, size_type c)
00096 { Assert(r<_rows); Assert(c<_cols); return _m(r,c); }
00097
00098 const_reference operator()(size_type r, size_type c) const
00099 { Assert(r<_rows); Assert(c<_cols); return _m(r,c); }
00100
00101 void resize(size_type rows, size_type cols)
00102 {
00103 a.resize(rows*cols);
00104 _rows = rows; _cols = cols;
00105 }
00106
00107
00108 matrix& operator=(const matrix& m)
00109 {
00110 if (&m != this) { _rows=m._rows; _cols=m._cols; a=m.a; }
00111 return *this;
00112 }
00113
00114 void reset(const matrix& m) { *this = m; }
00115
00116 matrix& operator+=(const matrix& m)
00117 {
00118 Assert(_rows == m._rows);
00119 Assert(_cols == m._cols);
00120 for(size_type i=0; i<a.size(); i++) a[i]+= m.a[i];
00121 return *this;
00122 }
00123
00124 matrix& operator-=(const matrix& m)
00125 {
00126 Assert(_rows == m._rows);
00127 Assert(_cols == m._cols);
00128 for(size_type i=0; i<a.size(); i++) a[i]-= m.a[i];
00129 return *this;
00130 }
00131
00132
00133 matrix& negate()
00134 {
00135 for(size_type i=0; i<a.size(); i++) a[i] = -a[i];
00136 return *this;
00137 }
00138
00139
00140 matrix& operator*=(const matrix& m2)
00141 {
00142 Assert(_cols == m2._rows);
00143
00144 matrix r(_rows, m2._cols);
00145
00146 for(size_type i=0; i<_rows; i++)
00147 for(size_type j=0; j<m2._cols; j++) {
00148 r._m(i,j) = value_type(0);
00149 for(size_type k=0; k<_cols; k++)
00150 r._m(i,j) += _m(i,k) * m2._m(k,j);
00151 }
00152
00153 return (*this = r);
00154 }
00155
00156
00157 matrix& operator*=(const_reference s)
00158 { for(size_type i=0; i<a.size(); i++) a[i]*=s; return *this; }
00159
00160 matrix& operator/=(const_reference s)
00161 { for(size_type i=0; i<a.size(); i++) a[i]/=s; return *this; }
00162
00163
00164 matrix& transpose()
00165 {
00166 matrix rm(_cols,_rows);
00167 for(size_type r=0; r<_rows; r++)
00168 for(size_type c=0; c<_cols; c++)
00169 rm(c,r) = _m(r,c);
00170 *this = rm;
00171 return *this;
00172 }
00173
00174
00175 pointer c_array() { return a.c_array(); }
00176 const_pointer c_array() const { return a.c_array(); }
00177
00178
00179
00180 protected:
00181 size_type _rows, _cols;
00182 array<value_type> a;
00183
00184 reference _m(size_type r, size_type c) { return a[(r*_cols)+c]; }
00185 const_reference _m(size_type r, size_type c) const { return a[(r*_cols)+c]; }
00186 };
00187
00188
00189
00190
00191
00192
00193
00194
00195 template<typename T>
00196 class const_matrixrow
00197 {
00198 public:
00199 typedef T value_type;
00200 typedef typename matrix<T>::size_type size_type;
00201
00202 const_matrixrow(const matrix<T>& m, size_type r) : m(m), r(r) {}
00203 const_matrixrow(const const_matrixrow& mr) : m(mr.m), r(mr.r) {}
00204 ~const_matrixrow() {}
00205
00206 const value_type& operator[](size_type c) const { return m(r,c); }
00207
00208 size_type size() const { return m.cols(); }
00209
00210 operator vector<T>() const {
00211 vector<T> v(m.cols());
00212 for(size_type c=0; c<m.cols(); c++) v[c] = m(r,c);
00213 return v;
00214 }
00215
00216 protected:
00217 const_matrixrow& operator=(const vector<T>& v) {}
00218 const_matrixrow() {}
00219
00220 const matrix<T>& m;
00221 size_type r;
00222 };
00223
00224
00225
00226
00227
00228
00229 template<typename T>
00230 class matrixrow
00231 {
00232 public:
00233 typedef T value_type;
00234 typedef typename matrix<T>::size_type size_type;
00235
00236 matrixrow(matrix<T>& m, size_type r) : m(m), r(r) {}
00237 matrixrow(const matrixrow& mr) : m(mr.m), r(mr.r) {}
00238 ~matrixrow() {}
00239
00240 value_type& operator[](size_type c) { return m(r,c); }
00241 const value_type& operator[](size_type c) const { return m(r,c); }
00242
00243 matrixrow& operator=(const matrixrow& mr)
00244 {
00245 Assert(m.cols() == mr.m.cols());
00246 for(size_type c=0; c<m.cols(); c++) m(r,c) = mr.m(mr.r,c);
00247 return *this;
00248 }
00249
00250 matrixrow& operator=(const vector<T>& v) {
00251 Assert(v.size() == m.cols());
00252 for(size_type c=0; c<m.cols(); c++) m(r,c) = v[c];
00253 return *this;
00254 }
00255
00256
00257 matrixrow& operator*=(const value_type& s)
00258 { for(size_type c=0; c<m.cols(); c++) m(r,c) *= s; return *this; }
00259
00260 matrixrow& operator/=(const value_type& s)
00261 { for(size_type c=0; c<m.cols(); c++) m(r,c) /= s; return *this; }
00262
00263
00264 size_type size() const { return m.cols(); }
00265
00266 operator const_matrixrow<T>() const { return const_matrixrow<T>(m,r); }
00267
00268 operator vector<T>() const {
00269 vector<T> v(m.cols());
00270 for(size_type c=0; c<m.cols(); c++) v[c] = m(r,c);
00271 return v;
00272 }
00273
00274 protected:
00275 matrixrow() {}
00276
00277 matrix<T>& m;
00278 size_type r;
00279 };
00280
00281
00282
00283 template<typename T>
00284 class const_matrixcolumn
00285 {
00286 public:
00287 typedef T value_type;
00288 typedef typename matrix<T>::size_type size_type;
00289
00290 const_matrixcolumn(const matrix<T>& m, size_type c) : m(m), c(c) {}
00291 const_matrixcolumn(const const_matrixcolumn& mc) : m(mc.m), c(mc.c) {}
00292 ~const_matrixcolumn() {}
00293
00294 const value_type& operator[](size_type r) const { return m(r,c); }
00295
00296 size_type size() const { return m.rows(); }
00297
00298 operator vector<T>() const {
00299 vector<T> v(m.rows());
00300 for(size_type r=0; r<m.rows(); r++) v[r] = m(r,c);
00301 return v;
00302 }
00303
00304 protected:
00305 const_matrixcolumn() {}
00306
00307 const matrix<T>& m;
00308 size_type c;
00309 };
00310
00311
00312
00313
00314 template<typename T>
00315 class matrixcolumn
00316 {
00317 public:
00318 typedef T value_type;
00319 typedef typename matrix<T>::size_type size_type;
00320
00321 matrixcolumn(matrix<T>& m, size_type c) : m(m), c(c) {}
00322 matrixcolumn(const matrixcolumn& mc) : m(mc.m), c(mc.c) {}
00323 ~matrixcolumn() {}
00324
00325 value_type& operator[](size_type r) { return m(r,c); }
00326 const value_type& operator[](size_type r) const { return m(r,c); }
00327
00328 matrixcolumn& operator=(const matrixcolumn& mc)
00329 {
00330 Assert(m.rows() == mc.m.rows());
00331 for(size_type r=0; r<m.rows(); r++) m(r,c) = mc.m(r,mc.c);
00332 return *this;
00333 }
00334
00335 matrixcolumn& operator=(const vector<T>& v) {
00336 Assert(v.size() == m.rows());
00337 for(size_type r=0; r<m.rows(); r++) m(r,c) = v[r];
00338 return *this;
00339 }
00340
00341 matrixcolumn& operator*=(const value_type& s)
00342 { for(size_type r=0; r<m.rows(); r++) m(r,c) *= s; return *this; }
00343
00344 matrixcolumn& operator/=(const value_type& s)
00345 { for(size_type r=0; r<m.rows(); r++) m(r,c) /= s; return *this; }
00346
00347
00348 operator const_matrixcolumn<T>() const { return const_matrixcolumn<T>(m,c); }
00349
00350 size_type size() const { return m.rows(); }
00351
00352 operator vector<T>() const {
00353 vector<T> v(m.rows());
00354 for(size_type r=0; r<m.rows(); r++) v[r] = m(r,c);
00355 return v;
00356 }
00357
00358 protected:
00359 matrixcolumn() {}
00360
00361 matrix<T>& m;
00362 size_type c;
00363 };
00364
00365
00366
00367 template<typename T>
00368 class const_matrixrange
00369 {
00370 public:
00371 typedef T value_type;
00372 typedef value_type& reference;
00373 typedef const value_type& const_reference;
00374 typedef typename matrix<T>::size_type size_type;
00375
00376 const_matrixrange(const matrix<T>& m, const range<size_type>& rr, const range<size_type>& cr) : m(m), rr(rr), cr(cr)
00377 {
00378 Assert((rr.b >= 0) && (rr.b < m.rows()));
00379 Assert((rr.e >= 0) && (rr.e <= m.rows()));
00380 Assert((cr.b >= 0) && (cr.b < m.cols()));
00381 Assert((cr.e >= 0) && (cr.e <= m.cols()));
00382 }
00383 const_matrixrange(const const_matrixrange<T>& mr) : m(mr.m), rr(mr.rr), cr(mr.cr) {}
00384 ~const_matrixrange() {}
00385
00386 size_type rows() const { return rr.e - rr.b; }
00387 size_type cols() const { return cr.e - cr.b; }
00388 size_type size1() const { return rows(); }
00389 size_type size2() const { return cols(); }
00390
00391 bool operator==(const const_matrixrange& mr) const { return (rr==mr.rr)&&(cr==mr.cr)&&(m==mr.m); }
00392 bool operator!=(const const_matrixrange& mr) const { return (rr!=mr.rr)||(cr!=mr.cr)||(m!=mr.m); }
00393
00394 bool equals(const const_matrixrange& mr, value_type eps = value_type(consts::epsilon) ) const
00395 { return (rr==mr.rr)&&(cr==mr.cr)&&m.equals(mr.m,eps); }
00396
00397 const_reference operator()(size_type r, size_type c) const
00398 { Assert(r<rows()); Assert(c<cols()); return _m(r, c); }
00399
00400 operator matrix<T>() const
00401 {
00402 matrix<T> rm(rows(), cols());
00403 for(size_type r=0; r<rows(); r++)
00404 for(size_type c=0; c<cols(); c++)
00405 rm(r,c) = _m(r,c);
00406 return rm;
00407 }
00408
00409 protected:
00410 const_matrixrange() {}
00411
00412 const matrix<T>& m;
00413 range<size_type> rr;
00414 range<size_type> cr;
00415
00416 const_reference _m(size_type r, size_type c) const { return m(rr.b+r, cr.b+c); }
00417 };
00418
00419
00420
00421 template<typename T>
00422 class matrixrange
00423 {
00424 public:
00425 typedef T value_type;
00426 typedef value_type& reference;
00427 typedef const value_type& const_reference;
00428 typedef typename matrix<T>::size_type size_type;
00429
00430 matrixrange(matrix<T>& m, const range<size_type>& rr, const range<size_type>& cr) : m(m), rr(rr), cr(cr)
00431 {
00432 Assert((rr.b >= 0) && (rr.b < m.rows()));
00433 Assert((rr.e >= 0) && (rr.e <= m.rows()));
00434 Assert((cr.b >= 0) && (cr.b < m.cols()));
00435 Assert((cr.e >= 0) && (cr.e <= m.cols()));
00436 }
00437 matrixrange(const matrixrange<T>& mr) : m(mr.m), rr(mr.rr), cr(mr.cr) {}
00438 ~matrixrange() {}
00439
00440 size_type rows() const { return rr.e - rr.b; }
00441 size_type cols() const { return cr.e - cr.b; }
00442 size_type size1() const { return rows(); }
00443 size_type size2() const { return cols(); }
00444
00445 bool operator==(const matrixrange& mr) const { return (rr==mr.rr)&&(cr==mr.cr)&&(m==mr.m); }
00446 bool operator!=(const matrixrange& mr) const { return (rr!=mr.rr)||(cr!=mr.cr)||(m!=mr.m); }
00447
00448 bool equals(const matrixrange& mr, value_type eps = value_type(consts::epsilon) ) const
00449 { return (rr==mr.rr)&&(cr==mr.cr)&&m.equals(mr.m,eps); }
00450
00451 const_reference operator()(size_type r, size_type c) const
00452 { Assert(r<rows()); Assert(c<cols()); return _m(r, c); }
00453
00454 reference operator()(size_type r, size_type c)
00455 { Assert(r<rows()); Assert(c<cols()); return _m(r, c); }
00456
00457
00458 matrixrange& operator=(const matrixrange& mr)
00459 {
00460 Assert(rows() == mr.rows()); Assert(cols() == mr.cols());
00461 for(size_type r=0; r<rows(); r++)
00462 for(size_type c=0; c<cols(); c++)
00463 _m(r, c) = mr(r,c);
00464 return *this;
00465 }
00466
00467
00468 matrixrange& operator=(const matrix<T>& sm)
00469 {
00470 Assert(rows() == sm.rows()); Assert(cols() == sm.cols());
00471 for(size_type r=0; r<rows(); r++)
00472 for(size_type c=0; c<cols(); c++)
00473 _m(r, c) = sm(r,c);
00474 return *this;
00475 }
00476
00477
00478 void reset(const matrixrange& mr) { *this = mr; }
00479 void reset(const matrix<T>& m) { *this = m; }
00480
00481 matrixrange& operator+=(const matrixrange& mr)
00482 {
00483 Assert(rows() == mr.rows()); Assert(cols() == mr.cols());
00484 for(size_type r=0; r<rows(); r++)
00485 for(size_type c=0; c<cols(); c++)
00486 _m(r,c) += mr(r,c);
00487 return *this;
00488 }
00489
00490 matrixrange& operator+=(const matrix<T>& sm)
00491 {
00492 Assert(rows() == sm.rows()); Assert(cols() == sm.cols());
00493 for(size_type r=0; r<rows(); r++)
00494 for(size_type c=0; c<cols(); c++)
00495 _m(r,c) += sm(r,c);
00496 return *this;
00497 }
00498
00499 matrixrange& operator-=(const matrixrange& mr)
00500 {
00501 Assert(rows() == mr.rows()); Assert(cols() == mr.cols());
00502 for(size_type r=0; r<rows(); r++)
00503 for(size_type c=0; c<cols(); c++)
00504 _m(r,c) -= mr(r,c);
00505 return *this;
00506 }
00507
00508 matrixrange& operator-=(const matrix<T>& sm)
00509 {
00510 Assert(rows() == sm.rows()); Assert(cols() == sm.cols());
00511 for(size_type r=0; r<rows(); r++)
00512 for(size_type c=0; c<cols(); c++)
00513 _m(r,c) -= sm(r,c);
00514 return *this;
00515 }
00516
00517
00518 matrixrange& negate()
00519 {
00520 for(size_type r=0; r<rows(); r++)
00521 for(size_type c=0; c<cols(); c++)
00522 _m(r,c) = -_m(r,c);
00523 return *this;
00524 }
00525
00526
00527 matrixrange& transpose()
00528 {
00529 Assert(rows() == cols());
00530 matrix<T> rm(cols(), rows());
00531 for(size_type r=0; r<_rows; r++)
00532 for(size_type c=0; c<_cols; c++)
00533 rm(c,r) = _m(r,c);
00534 *this = rm;
00535 return *this;
00536 }
00537
00538 operator const_matrixrange<T>() const { return const_matrixrange<T>(m,rr,cr); }
00539
00540 operator matrix<T>() const
00541 {
00542 matrix<T> rm(rows(), cols());
00543 for(size_type r=0; r<rows(); r++)
00544 for(size_type c=0; c<cols(); c++)
00545 rm(r,c) = _m(r,c);
00546 return rm;
00547 }
00548
00549 protected:
00550 matrixrange() {}
00551
00552 matrix<T>& m;
00553 range<size_type> rr;
00554 range<size_type> cr;
00555
00556 reference _m(size_type r, size_type c) { return m(rr.b+r, cr.b+c); }
00557 const_reference _m(size_type r, size_type c) const { return m(rr.b+r, cr.b+c); }
00558 };
00559
00560
00561
00562 typedef matrix<Real> Matrix;
00563 typedef matrixrow<Real> MatrixRow;
00564 typedef matrixcolumn<Real> MatrixColumn;
00565 typedef matrixrange<Real> MatrixRange;
00566 typedef const_matrixrow<Real> ConstMatrixRow;
00567 typedef const_matrixcolumn<Real> ConstMatrixColumn;
00568 typedef const_matrixrange<Real> ConstMatrixRange;
00569
00570
00571
00572
00573 inline MatrixRow matrixRow(Matrix& m, const Int r)
00574 {
00575 return MatrixRow(m,r);
00576 }
00577
00578 inline ConstMatrixRow matrixRow(const Matrix& m, const Int r)
00579 {
00580 return ConstMatrixRow(m,r);
00581 }
00582
00583
00584 inline MatrixColumn matrixColumn(Matrix& m, const Int c)
00585 {
00586 return MatrixColumn(m,c);
00587 }
00588
00589 inline ConstMatrixColumn matrixColumn(const Matrix& m, const Int c)
00590 {
00591 return ConstMatrixColumn(m,c);
00592 }
00593
00594
00595 inline MatrixRange matrixRange(Matrix& m, const Range& rr, const Range& cr)
00596 {
00597 return MatrixRange(m,rr,cr);
00598 }
00599
00600 inline ConstMatrixRange matrixRange(const Matrix& m, const Range& rr, const Range& cr)
00601 {
00602 return ConstMatrixRange(m,rr,cr);
00603 }
00604
00605
00606 inline Matrix operator+(const Matrix& m1, const Matrix& m2)
00607 { Matrix r(m1); r+=m2; return r; }
00608
00609 inline Matrix operator-(const Matrix& m1, const Matrix& m2)
00610 { Matrix r(m1); r-=m2; return r; }
00611
00612 inline Matrix operator-(const Matrix& m1)
00613 { Matrix r(m1); r.negate(); return r; }
00614
00615 inline Matrix operator*(const Matrix& m1, const Matrix& m2)
00616 { Matrix r(m1); r*=m2; return r; }
00617
00618 inline Vector operator*(const Matrix& m, const Vector& v)
00619 {
00620 Assert(m.cols() == v.size());
00621
00622 Vector r(m.rows());
00623
00624 for(Int i=0; i<m.rows(); i++) {
00625 r(i) = 0;
00626 for(Int k=0; k<m.cols(); k++)
00627 r(i) += m(i,k) * v(k);
00628 }
00629
00630 return r;
00631 }
00632
00633
00634 inline Vector operator*(const Vector& v, const Matrix& m) { return m*v; }
00635
00636
00637 inline Matrix operator*(const Matrix& m1, const Real& s)
00638 { Matrix r(m1); r*=s; return r; }
00639
00640 inline Matrix operator*(const Real& s, const Matrix& m1)
00641 { Matrix r(m1); r*=s; return r; }
00642
00643 inline Matrix operator/(const Matrix& m1, const Real& s)
00644 { Matrix r(m1); r/=s; return r; }
00645
00646 inline bool equals(const Matrix& m1, const Matrix& m2, Real eps = consts::epsilon)
00647 { return m1.equals(m2,eps); }
00648
00649
00650 inline Matrix transpose(const Matrix& m)
00651 { Matrix r(m); r.transpose(); return r; }
00652
00653 inline Matrix transpose(const Vector& v)
00654 { Matrix r(v); r.transpose(); return r; }
00655
00656
00657
00658 inline Matrix zeroMatrix(const Int M, const Int N)
00659 { return Matrix(M,N,0); }
00660
00661 inline Matrix identityMatrix(const Int M, const Int N)
00662 { return Matrix(M,N,1); }
00663
00664
00665
00666
00667
00668
00669
00670 inline base::Matrix4 toMatrix4(const Matrix& T)
00671 {
00672 Assert((T.size1() == 4) && (T.size2() == 4));
00673 return base::Matrix4(T(0,0),T(0,1),T(0,2),T(0,3),
00674 T(1,0),T(1,1),T(1,2),T(1,3),
00675 T(2,0),T(2,1),T(2,2),T(2,3),
00676 T(3,0),T(3,1),T(3,2),T(3,3));
00677 }
00678
00679
00680 inline Matrix fromMatrix4(const Matrix4& T4)
00681 {
00682 Matrix T(4,4);
00683 T(0,0)=T4(1,1); T(0,1)=T4(1,2); T(0,2)=T4(1,3); T(0,3)=T4(1,4);
00684 T(1,0)=T4(2,1); T(1,1)=T4(2,2); T(1,2)=T4(2,3); T(1,3)=T4(2,4);
00685 T(2,0)=T4(3,1); T(2,1)=T4(3,2); T(2,2)=T4(3,3); T(2,3)=T4(3,4);
00686 T(3,0)=T4(4,1); T(3,1)=T4(4,2); T(3,2)=T4(4,3); T(3,3)=T4(4,4);
00687 return T;
00688 }
00689
00690
00691 inline base::Matrix3 toMatrix3(const Matrix& T)
00692 {
00693 Assert((T.size1() == 3) && (T.size2() == 3));
00694 return base::Matrix3(T(0,0),T(0,1),T(0,2),
00695 T(1,0),T(1,1),T(1,2),
00696 T(2,0),T(2,1),T(2,2));
00697 }
00698
00699
00700 inline Matrix fromMatrix3(const Matrix3& T3)
00701 {
00702 Matrix T(3,3);
00703 T(0,0)=T3(1,1); T(0,1)=T3(1,2); T(0,2)=T3(1,3);
00704 T(1,0)=T3(2,1); T(1,1)=T3(2,2); T(1,2)=T3(2,3);
00705 T(2,0)=T3(3,1); T(2,1)=T3(3,2); T(2,2)=T3(3,3);
00706 return T;
00707 }
00708
00709
00710 inline std::ostream& operator<<(std::ostream& out, const Matrix& m)
00711 {
00712 out << std::setiosflags (std::ios_base::fixed) << std::setprecision(6) << std::setw(8);
00713 for(Int r=0; r<m.size1(); r++) {
00714 for(Int c=0; c<m.size2(); c++) {
00715 out << m(r,c) << " ";
00716 }
00717 out << "\n";
00718 }
00719 return out;
00720 }
00721
00722
00723 }
00724
00725
00726 #else
00727
00728
00729
00730
00731
00732 #include <boost/numeric/ublas/matrix.hpp>
00733
00734 #include <base/Vector>
00735 #include <base/Matrix4>
00736
00737 namespace base {
00738
00739 namespace ublas = boost::numeric::ublas;
00740
00741
00742 typedef ublas::matrix<base::Real, ublas::row_major> Matrix;
00743
00744 typedef ublas::matrix_range<Matrix> MatrixRange;
00745 typedef ublas::matrix_range<const Matrix> ConstMatrixRange;
00746 typedef ublas::matrix_row<Matrix> MatrixRow;
00747 typedef ublas::matrix_row<const Matrix> ConstMatrixRow;
00748 typedef ublas::matrix_column<Matrix> MatrixColumn;
00749 typedef ublas::matrix_column<const Matrix> ConstMatrixColumn;
00750
00751
00752
00753 inline MatrixRange matrixRange(Matrix& m, const Range& rr, const Range& cr)
00754 { return MatrixRange(m,rr,cr); }
00755
00756 inline ConstMatrixRange matrixRange(const Matrix& m, const Range& rr, const Range& cr)
00757 { return ConstMatrixRange(m,rr,cr); }
00758
00759
00760 inline MatrixRow matrixRow(Matrix& m, const Int r)
00761 { return MatrixRow(m,r); }
00762
00763 inline ConstMatrixRow matrixRow(const Matrix& m, const Int r)
00764 { return ConstMatrixRow(m,r); }
00765
00766
00767 inline MatrixColumn matrixColumn(Matrix& m, const Int c)
00768 { return MatrixColumn(m,c); }
00769
00770 inline ConstMatrixColumn matrixColumn(const Matrix& m, const Int c)
00771 { return ConstMatrixColumn(m,c); }
00772
00773
00774 typedef ublas::identity_matrix<base::Real> IdentityMatrix;
00775 typedef ublas::zero_matrix<base::Real> ZeroMatrix;
00776
00777
00778 inline IdentityMatrix identityMatrix(const Int M, const Int N)
00779 { return IdentityMatrix(M,N); }
00780
00781
00782 inline ZeroMatrix zeroMatrix(const Int M, const Int N)
00783 { return ZeroMatrix(M,N); }
00784
00785
00786
00787 inline base::Matrix4 toMatrix4(const Matrix& T)
00788 {
00789 Assert((T.size1() == 4) && (T.size2() == 4));
00790 return base::Matrix4(T(0,0),T(0,1),T(0,2),T(0,3),
00791 T(1,0),T(1,1),T(1,2),T(1,3),
00792 T(2,0),T(2,1),T(2,2),T(2,3),
00793 T(3,0),T(3,1),T(3,2),T(3,3));
00794 }
00795
00796
00797 inline base::Matrix fromMatrix4(const Matrix4& T4)
00798 {
00799 Matrix T(4,4);
00800 T(0,0)=T4(1,1); T(0,1)=T4(1,2); T(0,2)=T4(1,3); T(0,3)=T4(1,4);
00801 T(1,0)=T4(2,1); T(1,1)=T4(2,2); T(1,2)=T4(2,3); T(1,3)=T4(2,4);
00802 T(2,0)=T4(3,1); T(2,1)=T4(3,2); T(2,2)=T4(3,3); T(2,3)=T4(3,4);
00803 T(3,0)=T4(4,1); T(3,1)=T4(4,2); T(3,2)=T4(4,3); T(3,3)=T4(4,4);
00804 return T;
00805 }
00806
00807
00808 inline base::Matrix3 toMatrix3(const Matrix& T)
00809 {
00810 Assert((T.size1() == 3) && (T.size2() == 3));
00811 return base::Matrix3(T(0,0),T(0,1),T(0,2),
00812 T(1,0),T(1,1),T(1,2),
00813 T(2,0),T(2,1),T(2,2));
00814 }
00815
00816
00817 inline base::Matrix fromMatrix3(const Matrix3& T3)
00818 {
00819 Matrix T(3,3);
00820 T(0,0)=T3(1,1); T(0,1)=T3(1,2); T(0,2)=T3(1,3);
00821 T(1,0)=T3(2,1); T(1,1)=T3(2,2); T(1,2)=T3(2,3);
00822 T(2,0)=T3(3,1); T(2,1)=T3(3,2); T(2,2)=T3(3,3);
00823 return T;
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834 inline Vector operator*(const Matrix& A, const Vector& x)
00835 { return ublas::prod(A,x); }
00836
00837
00838
00839 inline Vector operator*(const Vector& x, const Matrix& A)
00840 {
00841 Assert(x.size() == A.size1());
00842 Matrix xm(1,x.size());
00843 matrixRow(xm,0) = x;
00844 return Vector( matrixRow( ublas::prod(xm,A),0) );
00845 }
00846
00847 inline Vector operator*(const Matrix& A, const ublas::vector_range<Vector>& x)
00848 { return ublas::prod(A,x); }
00849
00850 inline Vector operator*(const ublas::matrix_range<Matrix>& A, const Vector& x)
00851 { return ublas::prod(A,x); }
00852
00853 inline Vector operator*(const ublas::matrix_range<Matrix>& A, const ublas::vector_range<Vector>& x)
00854 { return ublas::prod(A,x); }
00855
00856
00857 inline Matrix operator*(const Matrix& A, const Matrix& B)
00858 { return ublas::prod(A,B); }
00859
00860 inline Matrix operator*(const ublas::matrix_range<Matrix>& A, const Matrix& B)
00861 { return ublas::prod(A,B); }
00862
00863 inline Matrix operator*(const Matrix& A, const ublas::matrix_range<Matrix>& B)
00864 { return ublas::prod(A,B); }
00865
00866 inline Matrix operator*(const ublas::matrix_range<Matrix>& A, const ublas::matrix_range<Matrix>& B)
00867 { return ublas::prod(A,B); }
00868
00869
00870
00871 inline Matrix transpose(const Matrix& m)
00872 { return ublas::trans(m); }
00873
00874
00875 inline bool operator==(const Matrix& m1, const Matrix& m2)
00876 {
00877 if (&m1 == &m2) return true;
00878
00879 Assert(m1.size1() == m2.size1());
00880 Assert(m1.size2() == m2.size2());
00881
00882 for(Int r=0; r<m1.size1(); r++)
00883 for(Int c=0; c<m1.size2(); c++)
00884 if (m1(r,c) != m2(r,c))
00885 return false;
00886 return true;
00887 }
00888
00889
00890 inline bool equals(const Matrix& m1, const Matrix& m2, Real epsilon = consts::epsilon)
00891 {
00892 if (&m1 == &m2) return true;
00893
00894 Assert(m1.size1() == m2.size1());
00895 Assert(m1.size2() == m2.size2());
00896
00897 for(Int r=0; r<m1.size1(); r++)
00898 for(Int c=0; c<m1.size2(); c++)
00899 if (!equals(m1(r,c),m2(r,c),epsilon))
00900 return false;
00901 return true;
00902 }
00903
00904
00905 inline std::ostream& operator<<(std::ostream& out, const Matrix& m)
00906 {
00907 out << std::setiosflags (std::ios_base::fixed) << std::setprecision(6) << std::setw(8);
00908 for(Int r=0; r<m.size1(); r++) {
00909 for(Int c=0; c<m.size2(); c++) {
00910 out << m(r,c) << " ";
00911 }
00912 out << "\n";
00913 }
00914 return out;
00915 }
00916
00917
00918
00919 }
00920
00921 #endif
00922
00923 #endif
00924