Mat_meat.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2009 NICTA
00002 // 
00003 // Authors:
00004 // - Conrad Sanderson (conradsand at ieee dot org)
00005 // 
00006 // This file is part of the Armadillo C++ library.
00007 // It is provided without any warranty of fitness
00008 // for any purpose. You can redistribute this file
00009 // and/or modify it under the terms of the GNU
00010 // Lesser General Public License (LGPL) as published
00011 // by the Free Software Foundation, either version 3
00012 // of the License or (at your option) any later version.
00013 // (see http://www.opensource.org/licenses for more info)
00014 
00015 
00016 //! \addtogroup Mat
00017 //! @{
00018 
00019 
00020 template<typename eT>
00021 inline
00022 Mat<eT>::~Mat()
00023   {
00024   arma_extra_debug_sigprint_this(this);
00025   
00026   if(n_elem > sizeof(mem_local)/sizeof(eT) )
00027     {
00028     delete [] mem;
00029     }
00030     
00031   if(arma_config::debug == true)
00032     {
00033     // try to expose buggy user code that accesses deleted objects
00034     access::rw(n_rows) = 0;
00035     access::rw(n_cols) = 0;
00036     access::rw(n_elem) = 0;
00037     access::rw(mem)    = 0;
00038     }
00039   
00040   isnt_supported_elem_type<eT>::check();
00041   }
00042 
00043 
00044 
00045 template<typename eT>
00046 inline
00047 Mat<eT>::Mat()
00048   : n_rows(0)
00049   , n_cols(0)
00050   , n_elem(0)
00051   //, mem(0)
00052   , mem(mem)
00053   {
00054   arma_extra_debug_sigprint_this(this);
00055   }
00056 
00057 
00058 //! construct the matrix to have user specified dimensions
00059 template<typename eT>
00060 inline
00061 Mat<eT>::Mat(const u32 in_n_rows, const u32 in_n_cols)
00062   : n_rows(0)
00063   , n_cols(0)
00064   , n_elem(0)
00065   //, mem(0)
00066   , mem(mem)
00067   {
00068   arma_extra_debug_sigprint_this(this);
00069   
00070   init(in_n_rows, in_n_cols);
00071   }
00072 
00073 
00074 
00075 //! change the matrix to have user specified dimensions (data is not preserved)
00076 template<typename eT>
00077 inline
00078 void
00079 Mat<eT>::set_size(const u32 in_n_rows, const u32 in_n_cols)
00080   {
00081   arma_extra_debug_sigprint(arma_boost::format("in_n_rows = %d, in_n_cols = %d") % in_n_rows % in_n_cols);
00082   
00083   init(in_n_rows,in_n_cols);
00084   }
00085 
00086 
00087 //! internal matrix construction; if the requested size is small enough, memory from the stack is used. otherwise memory is allocated via 'new'
00088 template<typename eT>
00089 inline
00090 void
00091 Mat<eT>::init(const u32 in_n_rows, const u32 in_n_cols)
00092   {
00093   arma_extra_debug_sigprint( arma_boost::format("in_n_rows = %d, in_n_cols = %d") % in_n_rows % in_n_cols );
00094   
00095   
00096   const u32 new_n_elem = in_n_rows * in_n_cols;
00097 
00098   if(n_elem == new_n_elem)
00099     {
00100     access::rw(n_rows) = in_n_rows;
00101     access::rw(n_cols) = in_n_cols;
00102     }
00103   else
00104     {
00105     
00106     if(n_elem > sizeof(mem_local)/sizeof(eT) )
00107       {
00108       delete [] mem;
00109       }
00110     
00111     if(new_n_elem <= sizeof(mem_local)/sizeof(eT) )
00112       {
00113       access::rw(mem) = mem_local;
00114       }
00115     else
00116       {
00117       access::rw(mem) = new(std::nothrow) eT[new_n_elem];
00118       arma_check( (mem == 0), "Mat::init(): out of memory" );
00119       }
00120     
00121     access::rw(n_elem) = new_n_elem;
00122 
00123     if(new_n_elem == 0)
00124       {
00125       access::rw(n_rows) = 0;
00126       access::rw(n_cols) = 0;
00127       }
00128     else
00129       {
00130       access::rw(n_rows) = in_n_rows;
00131       access::rw(n_cols) = in_n_cols;
00132       }
00133     
00134     }
00135   
00136   }
00137 
00138 
00139 //! create the matrix from a textual description
00140 template<typename eT>
00141 inline
00142 Mat<eT>::Mat(const char* text)
00143   : n_rows(0)
00144   , n_cols(0)
00145   , n_elem(0)
00146   //, mem(0)
00147   , mem(mem)
00148   {
00149   arma_extra_debug_sigprint_this(this);
00150   
00151   init( std::string(text) );
00152   }
00153   
00154   
00155   
00156 //! create the matrix from a textual description
00157 template<typename eT>
00158 inline
00159 const Mat<eT>&
00160 Mat<eT>::operator=(const char* text)
00161   {
00162   arma_extra_debug_sigprint();
00163   
00164   init( std::string(text) );
00165   return *this;
00166   }
00167   
00168   
00169 
00170 //! create the matrix from a textual description
00171 template<typename eT>
00172 inline
00173 Mat<eT>::Mat(const std::string& text)
00174   : n_rows(0)
00175   , n_cols(0)
00176   , n_elem(0)
00177   //, mem(0)
00178   , mem(mem)
00179   {
00180   arma_extra_debug_sigprint_this(this);
00181   
00182   init(text);
00183   }
00184   
00185   
00186   
00187 //! create the matrix from a textual description
00188 template<typename eT>
00189 inline
00190 const Mat<eT>&
00191 Mat<eT>::operator=(const std::string& text)
00192   {
00193   arma_extra_debug_sigprint();
00194   
00195   init(text);
00196   return *this;
00197   }
00198 
00199 
00200 
00201 //! internal function to create the matrix from a textual description
00202 template<typename eT>
00203 inline 
00204 void
00205 Mat<eT>::init(const std::string& text)
00206   {
00207   arma_extra_debug_sigprint();
00208   
00209   //
00210   // work out the size
00211   
00212   u32 t_n_rows = 0;
00213   u32 t_n_cols = 0;
00214   
00215   bool t_n_cols_found = false;
00216   
00217   std::string token;
00218   
00219   std::string::size_type line_start = 0;
00220   std::string::size_type   line_end = 0;
00221   
00222   while( line_start < text.length() )
00223     {
00224     
00225     line_end = text.find(';', line_start);
00226     
00227     if(line_end == std::string::npos)
00228       line_end = text.length()-1;
00229     
00230     std::string::size_type line_len = line_end - line_start + 1;
00231     std::stringstream line_stream( text.substr(line_start,line_len) );
00232     
00233     
00234     u32 line_n_cols = 0;
00235     while(line_stream >> token)
00236       {
00237       ++line_n_cols;
00238       }
00239     
00240     
00241     if(line_n_cols > 0)
00242       {
00243       if(t_n_cols_found == false)
00244         {
00245         t_n_cols = line_n_cols;
00246         t_n_cols_found = true;
00247         }
00248       else
00249         arma_check( (line_n_cols != t_n_cols), "Mat::init(): inconsistent number of columns in given string");
00250       
00251       ++t_n_rows;
00252       }
00253     line_start = line_end+1;
00254     
00255     }
00256     
00257   Mat<eT> &x = *this;
00258   x.set_size(t_n_rows, t_n_cols);
00259   
00260   line_start = 0;
00261   line_end = 0;
00262   
00263   u32 row = 0;
00264   
00265   while( line_start < text.length() )
00266     {
00267     
00268     line_end = text.find(';', line_start);
00269     
00270     if(line_end == std::string::npos)
00271       line_end = text.length()-1;
00272     
00273     std::string::size_type line_len = line_end - line_start + 1;
00274     std::stringstream line_stream( text.substr(line_start,line_len) );
00275     
00276 //     u32 col = 0;
00277 //     while(line_stream >> token)
00278 //       {
00279 //       x.at(row,col) = strtod(token.c_str(), 0);
00280 //       ++col;
00281 //       }
00282     
00283     u32 col = 0;
00284     eT val;
00285     while(line_stream >> val)
00286       {
00287       x.at(row,col) = val;
00288       ++col;
00289       }
00290     
00291     ++row;
00292     line_start = line_end+1;
00293     }
00294   
00295   }
00296 
00297 
00298 
00299 //! Set the matrix to be equal to the specified scalar.
00300 //! NOTE: the size of the matrix will be 1x1
00301 template<typename eT>
00302 arma_inline
00303 const Mat<eT>&
00304 Mat<eT>::operator=(const eT val)
00305   {
00306   arma_extra_debug_sigprint();
00307   
00308   init(1,1);
00309   access::rw(mem[0]) = val;
00310   return *this;
00311   }
00312 
00313 
00314 
00315 //! In-place addition of a scalar to all elements of the matrix
00316 template<typename eT>
00317 arma_inline
00318 const Mat<eT>&
00319 Mat<eT>::operator+=(const eT val)
00320   {
00321   arma_extra_debug_sigprint();
00322   
00323   for(u32 i=0; i<n_elem; ++i)
00324     {
00325     access::rw(mem[i]) += val;
00326     }
00327   
00328   return *this;
00329   }
00330 
00331 
00332 
00333 //! In-place subtraction of a scalar from all elements of the matrix
00334 template<typename eT>
00335 arma_inline
00336 const Mat<eT>&
00337 Mat<eT>::operator-=(const eT val)
00338   {
00339   arma_extra_debug_sigprint();
00340   
00341   for(u32 i=0; i<n_elem; ++i)
00342     {
00343     access::rw(mem[i]) -= val;
00344     }
00345       
00346   return *this;
00347   }
00348 
00349 
00350 
00351 //! In-place multiplication of all elements of the matrix with a scalar
00352 template<typename eT>
00353 arma_inline
00354 const Mat<eT>&
00355 Mat<eT>::operator*=(const eT val)
00356   {
00357   arma_extra_debug_sigprint();
00358   
00359   for(u32 i=0; i<n_elem; ++i)
00360     {
00361     access::rw(mem[i]) *= val;
00362     }
00363   
00364   return *this;
00365   }
00366 
00367 
00368 
00369 //! In-place division of all elements of the matrix with a scalar
00370 template<typename eT>
00371 arma_inline
00372 const Mat<eT>&
00373 Mat<eT>::operator/=(const eT val)
00374   {
00375   arma_extra_debug_sigprint();
00376   
00377   for(u32 i=0; i<n_elem; ++i)
00378     {
00379     access::rw(mem[i]) /= val;
00380     }
00381   
00382   return *this;
00383   }
00384 
00385 
00386 
00387 //! construct a matrix from a given matrix
00388 template<typename eT>
00389 inline
00390 Mat<eT>::Mat(const Mat<eT> &in_mat)
00391   : n_rows(0)
00392   , n_cols(0)
00393   , n_elem(0)
00394   //, mem(0)
00395   , mem(mem)
00396   {
00397   arma_extra_debug_sigprint(arma_boost::format("this = %x   in_mat = %x") % this % &in_mat);
00398   
00399   init(in_mat);
00400   }
00401 
00402 
00403 
00404 //! construct a matrix from a given matrix
00405 template<typename eT>
00406 inline
00407 const Mat<eT>&
00408 Mat<eT>::operator=(const Mat<eT>& x)
00409   {
00410   arma_extra_debug_sigprint();
00411   
00412   init(x);
00413   return *this;
00414   }
00415 
00416 
00417 
00418 //! construct a matrix from a given matrix
00419 template<typename eT>
00420 inline
00421 void
00422 Mat<eT>::init(const Mat<eT> &x)
00423   {
00424   arma_extra_debug_sigprint();
00425   
00426   if(this != &x)
00427     {
00428     init(x.n_rows, x.n_cols);
00429     syslib::copy_elem( memptr(), x.mem, n_elem );
00430     }
00431   }
00432 
00433 
00434 
00435 //! construct a matrix from a given auxillary array of eTs
00436 template<typename eT>
00437 inline
00438 Mat<eT>::Mat(const eT* aux_mem, const u32 aux_n_rows, const u32 aux_n_cols)
00439   : n_rows(0)
00440   , n_cols(0)
00441   , n_elem(0)
00442   //, mem(0)
00443   , mem(mem)
00444   {
00445   arma_extra_debug_sigprint_this(this);
00446   
00447   init(aux_n_rows, aux_n_cols);
00448   syslib::copy_elem( memptr(), aux_mem, n_elem );
00449   }
00450 
00451 
00452 
00453 //! in-place matrix addition
00454 template<typename eT>
00455 inline
00456 const Mat<eT>&
00457 Mat<eT>::operator+=(const Mat<eT>& m)
00458   {
00459   arma_extra_debug_sigprint();
00460   
00461   glue_plus::apply_inplace(*this, m);
00462   return *this;
00463   }
00464 
00465 
00466 
00467 //! in-place matrix subtraction
00468 template<typename eT>
00469 inline
00470 const Mat<eT>&
00471 Mat<eT>::operator-=(const Mat<eT>& m)
00472   {
00473   arma_extra_debug_sigprint();
00474   
00475   glue_minus::apply_inplace(*this, m);
00476   return *this;
00477   }
00478 
00479 
00480 
00481 //! in-place matrix multiplication
00482 template<typename eT>
00483 inline
00484 const Mat<eT>&
00485 Mat<eT>::operator*=(const Mat<eT>& m)
00486   {
00487   arma_extra_debug_sigprint();
00488   
00489   glue_times::apply_inplace(*this, m);
00490   return *this;
00491   }
00492 
00493 
00494 
00495 //! in-place element-wise matrix multiplication
00496 template<typename eT>
00497 inline
00498 const Mat<eT>&
00499 Mat<eT>::operator%=(const Mat<eT>& m)
00500   {
00501   arma_extra_debug_sigprint();
00502   
00503   glue_schur::apply_inplace(*this, m);
00504   return *this;
00505   }
00506 
00507 
00508 
00509 //! in-place element-wise matrix division
00510 template<typename eT>
00511 inline
00512 const Mat<eT>&
00513 Mat<eT>::operator/=(const Mat<eT>& m)
00514   {
00515   arma_extra_debug_sigprint();
00516   
00517   glue_div::apply_inplace(*this, m);
00518   return *this;
00519   }
00520 
00521 
00522 
00523 //! for constructing a complex matrix out of two non-complex matrices
00524 template<typename eT>
00525 template<typename T1, typename T2>
00526 inline
00527 Mat<eT>::Mat
00528   (
00529   const Base<typename Mat<eT>::pod_type,T1>& A,
00530   const Base<typename Mat<eT>::pod_type,T2>& B
00531   )
00532   : n_rows(0)
00533   , n_cols(0)
00534   , n_elem(0)
00535   //, mem(0)
00536   , mem(mem)
00537   {
00538   arma_extra_debug_sigprint_this(this);
00539   
00540   arma_type_check< is_complex<eT>::value == false >::apply();   //!< compile-time abort if eT isn't std::complex
00541   
00542   typedef typename T1::elem_type T;
00543   arma_type_check< is_complex<T>::value == true >::apply();   //!< compile-time abort if T is std::complex
00544   
00545   isnt_same_type<std::complex<T>, eT>::check();   //!< compile-time abort if types are not compatible
00546   
00547   const unwrap<T1> tmp_A(A.get_ref());
00548   const unwrap<T2> tmp_B(B.get_ref());
00549   
00550   const Mat<T>& X = tmp_A.M;
00551   const Mat<T>& Y = tmp_B.M;
00552   
00553   arma_assert_same_size(X, Y, "Mat()");
00554   
00555   init(X.n_rows, Y.n_cols);
00556   
00557   const T* X_mem = X.mem;
00558   const T* Y_mem = Y.mem;
00559   
00560   for(u32 i=0; i<n_elem; ++i)
00561     {
00562     access::rw(mem[i]) = std::complex<T>(X_mem[i], Y_mem[i]);
00563     }
00564   }
00565 
00566 
00567 
00568 //! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation)
00569 template<typename eT>
00570 inline
00571 Mat<eT>::Mat(const subview<eT>& X)
00572   : n_rows(0)
00573   , n_cols(0)
00574   , n_elem(0)
00575   //, mem(0)
00576   , mem(mem)
00577   {
00578   arma_extra_debug_sigprint_this(this);
00579   
00580   this->operator=(X);
00581   }
00582 
00583 
00584 
00585 //! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation)
00586 template<typename eT>
00587 inline
00588 const Mat<eT>&
00589 Mat<eT>::operator=(const subview<eT>& X)
00590   {
00591   arma_extra_debug_sigprint();
00592   
00593   subview<eT>::extract(*this, X);
00594   return *this;
00595   }
00596 
00597 
00598 //! in-place matrix addition (using a submatrix on the right-hand-side)
00599 template<typename eT>
00600 inline
00601 const Mat<eT>&
00602 Mat<eT>::operator+=(const subview<eT>& X)
00603   {
00604   arma_extra_debug_sigprint();
00605   
00606   subview<eT>::plus_inplace(*this, X);
00607   return *this;
00608   }
00609 
00610 
00611 //! in-place matrix subtraction (using a submatrix on the right-hand-side)
00612 template<typename eT>
00613 inline
00614 const Mat<eT>&
00615 Mat<eT>::operator-=(const subview<eT>& X)
00616   {
00617   arma_extra_debug_sigprint();
00618   
00619   subview<eT>::minus_inplace(*this, X);
00620   return *this;
00621   }
00622 
00623 
00624 
00625 //! in-place matrix mutiplication (using a submatrix on the right-hand-side)
00626 template<typename eT>
00627 inline
00628 const Mat<eT>&
00629 Mat<eT>::operator*=(const subview<eT>& X)
00630   {
00631   arma_extra_debug_sigprint();
00632   
00633   subview<eT>::times_inplace(*this, X);
00634   return *this;
00635   }
00636 
00637 
00638 
00639 //! in-place element-wise matrix mutiplication (using a submatrix on the right-hand-side)
00640 template<typename eT>
00641 inline
00642 const Mat<eT>&
00643 Mat<eT>::operator%=(const subview<eT>& X)
00644   {
00645   arma_extra_debug_sigprint();
00646   
00647   subview<eT>::schur_inplace(*this, X);
00648   return *this;
00649   }
00650 
00651 
00652 
00653 //! in-place element-wise matrix division (using a submatrix on the right-hand-side)
00654 template<typename eT>
00655 inline
00656 const Mat<eT>&
00657 Mat<eT>::operator/=(const subview<eT>& X)
00658   {
00659   arma_extra_debug_sigprint();
00660   
00661   subview<eT>::div_inplace(*this, X);
00662   return *this;
00663   }
00664 
00665 
00666 
00667 //! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation)
00668 template<typename eT>
00669 inline
00670 Mat<eT>::Mat(const diagview<eT>& X)
00671   : n_rows(0)
00672   , n_cols(0)
00673   , n_elem(0)
00674   //, mem(0)
00675   , mem(mem)
00676   {
00677   arma_extra_debug_sigprint_this(this);
00678   
00679   this->operator=(X);
00680   }
00681 
00682 
00683 
00684 //! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation)
00685 template<typename eT>
00686 inline
00687 const Mat<eT>&
00688 Mat<eT>::operator=(const diagview<eT>& X)
00689   {
00690   arma_extra_debug_sigprint();
00691   
00692   diagview<eT>::extract(*this, X);
00693   return *this;
00694   }
00695 
00696 
00697 
00698 //! creation of subview (row vector)
00699 template<typename eT>
00700 arma_inline
00701 subview_row<eT>
00702 Mat<eT>::row(const u32 row_num)
00703   {
00704   arma_extra_debug_sigprint();
00705   
00706   arma_debug_check( row_num >= n_rows, "Mat::row(): row out of bounds" );
00707   
00708   return subview_row<eT>(*this, row_num);
00709   }
00710 
00711 
00712 
00713 //! creation of subview (row vector)
00714 template<typename eT>
00715 arma_inline
00716 const subview_row<eT>
00717 Mat<eT>::row(const u32 row_num) const
00718   {
00719   arma_extra_debug_sigprint();
00720   
00721   arma_debug_check( row_num >= n_rows, "Mat::row(): row out of bounds" );
00722   
00723   return subview_row<eT>(*this, row_num);
00724   }
00725 
00726 
00727 
00728 //! creation of subview (column vector)
00729 template<typename eT>
00730 arma_inline
00731 subview_col<eT>
00732 Mat<eT>::col(const u32 col_num)
00733   {
00734   arma_extra_debug_sigprint();
00735   
00736   arma_debug_check( col_num >= n_cols, "Mat::col(): out of bounds");
00737   
00738   return subview_col<eT>(*this, col_num);
00739   }
00740 
00741 
00742 
00743 //! creation of subview (column vector)
00744 template<typename eT>
00745 arma_inline
00746 const subview_col<eT>
00747 Mat<eT>::col(const u32 col_num) const
00748   {
00749   arma_extra_debug_sigprint();
00750   
00751   arma_debug_check( col_num >= n_cols, "Mat::col(): out of bounds");
00752   
00753   return subview_col<eT>(*this, col_num);
00754   }
00755 
00756 
00757 
00758 //! creation of subview (submatrix comprised of specified row vectors)
00759 template<typename eT>
00760 arma_inline
00761 subview<eT>
00762 Mat<eT>::rows(const u32 in_row1, const u32 in_row2)
00763   {
00764   arma_extra_debug_sigprint();
00765   
00766   arma_debug_check
00767     (
00768     (in_row1 > in_row2) || (in_row2 >= n_rows),
00769     "Mat::rows(): indices out of bounds or incorrectly used"
00770     );
00771   
00772   return subview<eT>(*this, in_row1, 0, in_row2, n_cols-1);
00773   }
00774 
00775 
00776 
00777 //! creation of subview (submatrix comprised of specified row vectors)
00778 template<typename eT>
00779 arma_inline
00780 const subview<eT>
00781 Mat<eT>::rows(const u32 in_row1, const u32 in_row2) const
00782   {
00783   arma_extra_debug_sigprint();
00784   
00785   arma_debug_check
00786     (
00787     (in_row1 > in_row2) || (in_row2 >= n_rows),
00788     "Mat::rows(): indices out of bounds or incorrectly used"
00789     );
00790   
00791   return subview<eT>(*this, in_row1, 0, in_row2, n_cols-1);
00792   }
00793 
00794 
00795 
00796 //! creation of subview (submatrix comprised of specified column vectors)
00797 template<typename eT>
00798 arma_inline
00799 subview<eT>
00800 Mat<eT>::cols(const u32 in_col1, const u32 in_col2)
00801   {
00802   arma_extra_debug_sigprint();
00803   
00804   arma_debug_check
00805     (
00806     (in_col1 > in_col2) || (in_col2 >= n_cols),
00807     "Mat::cols(): indices out of bounds or incorrectly used"
00808     );
00809   
00810   return subview<eT>(*this, 0, in_col1, n_rows-1, in_col2);
00811   }
00812 
00813 
00814 
00815 //! creation of subview (submatrix comprised of specified column vectors)
00816 template<typename eT>
00817 arma_inline
00818 const subview<eT>
00819 Mat<eT>::cols(const u32 in_col1, const u32 in_col2) const
00820   {
00821   arma_extra_debug_sigprint();
00822   
00823   arma_debug_check
00824     (
00825     (in_col1 > in_col2) || (in_col2 >= n_cols),
00826     "Mat::cols(): indices out of bounds or incorrectly used"
00827     );
00828   
00829   return subview<eT>(*this, 0, in_col1, n_rows-1, in_col2);
00830   }
00831 
00832 
00833 
00834 //! creation of subview (submatrix)
00835 template<typename eT>
00836 arma_inline
00837 subview<eT>
00838 Mat<eT>::submat(const u32 in_row1, const u32 in_col1, const u32 in_row2, const u32 in_col2)
00839   {
00840   arma_extra_debug_sigprint();
00841   
00842   arma_debug_check
00843     (
00844     (in_row1 > in_row2) || (in_col1 >  in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
00845     "Mat::submat(): indices out of bounds or incorrectly used"
00846     );
00847   
00848   return subview<eT>(*this, in_row1, in_col1, in_row2, in_col2);
00849   }
00850 
00851 
00852 
00853 //! creation of subview (generic submatrix)
00854 template<typename eT>
00855 arma_inline
00856 const subview<eT>
00857 Mat<eT>::submat(const u32 in_row1, const u32 in_col1, const u32 in_row2, const u32 in_col2) const
00858   {
00859   arma_extra_debug_sigprint();
00860   
00861   arma_debug_check
00862     (
00863     (in_row1 > in_row2) || (in_col1 >  in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
00864     "Mat::submat(): indices out of bounds or incorrectly used"
00865     );
00866     
00867   return subview<eT>(*this, in_row1, in_col1, in_row2, in_col2);
00868   }
00869 
00870 
00871 
00872 //! creation of diagview (diagonal)
00873 template<typename eT>
00874 arma_inline
00875 diagview<eT>
00876 Mat<eT>::diag(const s32 in_id)
00877   {
00878   arma_extra_debug_sigprint();
00879   
00880   const u32 row_offset = (in_id < 0) ? -in_id : 0;
00881   const u32 col_offset = (in_id > 0) ?  in_id : 0;
00882   
00883   arma_debug_check
00884     (
00885     (row_offset >= n_rows) || (col_offset >= n_cols),
00886     "Mat::diag(): out of bounds"
00887     );
00888   
00889   const u32 len = (std::min)(n_rows - row_offset, n_cols - col_offset);
00890   
00891   return diagview<eT>(*this, row_offset, col_offset, len);
00892   }
00893 
00894 
00895 
00896 //! creation of diagview (diagonal)
00897 template<typename eT>
00898 arma_inline
00899 const diagview<eT>
00900 Mat<eT>::diag(const s32 in_id) const
00901   {
00902   arma_extra_debug_sigprint();
00903   
00904   const u32 row_offset = (in_id < 0) ? -in_id : 0;
00905   const u32 col_offset = (in_id > 0) ?  in_id : 0;
00906   
00907   arma_debug_check
00908     (
00909     (row_offset >= n_rows) || (col_offset >= n_cols),
00910     "Mat::diag(): out of bounds"
00911     );
00912   
00913   
00914   const u32 len = (std::min)(n_rows - row_offset, n_cols - col_offset);
00915   
00916   return diagview<eT>(*this, row_offset, col_offset, len);
00917   }
00918 
00919 
00920 
00921 template<typename eT>
00922 inline
00923 void
00924 Mat<eT>::swap_rows(const u32 in_row1, const u32 in_row2)
00925   {
00926   arma_extra_debug_sigprint();
00927   
00928   arma_debug_check
00929     (
00930     (in_row1 >= n_rows) || (in_row2 >= n_rows),
00931     "Mat::swap_rows(): out of bounds"
00932     );
00933   
00934   for(u32 col=0; col<n_cols; ++col)
00935     {
00936     const u32 offset = col*n_rows;
00937     const u32 pos1   = in_row1 + offset;
00938     const u32 pos2   = in_row2 + offset;
00939     
00940     const eT tmp          = mem[pos1];
00941     access::rw(mem[pos1]) = mem[pos2];
00942     access::rw(mem[pos2]) = tmp;
00943     }
00944   
00945   }
00946 
00947 
00948 
00949 template<typename eT>
00950 inline
00951 void
00952 Mat<eT>::swap_cols(const u32 in_col1, const u32 in_col2)
00953   {
00954   arma_extra_debug_sigprint();
00955   
00956   arma_debug_check
00957     (
00958     (in_col1 >= n_cols) || (in_col2 >= n_cols),
00959     "Mat::swap_cols(): out of bounds"
00960     );
00961   
00962   eT* ptr1 = colptr(in_col1);
00963   eT* ptr2 = colptr(in_col2);
00964   
00965   for(u32 row=0; row<n_rows; ++row)
00966     {
00967     const eT tmp = ptr1[row];
00968     ptr1[row]    = ptr2[row];
00969     ptr2[row]    = tmp;
00970     }
00971   
00972   }
00973 
00974 
00975 
00976 //! create a matrix from Op, i.e. run the previously delayed unary operations
00977 template<typename eT>
00978 template<typename T1, typename op_type>
00979 inline
00980 Mat<eT>::Mat(const Op<T1, op_type>& X)
00981   : n_rows(0)
00982   , n_cols(0)
00983   , n_elem(0)
00984   //, mem(0)
00985   , mem(mem)
00986   {
00987   arma_extra_debug_sigprint_this(this);
00988 
00989   isnt_same_type<eT, typename T1::elem_type>::check();
00990   
00991   op_type::apply(*this, X);
00992   }
00993 
00994 
00995 
00996 //! create a matrix from Op, i.e. run the previously delayed unary operations
00997 template<typename eT>
00998 template<typename T1, typename op_type>
00999 inline
01000 const Mat<eT>&
01001 Mat<eT>::operator=(const Op<T1, op_type>& X)
01002   {
01003   arma_extra_debug_sigprint();
01004 
01005   isnt_same_type<eT, typename T1::elem_type>::check();
01006   
01007   op_type::apply(*this, X);
01008   
01009   return *this;
01010   }
01011 
01012 
01013 
01014 //! in-place matrix addition, with the right-hand-side operand having delayed operations
01015 template<typename eT>
01016 template<typename T1, typename op_type>
01017 inline
01018 const Mat<eT>&
01019 Mat<eT>::operator+=(const Op<T1, op_type>& X)
01020   {
01021   arma_extra_debug_sigprint();
01022   
01023   isnt_same_type<eT, typename T1::elem_type>::check();
01024   
01025   glue_plus::apply_inplace(*this, X);
01026   
01027   return *this;
01028   }
01029 
01030 
01031 
01032 //! in-place matrix subtraction, with the right-hand-side operand having delayed operations
01033 template<typename eT>
01034 template<typename T1, typename op_type>
01035 inline
01036 const Mat<eT>&
01037 Mat<eT>::operator-=(const Op<T1, op_type>& X)
01038   {
01039   arma_extra_debug_sigprint();
01040   
01041   isnt_same_type<eT, typename T1::elem_type>::check();
01042   
01043   glue_minus::apply_inplace(*this, X);
01044   
01045   return *this;
01046   }
01047 
01048 
01049 
01050 //! in-place matrix multiplication, with the right-hand-side operand having delayed operations
01051 template<typename eT>
01052 template<typename T1, typename op_type>
01053 inline
01054 const Mat<eT>&
01055 Mat<eT>::operator*=(const Op<T1, op_type>& X)
01056   {
01057   arma_extra_debug_sigprint();
01058   
01059   isnt_same_type<eT, typename T1::elem_type>::check();
01060   
01061   glue_times::apply_inplace(*this, X);
01062   
01063   return *this;
01064   }
01065 
01066 
01067 
01068 //! in-place matrix element-wise multiplication, with the right-hand-side operand having delayed operations
01069 template<typename eT>
01070 template<typename T1, typename op_type>
01071 inline
01072 const Mat<eT>&
01073 Mat<eT>::operator%=(const Op<T1, op_type>& X)
01074   {
01075   arma_extra_debug_sigprint();
01076   
01077   isnt_same_type<eT, typename T1::elem_type>::check();
01078   glue_schur::apply_inplace(*this, X);
01079   
01080   return *this;
01081   }
01082 
01083 
01084 
01085 //! in-place matrix element-wise division, with the right-hand-side operand having delayed operations
01086 template<typename eT>
01087 template<typename T1, typename op_type>
01088 inline
01089 const Mat<eT>&
01090 Mat<eT>::operator/=(const Op<T1, op_type>& X)
01091   {
01092   arma_extra_debug_sigprint();
01093   
01094   isnt_same_type<eT, typename T1::elem_type>::check();
01095   glue_div::apply_inplace(*this, X);
01096   
01097   return *this;
01098   }
01099 
01100 
01101 
01102 //! create a matrix from Glue, i.e. run the previously delayed binary operations
01103 template<typename eT>
01104 template<typename T1, typename T2, typename glue_type>
01105 inline
01106 Mat<eT>::Mat(const Glue<T1, T2, glue_type>& X)
01107   : n_rows(0)
01108   , n_cols(0)
01109   , n_elem(0)
01110   //, mem(0)
01111   , mem(mem)
01112   {
01113   arma_extra_debug_sigprint_this(this);
01114   this->operator=(X);
01115   }
01116 
01117 
01118 
01119 //! create a matrix from Glue, i.e. run the previously delayed binary operations
01120 template<typename eT>
01121 template<typename T1, typename T2, typename glue_type>
01122 inline
01123 const Mat<eT>&
01124 Mat<eT>::operator=(const Glue<T1, T2, glue_type>& X)
01125   {
01126   arma_extra_debug_sigprint();
01127   
01128   // TODO:
01129   // it may be simpler to pass the two objects (currently wrapped in X)
01130   // directly to the apply function.
01131   // (many adjustments throughout the source code will be required)
01132   
01133   isnt_same_type<eT, typename T1::elem_type>::check();
01134   isnt_same_type<eT, typename T2::elem_type>::check();
01135   
01136   glue_type::apply(*this, X);
01137   
01138   return *this;
01139   }
01140 
01141 
01142 //! in-place matrix addition, with the right-hand-side operands having delayed operations
01143 template<typename eT>
01144 template<typename T1, typename T2, typename glue_type>
01145 inline
01146 const Mat<eT>&
01147 Mat<eT>::operator+=(const Glue<T1, T2, glue_type>& X)
01148   {
01149   arma_extra_debug_sigprint();
01150   
01151   isnt_same_type<eT, typename T1::elem_type>::check();
01152   isnt_same_type<eT, typename T2::elem_type>::check();
01153   
01154   glue_plus::apply_inplace(*this, X);
01155   
01156   return *this;
01157   }
01158 
01159 
01160 
01161 //! in-place matrix subtraction, with the right-hand-side operands having delayed operations
01162 template<typename eT>
01163 template<typename T1, typename T2, typename glue_type>
01164 inline
01165 const Mat<eT>&
01166 Mat<eT>::operator-=(const Glue<T1, T2, glue_type>& X)
01167   {
01168   arma_extra_debug_sigprint();
01169   
01170   isnt_same_type<eT, typename T1::elem_type>::check();
01171   isnt_same_type<eT, typename T2::elem_type>::check();
01172   
01173   glue_minus::apply_inplace(*this, X);
01174   
01175   return *this;
01176   }
01177 
01178 
01179 
01180 //! in-place matrix multiplications, with the right-hand-side operands having delayed operations
01181 template<typename eT>
01182 template<typename T1, typename T2, typename glue_type>
01183 inline
01184 const Mat<eT>&
01185 Mat<eT>::operator*=(const Glue<T1, T2, glue_type>& X)
01186   {
01187   arma_extra_debug_sigprint();
01188   
01189   isnt_same_type<eT, typename T1::elem_type>::check();
01190   isnt_same_type<eT, typename T2::elem_type>::check();
01191   
01192   glue_times::apply_inplace(*this, X);
01193   return *this;
01194   }
01195 
01196 
01197 
01198 //! in-place matrix element-wise multiplication, with the right-hand-side operands having delayed operations
01199 template<typename eT>
01200 template<typename T1, typename T2, typename glue_type>
01201 inline
01202 const Mat<eT>&
01203 Mat<eT>::operator%=(const Glue<T1, T2, glue_type>& X)
01204   {
01205   arma_extra_debug_sigprint();
01206   
01207   isnt_same_type<eT, typename T1::elem_type>::check();
01208   isnt_same_type<eT, typename T2::elem_type>::check();
01209   
01210   glue_schur::apply_inplace(*this, X);
01211   return *this;
01212   }
01213 
01214 
01215 
01216 //! in-place matrix element-wise division, with the right-hand-side operands having delayed operations
01217 template<typename eT>
01218 template<typename T1, typename T2, typename glue_type>
01219 inline
01220 const Mat<eT>&
01221 Mat<eT>::operator/=(const Glue<T1, T2, glue_type>& X)
01222   {
01223   arma_extra_debug_sigprint();
01224   
01225   isnt_same_type<eT, typename T1::elem_type>::check();
01226   isnt_same_type<eT, typename T2::elem_type>::check();
01227   
01228   glue_div::apply_inplace(*this, X);
01229   return *this;
01230   }
01231 
01232 
01233 
01234 //! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
01235 template<typename eT>
01236 arma_inline
01237 eT&
01238 Mat<eT>::operator() (const u32 i)
01239   {
01240   arma_debug_check( (i >= n_elem), "Mat::operator(): index out of bounds");
01241   return access::rw(mem[i]);
01242   }
01243 
01244 
01245 
01246 //! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
01247 template<typename eT>
01248 arma_inline
01249 eT
01250 Mat<eT>::operator() (const u32 i) const
01251   {
01252   arma_debug_check( (i >= n_elem), "Mat::operator(): index out of bounds");
01253   return mem[i];
01254   }
01255 
01256 
01257 //! linear element accessor (treats the matrix as a vector); no bounds check.  
01258 template<typename eT>
01259 arma_inline
01260 eT&
01261 Mat<eT>::operator[] (const u32 i)
01262   {
01263   return access::rw(mem[i]);
01264   }
01265 
01266 
01267 
01268 //! linear element accessor (treats the matrix as a vector); no bounds check
01269 template<typename eT>
01270 arma_inline
01271 eT
01272 Mat<eT>::operator[] (const u32 i) const
01273   {
01274   return mem[i];
01275   }
01276 
01277 
01278 
01279 //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
01280 template<typename eT>
01281 arma_inline
01282 eT&
01283 Mat<eT>::operator() (const u32 in_row, const u32 in_col)
01284   {
01285   arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): index out of bounds");
01286   return access::rw(mem[in_row + in_col*n_rows]);
01287   }
01288 
01289 
01290 
01291 //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
01292 template<typename eT>
01293 arma_inline
01294 eT
01295 Mat<eT>::operator() (const u32 in_row, const u32 in_col) const
01296   {
01297   arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): index out of bounds");
01298   return mem[in_row + in_col*n_rows];
01299   }
01300 
01301 
01302 
01303 //! element accessor; no bounds check
01304 template<typename eT>
01305 arma_inline
01306 eT&
01307 Mat<eT>::at(const u32 in_row, const u32 in_col)
01308   {
01309   return access::rw( mem[in_row + in_col*n_rows] );
01310   }
01311 
01312 
01313 
01314 //! element accessor; no bounds check
01315 template<typename eT>
01316 arma_inline
01317 eT
01318 Mat<eT>::at(const u32 in_row, const u32 in_col) const
01319   {
01320   return mem[in_row + in_col*n_rows];
01321   }
01322 
01323 
01324 
01325 //! prefix ++
01326 template<typename eT>
01327 arma_inline
01328 const Mat<eT>&
01329 Mat<eT>::operator++()
01330   {
01331   Mat_aux::prefix_pp(*this);
01332   return *this;
01333   }
01334 
01335 
01336 
01337 //! postfix ++  (must not return the object by reference)
01338 template<typename eT>
01339 arma_inline
01340 void
01341 Mat<eT>::operator++(int)
01342   {
01343   Mat_aux::postfix_pp(*this);
01344   }
01345 
01346 
01347 
01348 //! prefix --
01349 template<typename eT>
01350 arma_inline
01351 const Mat<eT>&
01352 Mat<eT>::operator--()
01353   {
01354   Mat_aux::prefix_mm(*this);
01355   return *this;
01356   }
01357 
01358 
01359 
01360 //! postfix --  (must not return the object by reference)
01361 template<typename eT>
01362 arma_inline
01363 void
01364 Mat<eT>::operator--(int)
01365   {
01366   Mat_aux::postfix_mm(*this);
01367   }
01368 
01369 
01370 
01371 //! returns true if the object can be interpreted as a column or row vector
01372 template<typename eT>
01373 arma_inline
01374 bool
01375 Mat<eT>::is_vec() const
01376   {
01377   return ( (n_rows == 1) || (n_cols == 1) );
01378   }
01379 
01380 
01381 
01382 //! returns true if the object has the same number of non-zero rows and columnns
01383 template<typename eT>
01384 arma_inline
01385 bool
01386 Mat<eT>::is_square() const
01387   {
01388   return ( (n_rows == n_cols) && (n_elem > 0) );
01389   }
01390 
01391 
01392 
01393 //! returns true if all of the elements are finite
01394 template<typename eT>
01395 arma_inline
01396 bool
01397 Mat<eT>::is_finite() const
01398   {
01399   for(u32 i=0; i<n_elem; ++i)
01400     {
01401     if(arma_isfinite(mem[i]) == false)
01402       {
01403       return false;
01404       }
01405     }
01406 
01407   return true;
01408   }
01409 
01410 
01411 
01412 //! returns a pointer to array of eTs for a specified column; no bounds check
01413 template<typename eT>
01414 arma_inline
01415 eT*
01416 Mat<eT>::colptr(const u32 in_col)
01417   {
01418   return & access::rw(mem[in_col*n_rows]);
01419   }
01420 
01421 
01422 
01423 //! returns a pointer to array of eTs for a specified column; no bounds check
01424 template<typename eT>
01425 arma_inline
01426 const eT*
01427 Mat<eT>::colptr(const u32 in_col) const
01428   {
01429   return & mem[in_col*n_rows];
01430   }
01431 
01432 
01433 
01434 //! returns a pointer to array of eTs used by the matrix
01435 template<typename eT>
01436 arma_inline
01437 eT*
01438 Mat<eT>::memptr()
01439   {
01440   return const_cast<eT*>(mem);
01441   }
01442 
01443 
01444 
01445 //! returns a pointer to array of eTs used by the matrix
01446 template<typename eT>
01447 arma_inline
01448 const eT*
01449 Mat<eT>::memptr() const
01450   {
01451   return mem;
01452   }
01453 
01454 
01455 
01456 //! print contents of the matrix (to the cout stream),
01457 //! optionally preceding with a user specified line of text.
01458 //! the precision and cell width are modified.
01459 //! on return, the stream's flags are restored to their original values.
01460 template<typename eT>
01461 inline
01462 void
01463 Mat<eT>::print(const std::string extra_text) const
01464   {
01465   arma_extra_debug_sigprint();
01466   
01467   if(extra_text.length() != 0)
01468     {
01469     cout << extra_text << '\n';
01470     }
01471   
01472   arma_ostream::print(cout, *this, true);
01473   }
01474 
01475 
01476 //! print contents of the matrix to a user specified stream,
01477 //! optionally preceding with a user specified line of text.
01478 //! the precision and cell width are modified.
01479 //! on return, the stream's flags are restored to their original values.
01480 template<typename eT>
01481 inline
01482 void
01483 Mat<eT>::print(std::ostream& user_stream, const std::string extra_text) const
01484   {
01485   arma_extra_debug_sigprint();
01486   
01487   if(extra_text.length() != 0)
01488     {
01489     user_stream << extra_text << '\n';
01490     }
01491   
01492   arma_ostream::print(user_stream, *this, true);
01493   }
01494 
01495 
01496 
01497 //! print contents of the matrix (to the cout stream),
01498 //! optionally preceding with a user specified line of text.
01499 //! the stream's flags are used as is and are not modified
01500 //! (i.e. the precision and cell width are not modified).
01501 template<typename eT>
01502 inline
01503 void
01504 Mat<eT>::raw_print(const std::string extra_text) const
01505   {
01506   arma_extra_debug_sigprint();
01507   
01508   if(extra_text.length() != 0)
01509     {
01510     cout << extra_text << '\n';
01511     }
01512   
01513   arma_ostream::print(cout, *this, false);
01514   }
01515 
01516 
01517 
01518 //! print contents of the matrix to a user specified stream,
01519 //! optionally preceding with a user specified line of text.
01520 //! the stream's flags are used as is and are not modified.
01521 //! (i.e. the precision and cell width are not modified).
01522 template<typename eT>
01523 inline
01524 void
01525 Mat<eT>::raw_print(std::ostream& user_stream, const std::string extra_text) const
01526   {
01527   arma_extra_debug_sigprint();
01528   
01529   if(extra_text.length() != 0)
01530     {
01531     user_stream << extra_text << '\n';
01532     }
01533   
01534   arma_ostream::print(user_stream, *this, false);
01535   }
01536 
01537 
01538 
01539 //! fill the matrix with the specified value
01540 template<typename eT>
01541 inline
01542 void
01543 Mat<eT>::fill(const eT val)
01544   {
01545   arma_extra_debug_sigprint();
01546   
01547   for(u32 i=0; i<n_elem; ++i)
01548     {
01549     access::rw(mem[i]) = val;
01550     }
01551   }
01552 
01553 
01554 
01555 template<typename eT>
01556 inline
01557 void
01558 Mat<eT>::zeros()
01559   {
01560   arma_extra_debug_sigprint();
01561   
01562   fill(eT(0));
01563   }
01564 
01565 
01566 
01567 template<typename eT>
01568 inline
01569 void
01570 Mat<eT>::zeros(const u32 in_rows, const u32 in_cols)
01571   {
01572   arma_extra_debug_sigprint( arma_boost::format("in_rows = %d, in_cols = %d") % in_rows % in_cols );
01573 
01574   set_size(in_rows, in_cols);
01575   fill(eT(0));
01576   }
01577 
01578 
01579 
01580 template<typename eT>
01581 inline
01582 void
01583 Mat<eT>::reset()
01584   {
01585   arma_extra_debug_sigprint();
01586   
01587   init(0,0);
01588   }
01589 
01590 
01591 
01592 //! save the matrix to a file
01593 template<typename eT>
01594 inline
01595 void
01596 Mat<eT>::save(const std::string name, const file_type type) const
01597   {
01598   arma_extra_debug_sigprint();
01599   
01600   switch(type)
01601     {
01602     case raw_ascii:
01603       diskio::save_raw_ascii(*this, name);
01604       break;
01605     
01606     case arma_ascii:
01607       diskio::save_arma_ascii(*this, name);
01608       break;
01609     
01610     case arma_binary:
01611       diskio::save_arma_binary(*this, name);
01612       break;
01613       
01614     case pgm_binary:
01615       diskio::save_pgm_binary(*this, name);
01616       break;
01617     
01618     default:
01619       arma_stop("Mat::save(): unsupported type");
01620     }
01621   
01622   }
01623 
01624 
01625 
01626 //! load a matrix from a file
01627 template<typename eT>
01628 inline
01629 void
01630 Mat<eT>::load(const std::string name, const file_type type)
01631   {
01632   arma_extra_debug_sigprint();
01633   
01634   switch(type)
01635     {
01636     case auto_detect:
01637       diskio::load_auto_detect(*this, name);
01638       break;
01639     
01640     case raw_ascii:
01641       diskio::load_raw_ascii(*this, name);
01642       break;
01643     
01644     case arma_ascii:
01645       diskio::load_arma_ascii(*this, name);
01646       break;
01647     
01648     case arma_binary:
01649       diskio::load_arma_binary(*this, name);
01650       break;
01651       
01652     case pgm_binary:
01653       diskio::load_pgm_binary(*this, name);
01654       break;
01655     
01656     default:
01657       arma_stop("Mat::load(): unsupported type");
01658     }
01659   
01660   }
01661 
01662 
01663 
01664 //! prefix ++
01665 template<typename eT>
01666 arma_inline
01667 void
01668 Mat_aux::prefix_pp(Mat<eT>& x)
01669   {
01670         eT* memptr = x.memptr();
01671   const u32 n_elem = x.n_elem;
01672 
01673   for(u32 i=0; i<n_elem; ++i)
01674     {
01675     ++(memptr[i]);
01676     }
01677   }
01678 
01679 
01680 
01681 //! prefix ++ for complex numbers (work around for limitations of the std::complex class)
01682 template<typename T>
01683 arma_inline
01684 void
01685 Mat_aux::prefix_pp(Mat< std::complex<T> >& x)
01686   {
01687   x += T(1);
01688   }
01689 
01690 
01691 
01692 //! postfix ++
01693 template<typename eT>
01694 arma_inline
01695 void
01696 Mat_aux::postfix_pp(Mat<eT>& x)
01697   {
01698         eT* memptr = x.memptr();
01699   const u32 n_elem = x.n_elem;
01700 
01701   for(u32 i=0; i<n_elem; ++i)
01702     {
01703     (memptr[i])++;
01704     }
01705   }
01706 
01707 
01708 
01709 //! postfix ++ for complex numbers (work around for limitations of the std::complex class)
01710 template<typename T>
01711 arma_inline
01712 void
01713 Mat_aux::postfix_pp(Mat< std::complex<T> >& x)
01714   {
01715   x += T(1);
01716   }
01717 
01718 
01719 
01720 //! prefix --
01721 template<typename eT>
01722 arma_inline
01723 void
01724 Mat_aux::prefix_mm(Mat<eT>& x)
01725   {
01726         eT* memptr = x.memptr();
01727   const u32 n_elem = x.n_elem;
01728 
01729   for(u32 i=0; i<n_elem; ++i)
01730     {
01731     --(memptr[i]);
01732     }
01733   }
01734 
01735 
01736 
01737 //! prefix -- for complex numbers (work around for limitations of the std::complex class)
01738 template<typename T>
01739 arma_inline
01740 void
01741 Mat_aux::prefix_mm(Mat< std::complex<T> >& x)
01742   {
01743   x -= T(1);
01744   }
01745 
01746 
01747 
01748 //! postfix --
01749 template<typename eT>
01750 arma_inline
01751 void
01752 Mat_aux::postfix_mm(Mat<eT>& x)
01753   {
01754         eT* memptr = x.memptr();
01755   const u32 n_elem = x.n_elem;
01756 
01757   for(u32 i=0; i<n_elem; ++i)
01758     {
01759     (memptr[i])--;
01760     }
01761   }
01762 
01763 
01764 
01765 //! postfix ++ for complex numbers (work around for limitations of the std::complex class)
01766 template<typename T>
01767 arma_inline
01768 void
01769 Mat_aux::postfix_mm(Mat< std::complex<T> >& x)
01770   {
01771   x -= T(1);
01772   }
01773 
01774 
01775 
01776 //! @}