matrix.h

Go to the documentation of this file.
00001 /*************************************************************************** 00002 matrix.h - description 00003 ------------------- 00004 email : georg.martius@web.de 00005 ***************************************************************************/ 00006 // provides Matrix class with convinient operators 00007 // and fast inversion for nonzero square matrixes 00008 // 00009 // $Log: matrix.h,v $ 00010 // Revision 1.7 2006/11/29 16:22:43 martius 00011 // name is a variable of configurable and is used as such 00012 // 00013 // Revision 1.6 2006/08/04 15:16:13 martius 00014 // documentation 00015 // 00016 // Revision 1.5 2006/07/20 17:14:35 martius 00017 // removed std namespace from matrix.h 00018 // storable interface 00019 // abstract model and invertablemodel as superclasses for networks 00020 // 00021 // Revision 1.4 2006/07/19 09:26:37 martius 00022 // namespace std removed from header 00023 // store and restore 00024 // read and write 00025 // columns accessor 00026 // 00027 // Revision 1.3 2006/07/18 14:13:09 martius 00028 // crucial bug fixing in *= operator! 00029 // 00030 // Revision 1.2 2006/07/14 12:24:01 martius 00031 // selforg becomes HEAD 00032 // 00033 // Revision 1.1.2.2 2006/07/14 08:56:53 der 00034 // New function NullTimesNull 00035 // 00036 // Revision 1.1.2.1 2006/07/10 12:01:02 martius 00037 // Matrixlib moved to selforg 00038 // 00039 // Revision 1.20.6.4 2006/03/30 23:08:53 martius 00040 // comments 00041 // 00042 // Revision 1.20.6.3 2006/03/30 12:34:45 martius 00043 // documentation updated 00044 // 00045 // Revision 1.20.6.2 2006/03/29 15:12:46 martius 00046 // column accessor function added 00047 // 00048 // Revision 1.20.6.1 2005/12/06 17:38:10 martius 00049 // *** empty log message *** 00050 // 00051 // Revision 1.20 2005/10/21 11:58:25 martius 00052 // map2 (similar to map but for 2 matrices) 00053 // changed naming of functions to be more consistent. 00054 // Functions with "to" in front indicate the change of this. (Still not consistent with add, mult ...) 00055 // 00056 // Revision 1.19 2005/10/06 17:10:06 martius 00057 // convertToList 00058 // above and toAbove 00059 // 00060 // Revision 1.18 2005/09/21 08:43:01 martius 00061 // convertToBuffer is const 00062 // 00063 // Revision 1.17 2005/08/06 20:47:36 martius 00064 // Commented 00065 // 00066 // Revision 1.16 2005/07/21 15:13:36 martius 00067 // mapP addid (mapping with additional parameter) 00068 // 00069 // Revision 1.15 2005/06/21 15:35:21 martius 00070 // hide invert3x3 and invert_nonzero for AVR to minimize binary size 00071 // 00072 // Revision 1.14 2005/06/17 15:19:03 martius 00073 // version workes with avr 00074 // 00075 // Revision 1.13 2005/06/10 08:23:15 martius 00076 // mult???wise are copy operations now! 00077 // toMult???wise are the inplace variant. 00078 // 00079 // Revision 1.11 2005/06/09 11:52:03 martius 00080 // multMT (M * M^T) and multTM (M^T * M) 00081 // 00082 // Revision 1.10 2005/06/02 22:48:54 martius 00083 // copy is inline and works correct now 00084 // 00085 // Revision 1.9 2005/06/02 08:48:31 martius 00086 // mult_row/column_wise 00087 // convertToBuffer 00088 // 00089 // Revision 1.8 2005/05/30 22:40:56 martius 00090 // map becomes toMap and the new map returns a new matrix 00091 // exp becomes toExp 00092 // 00093 // Revision 1.7 2005/05/30 21:46:54 martius 00094 // *** empty log message *** 00095 // 00096 // Revision 1.6 2005/05/30 17:21:26 martius 00097 // added zero 00098 // set() and constructor(m,n,0) initialise with zero 00099 // id returns void (more consistent) 00100 // 00101 // Revision 1.5 2005/05/30 16:42:56 martius 00102 // map function included (component-wise function application) 00103 // 00104 // Revision 1.4 2005/05/30 11:28:09 martius 00105 // marked "row" as untested 00106 // 00107 // Revision 1.3 2005/05/30 10:14:54 martius 00108 // 3x3 explicit matrix inversion 00109 // 00110 // Revision 1.2 2005/05/30 09:45:46 martius 00111 // Working. Interface not tested in pratice 00112 // 00113 // Revision 1.1 2005/05/29 22:43:08 martius 00114 // proper Makefile with dependencies and tag generator 00115 // 00116 /***************************************************************************/ 00117 00118 #ifndef MATRIX_H 00119 #define MATRIX_H 00120 00121 #include <string.h> 00122 #include <assert.h> 00123 #include <list> 00124 00125 #ifndef AVR 00126 #include <iostream> 00127 #endif 00128 00129 #include "storeable.h" 00130 00131 // TODO: add doxygen section 00132 00133 /** 00134 * namespace for matrix library 00135 *@author Georg Martius 00136 */ 00137 namespace matrix{ 00138 00139 /// integer constant for use with exp function and (^) operator to transpose the matrix 00140 extern const int T; 00141 00142 /// type for matrix elements 00143 typedef double D; 00144 #define D_Zero 0 00145 #define D_One 1 00146 /** Matrix type. Type D is datatype of matrix elements, which is fixed to double. 00147 There are basicly two different types of operation: 00148 Inplace operations and copy operations. 00149 Please use the latter ones unless you know what you are doing. 00150 Just in case of critical performance optimisation use the inplace operations. 00151 The most convinient way is to use the overloaded operators (like + * ...). 00152 All constructed matrices are initialised with zero elements (unless data is given). 00153 All functions perform range checks if in debug mode (NDEBUG is not defined). 00154 Please use -lmatrix_debug for testing. 00155 @author Georg Martius 00156 */ 00157 class Matrix : public Storeable { 00158 public: 00159 /// default constructor: zero matrix (0x0) 00160 Matrix() 00161 : m(0), n(0), buffersize(0), data(0) {}; 00162 /** constucts a matrix with the given size. 00163 If _data is null then the matrix is filled with zeros. 00164 otherwise matrix will be filled with _data in a row-wise manner. 00165 In this case _data must be at least _m*_n elements long 00166 */ 00167 Matrix(unsigned short _m, unsigned short _n, const D* _data=0); 00168 /// constucts a instance on the base of a deep copy of the given matrix 00169 Matrix (const Matrix& c); 00170 ~Matrix() { if(data) delete[] data; }; 00171 00172 public: 00173 // /////////////////// Accessors /////////////////////////////// 00174 /** @return number of rows */ 00175 unsigned short getM() const { return m; }; 00176 /** @return number of columns */ 00177 unsigned short getN() const { return n; }; 00178 /** @return element at position i,j (row, column index) */ 00179 D val(unsigned short i, unsigned short j) const { 00180 assert( i<m && j<n); 00181 return data[i*n+j]; 00182 }; 00183 /** @return reference to element at position i,j 00184 (can be used as left side value) */ 00185 D& val(unsigned short i, unsigned short j) { 00186 assert( i<m && j<n); 00187 return data[i*n+j]; 00188 }; 00189 00190 /** @return element at position i,j (row, column index) and 0 if out of bounds */ 00191 D valDef0(short i, short j) const { 00192 if(0<=i && i<m && 0<=j && j<n) 00193 return data[i*n+j]; 00194 else return 0; 00195 }; 00196 00197 /** sets the size of the matrix and maybe the data if given (row-wise). 00198 If data=null then the matrix is set to zero 00199 @see toZero() 00200 @see constructor Matrix(m,n,data) 00201 */ 00202 void set(unsigned short _m, unsigned short _n, const D* _data=0); 00203 /** sets the data (row-wise). 00204 @param _data if null then matrix elements are set to zero 00205 otherwise the field MUST have the length should be getM()*getN()*/ 00206 void set(const D* _data); 00207 /** @return row-vector(as 1xN matrix) containing the index'th row */ 00208 Matrix row(unsigned short index) const; 00209 /** @returns submatrix (as KxN matrix) 00210 containing row from startindex to endindex inclusively (K=stopindex-endindex) 00211 indices can be out of bounds, they are clipped in any case 00212 */ 00213 Matrix rows(unsigned short startindex, unsigned short endindex) const; 00214 /** @returns column-vector(as Nx1 matrix) containing the index'th column */ 00215 Matrix column(unsigned short index) const; 00216 /** @returns submatrix (as NxK matrix) 00217 containing column from startindex to endindex inclusively (K=stopindex-endindex) 00218 indices can be out of bounds, they are clipped in any case 00219 */ 00220 Matrix columns(unsigned short startindex, unsigned short endindex) const; 00221 00222 00223 00224 /** stores the content of the matrix (row-wise) in the given buffer 00225 @param buffer Buffer for storing the elements (should have the length given by len) 00226 @param len Length of the provided buffer. 00227 In any case only min(len, getM()*getN()) elements are copied. 00228 @return number of actually written elements 00229 */ 00230 int convertToBuffer(D* buffer, unsigned int len) const; 00231 00232 /** @return a list of the content of the matrix (row-wise) 00233 */ 00234 std::list<D> convertToList() const; 00235 00236 /* STOREABLE */ 00237 /** stores the Matrix into the given file stream (binary) 00238 */ 00239 bool store(FILE* f) const; 00240 00241 /** reads a Matrix from the given file stream (binary) 00242 */ 00243 bool restore(FILE* f); 00244 00245 /** writes the Matrix into the given file stream (ascii) 00246 */ 00247 bool write(FILE* f) const; 00248 00249 /** reads a Matrix from the given file stream (ascii) 00250 */ 00251 bool read(FILE* f); 00252 00253 00254 public: 00255 // //////////////////////////////////////////////////////////////////// 00256 // ///////////// operations ///////////////////////////// 00257 // (the result of the operation is not stored in one of the operands) 00258 void add(const Matrix& a, const Matrix& b); ///< addition: this = a + b 00259 void sub(const Matrix& a, const Matrix& b); ///< subtraction: this = a - b 00260 void mult(const Matrix& a, const Matrix& b);///< multiplication: this = a * b 00261 void mult(const Matrix& a, const D& fac);///< scaling: this = a * fac 00262 00263 /// returns true if matrix is a 0x0 matrix 00264 bool isNulltimesNull(); 00265 00266 /** maps the matrix to a new matrix 00267 with all elements mapped with the given function 00268 */ 00269 Matrix map(D (*fun)(D)) const; 00270 /** like map but with additional parameter for the mapping function 00271 */ 00272 Matrix mapP(void* param, D (*fun)(void*, D)) const; 00273 00274 // Exotic operations /////////// 00275 /** binary map operator for matrices. 00276 The resulting matrix consists of the function values applied to the elements of a and b. 00277 In haskell this would something like: map (uncurry . fun) $ zip a b 00278 */ 00279 static Matrix map2( D (*fun)(D,D), const Matrix& a, const Matrix& b) { 00280 assert(a.m == b.m && a.n == b.n); 00281 Matrix result(a); 00282 unsigned int len = a.m*a.n; 00283 for(unsigned short i=0; i < len; i++){ 00284 result.data[i] = fun(a.data[i], b.data[i]); 00285 } 00286 return result; 00287 } 00288 00289 /** row-wise multiplication 00290 @param factors column vector (Mx1) of factors, one for each row 00291 */ 00292 Matrix multrowwise(const Matrix& factors) const; 00293 /** column-wise multiplication 00294 @param factors column vector (Mx1) of factors, one for each column 00295 */ 00296 Matrix multcolwise(const Matrix& factors) const; 00297 00298 /// optimised multiplication of Matrix with its transposed: M * M^T 00299 Matrix multMT() const; 00300 /// optimised multiplication of transpsoed of Matrix with itself: M^T * M 00301 Matrix multTM() const; 00302 00303 /// returns the product of all elements (\Pi_{ij} m_{ij}) 00304 D elementProduct() const; 00305 /// returns the sum of all elements (\Sum_{ij} m_{ij}) 00306 D elementSum() const; 00307 00308 /// returns a matrix that consists of this above A 00309 Matrix above(const Matrix& a) const ; 00310 00311 public: /// normal binary Operators 00312 /// deep copy 00313 Matrix& operator = (const Matrix& c) { copy(c); return *this; } 00314 Matrix operator + (const Matrix& sum) const; 00315 Matrix operator - (const Matrix& sum) const; 00316 /** matrix product*/ 00317 Matrix operator * (const Matrix& fac) const; 00318 /** product with scalar (D) */ 00319 Matrix operator * (const D& fac) const; 00320 /** special matrix potence: 00321 @param exponent -1 -> inverse; 00322 0 -> Identity Matrix; 00323 1 -> itself; 00324 T -> Transpose 00325 */ 00326 Matrix operator ^ (int exponent) const; 00327 /// performant combined assigment operators 00328 Matrix& operator += (const Matrix& c) {toSum(c); return *this; } 00329 Matrix& operator -= (const Matrix& c) {toDiff(c); return *this; } 00330 Matrix& operator *= (const Matrix& c) { 00331 Matrix result; 00332 result.mult(*this, c); 00333 this->copy(result); 00334 return *this; 00335 } 00336 Matrix& operator *= (const D& fac) {toMult(fac); return *this; } 00337 00338 #ifndef AVR 00339 /// comparison operator (compares elements with tolerance distance of COMPARE_EPS) 00340 bool operator == (const Matrix& c) const; 00341 /** printing operator: 00342 output format: mxn (\n row0\n..rown \n) where rowX is tab seperated list of values 00343 */ 00344 friend std::ostream& operator<<(std::ostream& , const Matrix&); 00345 #endif 00346 00347 public: 00348 // /////////////////// inplace Operators /////////////////////////////// 00349 /** performs a deep copy of the given matrix */ 00350 void copy(const Matrix& c){ // Deep copy 00351 m=c.m; n=c.n; 00352 allocate(); 00353 memcpy(data,c.data,m*n*sizeof(D)); 00354 } 00355 00356 void toTranspose(); ///< inplace transpose 00357 void toZero(); ///< inplace converts matrix to zero matrix 00358 void toId(); ///< inplace converts matrix to identity (use ^0 to get a copy version of it) 00359 /// inplace addition: this = this + a 00360 void toSum(const Matrix& a) { 00361 assert(a.m==m && a.n==n); 00362 for(unsigned short i=0; i<m*n; i++){ 00363 data[i]+=a.data[i]; 00364 } 00365 } 00366 /// inplace subtraction: this = this - a 00367 void toDiff(const Matrix& a){ 00368 assert(a.m==m && a.n==n); 00369 for(unsigned short i=0; i<m*n; i++){ 00370 data[i]-=a.data[i]; 00371 } 00372 } 00373 00374 /// inplace multiplication with scalar: this = this*fac 00375 void toMult(const D& fac); 00376 00377 /** special inplace matrix potence: 00378 @param exponent -1 -> inverse; (matrix MUST be SQUARE and NONZERO) 00379 0 -> Identity Matrix; 00380 1 -> itself; 00381 T -> Transpose 00382 */ 00383 void toExp(int exponent); 00384 /** inplace mapping of matrix elements (element-wise application) */ 00385 void toMap(D (*fun)(D)); 00386 /** like toMap, but with an extra parameter for the mapping function. */ 00387 void toMapP(void* param, D (*fun)(void*, D)); 00388 // Exotic operations 00389 /** Inplace row-wise multiplication 00390 @param factors column vector of factors, one for each row 00391 */ 00392 void toMultrowwise(const Matrix& factors); 00393 /** Inplace column-wise multiplication 00394 @param factors column vector of factors, one for each column 00395 */ 00396 void toMultcolwise(const Matrix& factors); 00397 00398 /// sets the matrix a below (this) matrix 00399 void toAbove(const Matrix& a); 00400 00401 00402 private: 00403 // NOTE: buffersize determines available memory storage. 00404 // m and n define the actual size 00405 unsigned short m, n; 00406 unsigned int buffersize; // max number if elements 00407 D* data; // where the data contents of the matrix are stored 00408 00409 00410 private: // internals 00411 void allocate(); //internal allocation 00412 /*inplace matrix invertation: 00413 Matrix must be SQARE, in addition, all DIAGONAL ELEMENTS MUST BE NONZERO 00414 (positive definite) 00415 */ 00416 00417 #ifndef AVR 00418 void invertnonzero(); 00419 void invert3x3(); 00420 #endif 00421 void invert2x2(); 00422 }; 00423 00424 } // namespace matrix 00425 #endif

Generated on Tue Jan 16 02:14:36 2007 for Robotsystem of the Robot Group Leipzig by doxygen 1.3.8