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