Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

base/Matrix

Go to the documentation of this file.
00001 /* **-*-c++-*-**************************************************************
00002   Copyright (C)2002 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: Matrix 1029 2004-02-11 20:45:54Z jungd $
00019   $Revision: 1.22 $
00020   $Date: 2004-02-11 15:45:54 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
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 // array wrapper implementation
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) // Output
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 } // base
00724 
00725 
00726 #else
00727 
00728 //
00729 // uBlas wrapper implementation
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; // alias
00740 
00741 /// Matrix(rows==size1(),cols==size2())
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 /// extract a submatrix
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 /// extract a Matrix row
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 /// extract a Matrix column
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 // MxN identity Matrix
00778 inline IdentityMatrix identityMatrix(const Int M, const Int N)
00779 { return IdentityMatrix(M,N); }
00780 
00781 /// MxN zero Matrix
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 // ublas doesn't overload operators for matrix*vector & matrix*matrix
00830 
00831 /// \todo we're possibly short-circuiting the expression templates here!
00832 ///       (need to redefine the operator*()'s to return something else
00833 ///       appropriate (matrix_expression?).  For now, we expose prod().
00834 inline Vector operator*(const Matrix& A, const Vector& x)
00835 { return ublas::prod(A,x); }
00836 
00837 // this premult of Vector by Matrix behaves as if the Vector were
00838 //  a single row Matrix
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 //using ublas::prod;
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) // Output
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 } // base
00920 
00921 #endif 
00922 
00923 #endif
00924 

Generated on Thu Jul 29 15:56:07 2004 for OpenSim by doxygen 1.3.6