Main MRPT website > C++ reference
MRPT logo
CMatrixTemplate.h
Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                       http://www.mrpt.org/                                |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 #ifndef CMatrixTemplate_H
00029 #define CMatrixTemplate_H
00030 
00031 #include <mrpt/utils/utils_defs.h>
00032 #include <mrpt/system/memory.h>
00033 #include <mrpt/system/datetime.h>
00034 
00035 #include <mrpt/math/math_frwds.h>  // Fordward declarations
00036 #include <mrpt/math/matrix_adaptors.h>
00037 #include <mrpt/math/CArray.h>
00038 
00039 namespace mrpt
00040 {
00041         namespace math
00042         {
00043 
00044                 /**  This template class provides the basic functionality for a general 2D any-size, resizable container of numerical or non-numerical elements.
00045                  * NOTES:
00046                  *              - This class is not serializable since it is a template. For using serialization, see mrpt::math::CMatrixNumeric
00047                  *              - First row or column index is "0".
00048                  *              - This class includes range checks with ASSERT_() if compiling with "_DEBUG" or "MRPT_ALWAYS_CHECKS_DEBUG_MATRICES=1".
00049                  *              - Please DO NOT use as template class type any other class. It can be safely used the following types:
00050                  *                      - Elemental types (int,char,float,doble,...)
00051                  *                      - Data struct (Not classes!)
00052                  *                      - Any kind of pointers (user is responsible for allocating and freeing the memory addressed by pointers).
00053                  *
00054                  * \note Memory blocks for each row are 16-bytes aligned (since MRPT 0.7.0).
00055                  * \note For a complete introduction to Matrices and vectors in MRPT, see: http://www.mrpt.org/Matrices_vectors_arrays_and_Linear_Algebra_MRPT_and_Eigen_classes
00056                  * \sa CMatrixTemplateNumeric
00057                  * \ingroup mrpt_base_grp
00058                  */
00059                 template <class T>
00060                 class CMatrixTemplate
00061                 {
00062                 public:
00063                         // type definitions
00064                         typedef T              value_type;              //!< The type of the matrix elements
00065                         typedef T&             reference;
00066                         typedef const T&       const_reference;
00067                         typedef std::size_t    size_type;
00068                         typedef std::ptrdiff_t difference_type;
00069 
00070 
00071                 protected:
00072                         T                               **m_Val;
00073                         size_t                  m_Rows, m_Cols;
00074 
00075                         /** Internal use only: It reallocs the memory for the 2D matrix, maintaining the previous contents if posible.
00076                           */
00077                         void realloc(size_t row, size_t col, bool newElementsToZero = false)
00078                         {
00079                                 if (row!=m_Rows || col!=m_Cols || m_Val==NULL)
00080                                 {
00081                                         size_t  r;
00082                                         bool    doZeroColumns   = newElementsToZero && (col>m_Cols);
00083                                         size_t  sizeZeroColumns = sizeof(T)*(col-m_Cols);
00084 
00085                                         // If we are reducing rows, free that memory:
00086                                         for (r=row;r<m_Rows;r++)
00087                                                 mrpt::system::os::aligned_free( m_Val[r] );
00088 
00089                                         // Realloc the vector of pointers:
00090                                         if (!row)
00091                                                         { mrpt::system::os::aligned_free(m_Val); m_Val=NULL; }
00092                                         else    m_Val = static_cast<T**> (mrpt::system::os::aligned_realloc(m_Val, sizeof(T*) * row, 16 ) );
00093 
00094                                         // How many new rows/cols?
00095                                         size_t  row_size = col * sizeof(T);
00096 
00097                                         // Alloc new ROW pointers & resize previously existing rows, as required:
00098                                         for (r=0;r<row;r++)
00099                                         {
00100                                                 if (r<m_Rows)
00101                                                 {
00102                                                         // This was an existing row: Resize the memory:
00103                                                         m_Val[r] = static_cast<T*> (mrpt::system::os::aligned_realloc( m_Val[r], row_size, 16));
00104 
00105                                                         if (doZeroColumns)
00106                                                         {
00107                                                                 // Fill with zeros:
00108                                                                 ::memset(&m_Val[r][m_Cols],0,sizeZeroColumns);
00109                                                         }
00110                                                 }
00111                                                 else
00112                                                 {
00113                                                         // This is a new row, alloc the memory for the first time:
00114                                                         m_Val[r] = static_cast<T*> ( mrpt::system::os::aligned_calloc( row_size, 16 ));
00115                                                 }
00116                                         }
00117                                         // Done!
00118                                         m_Rows  = row;
00119                                         m_Cols  = col;
00120                                 }
00121                         }
00122 
00123                 public:
00124                         /**
00125                           * Checks whether the rows [r-N,r+N] and the columns [c-N,c+N] are present in the matrix.
00126                           */
00127                         template<size_t N> inline void ASSERT_ENOUGHROOM(size_t r,size_t c) const       {
00128                                 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00129                                         ASSERT_((r>=N)&&(r+N<getRowCount())&&(c>=N)&&(c+N<getColCount()));
00130                                 #endif
00131                         }
00132                         /*! Fill all the elements with a given value (Note: named "fillAll" since "fill" will be used by child classes) */
00133                         void fillAll(const T &val) {
00134                                 for (size_t r=0;r<m_Rows;r++)
00135                                         for (size_t c=0;c<m_Cols;c++)
00136                                                 m_Val[r][c]=val;
00137                         }
00138 
00139                         /** Swap with another matrix very efficiently (just swaps a pointer and two integer values). */
00140                         inline void  swap(CMatrixTemplate<T> &o)
00141                         {
00142                                 std::swap(m_Val,  o.m_Val  );
00143                                 std::swap(m_Rows, o.m_Rows );
00144                                 std::swap(m_Cols, o.m_Cols );
00145                         }
00146 
00147                         /** Constructors */
00148                         CMatrixTemplate (const CMatrixTemplate& m) : m_Val(NULL),m_Rows(0),m_Cols(0)
00149                         {
00150                                 (*this) = m;
00151                         }
00152 
00153                         CMatrixTemplate (size_t row = 1, size_t col = 1) :  m_Val(NULL),m_Rows(0),m_Cols(0)
00154                         {
00155                                 realloc(row,col);
00156                         }
00157 
00158                         /** Copy constructor & crop from another matrix
00159                         */
00160                         CMatrixTemplate (const CMatrixTemplate& m, const size_t cropRowCount, const size_t cropColCount) : m_Val(NULL),m_Rows(0),m_Cols(0)
00161                         {
00162                                 ASSERT_(m.m_Rows>=cropRowCount)
00163                                 ASSERT_(m.m_Cols>=cropColCount)
00164                                 realloc( cropRowCount, cropColCount );
00165                                 for (size_t i=0; i < m_Rows; i++)
00166                                         for (size_t j=0; j < m_Cols; j++)
00167                                                 m_Val[i][j] = m.m_Val[i][j];
00168                         }
00169 
00170                         /** Constructor from a given size and a C array. The array length must match cols x row.
00171                           * \code
00172                           *  const double numbers[] = {
00173                           *    1,2,3,
00174                           *    4,5,6 };
00175                           *      CMatrixDouble   M(3,2, numbers);
00176                           * \endcode
00177                           */
00178                         template <typename V, size_t N>
00179                         CMatrixTemplate (size_t row, size_t col, V (&theArray)[N] ) :  m_Val(NULL),m_Rows(0),m_Cols(0)
00180                         {
00181                                 MRPT_COMPILE_TIME_ASSERT(N!=0)
00182                                 realloc(row,col);
00183                                 if (m_Rows*m_Cols != N) THROW_EXCEPTION(format("Mismatch between matrix size %lu x %lu and array of length %lu",static_cast<long unsigned>(m_Rows),static_cast<long unsigned>(m_Cols),static_cast<long unsigned>(N)))
00184                                 size_t  idx=0;
00185                                 for (size_t i=0; i < m_Rows; i++)
00186                                         for (size_t j=0; j < m_Cols; j++)
00187                                                 m_Val[i][j] = static_cast<T>(theArray[idx++]);
00188                         }
00189 
00190                         /** Constructor from a given size and a STL container (std::vector, std::list,...) with the initial values. The vector length must match cols x row.
00191                         */
00192                         template <typename V>
00193                         CMatrixTemplate(size_t row, size_t col, const V &theVector ) :  m_Val(NULL),m_Rows(0),m_Cols(0)
00194                         {
00195                                 const size_t N = theVector.size();
00196                                 realloc(row,col);
00197                                 if (m_Rows*m_Cols != N)  THROW_EXCEPTION(format("Mismatch between matrix size %lu x %lu and array of length %lu",static_cast<long unsigned>(m_Rows),static_cast<long unsigned>(m_Cols),static_cast<long unsigned>(N)))
00198                                 typename V::const_iterator it = theVector.begin();
00199                                 for (size_t i=0; i < m_Rows; i++)
00200                                         for (size_t j=0; j < m_Cols; j++)
00201                                                 m_Val[i][j] = static_cast<T>( *(it++) );
00202                         }
00203 
00204                         /** Destructor */
00205                         virtual ~CMatrixTemplate() { realloc(0,0); }
00206 
00207                         /** Assignment operator from another matrix */
00208                         CMatrixTemplate& operator = (const CMatrixTemplate& m)
00209                         {
00210                                 realloc( m.m_Rows, m.m_Cols );
00211                                 for (size_t i=0; i < m_Rows; i++)
00212                                         for (size_t j=0; j < m_Cols; j++)
00213                                                 m_Val[i][j] = m.m_Val[i][j];
00214                                 return *this;
00215                         }
00216 
00217                         /** Assignment operator for initializing from a C array (The matrix must be set to the correct size before invoking this asignament)
00218                           * \code
00219                           *      CMatrixDouble   M(3,2);
00220                           *  const double numbers[] = {
00221                           *    1,2,3,
00222                           *    4,5,6 };
00223                           *  M = numbers;
00224                           * \endcode
00225                           *  Refer also to the constructor with initialization data CMatrixTemplate::CMatrixTemplate
00226                           */
00227                         template <typename V, size_t N>
00228                         CMatrixTemplate& operator = (V (&theArray)[N] )
00229                         {
00230                                 MRPT_COMPILE_TIME_ASSERT(N!=0)
00231                                 if (m_Rows*m_Cols != N)
00232                                 {
00233                                         THROW_EXCEPTION(format("Mismatch between matrix size %lu x %lu and array of length %lu",m_Rows,m_Cols,N))
00234                                 }
00235                                 size_t  idx=0;
00236                                 for (size_t i=0; i < m_Rows; i++)
00237                                         for (size_t j=0; j < m_Cols; j++)
00238                                                 m_Val[i][j] = static_cast<T>(theArray[idx++]);
00239                                 return *this;
00240                         }
00241 
00242                         /** Number of rows in the matrix
00243                           * \sa getRowCount, getColCount, nr, nc
00244                           */
00245                         inline size_t getRowCount() const { return m_Rows; }
00246 
00247                         /** Number of columns in the matrix
00248                           * \sa getRowCount, getColCount, nr, nc
00249                          */
00250                         inline size_t getColCount() const { return m_Cols; }
00251 
00252                         /** Get a 2-vector with [NROWS NCOLS] (as in MATLAB command size(x)) */
00253                         inline CMatrixTemplateSize size() const
00254                         {
00255                                 CMatrixTemplateSize dims;
00256                                 dims[0]=m_Rows;
00257                                 dims[1]=m_Cols;
00258                                 return dims;
00259                         }
00260 
00261                         /** Changes the size of matrix, maintaining the previous contents. */
00262                         void setSize(size_t row, size_t col,bool zeroNewElements=false)
00263                         {
00264                                 realloc(row,col,zeroNewElements);
00265                         }
00266 
00267                         /** This method just checks has no effects in this class, but raises an exception if the expected size does not match */
00268                         inline void resize(const CMatrixTemplateSize &siz,bool zeroNewElements=false)
00269                         {
00270                                 setSize(siz[0],siz[1],zeroNewElements);
00271                         }
00272 
00273                         /** Subscript operator to get/set individual elements
00274                                 */
00275                         inline T& operator () (size_t row, size_t col)
00276                         {
00277                 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00278                                 if (row >= m_Rows || col >= m_Cols)
00279                                         THROW_EXCEPTION( format("Indexes (%lu,%lu) out of range. Matrix is %lux%lu",static_cast<unsigned long>(row),static_cast<unsigned long>(col),static_cast<unsigned long>(m_Rows),static_cast<unsigned long>(m_Cols)) );
00280                 #endif
00281                                 return m_Val[row][col];
00282                         }
00283 
00284                         /** Subscript operator to get individual elements
00285                                 */
00286                         inline const T &operator () (size_t row, size_t col) const
00287                         {
00288                 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00289                                 if (row >= m_Rows || col >= m_Cols)
00290                                         THROW_EXCEPTION( format("Indexes (%lu,%lu) out of range. Matrix is %lux%lu",static_cast<unsigned long>(row),static_cast<unsigned long>(col),static_cast<unsigned long>(m_Rows),static_cast<unsigned long>(m_Cols)) );
00291                 #endif
00292                                 return m_Val[row][col];
00293                         }
00294 
00295                         /** Subscript operator to get/set an individual element from a row or column matrix.
00296                           * \exception std::exception If the object is not a column or row matrix.
00297                           */
00298                         inline T& operator () (size_t ith)
00299                         {
00300                 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00301                                 ASSERT_(m_Rows==1 || m_Cols==1);
00302                 #endif
00303                                 if (m_Rows==1)
00304                                 {
00305                                         // A row matrix:
00306                 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00307                                         if (ith >= m_Cols)
00308                                                 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00309                 #endif
00310                                         return m_Val[0][ith];
00311                                 }
00312                                 else
00313                                 {
00314                                         // A columns matrix:
00315                 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00316                                         if (ith >= m_Rows)
00317                                                 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00318                 #endif
00319                                         return m_Val[ith][0];
00320                                 }
00321                         }
00322 
00323                         /** Subscript operator to get/set an individual element from a row or column matrix.
00324                           * \exception std::exception If the object is not a column or row matrix.
00325                           */
00326                         inline T operator () (size_t ith) const
00327                         {
00328                 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00329                                 ASSERT_(m_Rows==1 || m_Cols==1);
00330                 #endif
00331                                 if (m_Rows==1)
00332                                 {
00333                                         // A row matrix:
00334                 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00335                                         if (ith >= m_Cols)
00336                                                 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00337                 #endif
00338                                         return m_Val[0][ith];
00339                                 }
00340                                 else
00341                                 {
00342                                         // A columns matrix:
00343                 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00344                                         if (ith >= m_Rows)
00345                                                 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00346                 #endif
00347                                         return m_Val[ith][0];
00348                                 }
00349                         }
00350 
00351                         /** Fast but unsafe method to write a value in the matrix
00352                                 */
00353                         inline void set_unsafe(size_t row, size_t col,const T &v)
00354                         {
00355                 #ifdef _DEBUG
00356                                 if (row >= m_Rows || col >= m_Cols)
00357                                         THROW_EXCEPTION( format("Indexes (%lu,%lu) out of range. Matrix is %lux%lu",static_cast<unsigned long>(row),static_cast<unsigned long>(col),static_cast<unsigned long>(m_Rows),static_cast<unsigned long>(m_Cols)) );
00358                 #endif
00359                                 m_Val[row][col] = v;
00360                         }
00361 
00362                         /** Fast but unsafe method to read a value from the matrix
00363                                 */
00364                         inline const T &get_unsafe(size_t row, size_t col) const
00365                         {
00366                 #ifdef _DEBUG
00367                                 if (row >= m_Rows || col >= m_Cols)
00368                                         THROW_EXCEPTION( format("Indexes (%lu,%lu) out of range. Matrix is %lux%lu",static_cast<unsigned long>(row),static_cast<unsigned long>(col),static_cast<unsigned long>(m_Rows),static_cast<unsigned long>(m_Cols)) );
00369                 #endif
00370                                 return m_Val[row][col];
00371                         }
00372 
00373                         /** Fast but unsafe method to get a reference from the matrix
00374                                 */
00375                         inline T &get_unsafe(size_t row,size_t col)
00376                         {
00377                 #ifdef _DEBUG
00378                                 if (row >= m_Rows || col >= m_Cols)
00379                                         THROW_EXCEPTION( format("Indexes (%lu,%lu) out of range. Matrix is %lux%lu",static_cast<unsigned long>(row),static_cast<unsigned long>(col),static_cast<unsigned long>(m_Rows),static_cast<unsigned long>(m_Cols)) );
00380                 #endif
00381                                 return m_Val[row][col];
00382                         }
00383 
00384                         /** Fast but unsafe method to obtain a pointer to a given row of the matrix (Use only in time critical applications)
00385                                 */
00386                         inline T* get_unsafe_row(size_t row)
00387                         {
00388                 #ifdef _DEBUG
00389                                 if (row >= m_Rows)
00390                                         THROW_EXCEPTION( format("Row index %"PRIuPTR" out of range. Matrix is %"PRIuPTR"x%"PRIuPTR,static_cast<unsigned long>(row),static_cast<unsigned long>(m_Rows),static_cast<unsigned long>(m_Cols)) );
00391                 #endif
00392                                 return m_Val[row];
00393                         }
00394 
00395                         /** Fast but unsafe method to obtain a pointer to a given row of the matrix (Use only in critical applications)
00396                                 */
00397                         inline const T* get_unsafe_row(size_t row) const        {
00398                                 return m_Val[row];
00399                         }
00400 
00401                         /** Subscript operator to get a submatrix
00402                           */
00403                         inline CMatrixTemplate<T> operator() (const size_t row1,const size_t row2,const size_t col1,const size_t col2) const    {
00404                                 CMatrixTemplate<T> val(0,0);
00405                                 extractSubmatrix(row1,row2,col1,col2,val);
00406                                 return val;
00407                         }
00408 
00409                         /** Get a submatrix, given its bounds
00410                           * \sa extractSubmatrixSymmetricalBlocks
00411                           */
00412                         void extractSubmatrix(const size_t row1,const size_t row2,const size_t col1,const size_t col2,CMatrixTemplate<T> &out) const
00413                         {
00414                                 size_t nrows=row2-row1+1;
00415                                 size_t ncols=col2-col1+1;
00416                                 if (nrows<=0||ncols<=0) {
00417                                         out.realloc(0,0);
00418                                         return;
00419                                 }
00420                                 if (row1<0||row2>=m_Rows||col1<0||col2>=m_Cols) THROW_EXCEPTION("Indices out of range!");
00421                                 out.realloc(nrows,ncols);
00422                                 for (size_t i=0;i<nrows;i++) for (size_t j=0;j<ncols;j++) out.m_Val[i][j]=m_Val[i+row1][j+col1];
00423                         }
00424                         /// @overload
00425                         template <class Derived>
00426                         void extractSubmatrix(const size_t row1,const size_t row2,const size_t col1,const size_t col2,Eigen::MatrixBase<Derived> &out) const
00427                         {
00428                                 size_t nrows=row2-row1+1;
00429                                 size_t ncols=col2-col1+1;
00430                                 if (nrows<=0||ncols<=0) {
00431                                         out = typename Eigen::MatrixBase<Derived>::PlainObject();
00432                                         return;
00433                                 }
00434                                 if (row1<0||row2>=m_Rows||col1<0||col2>=m_Cols) THROW_EXCEPTION("Indices out of range!");
00435                                 out.resize(nrows,ncols);
00436                                 for (size_t i=0;i<nrows;i++) for (size_t j=0;j<ncols;j++) out.coeffRef(i,j)=m_Val[i+row1][j+col1];
00437                         }
00438 
00439 
00440                         /** Gets a series of contiguous rows.
00441                                 * \exception std::logic_error On index out of bounds
00442                                 * \sa extractRow
00443                                 * \sa extractColumns
00444                                 */
00445                         inline void extractRows(size_t firstRow,size_t lastRow,CMatrixTemplate<T> &out) const   {
00446                                 out.setSize(lastRow-firstRow+1,m_Cols);
00447                                 detail::extractMatrix(*this,firstRow,0,out);
00448                         }
00449 
00450                         /** Gets a series of contiguous columns.
00451                                 * \exception std::logic_error On index out of bounds
00452                                 * \sa extractColumn
00453                                 * \sa extractRows
00454                                 */
00455                         inline void extractColumns(size_t firstCol,size_t lastCol,CMatrixTemplate<T> &out) const        {
00456                                 out.setSize(m_Rows,lastCol-firstCol+1);
00457                                 detail::extractMatrix(*this,0,firstCol,out);
00458                         }
00459 
00460                         /** Returns a given column to a vector (without modifying the matrix)
00461                                 * \exception std::exception On index out of bounds
00462                                 */
00463                         void  extractCol(size_t nCol, std::vector<T> &out, int startingRow = 0) const
00464                         {
00465                                 size_t          i,n;
00466                         #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00467                                 if (nCol>=m_Cols)
00468                                         THROW_EXCEPTION("extractCol: Column index out of bounds");
00469                         #endif
00470 
00471                                 n = m_Rows - startingRow;
00472                                 out.resize( n );
00473 
00474                                 for (i=0;i<n;i++)
00475                                         out[i] = m_Val[i+startingRow][nCol];
00476                         }
00477 
00478                         /** Gets a given column to a vector (without modifying the matrix)
00479                                 * \exception std::exception On index out of bounds
00480                                 */
00481                         void  extractCol(size_t nCol, CMatrixTemplate<T> &out, int startingRow = 0) const
00482                         {
00483                                 size_t          i,n;
00484                         #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00485                                 if (nCol>=m_Cols)
00486                                         THROW_EXCEPTION("extractCol: Column index out of bounds");
00487                         #endif
00488 
00489                                 n = m_Rows - startingRow;
00490                                 out.setSize(n,1);
00491 
00492                                 for (i=0;i<n;i++)
00493                                         out(i,0) = m_Val[i+startingRow][nCol];
00494                         }
00495 
00496                         /** Appends a new row to the MxN matrix from a 1xN vector.
00497                                 *  The lenght of the vector must match the width of the matrix, unless it's empty: in that case the matrix is resized to 1xN.
00498                                 *  \code
00499                                 *    CMatrixDouble  M(0,0);
00500                                 *    vector_double  v(7),w(7);
00501                                 *    // ...
00502                                 *    M.appendRow(v);
00503                                 *    M.appendRow(w);
00504                                 *  \endcode
00505                                 * \exception std::exception On incorrect vector length.
00506                                 * \sa extractRow
00507                                 * \sa appendCol
00508                                 */
00509                         void  appendRow(const std::vector<T> &in)
00510                         {
00511                                 size_t          i,n, row;
00512 
00513                                 n = m_Cols;
00514                                 row = m_Rows;
00515 
00516                                 if (m_Cols==0 || m_Rows==0)
00517                                 {
00518                                         ASSERT_(!in.empty());
00519                                         n=m_Cols=in.size();
00520                                 }
00521                                 else
00522                                 {
00523                                         ASSERT_(in.size()==m_Cols);
00524                                 }
00525 
00526                                 realloc( row+1,n );
00527 
00528                                 for (i=0;i<n;i++)
00529                                         m_Val[row][i] = in[i];
00530                         }
00531 
00532                         /** Appends a new column to the matrix from a vector.
00533                                 * The length of the vector must match the number of rows of the matrix, unless it is (0,0).
00534                                 * \exception std::exception On size mismatch.
00535                                 * \sa extractCol
00536                                 * \sa appendRow
00537                                 */
00538                         void appendCol(const std::vector<T> &in)        {
00539                                 size_t r=m_Rows,c=m_Cols;
00540                                 if (m_Cols==0||m_Rows==0)       {
00541                                         ASSERT_(!in.empty());
00542                                         r=in.size();
00543                                         c=0;
00544                                 }       else ASSERT_(in.size()==m_Rows);
00545                                 realloc(r,c+1);
00546                                 for (size_t i=0;i<m_Rows;i++) m_Val[i][m_Cols-1]=in[i];
00547                         }
00548 
00549                         /** Inserts a column from a vector, replacing the current contents of that column.
00550                                 * \exception std::exception On index out of bounds
00551                                 * \sa extractCol
00552                                 */
00553                         void  insertCol(size_t nCol, const std::vector<T> &in)
00554                         {
00555                                 if (nCol>=m_Cols) THROW_EXCEPTION("insertCol: Row index out of bounds");
00556 
00557                                 size_t n = in.size();
00558                                 ASSERT_( m_Rows >= in.size() );
00559 
00560                                 for (size_t i=0;i<n;i++)
00561                                         m_Val[i][nCol] = in[i];
00562                         }
00563 
00564                         /** Returns a vector containing the matrix's values.
00565                           */
00566                         void getAsVector(std::vector<T> &out) const     {
00567                                 out.clear();
00568                                 out.reserve(m_Rows*m_Cols);
00569                                 for (size_t i=0;i<m_Rows;i++) out.insert(out.end(),&(m_Val[i][0]),&(m_Val[i][m_Cols]));
00570                         }
00571 
00572                 }; // end of class CMatrixTemplate
00573 
00574 
00575         } // End of namespace
00576 } // End of namespace
00577 
00578 
00579 #endif



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011