latest version v1.9 - last update 10 Apr 2010 |
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