Robot Simulator of the Robotics Group for Self-Organization of Control: matrix.h Source File

- Main Page
- Namespaces
- Classes
- Files
- Directories
- Related Pages
- Examples

- Search for |

- File List
- File Members

# 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.33  2009/10/27 16:52:21  martius
    00011 // documentation
    00012 //
    00013 // Revision 1.32  2009/10/27 12:50:27  martius
    00014 // remove & in comment to make doxygen (latex) work
    00015 //
    00016 // Revision 1.31  2009/08/05 18:28:10  martius
    00017 // added isVector
    00018 // mapP and toMapP support double parameters
    00019 //
    00020 // Revision 1.30  2009/03/27 06:16:57  guettler
    00021 // support for gcc 4.3 compatibility (has to be checked), StatisticTools moves from utils to statistictools
    00022 //
    00023 // Revision 1.29  2009/02/02 15:21:28  martius
    00024 // added pseudoinverse
    00025 //
    00026 // Revision 1.28  2009/01/05 08:45:00  martius
    00027 // exp again as function
    00028 //
    00029 // Revision 1.27  2008/12/22 14:40:47  martius
    00030 // added & operator for multrowwise
    00031 //
    00032 // Revision 1.26  2008/12/22 14:37:42  martius
    00033 // comments
    00034 //
    00035 // Revision 1.25  2008/11/14 09:15:29  martius
    00036 // tried some autovectorization but without success
    00037 // moved some function to CPP file
    00038 //
    00039 // Revision 1.24  2008/06/18 13:46:20  martius
    00040 // beside and toBeside added
    00041 // addColumns and addRows is now based on toAbove and toBeside
    00042 // bug fix in removeColumns
    00043 //
    00044 // Revision 1.23  2008/05/30 11:58:08  martius
    00045 // equals method and cmath
    00046 //
    00047 // Revision 1.22  2008/05/07 16:45:52  martius
    00048 // code cosmetics and documentation
    00049 //
    00050 // Revision 1.21  2008/05/02 17:20:04  martius
    00051 // *** empty log message ***
    00052 //
    00053 // Revision 1.20  2008/04/30 14:54:14  guettler
    00054 // -indextype of matrices is now unsigned int (bigger matrices than
    00055 //  256x256 can be used now, if not AVR defined)
    00056 // -code cleaned up
    00057 //
    00058 // Revision 1.19  2008/04/29 11:04:44  guettler
    00059 // forgot to deactivate += operator
    00060 //
    00061 // Revision 1.18  2008/04/29 11:01:32  guettler
    00062 // -added toMap2 and toMap2P
    00063 // -removed operator + for scalar (use add or toSum instead)
    00064 //
    00065 // Revision 1.17  2008/04/28 15:24:14  guettler
    00066 // -added deleteRows and deleteColumns
    00067 // -fixed memory leak in addColumns
    00068 //
    00069 // Revision 1.16  2008/04/28 10:33:05  guettler
    00070 // -added operator + and += for adding a scalar to each element of the matrix
    00071 // -added add function and toSum for adding a scalar to each element
    00072 // -added addRows and addColumns for adding new rows or colums to the matrix
    00073 //
    00074 // Revision 1.15  2008/03/01 01:33:30  martius
    00075 // size added
    00076 //
    00077 // Revision 1.14  2007/08/22 08:28:07  martius
    00078 // contrains for reshape relaxed
    00079 //
    00080 // Revision 1.13  2007/06/21 16:29:18  martius
    00081 // added map2P
    00082 // map2 into cpp
    00083 //
    00084 // Revision 1.12  2007/06/08 15:50:29  martius
    00085 // added unsafeGetData
    00086 //
    00087 // Revision 1.11  2007/05/22 13:52:36  martius
    00088 // inplace operators return *this which makes them more useable for temporary matrices
    00089 //
    00090 // Revision 1.10  2007/04/03 09:58:20  martius
    00091 // memory management done with free and malloc
    00092 //
    00093 // Revision 1.9  2007/04/03 07:13:32  der
    00094 // plus lambdaI
    00095 //
    00096 // Revision 1.8  2007/02/05 12:31:21  martius
    00097 // reshape
    00098 //
    00099 // Revision 1.7  2006/11/29 16:22:43  martius
    00100 // name is a variable of configurable and is used as such
    00101 //
    00102 // Revision 1.6  2006/08/04 15:16:13  martius
    00103 // documentation
    00104 //
    00105 // Revision 1.5  2006/07/20 17:14:35  martius
    00106 // removed std namespace from matrix.h
    00107 // storable interface
    00108 // abstract model and invertablemodel as superclasses for networks
    00109 //
    00110 // Revision 1.4  2006/07/19 09:26:37  martius
    00111 // namespace std removed from header
    00112 // store and restore
    00113 // read and write
    00114 // columns accessor
    00115 //
    00116 // Revision 1.3  2006/07/18 14:13:09  martius
    00117 // crucial bug fixing in *= operator!
    00118 //
    00119 // Revision 1.2  2006/07/14 12:24:01  martius
    00120 // selforg becomes HEAD
    00121 //
    00122 // Revision 1.1.2.2  2006/07/14 08:56:53  der
    00123 // New function NullTimesNull
    00124 //
    00125 // Revision 1.1.2.1  2006/07/10 12:01:02  martius
    00126 // Matrixlib moved to selforg
    00127 //
    00128 // Revision 1.20.6.4  2006/03/30 23:08:53  martius
    00129 // comments
    00130 //
    00131 // Revision 1.20.6.3  2006/03/30 12:34:45  martius
    00132 // documentation updated
    00133 //
    00134 // Revision 1.20.6.2  2006/03/29 15:12:46  martius
    00135 // column accessor function added
    00136 //
    00137 // Revision 1.20.6.1  2005/12/06 17:38:10  martius
    00138 // *** empty log message ***
    00139 //
    00140 // Revision 1.20  2005/10/21 11:58:25  martius
    00141 // map2 (similar to map but for 2 matrices)
    00142 // changed naming of functions to be more consistent.
    00143 //  Functions with "to" in front indicate the change of this. (Still not consistent with add, mult ...)
    00144 //
    00145 // Revision 1.19  2005/10/06 17:10:06  martius
    00146 // convertToList
    00147 // above and toAbove
    00148 //
    00149 // Revision 1.18  2005/09/21 08:43:01  martius
    00150 // convertToBuffer is const
    00151 //
    00152 // Revision 1.17  2005/08/06 20:47:36  martius
    00153 // Commented
    00154 //
    00155 // Revision 1.16  2005/07/21 15:13:36  martius
    00156 // mapP addid (mapping with additional parameter)
    00157 //
    00158 // Revision 1.15  2005/06/21 15:35:21  martius
    00159 // hide invert3x3 and invert_nonzero for AVR to minimize binary size
    00160 //
    00161 // Revision 1.14  2005/06/17 15:19:03  martius
    00162 // version workes with avr
    00163 //
    00164 // Revision 1.13  2005/06/10 08:23:15  martius
    00165 // mult???wise are copy operations now!
    00166 // toMult???wise are the inplace variant.
    00167 //
    00168 // Revision 1.11  2005/06/09 11:52:03  martius
    00169 // multMT (M * M^T) and multTM (M^T * M)
    00170 //
    00171 // Revision 1.10  2005/06/02 22:48:54  martius
    00172 // copy is inline and works correct now
    00173 //
    00174 // Revision 1.9  2005/06/02 08:48:31  martius
    00175 // mult_row/column_wise
    00176 // convertToBuffer
    00177 //
    00178 // Revision 1.8  2005/05/30 22:40:56  martius
    00179 // map becomes toMap and the new map returns a new matrix
    00180 // exp becomes toExp
    00181 //
    00182 // Revision 1.7  2005/05/30 21:46:54  martius
    00183 // *** empty log message ***
    00184 //
    00185 // Revision 1.6  2005/05/30 17:21:26  martius
    00186 // added zero
    00187 // set() and constructor(m,n,0) initialise with zero
    00188 // id returns void (more consistent)
    00189 //
    00190 // Revision 1.5  2005/05/30 16:42:56  martius
    00191 // map function included (component-wise function application)
    00192 //
    00193 // Revision 1.4  2005/05/30 11:28:09  martius
    00194 // marked "row" as untested
    00195 //
    00196 // Revision 1.3  2005/05/30 10:14:54  martius
    00197 // 3x3 explicit matrix inversion
    00198 //
    00199 // Revision 1.2  2005/05/30 09:45:46  martius
    00200 // Working. Interface not tested in pratice
    00201 //
    00202 // Revision 1.1  2005/05/29 22:43:08  martius
    00203 // proper Makefile with dependencies and tag generator
    00204 //
    00205 /***************************************************************************/
    00206
    00207 #ifndef MATRIX_H
    00208 #define MATRIX_H
    00209
    00210 #include <string.h>
    00211 #include <assert.h>
    00212 #include <list>
    00213 #include <cstdlib>
    00214
    00215 #ifndef AVR
    00216 #include <iostream>
    00217 #endif
    00218
    00219 #include "storeable.h"
    00220
    00221 // TODO: add doxygen section
    00222
    00223 /**
    00224  * namespace for the matrix library
    00225  *@author Georg Martius
    00226  */
    00227 namespace matrix{
    00228
    00229   /// integer constant for use with exp function and (^) operator to transpose the matrix
    00230   extern const int T;
    00231
    00232 #ifndef AVR
    00233 /// type for matrix indices
    00234   typedef unsigned int I;
    00235   /// type for matrix elements
    00236   typedef double D;
    00237 #else
    00238 /// type for matrix indices, if AVR
    00239 /// NOTE: You cannot use matrices bigger than m*n>255 if AVR!
    00240   typedef unsigned short I;
    00241   /// type for matrix elements
    00242   typedef float D;
    00243 #endif
    00244
    00245
    00246 #define D_Zero 0
    00247 #define D_One 1
    00248   /** Matrix type. Type D is datatype of matrix elements,
    00249    * which is fixed to double.
    00250    * Type I is the indextype of matrix elements,
    00251    * which is fixed to unsigned int, if AVR is not defined.
    00252    * There are basicly two different types of operation:
    00253    * Inplace operations and copy operations.
    00254    * Please use the latter ones unless you know what you are doing.
    00255    * Just in case of critical performance optimisation use the inplace
    00256    * operations.
    00257    * The most convinient way is to use the overloaded operators
    00258    * (like + * ...).
    00259    * All constructed matrices are initialised with zero elements
    00260    * (unless data is given).
    00261    * All functions perform range checks if in debug mode
    00262    * (NDEBUG is not defined).
    00263    * Please use debug the version (default) for testing
    00264    * @see examples/matrix/matrixexample.cpp
    00265    *
    00266    * @author Georg Martius
    00267    */
    00268   class Matrix : public Storeable {
    00269   public:
    00270     /// default constructor: zero matrix (0x0)
    00271     Matrix()
    00272       : m(0), n(0), buffersize(0), data(0) {};
    00273     /** constucts a matrix with the given size.
    00274         If _data is null then the matrix is filled with zeros.
    00275         otherwise matrix will be filled with _data in a row-wise manner.
    00276         In this case _data must be at least _m*_n elements long
    00277     */
    00278     Matrix(I _m, I _n, const D* _data=0);
    00279     /** constucts a matrix with the given size and fills it with the default value
    00280     */
    00281     Matrix(I _m, I _n, D def);
    00282     /// constucts a instance on the base of a deep copy of the given matrix
    00283     Matrix (const Matrix& c);
    00284     ~Matrix() { if(data) free(data); };
    00285
    00286   public:
    00287     //  /////////////////// Accessors ///////////////////////////////
    00288     /** @return number of rows */
    00289     I getM() const { return m; };
    00290     /** @return number of columns */
    00291     I getN() const { return n; };
    00292     /// @return number number elements in the matrix (getM()*getN())
    00293     I size() const { return n*m; };
    00294
    00295
    00296     /** @return element at position i,j (row, column index) */
    00297     inline D val(I i, I j) const {
    00298       assert( i<m && j<n);
    00299       return data[i*n+j];
    00300     };
    00301     /** @return reference to element at position i,j
    00302         (can be used as left side value) */
    00303     inline D& val(I i, I j) {
    00304       assert( i<m && j<n);
    00305       return data[i*n+j];
    00306     };
    00307
    00308     /** @return element at position i,j (row, column index) and 0 if out of bounds */
    00309     inline D valDef0(I i, I j) const {
    00310       if(0<=i && i<m && 0<=j && j<n)
    00311         return data[i*n+j];
    00312       else return 0;
    00313     };
    00314
    00315     /** sets the size of the matrix and maybe the data if given (row-wise).
    00316         If data=null then the matrix is set to zero
    00317         @see toZero()
    00318         @see constructor Matrix(m,n,data)
    00319     */
    00320     void set(I _m, I _n, const D* _data=0);
    00321     /** sets the data (row-wise).
    00322         @param _data if null then matrix elements are set to zero
    00323         otherwise the field MUST have the length should be getM()*getN()*/
    00324     void set(const D* _data);
    00325     /** @return row-vector(as 1xN matrix) containing the index'th row */
    00326     Matrix row(I index) const;
    00327     /** @returns submatrix (as KxN matrix)
    00328         containing row from startindex to endindex inclusively (K=stopindex-endindex)
    00329         indices can be out of bounds, they are clipped in any case
    00330     */
    00331     Matrix rows(I startindex, I endindex) const;
    00332     /** @returns column-vector(as Mx1 matrix) containing the index'th column */
    00333     Matrix column(I index) const;
    00334     /** @returns submatrix (as MxK matrix)
    00335         containing column from startindex to endindex inclusively (K=endindex-startindex)
    00336         indices can be out of bounds, they are clipped in any case
    00337     */
    00338     Matrix columns(I startindex, I endindex) const;
    00339
    00340
    00341     /** stores the content of the matrix (row-wise) in the given buffer
    00342         @param buffer Buffer for storing the elements (should have the length given by len)
    00343         @param len Length of the provided buffer.
    00344                In any case only min(len, getM()*getN()) elements are copied.
    00345         @return number of actually written elements
    00346      */
    00347     int convertToBuffer(D* buffer, I len) const;
    00348
    00349     /** @return a list of the content of the matrix (row-wise)
    00350      */
    00351     std::list<D> convertToList() const;
    00352
    00353     /// returns a pointer to the data. UNSAFE!!!
    00354     const double* unsafeGetData() const{return data;}
    00355
    00356     /*       STOREABLE       */
    00357     /** stores the Matrix into the given file stream (binary)
    00358      */
    00359     bool store(FILE* f) const;
    00360
    00361     /** reads a Matrix from the given file stream (binary)
    00362      */
    00363     bool restore(FILE* f);
    00364
    00365     /** writes the Matrix into the given file stream (ascii)
    00366      */
    00367     bool write(FILE* f) const;
    00368
    00369     /** reads a Matrix from the given file stream (ascii)
    00370      */
    00371     bool read(FILE* f);
    00372
    00373
    00374   public:
    00375     // ////////////////////////////////////////////////////////////////////
    00376     // /////////////  operations  /////////////////////////////
    00377     //  (the result of the operation is not stored in one of the operands)
    00378     void add(const Matrix& a, const Matrix& b); ///< addition:    this = a + b
    00379     void add(const Matrix& a, const D& summand); /// add scalar to each element
    00380     void sub(const Matrix& a, const Matrix& b); ///< subtraction: this = a - b
    00381     void mult(const Matrix& a, const Matrix& b);///< multiplication: this = a * b
    00382     void mult(const Matrix& a, const D& fac);///< scaling: this = a * fac
    00383
    00384     void exp(const Matrix& a, int exponent);///< exponent, this = a^i, @see toExp
    00385
    00386     /// returns true if matrix is a 0x0 matrix
    00387     bool isNulltimesNull() const;
    00388
    00389     /// returns true if matrix is a vector
    00390     bool isVector() const;
    00391
    00392     /** bytewise comparison (compares data buffer bytewise, which implies that
    00393         n1*m1 == n2*m2 but not necessarily n1==n2) */
    00394     bool equals(const Matrix& a) const;
    00395
    00396     /** calculates the pseudoinverse, depending on the shape of the matrix
    00397         the left or right pseudoinverse is used.
    00398         If the matrix has more columns than rows then we use
    00399         \f[A^{+} = (A^T A + \lambda \mathbb I)^{-1}A^T\f]
    00400         otherwise
    00401         \f[A^{+} = A^T(A A^T + \lambda \mathbb I)^{-1}\f]
    00402      */
    00403     Matrix pseudoInverse(const D& lambda = 10e-8) const ;
    00404
    00405     /**  maps the matrix to a new matrix
    00406          with all elements mapped with the given function
    00407     */
    00408     Matrix map(D (*fun)(D)) const;
    00409     /**  like map but with additional double parameter for the mapping function
    00410          (first argument of fun is parameter, the second is the value)*/
    00411     Matrix mapP(D param, D (*fun)(D, D)) const;
    00412     /**  like map but with additional arbitrary parameter for the mapping function */
    00413     Matrix mapP(void* param, D (*fun)(void*, D)) const;
    00414
    00415     // Exotic operations ///////////
    00416     /** binary map operator for matrices.
    00417        The resulting matrix consists of the function values applied to the elements of a and b.
    00418        In haskell this would something like: map (uncurry . fun) $ zip a b
    00419     */
    00420     static Matrix map2( D (*fun)(D,D), const Matrix& a, const Matrix& b);
    00421
    00422     /** binary map operator for matrices with parameter.
    00423        The resulting matrix consists of the function values applied to the elements of a and b.
    00424        In haskell this would something like: map (uncurry . (fun p)) $ zip a b
    00425     */
    00426     static Matrix map2P( void* param, D (*fun)(void*, D,D), const Matrix& a, const Matrix& b);
    00427
    00428     /** row-wise multiplication
    00429         @param factors column vector (Mx1) of factors, one for each row
    00430     */
    00431     Matrix multrowwise(const Matrix& factors) const;
    00432     /** column-wise multiplication
    00433         @param factors column vector (Mx1) of factors, one for each column
    00434     */
    00435     Matrix multcolwise(const Matrix& factors) const;
    00436
    00437     /// optimised multiplication of Matrix with its transposed: M * M^T
    00438     Matrix multMT() const;
    00439     /// optimised multiplication of transpsoed of Matrix with itself: M^T * M
    00440     Matrix multTM() const;
    00441
    00442     /// returns the product of all elements (\f$ \Pi_{ij} m_{ij} \f$)
    00443     D elementProduct() const;
    00444     /// returns the sum of all elements (\f$ \sum_{ij} m_{ij} \f$)
    00445     D elementSum() const;
    00446
    00447     /// returns a matrix that consists of this matrix above A (number of rows is getM + a.getM())
    00448     Matrix above(const Matrix& a) const ;
    00449     /// returns a matrix that consists of this left beside A  (number of columns is getN + a.getN())
    00450     Matrix beside(const Matrix& a) const ;
    00451
    00452   public:   // normal binary Operators
    00453     /// deep copy
    00454     Matrix& operator = (const Matrix& c) { copy(c); return *this; }
    00455     /// sum of two matrices
    00456     Matrix operator +  (const Matrix& sum) const;
    00457     //    Matrix operator +  (const D& sum) const; /// new operator (guettler)
    00458     /// difference of two matrices
    00459     Matrix operator -  (const Matrix& sum) const;
    00460     /** matrix product*/
    00461     Matrix operator *  (const Matrix& fac) const;
    00462     /** product with scalar (D) (only right side) */
    00463     Matrix operator *  (const D& fac) const;
    00464     /** special matrix potence:
    00465         @param exponent -1 -> inverse;
    00466                        0 -> Identity Matrix;
    00467                     1 -> itself;
    00468                     T -> Transpose
    00469     */
    00470     Matrix operator ^ (int exponent) const;
    00471     /// row-wise multiplication
    00472     Matrix operator & (const Matrix& b) const;
    00473     /// combined assigment operator (higher performance)
    00474     Matrix& operator += (const Matrix& c) {toSum(c);   return *this; }
    00475     /// combined assigment operator (higher performance)
    00476     Matrix& operator -= (const Matrix& c) {toDiff(c);  return *this; }
    00477     /// combined assigment operator (higher performance)
    00478     Matrix& operator *= (const Matrix& c) {
    00479       Matrix result;
    00480       result.mult(*this, c);
    00481       this->copy(result);
    00482       return *this;
    00483     }
    00484     /// combined assigment operator (higher performance)
    00485     Matrix& operator *= (const D& fac) {toMult(fac); return *this; }
    00486     /// combined assigment operator (higher performance)
    00487     Matrix& operator &= (const Matrix& c) {toMultrowwise(c); return *this; }
    00488
    00489 #ifndef AVR
    00490     /// comparison operator (compares elements with tolerance distance of COMPARE_EPS)
    00491     bool operator == (const Matrix& c) const;
    00492     /** printing operator:
    00493         output format: mxn (\n row0\n..rown \n) where rowX is tab seperated list of values
    00494     */
    00495     friend std::ostream& operator<<(std::ostream& , const Matrix&);
    00496 #endif
    00497
    00498   public:
    00499     // /////////////////// inplace Operators ///////////////////////////////
    00500     /** performs a deep copy of the given matrix */
    00501     void copy(const Matrix& c){ // Deep copy
    00502       m=c.m; n=c.n;
    00503       allocate();
    00504       memcpy(data,c.data,m*n*sizeof(D));
    00505     }
    00506
    00507     Matrix& toTranspose();  ///< inplace transpose
    00508     Matrix& toZero();       ///< inplace converts matrix to zero matrix
    00509     Matrix& toId();         ///< inplace converts matrix to identity (use ^0 to get a copy version of it)
    00510     /// inplace addition: this = this + a
    00511     Matrix& toSum(const Matrix& a);
    00512     /// inplace addition: this = this + a, where a is a scalar
    00513     Matrix& toSum(const D& sum);
    00514
    00515     /// inplace subtraction: this = this - a
    00516     Matrix& toDiff(const Matrix& a);
    00517
    00518     /// inplace multiplication: this = this * a
    00519     Matrix& toMult(const Matrix& a);
    00520     /// inplace multiplication with scalar: this = this*fac
    00521     Matrix& toMult(const D& fac);
    00522
    00523     /** special inplace matrix power:
    00524         @param exponent -1 -> inverse; (matrix MUST be SQUARE and NONZERO)
    00525                     0 -> Identity Matrix;
    00526                     1 -> itself;
    00527                     T -> Transpose
    00528     */
    00529     Matrix& toExp(int exponent);
    00530     /**  inplace mapping of matrix elements (element-wise application) */
    00531     Matrix& toMap(D (*fun)(D));
    00532     /**  like toMap, but with an extra double parameter for the mapping function. */
    00533     Matrix& toMapP(D param, D (*fun)(D, D));
    00534     /**  like toMap, but with an extra arbitrary parameter for the mapping function. */
    00535     Matrix& toMapP(void* param, D (*fun)(void*, D));
    00536
    00537     /**  like toMap, but with 2 arguments for the mapping function. */
    00538     Matrix& toMap2(D (*fun)(D,D), const Matrix& b);
    00539
    00540     Matrix& toMap2P( void* param, D (*fun)(void*, D,D), const Matrix& b);
    00541
    00542     // Exotic operations
    00543     /** Inplace row-wise multiplication
    00544         @param factors column vector of factors, one for each row
    00545     */
    00546     Matrix& toMultrowwise(const Matrix& factors);
    00547     /** Inplace column-wise multiplication
    00548         @param factors column vector of factors, one for each column
    00549     */
    00550     Matrix& toMultcolwise(const Matrix& factors);
    00551
    00552     /// sets the matrix a below this matrix
    00553     Matrix& toAbove(const Matrix& a);
    00554     /// sets the matrix a right beside this matrix
    00555     Matrix& toBeside(const Matrix& a);
    00556
    00557     /// sorts the matrix (rowwise)
    00558     Matrix& toSort();
    00559
    00560     /** reshapes the matrix without destroying the data.
    00561         Remember: The data is stored rowwise.
    00562
    00563         Only shrinking is allowed i.e. m*n must be lower or equal to getM()*getN()
    00564     */
    00565     Matrix& reshape(I m, I n);
    00566
    00567     /// adds the given value to the diagonal
    00568     Matrix& pluslambdaI(double lambda);
    00569
    00570     /** adds one or more rows to the existing matrix and fills it with the given data
    00571      *
    00572      * same as toAbove(Matrix(numberRows,getN(),data))
    00573      * @param numberRows number of rows to add (this extends m)
    00574      * @param _data data to add
    00575      * @return the address of the matrix itself
    00576      */
    00577     Matrix& addRows(I numberRows, const D* _data=0);
    00578
    00579     /**
    00580      * same as toAbove(dataMatrix)
    00581      * @param numberRows number of rows to add (unused)
    00582      * @param dataMatrix matrix which contains the data of the new rows
    00583      * @return the address of the matrix itself
    00584      */
    00585     Matrix& addRows(I numberRows, const Matrix& dataMatrix);
    00586
    00587     /** adds one or more columns to the existing matrix
    00588      * same as toBeside(Matrix(getM, numberColumns, _data))
    00589      * @see toBeside()
    00590      * @param numberColumns number of columns to add (this extends n)
    00591      * @param _data data to add
    00592      * @return the address of the matrix itself
    00593      */
    00594      Matrix& addColumns(I numberColumns, const D* _data=0);
    00595
    00596     /**
    00597      * same as toBeside(dataMatrix)
    00598      * @see toBeside()
    00599      * @param numberColumns number of columns to add (unused)
    00600      * @param dataMatrix matrix which contains the data of the new rows
    00601      * @return the address of the matrix itself
    00602      */
    00603     Matrix& addColumns(I numberColumns, const Matrix& dataMatrix);
    00604
    00605
    00606     /** removes one or more rows of the existing matrix,
    00607         same as reshape(getM()-numberRows, getN());
    00608      * @param numberRows number of rows to remove (this reduces m)
    00609      * @return the address of the matrix itself
    00610      */
    00611     Matrix& removeRows(I numberRows);
    00612
    00613     /** removes one or more columns of the existing matrix
    00614      * resets the size of the matrix and deletes the appropiate data.
    00615      * @param numberColumns number of columns to remove (this reduces n)
    00616      * @return the address of the matrix itself
    00617      */
    00618     Matrix& removeColumns(I numberColumns);
    00619
    00620   private:
    00621     // NOTE: buffersize determines available memory storage.
    00622     // m and n define the actual size
    00623     I m, n;
    00624     I buffersize;  // max number if elements
    00625     D* data;      // where the data contents of the matrix are stored
    00626
    00627
    00628   private: // internals
    00629     void allocate();  //internal allocation
    00630     /*inplace matrix invertation:
    00631         Matrix must be SQARE, in addition, all DIAGONAL ELEMENTS MUST BE NONZERO
    00632         (positive definite)
    00633     */
    00634
    00635 #ifndef AVR
    00636     void invertnonzero();
    00637     void invert3x3();
    00638 #endif
    00639     void invert2x2();
    00640   };
    00641
    00642 } // namespace matrix
    00643 #endif