TooN 2.0.0-beta8
|
00001 // -*- c++ -*- 00002 00003 // Copyright (C) 2009 Tom Drummond (twd20@cam.ac.uk), 00004 // Ed Rosten (er258@cam.ac.uk) 00005 // 00006 // This file is part of the TooN Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 2, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // You should have received a copy of the GNU General Public License along 00018 // with this library; see the file COPYING. If not, write to the Free 00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00020 // USA. 00021 00022 // As a special exception, you may use this file as part of a free software 00023 // library without restriction. Specifically, if other files instantiate 00024 // templates or use macros or inline functions from this file, or you compile 00025 // this file and link it with other files to produce an executable, this 00026 // file does not by itself cause the resulting executable to be covered by 00027 // the GNU General Public License. This exception does not however 00028 // invalidate any other reasons why the executable file might be covered by 00029 // the GNU General Public License. 00030 00031 namespace TooN { 00032 00033 /** 00034 A matrix. 00035 Support is provided for all the usual matrix operations: 00036 - the (a,b) notation can be used to access an element directly 00037 - the [] operator can be used to yield a vector from a matrix (which can be used 00038 as an l-value) 00039 - they can be added and subtracted 00040 - they can be multiplied (on either side) or divided by a scalar on the right: 00041 - they can be multiplied by matrices or vectors 00042 - submatrices can be extracted using the templated slice() member function 00043 - they can be transposed (and the transpose used as an l-value) 00044 - inverse is \e not supported. Use one of the @link gDecomps matrix 00045 decompositions @endlink instead 00046 00047 See individual member function documentation for examples of usage. 00048 00049 \par Statically-sized matrices 00050 00051 The library provides classes for statically and dynamically sized matrices. As 00052 with @link Vector Vectors@endlink, statically sized matrices are more efficient, 00053 since their size is determined at compile-time, not run-time. 00054 To create a \f$3\times4\f$ matrix, use: 00055 @code 00056 Matrix<3,4> M; 00057 @endcode 00058 or replace 3 and 4 with the dimensions of your choice. If the matrix is square, 00059 it can be declared as: 00060 @code 00061 Matrix<3> M; 00062 @endcode 00063 which just is a synonym for <code>Matrix<3,3></code>. Matrices can also be 00064 constructed from pointers or static 1D or 2D arrays of doubles: 00065 @code 00066 00067 double dvals1[9]={1,2,3,4,5,6}; 00068 Matrix<2,3, Reference::RowMajor> M2 (dvals1); 00069 @endcode 00070 00071 \par Dynamically-sized matrices 00072 00073 To create a dynamically sized matrix, use: 00074 @code 00075 Matrix<> M(num_rows, num_cols); 00076 @endcode 00077 where \a num_rows and \a num_cols are integers which will be evaluated at run 00078 time. 00079 00080 Half-dynamic matriced can be constructed in either dimension: 00081 @code 00082 Matrix<Dynamic, 2> M(num_rows, 2); 00083 @endcode 00084 note that the static dimension must be provided, but it is ignored. 00085 00086 @endcode 00087 00088 <code>Matrix<></code> is a synonym for <code> Matrix<Dynamic, Dynamic> </code> which is 00089 <code>%Matrix<-1,-1></code> 00090 00091 \par Row-major and column-major 00092 00093 The library supports both row major (the default - but you can change this if 00094 you prefer) and column major layout ordering. Row major implies that the matrix 00095 is laid out in memory in raster scan order: 00096 \f[\begin{matrix}\text{Row major} & \text {Column major}\\ 00097 \begin{bmatrix}1&2&3\\4&5&6\\7&8&9\end{bmatrix} & 00098 \begin{bmatrix}1&4&7\\2&5&8\\3&6&9\end{bmatrix} \end{matrix}\f] 00099 You can override the default for a specific matrix by specifying the layout when 00100 you construct it: 00101 @code 00102 Matrix<3,3,double,ColMajor> M1; 00103 Matrix<-1,-1,double,RowMajor> M2(nrows, ncols); 00104 @endcode 00105 In this case the precision template argument must be given as it precedes the layout argument 00106 00107 @ingroup gLinAlg 00108 **/ 00109 template <int Rows=-1, int Cols=Rows, class Precision=DefaultPrecision, class Layout = RowMajor> 00110 struct Matrix : public Layout::template MLayout<Rows, Cols, Precision> 00111 { 00112 public: 00113 00114 using Layout::template MLayout<Rows, Cols, Precision>::my_data; 00115 using Layout::template MLayout<Rows, Cols, Precision>::num_rows; 00116 using Layout::template MLayout<Rows, Cols, Precision>::num_cols; 00117 00118 //Use Tom's sneaky constructor hack... 00119 00120 ///@name Construction and destruction 00121 ///@{ 00122 00123 ///Construction of static matrices. Values are not initialized. 00124 Matrix(){} 00125 00126 ///Construction of dynamic matrices. Values are not initialized. 00127 Matrix(int rows, int cols) : 00128 Layout::template MLayout<Rows,Cols,Precision>(rows, cols) 00129 {} 00130 00131 ///Construction of statically sized slice matrices 00132 Matrix(Precision* p) : 00133 Layout::template MLayout<Rows, Cols, Precision>(p) 00134 {} 00135 00136 ///Construction of dynamically sized slice matrices 00137 Matrix(Precision* p, int r, int c) : 00138 Layout::template MLayout<Rows, Cols, Precision>(p, r, c) 00139 {} 00140 00141 /// Advanced construction of dynamically sized slice matrices. 00142 /// Internal constructor used by GenericMBase::slice(...). 00143 Matrix(Precision* data, int rows, int cols, int rowstride, int colstride, Internal::Slicing) 00144 :Layout::template MLayout<Rows, Cols, Precision>(data, rows, cols, rowstride, colstride){} 00145 00146 00147 //See vector.hh and allocator.hh for details about why the 00148 //copy constructor should be default. 00149 ///Construction from an operator. 00150 template <class Op> 00151 inline Matrix(const Operator<Op>& op) 00152 :Layout::template MLayout<Rows,Cols,Precision>(op) 00153 { 00154 op.eval(*this); 00155 } 00156 00157 /// constructor from arbitrary matrix 00158 template<int Rows2, int Cols2, typename Precision2, typename Base2> 00159 inline Matrix(const Matrix<Rows2, Cols2,Precision2,Base2>& from) 00160 :Layout::template MLayout<Rows,Cols,Precision>(from.num_rows(), from.num_cols()) 00161 { 00162 operator=(from); 00163 } 00164 ///@} 00165 00166 ///@name Assignment 00167 ///@{ 00168 /// operator = from copy 00169 inline Matrix& operator= (const Matrix& from) 00170 { 00171 SizeMismatch<Rows, Rows>::test(num_rows(), from.num_rows()); 00172 SizeMismatch<Cols, Cols>::test(num_cols(), from.num_cols()); 00173 00174 for(int r=0; r < num_rows(); r++) 00175 for(int c=0; c < num_cols(); c++) 00176 (*this)[r][c] = from[r][c]; 00177 00178 return *this; 00179 } 00180 00181 // operator = 0-ary operator 00182 template<class Op> inline Matrix& operator= (const Operator<Op>& op) 00183 { 00184 op.eval(*this); 00185 return *this; 00186 } 00187 00188 // operator = 00189 template<int Rows2, int Cols2, typename Precision2, typename Base2> 00190 Matrix& operator= (const Matrix<Rows2, Cols2, Precision2, Base2>& from) 00191 { 00192 SizeMismatch<Rows, Rows2>::test(num_rows(), from.num_rows()); 00193 SizeMismatch<Cols, Cols2>::test(num_cols(), from.num_cols()); 00194 00195 for(int r=0; r < num_rows(); r++) 00196 for(int c=0; c < num_cols(); c++) 00197 (*this)[r][c] = from[r][c]; 00198 00199 return *this; 00200 } 00201 ///@} 00202 00203 ///@name operations on the matrix 00204 ///@{ 00205 00206 Matrix& operator*=(const Precision& rhs) 00207 { 00208 for(int r=0; r < num_rows(); r++) 00209 for(int c=0; c < num_cols(); c++) 00210 (*this)[r][c] *= rhs; 00211 00212 return *this; 00213 } 00214 00215 Matrix& operator/=(const Precision& rhs) 00216 { 00217 for(int r=0; r < num_rows(); r++) 00218 for(int c=0; c < num_cols(); c++) 00219 (*this)[r][c] /= rhs; 00220 00221 return *this; 00222 } 00223 00224 template<int Rows2, int Cols2, typename Precision2, typename Base2> 00225 Matrix& operator+= (const Matrix<Rows2, Cols2, Precision2, Base2>& from) 00226 { 00227 SizeMismatch<Rows, Rows2>::test(num_rows(), from.num_rows()); 00228 SizeMismatch<Cols, Cols2>::test(num_cols(), from.num_cols()); 00229 00230 for(int r=0; r < num_rows(); r++) 00231 for(int c=0; c < num_cols(); c++) 00232 (*this)[r][c] += from[r][c]; 00233 00234 return *this; 00235 } 00236 00237 template<class Op> 00238 Matrix& operator+=(const Operator<Op>& op) 00239 { 00240 op.plusequals(*this); 00241 return *this; 00242 } 00243 00244 template<class Op> 00245 Matrix& operator-=(const Operator<Op>& op) 00246 { 00247 op.minusequals(*this); 00248 return *this; 00249 } 00250 00251 template<int Rows2, int Cols2, typename Precision2, typename Base2> 00252 Matrix& operator-= (const Matrix<Rows2, Cols2, Precision2, Base2>& from) 00253 { 00254 SizeMismatch<Rows, Rows2>::test(num_rows(), from.num_rows()); 00255 SizeMismatch<Cols, Cols2>::test(num_cols(), from.num_cols()); 00256 00257 for(int r=0; r < num_rows(); r++) 00258 for(int c=0; c < num_cols(); c++) 00259 (*this)[r][c] -= from[r][c]; 00260 00261 return *this; 00262 } 00263 00264 template<int Rows2, int Cols2, typename Precision2, typename Base2> 00265 bool operator== (const Matrix<Rows2, Cols2, Precision2, Base2>& rhs) const 00266 { 00267 SizeMismatch<Rows, Rows2>::test(num_rows(), rhs.num_rows()); 00268 SizeMismatch<Cols, Cols2>::test(num_cols(), rhs.num_cols()); 00269 00270 for(int r=0; r < num_rows(); r++) 00271 for(int c=0; c < num_cols(); c++) 00272 if((*this)[r][c] != rhs[r][c]) 00273 return 0; 00274 return 1; 00275 } 00276 00277 template<int Rows2, int Cols2, typename Precision2, typename Base2> 00278 bool operator!= (const Matrix<Rows2, Cols2, Precision2, Base2>& rhs) const 00279 { 00280 SizeMismatch<Rows, Rows2>::test(num_rows(), rhs.num_rows()); 00281 SizeMismatch<Cols, Cols2>::test(num_cols(), rhs.num_cols()); 00282 00283 for(int r=0; r < num_rows(); r++) 00284 for(int c=0; c < num_cols(); c++) 00285 if((*this)[r][c] != rhs[r][c]) 00286 return 1; 00287 return 0; 00288 } 00289 00290 ///@} 00291 00292 /// @name Misc 00293 /// @{ 00294 00295 /// return me as a non const reference - useful for temporaries 00296 Matrix& ref() 00297 { 00298 return *this; 00299 } 00300 ///@} 00301 00302 #ifdef DOXYGEN_INCLUDE_ONLY_FOR_DOCS 00303 00304 /** 00305 Access an element from the matrix. 00306 The index starts at zero, i.e. the top-left element is m(0, 0). 00307 @code 00308 double d[2][3] = {{1, 2, 3}, {4, 5, 6}}; 00309 Matrix<2,3> m(d); 00310 double e = m(1,2); // now e = 6.0; 00311 @endcode 00312 @internal 00313 This method is not defined by Matrix: it is inherited. 00314 */ 00315 const double& operator() (int r, int c) const; 00316 00317 /** 00318 Access an element from the matrix. 00319 @param row_col <code>row_col.first</code> holds the row, <code>row_col.second</code> holds the column. 00320 @internal 00321 This method is not defined by Matrix: it is inherited. 00322 */ 00323 const double& operator[](const std::pair<int,int>& row_col) const; 00324 /** 00325 @overload 00326 */ 00327 double& operator[](const std::pair<int,int>& row_col); 00328 00329 /** 00330 Access an element from the matrix. 00331 This can be used as either an r-value or an l-value. The index starts at zero, 00332 i.e. the top-left element is m(0, 0). 00333 @code 00334 double d[2][3] = {{1, 2, 3}, {4, 5, 6}}; 00335 Matrix<2,3> m(d); 00336 m(1,2) = 8; // now d = [1 2 3] 00337 // [4 5 8] 00338 @endcode 00339 @internal 00340 This method is not defined by Matrix: it is inherited. 00341 */ 00342 double& operator() (int r, int c); 00343 00344 /** 00345 Access a row from the matrix. 00346 This can be used either as an r-value or an l-value. The index starts at zero, 00347 i.e. the first row is m[0]. To extract a column from a matrix, apply [] to the 00348 transpose of the matrix (see example). This can be used either as an r-value 00349 or an l-value. The index starts at zero, i.e. the first row (or column) is 00350 m[0]. 00351 @code 00352 double d[2][3] = {{1, 2, 3}, {4, 5, 6}}; 00353 Matrix<2,3> m(d); 00354 Vector<3> v = m[1]; // now v = [4 5 6]; 00355 Vector<2> v2 = m.T()[0]; // now v2 = [1 4]; 00356 @endcode 00357 @internal 00358 This method is not defined by Matrix: it is inherited. 00359 */ 00360 const Vector& operator[] (int r) const; 00361 00362 /** 00363 Access a row from the matrix. 00364 This can be used either as an r-value or an l-value. The index starts at zero, 00365 i.e. the first row is m[0]. To extract a column from a matrix, apply [] to the 00366 transpose of the matrix (see example). This can be used either as an r-value 00367 or an l-value. The index starts at zero, i.e. the first row (or column) is 00368 m[0]. 00369 @code 00370 double d[2][3] = {{1, 2, 3}, {4, 5, 6}}; 00371 Matrix<2,3> m(d); 00372 Zero(m[0]); // set the first row to zero 00373 Vector<2> v = 8,9; 00374 m.T()[1] = v; // now m = [0 8 0] 00375 // [4 9 6] 00376 @endcode 00377 @internal 00378 This method is not defined by Matrix: it is inherited. 00379 */ 00380 Vector& operator[] (int r); 00381 00382 /// How many rows does this matrix have? 00383 /// @internal 00384 /// This method is not defined by Matrix: it is inherited. 00385 int num_rows() const; 00386 00387 /// How many columns does this matrix have? 00388 /// @internal 00389 /// This method is not defined by Matrix: it is inherited. 00390 int num_cols() const; 00391 00392 /// @name Transpose and sub-matrices 00393 //@{ 00394 /** 00395 The transpose of the matrix. This is a very fast operation--it simply 00396 reinterprets a row-major matrix as column-major or vice-versa. This can be 00397 used as an l-value. 00398 @code 00399 double d[2][3] = {{1, 2, 3}, {4, 5, 6}}; 00400 Matrix<2,3> m(d); 00401 Zero(m[0]); // set the first row to zero 00402 Vector<2> v = 8,9; 00403 m.T()[1] = v; // now m = [0 8 0] 00404 // [4 9 6] 00405 @endcode 00406 @internal 00407 This method is not defined by Matrix: it is inherited. 00408 */ 00409 const Matrix<Cols, Rows>& T() const; 00410 00411 /** 00412 The transpose of the matrix. This is a very fast operation--it simply 00413 reinterprets a row-major matrix as column-major or vice-versa. The result can 00414 be used as an l-value. 00415 @code 00416 double d[2][3] = {{1, 2, 3}, {4, 5, 6}}; 00417 Matrix<2,3> m(d); 00418 Vector<2> v = 8,9; 00419 // Set the first column to v 00420 m.T()[0] = v; // now m = [8 2 3] 00421 // [9 5 6] 00422 @endcode 00423 <b>This means that the semantics of <code>M=M.T()</code> are broken</b>. In 00424 general, it is not necessary to say <code>M=M.T()</code>, since you can use 00425 M.T() for free whenever you need the transpose, but if you do need to, you 00426 have to use the Tranpose() function defined in <code>helpers.h</code>. 00427 @internal 00428 This method is not defined by Matrix: it is inherited. 00429 */ 00430 Matrix<Cols, Rows>& T(); 00431 00432 /** 00433 Extract a sub-matrix. The matrix extracted will be begin at element 00434 (Rstart, Cstart) and will contain the next Rsize by Csize elements. 00435 @code 00436 double d[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; 00437 Matrix<3> m(d); 00438 Extract the top-left 2x2 matrix 00439 Matrix<2> b = m.slice<0,0,2,2>(); // b = [1 2] 00440 // [4 5] 00441 @endcode 00442 @internal 00443 This method is not defined by Matrix: it is inherited. 00444 */ 00445 template<Rstart, Cstart, Rsize, Csize> 00446 const Matrix<Rsize, Csize>& slice() const; 00447 00448 /** 00449 Extract a sub-matrix. The matrix extracted will be begin at element (Rstart, 00450 Cstart) and will contain the next Rsize by Csize elements. This can be used as 00451 either an r-value or an l-value. 00452 @code 00453 double d[2][3] = {{1, 2, 3}, {4, 5, 6}}; 00454 Matrix<2,3> m(d); 00455 Zero(m.slice<0,2,2,1>()); // b = [1 2 0] 00456 // [4 5 0] 00457 @endcode 00458 @internal 00459 This method is not defined by Matrix: it is inherited. 00460 */ 00461 template<Rstart, Cstart, Rsize, Csize> 00462 Matrix<Rsize, Csize>& slice(); 00463 00464 /** 00465 Extract a sub-matrix with runtime location and size. The matrix extracted will 00466 begin at element (rstart, cstart) and will 00467 contain the next rsize by csize elements. 00468 @code 00469 Matrix<> m(3,3); 00470 Extract the top-left 2x2 matrix 00471 Matrix<2> b = m.slice(0,0,2,2); 00472 @endcode 00473 @internal 00474 This method is not defined by Matrix: it is inherited. 00475 */ 00476 const Matrix<>& slice(int rstart, int cstart, int rsize, int csize) const; 00477 00478 /** 00479 Extract a sub-matrix with runtime location and size, which can be used as 00480 an l-value. The matrix extracted will be begin at element (rstart, cstart) and 00481 will contain the next rsize by csize elements. 00482 @code 00483 Matrix<> m(3,3); 00484 Zero(m.slice(0,0,2,2)); 00485 @endcode 00486 @internal 00487 This method is not defined by Matrix: it is inherited. 00488 */ 00489 Matrix<>& slice(int rstart, int cstart, int rsize, int csize); 00490 00491 //@} 00492 00493 00494 #endif 00495 }; 00496 00497 }