LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiMatrix.h

00001 /*
00002  * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  * This file is part of the LTI-Computer Vision Library (LTI-Lib)
00006  *
00007  * The LTI-Lib is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License (LGPL)
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * The LTI-Lib is distributed in the hope that it will be
00013  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00014  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with the LTI-Lib; see the file LICENSE.  If
00019  * not, write to the Free Software Foundation, Inc., 59 Temple Place -
00020  * Suite 330, Boston, MA 02111-1307, USA.
00021  */
00022 
00023 
00024 /*----------------------------------------------------------------
00025  * project ....: LTI Digital Image/Signal Processing Library
00026  * file .......: ltiMatrix.h
00027  * authors ....: Pablo Alvarado
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 09.04.99
00030  * revisions ..: $Id: ltiMatrix.h,v 1.15 2006/02/08 12:34:42 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_MATRIX_H_
00034 #define _LTI_MATRIX_H_
00035 
00036 #include "ltiMathObject.h"
00037 #include "ltiVector.h"
00038 #include "ltiPoint.h"
00039 #include "ltiRectangle.h"
00040 
00041 #define _LTI_GENERIC_MATRIX_DONT_INSTANTIATE_REQUEST 1
00042 #include "ltiGenericMatrix.h"
00043 #undef _LTI_GENERIC_MATRIX_DONT_INSTANTIATE_REQUEST
00044 
00045 namespace lti {
00046   /**
00047    * Mathematical matrix container class.
00048    *
00049    * The lti::matrix class allows the representation of \e n x \e m matrices.
00050    * The rows will be indexed between 0 and n-1, and the columns between 0
00051    * and m-1.
00052    *
00053    * All types defined in ltiTypes.h use static members and can be contained
00054    * by the lti::vector and lti::matrix classes.
00055    *
00056    * The matrix class is a container class implemented as template.
00057    *
00058    * If you need to create a matrix of floats with 20 rows and 15 columns,
00059    * all elements initialized with an initial value of 4.27 just create it:
00060    *
00061    * \code
00062    * lti::matrix<float> myMat(20,15,4.27f) // creates matrix with 300 elements
00063    *                                       // all initialized with 4.27f
00064    * \endcode
00065    *
00066    * To access the matrix elements use the access operators.  There are many
00067    * possibilities.  With at(const int row, const int col) is possible to
00068    * access an element directly.  With at(const int row) you can get the row
00069    * vector.  You cannot for instance resize nor change the memory referenced
00070    * in this vector (see lti::vector::resize).  For example:
00071    *
00072    * \code
00073    * float accu = 0; // initialize accumulator
00074    * lti::matrix<float> myMat(20,15,4.27f)
00075    * lti::vector<float> myVct;
00076    *
00077    * for (int j = 0; j < myMat.rows(); j++) {
00078    *   for (int i = 0; i < myMat.columns(); i++) {
00079    *   tmp += myMat.at(j,i); // access each element of the matrix:
00080    *                         // j is the row and i the column
00081    *   }
00082    * }
00083    *
00084    * myMat.getRowCopy(5,myVct); // copy the sixth row in myVct!
00085    * myVct.resize(6);           // Valid, the vector has its own memory!
00086    * myMat.at(5).resize(6)      // ERROR!! the vector is not resizable!
00087    *
00088    * \endcode
00089    *
00090    * The image representation in the LTI-Lib is based on the lti::matrix
00091    * class.  It is quite confusing to use first the y-coordinate and then
00092    * the x-coordinate to access the image elements.  To avoid confusion use
00093    * the lti::point class to access the elements of the matrix:
00094    *
00095    * \code
00096    *
00097    * lti::channel8 aChannel(20,15); // creates an 8bit image
00098    * lti::channel8::value_type tmp; // tmp is of the element type of the
00099    *                                // channel8!
00100    * lti::point p;
00101    *
00102    *
00103    * for (p.y = 0; p.y < aChannel.rows(); p.y++) {
00104    *   for (p.x = 0; p.x < aChannel.columns(); p.x++) {
00105    *   tmp += aChannel.at(p); // access each element of the matrix:
00106    *                          // equivalent to: tmp += aChannel.at(p.y,p.x)!
00107    *   }
00108    * }
00109    *
00110    * \endcode
00111    *
00112    * @see lti::image, lti::channel, lti::channel8,
00113    *      lti::dmatrix, lti::fmatrix, lti::imatrix
00114    *
00115    * The parent class is lti::genericMatrix and provides many memory
00116    * management options.
00117    *
00118    * The matrix has following methods:
00119    * - Constructors Constructors
00120    *   -  You can construct an empty matrix with the default constructor
00121    *      (matrix()).
00122    *   -  If you know the number of rows and columns use
00123    *      matrix(const int rows,const int columns,const T& initialValue)
00124    *   -  You can create a copy of another matrix or just copy a submatrix
00125    *      with the copy constructor (matrix(const matrix<T>& otherMatrix))
00126    * - Access members
00127    *   - at(), operator[]()
00128    *   - The rows() member returns the number of rows of the matrix.
00129    *   - The columns() member returns the number of columns of the matrix.
00130    * - Fill and Copy members
00131    *   -  With the fill() members you can fill the matrix with a given
00132    *      constant value or with values taken from other matrices.
00133    *   -  With the copy() member you can copy another matrix.
00134    *   -  You can specify, that the matrix should be used just as a
00135    *      wrapper-object to access external memory regions: useExternData().
00136    *      To check if a matrix is a wrapper-object you can use ownsData().
00137    * - Mathematical operations
00138    *   - Matrix multiplication: multiply()
00139    *   - Elementwise multiplication: emultiply()
00140    *   - Add another matrix to the actual matrix: add()
00141    *   - Add another <b>scaled</b> matrix to the actual matrix: addScaled()
00142    *   - Add a constant value to all elements of the matrix: add(const T& cst)
00143    *   - Subtract another vector from the actual vector: subtract()
00144    *   - Multiply the vector with a constant value: multiply()
00145    *   - Transpose the matrix: transpose()
00146    * - Iterators
00147    *   - It is possible to iterate within the matrix by making use of
00148    *     the matrix iterators.  (see begin() for more information)
00149    *   - Instead of reverse_iterators as in the STL we use iterators
00150    *     going backwards, due to faster execution times (see
00151    *     inverseBegin() for more information)
00152    *
00153    * @ingroup gLinearAlgebra
00154    * @ingroup gAggregate
00155    */
00156   template<class T>
00157   class matrix : public genericMatrix<T> {
00158     public:
00159     /**
00160      * type of the contained data
00161      */
00162     typedef T value_type;
00163 
00164     /**
00165      * return type of the size() member
00166      */
00167     typedef ipoint size_type;
00168 
00169     // iterator types of the parent class
00170     typedef typename genericMatrix<T>::iterator iterator;
00171     typedef typename genericMatrix<T>::const_iterator const_iterator;
00172 
00173 
00174     /**
00175      * default constructor creates an empty matrix
00176      */
00177     matrix();
00178 
00179     /**
00180      * this constructor creates a connected <code>rows x cols</code> Matrix
00181      * and initializes all elements with <code>iniValue</code>
00182      * @param rows number of rows of the matrix
00183      * @param cols number of columns of the matrix
00184      * @param iniValue all elements will be initialized with this value
00185      */
00186     matrix(const int rows,const int cols,const T& iniValue = T());
00187 
00188     /**
00189      * this constructor creates a connected <code>rows x cols</code> Matrix
00190      * and initializes all elements with the data pointed by
00191      * <code>data</code>.  The first <code>cols</code>-elements of the data
00192      * will be copied on the first row, the next ones on the second row and
00193      * so on.
00194      * @param rows number of rows of the matrix
00195      * @param cols number of columns of the matrix
00196      * @param data pointer to the memory block with the data to be initialized
00197      *            with.
00198      */
00199     matrix(const int rows,const int cols,const T data[]);
00200 
00201     /**
00202      * this constructor creates a connected <code>size.y x size.x</code>
00203      * Matrix and initializes all elements with <code>iniValue</code>
00204      * @param size lti::point with the size of the matrix
00205      *             (size.x is the number of columns and
00206      *              size.y the number of rows)
00207      * @param iniValue all elements will be initialized with this value
00208      */
00209     matrix(const ipoint& size,const T& iniValue = T());
00210 
00211     /**
00212      * copy constructor.
00213      *
00214      * create this matrix as a connected copy of another matrix
00215      * for this const version, the data will be always copied!
00216      * It is also possible to create a copy of a submatrix of another matrix.
00217      *
00218      * @param other the matrix to be copied.
00219      * @param fromRow initial row of the other matrix to be copied
00220      * @param toRow last row to be copied of the other matrix
00221      * @param fromCol initial column of the other matrix to be copied
00222      * @param toCol last column to be copied of the other matrix
00223      *
00224      * Example:
00225      * \code
00226      * lti::matrix<int> m(4,6,0); // integer matrix with 25 elements
00227      * // ...
00228      * // initialize Matrix with:
00229      * //        0  1  2  3  4  5
00230      * //        2  1  5  4  0  3
00231      * //        1  2  1  2  3  2
00232      * //        3  3  2  1  2  3
00233      *
00234      * lti::matrix<int> sm(m,0,2,1,3)  // last line will lead to
00235      * //                                 following contents in sm:
00236      * //        1  2  3
00237      * //        1  5  4
00238      * //        2  1  2
00239      * \endcode
00240      */
00241     matrix(const matrix<T>& other,
00242            const int fromRow=0,const int toRow=MaxInt32,
00243            const int fromCol=0,const int toCol=MaxInt32);
00244 
00245     /**
00246      * copy constructor (reference to a submatrix).
00247      * creates submatrix of another matrix.
00248      *
00249      * if <code>copyData == true</code>, the new object has its own data
00250      * (equivalent to previous copy constructor).
00251      *
00252      * if <code>copyData == false</code>, the new object has references to
00253      * the other matrix, which means that the data is not necessarily
00254      * consecutive.  (This will not be a connected but a lined matrix)
00255      *
00256      * Those algorithms which use direct access to the matrix memory block
00257      * should check first if the memory lies in a consecutive block!
00258      * (see getMode())
00259      *
00260      * @param copyData should the data of the other matrix be copied or not
00261      * @param other the matrix with the data to be copied or to be shared
00262      * @param fromRow initial row of the other matrix to be copied
00263      * @param toRow last row to be copied of the other matrix
00264      * @param fromCol initial column of the other matrix to be copied
00265      * @param toCol last column to be copied of the other matrix
00266      */
00267     matrix(const bool copyData, matrix<T>& other,
00268            const int fromRow=0,const int toRow=MaxInt32,
00269            const int fromCol=0,const int toCol=MaxInt32);
00270 
00271     /**
00272      * If \a init is true this constructor is equivalent to calling
00273      * matrix(const int rows, const int cols), and thus initializing
00274      * all elements with T(). However, in some cases the elements need
00275      * not be initialized during construction, since complex
00276      * initializion is required. Especially for large matrices, the
00277      * unnecessary constructor initialization is very time consuming.
00278      *
00279      * If \a init is false, memory is allocated but no initialization
00280      * takes place. Thus the following is equivalent:
00281      * \code
00282      * matrix<int> a(false,100,100);
00283      *
00284      * matrix<int> a;
00285      * a.resize(100,100,0,false,false);
00286      * \endcode
00287      *
00288      * @param init initialize matrix or not
00289      * @param rows number of rows of the matrix
00290      * @param cols number of columns of the matrix
00291      */
00292     matrix(const bool init, const int rows, const int cols);
00293 
00294     /**
00295      * If \a init is true this constructor is equivalent to calling
00296      * matrix(const int rows, const int cols), and thus initializing
00297      * all elements with T(). However, in some cases the elements need
00298      * not be initialized during construction, since complex
00299      * initializion is required. Especially for large matrices, the
00300      * unnecessary constructor initialization is very time consuming.
00301      *
00302      * If \a init is false, memory is allocated but no initialization
00303      * takes place. Thus the following is equivalent:
00304      * \code
00305      * matrix<int> a(false,100,100);
00306      *
00307      * matrix<int> a;
00308      * a.resize(100,100,0,false,false);
00309      * \endcode
00310      *
00311      * @param init initialize matrix or not
00312      * @param size desired size for the matrix
00313      */
00314     matrix(const bool init, const ipoint& size);
00315 
00316     /**
00317      * copy constructor.
00318      *
00319      * create this matrix as a connected copy of another matrix
00320      * taking only the rows indicated by the vector.
00321      * for this const version, the data will be always copied!
00322      * Multiple occurence of one row index in <code>rows</code> is allowed.
00323      *
00324      * @param other the matrix to be copied.
00325      * @param rows inidices of the rows to be copied
00326      *
00327      * Example:
00328      * \code
00329      * lti::vector<int> rows(2);
00330      * // initialize with
00331      * // 1 3
00332      * lti::matrix<int> m(4,6,0); // integer matrix with 25 elements
00333      * // ...
00334      * // initialize Matrix with:
00335      * //        0  1  2  3  4  5
00336      * //        2  1  5  4  0  3
00337      * //        1  2  1  2  3  2
00338      * //        3  3  2  1  2  3
00339      *
00340      * lti::matrix<int> sm(m,rows)     // last line will lead to
00341      * //                                 following contents in sm:
00342      * //        2  1  5  4  0  3
00343      * //        3  3  2  1  2  3
00344      * \endcode
00345      */
00346     matrix(const matrix<T>& other,
00347            const genericVector<int>& rows);
00348 
00349     /**
00350      * destructor
00351      */
00352     virtual ~matrix();
00353 
00354     /**
00355      * returns the name of this class: "matrix"
00356      */
00357     virtual const char* getTypeName() const;
00358 
00359     /**
00360      * return matrix-row as a vector.
00361      * This method works fast, since it returns a reference to the row vector.
00362      * The data will NOT be copied.
00363      * @param row the row to be accessed
00364      * @return a reference to the vector row
00365      */
00366     inline vector<T>& getRow(const int row);
00367 
00368     /**
00369      * return matrix-row as a const vector.
00370      * This method works fast, since it returns a reference to the row vector.
00371      * The data will NOT be copied.
00372      * @param row the row to be accessed
00373      * @return a const reference to the vector row
00374      */
00375     inline const vector<T>& getRow(const int row) const;
00376 
00377     /**
00378      * alias for getRow()
00379      */
00380     inline vector<T>& operator[](const int row);
00381 
00382     /**
00383      * alias for getRow()
00384      */
00385     inline const vector<T>& operator[](const int row) const;
00386 
00387     /**
00388      * return matrix-row as a vector.
00389      * This method copies the data of the matrix, therefore is not as
00390      * fast as getRow()
00391      * @param row the number of tthe row to be copied
00392      * @return a vector with the contents of the row of the matrix
00393      */
00394     inline vector<T> getRowCopy(const int row) const;
00395 
00396     /**
00397      * Copy a row vector in the given parameter.
00398      *
00399      * This method copies the data of a given row of the genericMatrix
00400      * in the given vector.
00401      *
00402      * @param row the number of the row to be copied
00403      * @param theRow the vector, where the data will be copied
00404      * @see getRow()
00405      */
00406     inline void getRowCopy(const int row,vector<T>& theRow) const;
00407 
00408     /**
00409      * return matrix-column as a vector.
00410      * This method copies the data of the matrix, therefore is not as
00411      * fast as getRow()
00412      * @param col the number of the column to be copied
00413      * @return a vector with the contents of the column of the matrix
00414      */
00415     inline vector<T> getColumnCopy(const int col) const;
00416 
00417     /**
00418      * return genericMatrix-column as a vector.
00419      * This method copies the data of the genericMatrix, therefore is not as
00420      * fast as getRow()
00421      * @param col the number of the column to be copied
00422      * @param theCol a vector, where the column vector of the genericMatrix
00423      *               should be copied.
00424      */
00425     inline void getColumnCopy(const int col,vector<T>& theCol) const;
00426 
00427     /**
00428      * Return the diagonal elements of the matrix as vector.
00429      * This method copies the diagonal elements of the matrix into
00430      * the vector. If the matrix is non-symmetrical, the vector will
00431      * be of dimension min(rows(),columns()).
00432      * @return a vector with the diagonal elements of the matrix.
00433      */
00434     inline vector<T> getDiagonal() const;
00435 
00436     /**
00437      * Return the diagonal elements of the genericMatrix as vector.
00438      * This method copies the diagonal elements of the genericMatrix into
00439      * the vector. If the genericMatrix is non-symmetrical, the vector will
00440      * be of dimension min(rows(),columns()).
00441      * @param diag a vector, where the diagonal of the genericMatrix
00442      *             should be copied.
00443      */
00444     inline void getDiagonal(vector<T>& diag) const;
00445 
00446     /**
00447      * assigment operator.
00448      *
00449      * copy the contents of <code>other</code> in this object.
00450      *
00451      * The result of the copy is always a connected matrix.  I.e. you cannot
00452      * copy the sub-matrix property of another matrix.
00453      *
00454      * @param other the other matrix to be copied
00455      */
00456     inline matrix<T>& copy(const matrix<T>& other);
00457 
00458     /**
00459      * assigment operator.
00460      *
00461      * copy the contents of <code>other</code> in this object.
00462      *
00463      * The result of the copy is always a connected matrix.  I.e. you cannot
00464      * copy the sub-matrix property of another matrix.
00465      *
00466      * @param other the other matrix to be copied
00467      * @param fromRow initial row of the other matrix to be copied
00468      * @param toRow last row to be copied of the other matrix
00469      * @param fromCol initial column of the other matrix to be copied
00470      * @param toCol last column to be copied of the other matrix
00471      */
00472     inline matrix<T>& copy(const matrix<T>& other,
00473                            const int fromRow,
00474                            const int toRow=MaxInt32,
00475                            const int fromCol=0,
00476                            const int toCol=MaxInt32);
00477 
00478     /**
00479      * assigment operator.
00480      *
00481      * copy the contents of <code>other</code> in this object.
00482      *
00483      * The result of the copy is always a connected matrix.  I.e. you cannot
00484      * copy the sub-matrix property of another matrix.
00485      *
00486      * @param other the other matrix to be copied
00487      * @param window rectangle define the copy area
00488      */
00489     inline matrix<T>& copy(const matrix<T>& other,const irectangle& window);
00490 
00491     /**
00492      * assigment operator.
00493      *
00494      * copy the contents of the specified rows/columns of
00495      * <code>other</code> into this object. Multiple occurence of one
00496      * row/column index in <code>idx</code> is allowed. If the
00497      * argument \b rows is true, \b idx specifies rows, if false \b
00498      * idx specifies columns.
00499      *
00500      * The result of the copy is always a connected matrix.  I.e. you cannot
00501      * copy the sub-matrix property of another matrix.
00502      *
00503      * @param other the other matrix to be copied
00504      * @param idx indices of the rows to be copied.
00505      * @param rows if true works on rows, else on columns
00506      */
00507     inline matrix<T>& copy(const matrix<T>& other, const vector<int>& idx,
00508                            bool rows=true);
00509 
00510     /**
00511      * copy the <code>other</code> matrix by casting each of its elements
00512      * @param other The matrix to be casted
00513      * Example:
00514      * \code
00515      *   lti::matrix<int> matA(10,10,1);// a matrix of integers
00516      *   lti::matrix<double> matB;      // a matrix of doubles
00517      *
00518      *   matB.castFrom(matA);          // this will copy matA in matB!!
00519      * \endcode
00520      */
00521     template<class U>
00522     matrix<T>& castFrom(const matrix<U>& other) {
00523       resize(other.rows(),other.columns(),T(),false,false);
00524       int y;
00525       for (y=0;y<this->rows();y++) {
00526         this->getRow(y).castFrom(other.getRow(y));
00527       }
00528 
00529       return (*this);
00530     };
00531 
00532     /**
00533      * create a clone of this matrix
00534      * @return a pointer to a copy of this matrix
00535      */
00536     virtual mathObject* clone() const;
00537 
00538     /**
00539      * compare this matrix with other, and use the given tolerance to
00540      * determine if the value of each element of the other matrix
00541      * approximately equals the values of the actual matrix elements.
00542      *
00543      * An element <i>x</i> is approximately equal to another element <i>y</i>
00544      * with a tolerance <i>t</i>, if following equation holds:
00545      * <i>x</i>-t < <i>y</i> < <i>x</i>+t
00546      *
00547      * @param other the other matrix to be compared with
00548      * @param tolerance the tolerance to be used
00549      *
00550      * @return true if both matrices are approximatly equal
00551      */
00552     bool prettyCloseTo(const matrix<T>& other,const T& tolerance) const;
00553 
00554     /**
00555      * assigment operator (alias for copy(other)).
00556      * @param other the matrix to be copied
00557      * @return a reference to the actual matrix
00558      */
00559     inline matrix<T>& operator=(const matrix<T>& other);
00560 
00561     /**
00562      * @name Apply Methods
00563      * Following methods are used to apply simple functions to each element
00564      * of the vector.
00565      */
00566     //@{
00567 
00568     /**
00569      * applies a C-function to each element of the matrix.
00570      * @param function a pointer to a C-function
00571      * @return a reference to the actual matrix
00572      */
00573     matrix<T>& apply(T (*function)(T));
00574 
00575     /**
00576      * applies a C-function to each element of the other matrix
00577      * @param other the matrix which elements will go through the given
00578      *              function.
00579      * @param function a pointer to a C-function
00580      * @return a reference to the actual matrix
00581      */
00582     matrix<T>& apply(const matrix<T>& other,T (*function)(T));
00583 
00584     /**
00585      * applies a C-function to each element of the matrix.
00586      * @param function a pointer to a C-function
00587      * @return a reference to the actual matrix
00588      */
00589     matrix<T>& apply(T (*function)(const T&));
00590 
00591     /**
00592      * applies a C-function to each element of the other matrix
00593      * @param other the matrix which elements will go through the given
00594      *              function.
00595      * @param function a pointer to a C-function
00596      * @return a reference to the actual matrix
00597      */
00598     matrix<T>& apply(const matrix<T>& other,T (*function)(const T&));
00599 
00600     /**
00601      * a two-parameter C-function receives the i-th elements of this
00602      * and the given matrix and the result will be left in this
00603      * matrix.  Note that both matrices must have the same size!
00604      * @param other the second matrix to be considered (the first
00605      *              matrix will be this object!)
00606      * @param function a pointer to C-function with two parameters
00607      * @return a reference to the actual matrix
00608      */
00609     matrix<T>& apply(const matrix<T>& other,T (*function)(const T&,const T&));
00610 
00611     /**
00612      * a two-parameter C-function receives the i-th elements of this
00613      * and the given matrix and the result will be left in this
00614      * matrix.  Note that both matrices must have the same size!
00615      * @param other the second matrix to be considered (the first
00616      *              matrix will be this object!)
00617      * @param function a pointer to C-function with two parameters
00618      * @return a reference to the actual matrix
00619      */
00620     matrix<T>& apply(const matrix<T>& other,T (*function)(T,T));
00621 
00622     /**
00623      * a two-parameter C-function receives the i-th elements of both given
00624      * matrices and leaves the result here.
00625      * Note that both matrices must have the same size!
00626      * @param a the first matrix
00627      * @param b the second matrix
00628      * @param function a pointer to C-function with two parameters
00629      * @return a reference to the actual matrix
00630      */
00631     matrix<T>& apply(const matrix<T>& a,
00632                      const matrix<T>& b,
00633                      T (*function)(const T&,const T&));
00634 
00635     /**
00636      * a two-parameter C-function receives the i-th elements of both given
00637      * matrices and leaves the result here.
00638      * Note that both matrices must have the same size!
00639      * @param a the first matrix
00640      * @param b the second matrix
00641      * @param function a pointer to C-function with two parameters
00642      * @return a reference to the actual matrix
00643      */
00644     matrix<T>& apply(const matrix<T>& a,
00645                      const matrix<T>& b,
00646                      T (*function)(T,T));
00647 
00648     //@}
00649 
00650     /**
00651      * @name Arithmetical Operations
00652      */
00653     //@{
00654 
00655     /**
00656      * add <code>other</code> matrix to this matrix, and leave result here
00657      * @param other the matrix to be added with
00658      * @return a reference to the actual matrix
00659      */
00660     matrix<T>& add(const matrix<T>& other);
00661 
00662     /**
00663      * add  matrices <code>a</code> and <code>b</code> and write the result
00664      * in this matrix
00665      * @param a the first matrix
00666      * @param b the second matrix
00667      * @return a reference to the actual matrix
00668      */
00669     matrix<T>& add(const matrix<T>& a, const matrix<T>& b);
00670 
00671     /**
00672      * add constant value to this matrix, and leave result here
00673      * @param value a constant value to be added to all matrix elements
00674      * @return a reference to the actual matrix
00675      */
00676     matrix<T>& add(const T value);
00677 
00678     /**
00679      * add constant value to the other matrix and leave result here.
00680      * @param other the other matrix
00681      * @param value a constant value to be added to all matrix elements
00682      * @return a reference to the actual matrix
00683      */
00684     matrix<T>& add(const matrix<T>& other,const T value);
00685 
00686     /**
00687      * alias for add(const T value)
00688      * @param value a constant value to be added to all matrix elements
00689      * @return a reference to the actual matrix
00690      */
00691     matrix<T>& operator+=(const T value) {return add(value);};
00692 
00693     /**
00694      * alias for add(const matrix)
00695      * @param other the matrix to be added with
00696      * @return a reference to the actual matrix
00697      */
00698     matrix<T>& operator+=(const matrix<T>& other) {return add(other);};
00699 
00700     /**
00701      * add <code> other</code> matrix to this matrix and leave the result in
00702      * a new matrix.  This object is not changed.
00703      * @param other the other matrix to be added with.
00704      * @return a matrix with the sum of this matrix and <code>other</code>
00705      *
00706      * Note that the use of this operator is not as efficient as the use of
00707      * the add() methods, in which the programmer can decide when to use
00708      * temporal and when not...
00709      */
00710     matrix<T> operator+(const matrix<T>& other) const;
00711 
00712     /**
00713      * add constant value to this matrix, and leave result in a new
00714      * matrix. This object is not changed.
00715      * @param value a constant value to be added to all matrix elements
00716      * @return a new matrix with the result
00717      */
00718     matrix<T> operator+(const T value) const;
00719 
00720     /**
00721      * Add another matrix scaled by \f$b\f$ to this matrix. The matrices
00722      * must be of the same types and dimensions. Let \f$A\f$ be this matrix
00723      * and \f$B\f$ the other matrix, then this method performs:<p>
00724      * \f$A=A+b\cdot B\f$
00725      * @param b scaling factor for <b>other</b>
00726      * @param other the matrix to be added after scaling
00727      * @return a reference to this matrix
00728      */
00729     matrix<T>& addScaled(const T b, const matrix<T>& other);
00730 
00731     /**
00732      * Add a matrix A with a matrix B scaled by \f$b\f$, and leave the
00733      * result in this matrix. The matrices must be of the same types
00734      * and dimensions. This method performs:<p> \f$A+b\cdot B\f$
00735      * @param matA the first matrix
00736      * @param b scaling factor for <b>matB</b>
00737      * @param matB the matrix to be added after scaling
00738      * @return a reference to this matrix
00739      */
00740     matrix<T>& addScaled(const matrix<T>& matA,
00741                          const T b,
00742                          const matrix<T>& matB);
00743 
00744     /**
00745      * Leave the scaled %sum of two matrices in this matrix. The matrices
00746      * must be of the same types and dimensions. Let \f$A\f$ be the
00747      * first matrix and \f$B\f$ the second matrix with corresponding
00748      * scaling factors \f$a\f$ and \f$b\f$, further \f$C\f$ this
00749      * matrix, then this method performs:<p>
00750      * \f$C=a\cdot A+b\cdot B\f$
00751      * @param a scaling factor for <b>first</b>
00752      * @param first the first matrix to be added after scaling
00753      * @param b scaling factor for <b>second</b>
00754      * @param second the second matrix to be added after scaling
00755      * @return a reference to this matrix
00756      */
00757     matrix<T>& addScaled(const T a, const matrix<T>& first,
00758                          const T b, const matrix<T>& second);
00759 
00760 
00761     /**
00762      * subtract <code>other</code> matrix from this matrix, and leave result
00763      * here.
00764      * @param other the matrix to be subtracted
00765      * @return a reference to this matrix.
00766      */
00767     matrix<T>& subtract(const matrix<T>& other);
00768 
00769     /**
00770      * subtract matrices <code>b</code> from <code>a</code> and write result
00771      * in this matrix.
00772      * @param a the first matrix
00773      * @param b the second matrix
00774      * @return a reference to this matrix, which is now a-b.
00775      */
00776     matrix<T>& subtract(const matrix<T>& a, const matrix<T>& b);
00777 
00778     /**
00779      * subtract constant value from this matrix, and leave result here
00780      * @param value a constant value to be subtracted from all matrix elements
00781      * @return a reference to the actual matrix
00782      */
00783     matrix<T>& subtract(const T value);
00784 
00785     /**
00786      * subtract constant value from the other matrix and leave result here.
00787      * @param other the other matrix
00788      * @param value a constant value to be subtracted from all matrix elements
00789      * @return a reference to the actual matrix
00790      */
00791     matrix<T>& subtract(const matrix<T>& other,const T value);
00792 
00793     /**
00794      * alias for subtract(const T value)
00795      * @param value a constant value to be subtracted from all matrix elements
00796      * @return a reference to the actual matrix
00797      */
00798     matrix<T>& operator-=(const T value) {return subtract(value);};
00799 
00800     /**
00801      * alias for subtract(const matrix)
00802      * @param other the matrix to be subtracted 
00803      * @return a reference to the actual matrix
00804      */
00805     matrix<T>& operator-=(const matrix<T>& other) {return subtract(other);};
00806 
00807     /**
00808      * multiply this matrix with <code>other</code> matrix, and leave result
00809      * here. The dimensions of this matrix will change if needed!
00810      * @param other the other matrix to be multiplied with.
00811      * @return a reference to this matrix.
00812      */
00813     matrix<T>& multiply(const matrix<T>& other);
00814 
00815     /**
00816      * multiply <code>first</code> with <code>second</code> and leave the
00817      * result in this object.
00818      * @param first the first matrix
00819      * @param second this second matrix will be multiplied with the first one.
00820      * @return a reference to this matrix, which has now the multiplication
00821      *         result.
00822      */
00823     matrix<T>& multiply(const matrix<T>& first,
00824                         const matrix<T>& second);
00825 
00826     /**
00827      * multiply this matrix with a vector and leave the result in
00828      * <code>result</code>.
00829      * A reference to <code>result</code> is returned.
00830      * @param other the vector to be multiplied with.  Its dimension must be
00831      *              equal to the number of columns of the matrix.
00832      * @param result the resulting vector.  It will have a number of
00833      *              dimensions equal to the number of rows of the matrix.
00834      * @return a reference to the result
00835      */
00836     vector<T>& multiply(const vector<T>& other,
00837             vector<T>& result) const;
00838 
00839     /**
00840      * multiply this matrix with a vector and leave the result in
00841      * same vector (In-Place Method)
00842      * A reference to the vector is returned.
00843      * @param srcdest the vector to be multiplied with.  Its dimension must be
00844      *              equal to the number of columns of the matrix.  The result
00845      *              vector will be left here too, and the resulting size
00846      *              will be the number of rows of the matrix.
00847      * @return a reference to the result
00848      */
00849     vector<T>& multiply(vector<T>& srcdest) const;
00850 
00851     /**
00852      * multiply constant value with this matrix, and leave result here
00853      * @param value the constant value to be multiplied with
00854      * @return a reference to the actual matrix
00855      */
00856     matrix<T>& multiply(const T value);
00857 
00858     /**
00859      * multiply constant value with the other matrix and leave result here.
00860      * @param other the other matrix
00861      * @param value the constant value to be multiplied with
00862      * @return a reference to the actual matrix
00863      */
00864     matrix<T>& multiply(const matrix<T>& other,const T value);
00865 
00866     /**
00867      * alias for multiply(const matrix)
00868      * @param other the other matrix to be multiplied with.
00869      * @return a reference to this matrix.
00870      */
00871     matrix<T>& operator*=(const matrix<T>& other) {
00872       return multiply(other);
00873     };
00874 
00875     /**
00876      * alias for multiply(const T& value)
00877      * @param value the constant value to be multiplied with
00878      * @return a reference to this matrix.
00879      */
00880     matrix<T>& operator*=(const T value) {return multiply(value);};
00881 
00882     /**
00883      * multiply the vector <code>vct</code> with this matrix, and save
00884      * the result in the vector <code>result</code>.
00885      *
00886      * The given vector will be interpreted as a row-vector (or a transposed
00887      * column vector).
00888      *
00889      * @param vct the vector to be multiplied with.
00890      * @param result the resulting vector.
00891      * @return a reference to the result vector
00892      */
00893     vector<T>& leftMultiply(const vector<T>& vct,
00894                                   vector<T>& result) const;
00895 
00896     /**
00897      * multiply the given vector <code>srcdest</code> with this
00898      * matrix, and save the result in the same vector.
00899      *
00900      * The given vector will be interpreted as a row-vector (or a
00901      * transposed column vector).
00902      *
00903      * @param srcDest the vector to be multiplied with, and where the
00904      *                result must be written.
00905      * @return a reference to the result vector
00906      */
00907     vector<T>& leftMultiply(vector<T>& srcDest) const;
00908 
00909     /**
00910      * multiply the matrix \a mat with \a this matrix, and leave
00911      * the result in \a this matrix.
00912      *
00913      * @param mat the matrix to be multiplied with.
00914      * @return a reference to \a this  matrix
00915      */
00916     matrix<T>& leftMultiply(const matrix<T>& mat);
00917 
00918     /**
00919      * divide the elements of the matrix by a constant value, and leave
00920      * the result here
00921      * @param value the constant value (divisor)
00922      * @return a reference to the actual matrix
00923      */
00924     matrix<T>& divide(const T value);
00925 
00926     /**
00927      * divide the elements of the other matrix by a constant value and leave
00928      * the result here.
00929      * @param other the other matrix
00930      * @param value the constant value (divisor)
00931      * @return a reference to the actual matrix
00932      */
00933     matrix<T>& divide(const matrix<T>& other,const T value);
00934 
00935     /**
00936      * alias for divide(const T& value)
00937      * @param value the constant value to be divided by
00938      * @return a reference to this matrix.
00939      */
00940     matrix<T>& operator/=(const T value) {return divide(value);};
00941 
00942     /**
00943      * element-wise multiplication with other matrix
00944      * @param other the other matrix.  It should have the same dimensions of
00945      *              this matrix.
00946      * @return a reference to the actual matrix
00947      */
00948     matrix<T>& emultiply(const matrix<T>& other);
00949 
00950     /**
00951      * element-wise multiplication of <code>a</code> and <code>b</code>.
00952      * @param a the first matrix
00953      * @param b the second matrix (with same dimensions of a)
00954      * @return a reference to the actual matrix
00955      */
00956     matrix<T>& emultiply(const matrix<T>& a, const matrix<T>& b);
00957 
00958     /**
00959      * element-wise division with other matrix
00960      * @param other the other matrix.  It should have the same dimensions of
00961      *              this matrix.
00962      * @return a reference to the actual matrix
00963      */
00964     matrix<T>& edivide(const matrix<T>& other);
00965 
00966     /**
00967      * element-wise division of <code>a</code> and <code>b</code>.
00968      * @param a the first matrix
00969      * @param b the second matrix (with same dimensions of a)
00970      * @return a reference to the actual matrix
00971      */
00972     matrix<T>& edivide(const matrix<T>& a, const matrix<T>& b);
00973 
00974     /**
00975      * outer-product of two vectors.
00976      * The result will be left in this matrix.
00977      * The dimensions of this matrix will change if needed.
00978      * The outer product of two column vectors is defined as
00979      * \f$a \cdot b^T\f$
00980      * @param a first vector (will determine the number of rows)
00981      * @param b second vector (will determine the number of columns)
00982      * @return a reference to the actual matrix
00983      */
00984     matrix<T>& outerProduct(const vector<T>& a,
00985                             const vector<T>& b);
00986 
00987     /**
00988      * transpose matrix and leave the result here.
00989      * @return a reference to the actual (now transposed) matrix
00990      */
00991     matrix<T>& transpose();
00992 
00993     /**
00994      * transpose the other matrix and leave the result here.
00995      * @return a reference to the actual (now transposed) matrix
00996      */
00997     matrix<T>& transpose(const matrix<T>& other);
00998 
00999     /**
01000      * calculate the sum of all elements of the matrix.
01001      * This member can be used with classes which define the operator '+='
01002      */
01003     T sumOfElements() const;
01004 
01005     /**
01006      * get the smallest element of the matrix
01007      */
01008     T minimum() const;
01009 
01010     /**
01011      * get the index of the smallest element of the matrix
01012      */
01013     ipoint getIndexOfMinimum() const;
01014 
01015     /**
01016      * get the biggest element of the matrix
01017      */
01018     T maximum() const;
01019 
01020     /**
01021      * get the index of the biggest element of the matrix
01022      */
01023     ipoint getIndexOfMaximum() const;
01024 
01025     /**
01026      * get the extremes of the matrix (smallest and biggest elements)
01027      */
01028     void getExtremes(T& theMinimum, T& theMaximum) const;
01029 
01030     /**
01031      * get the indices of the extremes of the matrix
01032      * (smallest and biggest elements)
01033      */
01034     void getIndexOfExtremes(point& theIdxMinimum, ipoint& theIdxMaximum) const;
01035 
01036     /**
01037      * Set the diagonal of this matrix to scale (default: 1), and all other
01038      * elements to 0. If the matrix is square (which it need not be), this
01039      * results in a scaled identity matrix.
01040      */
01041     void setIdentity(const T scale = T(1));
01042 
01043     /**
01044      * returns the trace (i.e. the sum of the diagonal elements) of this
01045      * matrix. If the matrix is not symmetrical, it will return the sum
01046      * of all elements (i,i) with i from 0 to n-1;
01047      * n being min(rows(),columns())
01048      */
01049     T trace() const;
01050 
01051     //@}
01052   protected:
01053     /**
01054      * Allocate \a n number of rows or the appropriate type.
01055      */
01056     inline virtual genericVector<T>* allocRows(const int n);
01057    
01058   };
01059 }
01060 
01061 #include "ltiMatrix_inline.h"
01062 
01063 namespace lti {
01064   /**
01065    * Matrix of double
01066    */
01067   typedef matrix<double> dmatrix;
01068   /**
01069    * Matrix of float
01070    */
01071   typedef matrix<float>  fmatrix;
01072   /**
01073    * Matrix of integer
01074    */
01075   typedef matrix<int>    imatrix;
01076 
01077 }
01078 
01079 #endif

Generated on Sat Apr 10 15:25:49 2010 for LTI-Lib by Doxygen 1.6.1