Mat_meat.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2010 NICTA and the authors listed below
00002 // http://nicta.com.au
00003 // 
00004 // Authors:
00005 // - Conrad Sanderson (conradsand at ieee dot org)
00006 // 
00007 // This file is part of the Armadillo C++ library.
00008 // It is provided without any warranty of fitness
00009 // for any purpose. You can redistribute this file
00010 // and/or modify it under the terms of the GNU
00011 // Lesser General Public License (LGPL) as published
00012 // by the Free Software Foundation, either version 3
00013 // of the License or (at your option) any later version.
00014 // (see http://www.opensource.org/licenses for more info)
00015 
00016 
00017 //! \addtogroup Mat
00018 //! @{
00019 
00020 
00021 template<typename eT>
00022 inline
00023 Mat<eT>::~Mat()
00024   {
00025   arma_extra_debug_sigprint_this(this);
00026   
00027   if(use_aux_mem == false)
00028     {
00029     if(n_elem > sizeof(mem_local)/sizeof(eT) )
00030       {
00031       delete [] mem;
00032       }
00033     }
00034     
00035   if(arma_config::debug == true)
00036     {
00037     // try to expose buggy user code that accesses deleted objects
00038     access::rw(n_rows) = 0;
00039     access::rw(n_cols) = 0;
00040     access::rw(n_elem) = 0;
00041     access::rw(mem)    = 0;
00042     }
00043   
00044   isnt_supported_elem_type<eT>::check();
00045   }
00046 
00047 
00048 
00049 template<typename eT>
00050 inline
00051 Mat<eT>::Mat()
00052   : n_rows(0)
00053   , n_cols(0)
00054   , n_elem(0)
00055   , use_aux_mem(false)
00056   //, mem(0)
00057   , mem(mem)
00058   {
00059   arma_extra_debug_sigprint_this(this);
00060   }
00061 
00062 
00063 //! construct the matrix to have user specified dimensions
00064 template<typename eT>
00065 inline
00066 Mat<eT>::Mat(const u32 in_n_rows, const u32 in_n_cols)
00067   : n_rows(0)
00068   , n_cols(0)
00069   , n_elem(0)
00070   , use_aux_mem(false)
00071   //, mem(0)
00072   , mem(mem)
00073   {
00074   arma_extra_debug_sigprint_this(this);
00075   
00076   init(in_n_rows, in_n_cols);
00077   }
00078 
00079 
00080 
00081 //! internal matrix construction; if the requested size is small enough, memory from the stack is used. otherwise memory is allocated via 'new'
00082 template<typename eT>
00083 inline
00084 void
00085 Mat<eT>::init(const u32 in_n_rows, const u32 in_n_cols)
00086   {
00087   arma_extra_debug_sigprint( arma_boost::format("in_n_rows = %d, in_n_cols = %d") % in_n_rows % in_n_cols );
00088   
00089   const u32 new_n_elem = in_n_rows * in_n_cols;
00090 
00091   if(n_elem == new_n_elem)
00092     {
00093     access::rw(n_rows) = in_n_rows;
00094     access::rw(n_cols) = in_n_cols;
00095     }
00096   else
00097     {
00098     arma_debug_check
00099       (
00100       (use_aux_mem == true),
00101       "Mat::init(): can't change the amount of memory as auxiliary memory is in use"
00102       );
00103 
00104     if(n_elem > sizeof(mem_local)/sizeof(eT) )
00105       {
00106       delete [] mem;
00107       }
00108     
00109     if(new_n_elem <= sizeof(mem_local)/sizeof(eT) )
00110       {
00111       access::rw(mem) = mem_local;
00112       }
00113     else
00114       {
00115       access::rw(mem) = new(std::nothrow) eT[new_n_elem];
00116       arma_check( (mem == 0), "Mat::init(): out of memory" );
00117       }
00118     
00119     access::rw(n_elem) = new_n_elem;
00120 
00121     if(new_n_elem == 0)
00122       {
00123       access::rw(n_rows) = 0;
00124       access::rw(n_cols) = 0;
00125       }
00126     else
00127       {
00128       access::rw(n_rows) = in_n_rows;
00129       access::rw(n_cols) = in_n_cols;
00130       }
00131     
00132     }
00133   }
00134 
00135 
00136 //! create the matrix from a textual description
00137 template<typename eT>
00138 inline
00139 Mat<eT>::Mat(const char* text)
00140   : n_rows(0)
00141   , n_cols(0)
00142   , n_elem(0)
00143   , use_aux_mem(false)
00144   //, mem(0)
00145   , mem(mem)
00146   {
00147   arma_extra_debug_sigprint_this(this);
00148   
00149   init( std::string(text) );
00150   }
00151   
00152   
00153   
00154 //! create the matrix from a textual description
00155 template<typename eT>
00156 inline
00157 const Mat<eT>&
00158 Mat<eT>::operator=(const char* text)
00159   {
00160   arma_extra_debug_sigprint();
00161   
00162   init( std::string(text) );
00163   return *this;
00164   }
00165   
00166   
00167 
00168 //! create the matrix from a textual description
00169 template<typename eT>
00170 inline
00171 Mat<eT>::Mat(const std::string& text)
00172   : n_rows(0)
00173   , n_cols(0)
00174   , n_elem(0)
00175   , use_aux_mem(false)
00176   //, mem(0)
00177   , mem(mem)
00178   {
00179   arma_extra_debug_sigprint_this(this);
00180   
00181   init(text);
00182   }
00183   
00184   
00185   
00186 //! create the matrix from a textual description
00187 template<typename eT>
00188 inline
00189 const Mat<eT>&
00190 Mat<eT>::operator=(const std::string& text)
00191   {
00192   arma_extra_debug_sigprint();
00193   
00194   init(text);
00195   return *this;
00196   }
00197 
00198 
00199 
00200 //! internal function to create the matrix from a textual description
00201 template<typename eT>
00202 inline 
00203 void
00204 Mat<eT>::init(const std::string& text)
00205   {
00206   arma_extra_debug_sigprint();
00207   
00208   //
00209   // work out the size
00210   
00211   u32 t_n_rows = 0;
00212   u32 t_n_cols = 0;
00213   
00214   bool t_n_cols_found = false;
00215   
00216   std::string token;
00217   
00218   std::string::size_type line_start = 0;
00219   std::string::size_type   line_end = 0;
00220   
00221   while( line_start < text.length() )
00222     {
00223     
00224     line_end = text.find(';', line_start);
00225     
00226     if(line_end == std::string::npos)
00227       line_end = text.length()-1;
00228     
00229     std::string::size_type line_len = line_end - line_start + 1;
00230     std::stringstream line_stream( text.substr(line_start,line_len) );
00231     
00232     
00233     u32 line_n_cols = 0;
00234     while(line_stream >> token)
00235       {
00236       ++line_n_cols;
00237       }
00238     
00239     
00240     if(line_n_cols > 0)
00241       {
00242       if(t_n_cols_found == false)
00243         {
00244         t_n_cols = line_n_cols;
00245         t_n_cols_found = true;
00246         }
00247       else
00248         arma_check( (line_n_cols != t_n_cols), "Mat::init(): inconsistent number of columns in given string");
00249       
00250       ++t_n_rows;
00251       }
00252     line_start = line_end+1;
00253     
00254     }
00255     
00256   Mat<eT>& x = *this;
00257   x.set_size(t_n_rows, t_n_cols);
00258   
00259   line_start = 0;
00260   line_end = 0;
00261   
00262   u32 row = 0;
00263   
00264   while( line_start < text.length() )
00265     {
00266     
00267     line_end = text.find(';', line_start);
00268     
00269     if(line_end == std::string::npos)
00270       line_end = text.length()-1;
00271     
00272     std::string::size_type line_len = line_end - line_start + 1;
00273     std::stringstream line_stream( text.substr(line_start,line_len) );
00274     
00275 //     u32 col = 0;
00276 //     while(line_stream >> token)
00277 //       {
00278 //       x.at(row,col) = strtod(token.c_str(), 0);
00279 //       ++col;
00280 //       }
00281     
00282     u32 col = 0;
00283     eT val;
00284     while(line_stream >> val)
00285       {
00286       x.at(row,col) = val;
00287       ++col;
00288       }
00289     
00290     ++row;
00291     line_start = line_end+1;
00292     }
00293   
00294   }
00295 
00296 
00297 
00298 //! Set the matrix to be equal to the specified scalar.
00299 //! NOTE: the size of the matrix will be 1x1
00300 template<typename eT>
00301 arma_inline
00302 const Mat<eT>&
00303 Mat<eT>::operator=(const eT val)
00304   {
00305   arma_extra_debug_sigprint();
00306   
00307   init(1,1);
00308   access::rw(mem[0]) = val;
00309   return *this;
00310   }
00311 
00312 
00313 
00314 //! In-place addition of a scalar to all elements of the matrix
00315 template<typename eT>
00316 arma_inline
00317 const Mat<eT>&
00318 Mat<eT>::operator+=(const eT val)
00319   {
00320   arma_extra_debug_sigprint();
00321   
00322         eT* local_ptr    = memptr();
00323   const u32 local_n_elem = n_elem;
00324     
00325   u32 i,j;
00326   
00327   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00328     {
00329     local_ptr[i] += val;
00330     local_ptr[j] += val;
00331     }
00332   
00333   if(i < local_n_elem)
00334     {
00335     local_ptr[i] += val;
00336     }
00337   
00338   return *this;
00339   }
00340 
00341 
00342 
00343 //! In-place subtraction of a scalar from all elements of the matrix
00344 template<typename eT>
00345 arma_inline
00346 const Mat<eT>&
00347 Mat<eT>::operator-=(const eT val)
00348   {
00349   arma_extra_debug_sigprint();
00350   
00351         eT* local_ptr    = memptr();
00352   const u32 local_n_elem = n_elem;
00353     
00354   u32 i,j;
00355   
00356   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00357     {
00358     local_ptr[i] -= val;
00359     local_ptr[j] -= val;
00360     }
00361   
00362   if(i < local_n_elem)
00363     {
00364     local_ptr[i] -= val;
00365     }
00366   
00367   return *this;
00368   }
00369 
00370 
00371 
00372 //! In-place multiplication of all elements of the matrix with a scalar
00373 template<typename eT>
00374 arma_inline
00375 const Mat<eT>&
00376 Mat<eT>::operator*=(const eT val)
00377   {
00378   arma_extra_debug_sigprint();
00379   
00380         eT* local_ptr    = memptr();
00381   const u32 local_n_elem = n_elem;
00382     
00383   u32 i,j;
00384   
00385   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00386     {
00387     local_ptr[i] *= val;
00388     local_ptr[j] *= val;
00389     }
00390   
00391   if(i < local_n_elem)
00392     {
00393     local_ptr[i] *= val;
00394     }
00395   
00396   return *this;
00397   }
00398 
00399 
00400 
00401 //! In-place division of all elements of the matrix with a scalar
00402 template<typename eT>
00403 arma_inline
00404 const Mat<eT>&
00405 Mat<eT>::operator/=(const eT val)
00406   {
00407   arma_extra_debug_sigprint();
00408   
00409         eT* local_ptr    = memptr();
00410   const u32 local_n_elem = n_elem;
00411     
00412   u32 i,j;
00413   
00414   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00415     {
00416     local_ptr[i] /= val;
00417     local_ptr[j] /= val;
00418     }
00419   
00420   if(i < local_n_elem)
00421     {
00422     local_ptr[i] /= val;
00423     }
00424   
00425   return *this;
00426   }
00427 
00428 
00429 
00430 //! construct a matrix from a given matrix
00431 template<typename eT>
00432 inline
00433 Mat<eT>::Mat(const Mat<eT>& in_mat)
00434   : n_rows(0)
00435   , n_cols(0)
00436   , n_elem(0)
00437   , use_aux_mem(false)
00438   //, mem(0)
00439   , mem(mem)
00440   {
00441   arma_extra_debug_sigprint(arma_boost::format("this = %x   in_mat = %x") % this % &in_mat);
00442   
00443   init(in_mat);
00444   }
00445 
00446 
00447 
00448 //! construct a matrix from a given matrix
00449 template<typename eT>
00450 inline
00451 const Mat<eT>&
00452 Mat<eT>::operator=(const Mat<eT>& x)
00453   {
00454   arma_extra_debug_sigprint();
00455   
00456   init(x);
00457   return *this;
00458   }
00459 
00460 
00461 
00462 //! construct a matrix from a given matrix
00463 template<typename eT>
00464 inline
00465 void
00466 Mat<eT>::init(const Mat<eT>& x)
00467   {
00468   arma_extra_debug_sigprint();
00469   
00470   if(this != &x)
00471     {
00472     init(x.n_rows, x.n_cols);
00473     syslib::copy_elem( memptr(), x.mem, n_elem );
00474     }
00475   }
00476 
00477 
00478 
00479 //! construct a matrix from a given auxiliary array of eTs.
00480 //! if copy_aux_mem is true, new memory is allocated and the array is copied.
00481 //! if copy_aux_mem is false, the auxiliary array is used directly (without allocating memory and copying).
00482 //! the default is to copy the array.
00483 
00484 template<typename eT>
00485 inline
00486 Mat<eT>::Mat(eT* aux_mem, const u32 aux_n_rows, const u32 aux_n_cols, const bool copy_aux_mem)
00487   : n_rows     (copy_aux_mem ? 0     : aux_n_rows           )
00488   , n_cols     (copy_aux_mem ? 0     : aux_n_cols           )
00489   , n_elem     (copy_aux_mem ? 0     : aux_n_rows*aux_n_cols)
00490   , use_aux_mem(copy_aux_mem ? false : true                 )
00491   , mem        (copy_aux_mem ? mem   : aux_mem              )
00492   {
00493   arma_extra_debug_sigprint_this(this);
00494   
00495   if(copy_aux_mem == true)
00496     {
00497     init(aux_n_rows, aux_n_cols);
00498     syslib::copy_elem( memptr(), aux_mem, n_elem );
00499     }
00500   }
00501 
00502 
00503 
00504 //! construct a matrix from a given auxiliary read-only array of eTs.
00505 //! the array is copied.
00506 template<typename eT>
00507 inline
00508 Mat<eT>::Mat(const eT* aux_mem, const u32 aux_n_rows, const u32 aux_n_cols)
00509   : n_rows(0)
00510   , n_cols(0)
00511   , n_elem(0)
00512   , use_aux_mem(false)
00513   //, mem(0)
00514   , mem(mem)
00515   {
00516   arma_extra_debug_sigprint_this(this);
00517   
00518   init(aux_n_rows, aux_n_cols);
00519   syslib::copy_elem( memptr(), aux_mem, n_elem );
00520   }
00521 
00522 
00523 
00524 //! DANGEROUS! Construct a temporary matrix, using auxiliary memory.
00525 //! This constructor is NOT intended for usage by user code.
00526 //! Its sole purpose is to be used by the Cube class.
00527 
00528 template<typename eT>
00529 inline
00530 Mat<eT>::Mat(const char junk, const eT* aux_mem, const u32 aux_n_rows, const u32 aux_n_cols)
00531   : n_rows     (aux_n_rows           )
00532   , n_cols     (aux_n_cols           )
00533   , n_elem     (aux_n_rows*aux_n_cols)
00534   , use_aux_mem(true                 )
00535   , mem        (aux_mem              )
00536   {
00537   arma_extra_debug_sigprint_this(this);
00538   }
00539 
00540 
00541 
00542 //! in-place matrix addition
00543 template<typename eT>
00544 inline
00545 const Mat<eT>&
00546 Mat<eT>::operator+=(const Mat<eT>& m)
00547   {
00548   arma_extra_debug_sigprint();
00549   
00550   arma_debug_assert_same_size(*this, m, "matrix addition");
00551   
00552   const u32 local_n_elem = m.n_elem;
00553   
00554         eT* out_mem = (*this).memptr();
00555   const eT* m_mem   = m.memptr();
00556   
00557   u32 i,j;
00558   
00559   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00560     {
00561     out_mem[i] += m_mem[i];
00562     out_mem[j] += m_mem[j];
00563     }
00564   
00565   if(i < local_n_elem)
00566     {
00567     out_mem[i] += m_mem[i];
00568     }
00569   
00570   return *this;
00571   }
00572 
00573 
00574 
00575 //! in-place matrix subtraction
00576 template<typename eT>
00577 inline
00578 const Mat<eT>&
00579 Mat<eT>::operator-=(const Mat<eT>& m)
00580   {
00581   arma_extra_debug_sigprint();
00582   
00583   arma_debug_assert_same_size(*this, m, "matrix subtraction");
00584   
00585   const u32 local_n_elem = m.n_elem;
00586   
00587         eT* out_mem = (*this).memptr();
00588   const eT* m_mem   = m.memptr();
00589   
00590   u32 i,j;
00591   
00592   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00593     {
00594     out_mem[i] -= m_mem[i];
00595     out_mem[j] -= m_mem[j];
00596     }
00597   
00598   if(i < local_n_elem)
00599     {
00600     out_mem[i] -= m_mem[i];
00601     }
00602   
00603   return *this;
00604   }
00605 
00606 
00607 
00608 //! in-place matrix multiplication
00609 template<typename eT>
00610 inline
00611 const Mat<eT>&
00612 Mat<eT>::operator*=(const Mat<eT>& m)
00613   {
00614   arma_extra_debug_sigprint();
00615   
00616   glue_times::apply_inplace(*this, m);
00617   return *this;
00618   }
00619 
00620 
00621 
00622 //! in-place element-wise matrix multiplication
00623 template<typename eT>
00624 inline
00625 const Mat<eT>&
00626 Mat<eT>::operator%=(const Mat<eT>& m)
00627   {
00628   arma_extra_debug_sigprint();
00629   
00630   arma_debug_assert_same_size(*this, m, "element-wise matrix multplication");
00631   
00632   const u32 local_n_elem = m.n_elem;
00633   
00634         eT* out_mem = (*this).memptr();
00635   const eT* m_mem   = m.memptr();
00636   
00637   u32 i,j;
00638   
00639   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00640     {
00641     out_mem[i] *= m_mem[i];
00642     out_mem[j] *= m_mem[j];
00643     }
00644   
00645   if(i < local_n_elem)
00646     {
00647     out_mem[i] *= m_mem[i];
00648     }
00649   
00650   return *this;
00651   }
00652 
00653 
00654 
00655 //! in-place element-wise matrix division
00656 template<typename eT>
00657 inline
00658 const Mat<eT>&
00659 Mat<eT>::operator/=(const Mat<eT>& m)
00660   {
00661   arma_extra_debug_sigprint();
00662   
00663   arma_debug_assert_same_size(*this, m, "element-wise matrix division");
00664   
00665   const u32 local_n_elem = m.n_elem;
00666   
00667         eT* out_mem = (*this).memptr();
00668   const eT* m_mem   = m.memptr();
00669   
00670   u32 i,j;
00671   
00672   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00673     {
00674     out_mem[i] /= m_mem[i];
00675     out_mem[j] /= m_mem[j];
00676     }
00677   
00678   if(i < local_n_elem)
00679     {
00680     out_mem[i] /= m_mem[i];
00681     }
00682   
00683   return *this;
00684   }
00685 
00686 
00687 
00688 //! for constructing a complex matrix out of two non-complex matrices
00689 template<typename eT>
00690 template<typename T1, typename T2>
00691 inline
00692 Mat<eT>::Mat
00693   (
00694   const Base<typename Mat<eT>::pod_type,T1>& A,
00695   const Base<typename Mat<eT>::pod_type,T2>& B
00696   )
00697   : n_rows(0)
00698   , n_cols(0)
00699   , n_elem(0)
00700   , use_aux_mem(false)
00701   //, mem(0)
00702   , mem(mem)
00703   {
00704   arma_extra_debug_sigprint_this(this);
00705   
00706   arma_type_check< is_complex<eT>::value == false >::apply();   //!< compile-time abort if eT isn't std::complex
00707   
00708   typedef typename T1::elem_type T;
00709   arma_type_check< is_complex<T>::value == true >::apply();   //!< compile-time abort if T is std::complex
00710   
00711   isnt_same_type<std::complex<T>, eT>::check();   //!< compile-time abort if types are not compatible
00712   
00713   const unwrap<T1> tmp_A(A.get_ref());
00714   const unwrap<T2> tmp_B(B.get_ref());
00715   
00716   const Mat<T>& X = tmp_A.M;
00717   const Mat<T>& Y = tmp_B.M;
00718   
00719   arma_assert_same_size(X, Y, "Mat()");
00720   
00721   init(X.n_rows, Y.n_cols);
00722   
00723   const T* X_mem = X.mem;
00724   const T* Y_mem = Y.mem;
00725   
00726   for(u32 i=0; i<n_elem; ++i)
00727     {
00728     access::rw(mem[i]) = std::complex<T>(X_mem[i], Y_mem[i]);
00729     }
00730   }
00731 
00732 
00733 
00734 //! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation)
00735 template<typename eT>
00736 inline
00737 Mat<eT>::Mat(const subview<eT>& X)
00738   : n_rows(0)
00739   , n_cols(0)
00740   , n_elem(0)
00741   , use_aux_mem(false)
00742   //, mem(0)
00743   , mem(mem)
00744   {
00745   arma_extra_debug_sigprint_this(this);
00746   
00747   this->operator=(X);
00748   }
00749 
00750 
00751 
00752 //! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation)
00753 template<typename eT>
00754 inline
00755 const Mat<eT>&
00756 Mat<eT>::operator=(const subview<eT>& X)
00757   {
00758   arma_extra_debug_sigprint();
00759   
00760   subview<eT>::extract(*this, X);
00761   return *this;
00762   }
00763 
00764 
00765 //! in-place matrix addition (using a submatrix on the right-hand-side)
00766 template<typename eT>
00767 inline
00768 const Mat<eT>&
00769 Mat<eT>::operator+=(const subview<eT>& X)
00770   {
00771   arma_extra_debug_sigprint();
00772   
00773   subview<eT>::plus_inplace(*this, X);
00774   return *this;
00775   }
00776 
00777 
00778 //! in-place matrix subtraction (using a submatrix on the right-hand-side)
00779 template<typename eT>
00780 inline
00781 const Mat<eT>&
00782 Mat<eT>::operator-=(const subview<eT>& X)
00783   {
00784   arma_extra_debug_sigprint();
00785   
00786   subview<eT>::minus_inplace(*this, X);
00787   return *this;
00788   }
00789 
00790 
00791 
00792 //! in-place matrix mutiplication (using a submatrix on the right-hand-side)
00793 template<typename eT>
00794 inline
00795 const Mat<eT>&
00796 Mat<eT>::operator*=(const subview<eT>& X)
00797   {
00798   arma_extra_debug_sigprint();
00799   
00800   glue_times::apply_inplace(*this, X);
00801   return *this;
00802   }
00803 
00804 
00805 
00806 //! in-place element-wise matrix mutiplication (using a submatrix on the right-hand-side)
00807 template<typename eT>
00808 inline
00809 const Mat<eT>&
00810 Mat<eT>::operator%=(const subview<eT>& X)
00811   {
00812   arma_extra_debug_sigprint();
00813   
00814   subview<eT>::schur_inplace(*this, X);
00815   return *this;
00816   }
00817 
00818 
00819 
00820 //! in-place element-wise matrix division (using a submatrix on the right-hand-side)
00821 template<typename eT>
00822 inline
00823 const Mat<eT>&
00824 Mat<eT>::operator/=(const subview<eT>& X)
00825   {
00826   arma_extra_debug_sigprint();
00827   
00828   subview<eT>::div_inplace(*this, X);
00829   return *this;
00830   }
00831 
00832 
00833 
00834 //! construct a matrix from a subview_cube instance
00835 template<typename eT>
00836 inline
00837 Mat<eT>::Mat(const subview_cube<eT>& x)
00838   : n_rows(0)
00839   , n_cols(0)
00840   , n_elem(0)
00841   , use_aux_mem(false)
00842   //, mem(0)
00843   , mem(mem)
00844   {
00845   arma_extra_debug_sigprint_this(this);
00846   
00847   this->operator=(x);
00848   }
00849 
00850 
00851 
00852 //! construct a matrix from a subview_cube instance
00853 template<typename eT>
00854 inline
00855 const Mat<eT>&
00856 Mat<eT>::operator=(const subview_cube<eT>& X)
00857   {
00858   arma_extra_debug_sigprint();
00859   
00860   subview_cube<eT>::extract(*this, X);
00861   return *this;
00862   }
00863 
00864 
00865 
00866 //! in-place matrix addition (using a single-slice subcube on the right-hand-side)
00867 template<typename eT>
00868 inline
00869 const Mat<eT>&
00870 Mat<eT>::operator+=(const subview_cube<eT>& X)
00871   {
00872   arma_extra_debug_sigprint();
00873 
00874   subview_cube<eT>::plus_inplace(*this, X);
00875   return *this;
00876   }
00877 
00878 
00879 
00880 //! in-place matrix subtraction (using a single-slice subcube on the right-hand-side)
00881 template<typename eT>
00882 inline
00883 const Mat<eT>&
00884 Mat<eT>::operator-=(const subview_cube<eT>& X)
00885   {
00886   arma_extra_debug_sigprint();
00887   
00888   subview_cube<eT>::minus_inplace(*this, X);
00889   return *this;
00890   }
00891 
00892 
00893 
00894 //! in-place matrix mutiplication (using a single-slice subcube on the right-hand-side)
00895 template<typename eT>
00896 inline
00897 const Mat<eT>&
00898 Mat<eT>::operator*=(const subview_cube<eT>& X)
00899   {
00900   arma_extra_debug_sigprint();
00901 
00902   const Mat<eT> tmp(X);
00903   glue_times::apply_inplace(*this, tmp);
00904   return *this;
00905   }
00906 
00907 
00908 
00909 //! in-place element-wise matrix mutiplication (using a single-slice subcube on the right-hand-side)
00910 template<typename eT>
00911 inline
00912 const Mat<eT>&
00913 Mat<eT>::operator%=(const subview_cube<eT>& X)
00914   {
00915   arma_extra_debug_sigprint();
00916   
00917   subview_cube<eT>::schur_inplace(*this, X);
00918   return *this;
00919   }
00920 
00921 
00922 
00923 //! in-place element-wise matrix division (using a single-slice subcube on the right-hand-side)
00924 template<typename eT>
00925 inline
00926 const Mat<eT>&
00927 Mat<eT>::operator/=(const subview_cube<eT>& X)
00928   {
00929   arma_extra_debug_sigprint();
00930   
00931   subview_cube<eT>::div_inplace(*this, X);
00932   return *this;
00933   }
00934 
00935 
00936 
00937 //! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation)
00938 template<typename eT>
00939 inline
00940 Mat<eT>::Mat(const diagview<eT>& X)
00941   : n_rows(0)
00942   , n_cols(0)
00943   , n_elem(0)
00944   , use_aux_mem(false)
00945   //, mem(0)
00946   , mem(mem)
00947   {
00948   arma_extra_debug_sigprint_this(this);
00949   
00950   this->operator=(X);
00951   }
00952 
00953 
00954 
00955 //! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation)
00956 template<typename eT>
00957 inline
00958 const Mat<eT>&
00959 Mat<eT>::operator=(const diagview<eT>& X)
00960   {
00961   arma_extra_debug_sigprint();
00962   
00963   diagview<eT>::extract(*this, X);
00964   return *this;
00965   }
00966 
00967 
00968 
00969 //! in-place matrix addition (using a diagview on the right-hand-side)
00970 template<typename eT>
00971 inline
00972 const Mat<eT>&
00973 Mat<eT>::operator+=(const diagview<eT>& X)
00974   {
00975   arma_extra_debug_sigprint();
00976   
00977   diagview<eT>::plus_inplace(*this, X);
00978   return *this;
00979   }
00980 
00981 
00982 //! in-place matrix subtraction (using a diagview on the right-hand-side)
00983 template<typename eT>
00984 inline
00985 const Mat<eT>&
00986 Mat<eT>::operator-=(const diagview<eT>& X)
00987   {
00988   arma_extra_debug_sigprint();
00989   
00990   diagview<eT>::minus_inplace(*this, X);
00991   return *this;
00992   }
00993 
00994 
00995 
00996 //! in-place matrix mutiplication (using a diagview on the right-hand-side)
00997 template<typename eT>
00998 inline
00999 const Mat<eT>&
01000 Mat<eT>::operator*=(const diagview<eT>& X)
01001   {
01002   arma_extra_debug_sigprint();
01003   
01004   glue_times::apply_inplace(*this, X);
01005   return *this;
01006   }
01007 
01008 
01009 
01010 //! in-place element-wise matrix mutiplication (using a diagview on the right-hand-side)
01011 template<typename eT>
01012 inline
01013 const Mat<eT>&
01014 Mat<eT>::operator%=(const diagview<eT>& X)
01015   {
01016   arma_extra_debug_sigprint();
01017   
01018   diagview<eT>::schur_inplace(*this, X);
01019   return *this;
01020   }
01021 
01022 
01023 
01024 //! in-place element-wise matrix division (using a diagview on the right-hand-side)
01025 template<typename eT>
01026 inline
01027 const Mat<eT>&
01028 Mat<eT>::operator/=(const diagview<eT>& X)
01029   {
01030   arma_extra_debug_sigprint();
01031   
01032   diagview<eT>::div_inplace(*this, X);
01033   return *this;
01034   }
01035 
01036 
01037 
01038 //! creation of subview (row vector)
01039 template<typename eT>
01040 arma_inline
01041 subview_row<eT>
01042 Mat<eT>::row(const u32 row_num)
01043   {
01044   arma_extra_debug_sigprint();
01045   
01046   arma_debug_check( row_num >= n_rows, "Mat::row(): row out of bounds" );
01047   
01048   return subview_row<eT>(*this, row_num);
01049   }
01050 
01051 
01052 
01053 //! creation of subview (row vector)
01054 template<typename eT>
01055 arma_inline
01056 const subview_row<eT>
01057 Mat<eT>::row(const u32 row_num) const
01058   {
01059   arma_extra_debug_sigprint();
01060   
01061   arma_debug_check( row_num >= n_rows, "Mat::row(): row out of bounds" );
01062   
01063   return subview_row<eT>(*this, row_num);
01064   }
01065 
01066 
01067 
01068 //! creation of subview (column vector)
01069 template<typename eT>
01070 arma_inline
01071 subview_col<eT>
01072 Mat<eT>::col(const u32 col_num)
01073   {
01074   arma_extra_debug_sigprint();
01075   
01076   arma_debug_check( col_num >= n_cols, "Mat::col(): out of bounds");
01077   
01078   return subview_col<eT>(*this, col_num);
01079   }
01080 
01081 
01082 
01083 //! creation of subview (column vector)
01084 template<typename eT>
01085 arma_inline
01086 const subview_col<eT>
01087 Mat<eT>::col(const u32 col_num) const
01088   {
01089   arma_extra_debug_sigprint();
01090   
01091   arma_debug_check( col_num >= n_cols, "Mat::col(): out of bounds");
01092   
01093   return subview_col<eT>(*this, col_num);
01094   }
01095 
01096 
01097 
01098 //! creation of subview (submatrix comprised of specified row vectors)
01099 template<typename eT>
01100 arma_inline
01101 subview<eT>
01102 Mat<eT>::rows(const u32 in_row1, const u32 in_row2)
01103   {
01104   arma_extra_debug_sigprint();
01105   
01106   arma_debug_check
01107     (
01108     (in_row1 > in_row2) || (in_row2 >= n_rows),
01109     "Mat::rows(): indices out of bounds or incorrectly used"
01110     );
01111   
01112   return subview<eT>(*this, in_row1, 0, in_row2, ((n_cols>0) ? n_cols-1 : 0) );
01113   }
01114 
01115 
01116 
01117 //! creation of subview (submatrix comprised of specified row vectors)
01118 template<typename eT>
01119 arma_inline
01120 const subview<eT>
01121 Mat<eT>::rows(const u32 in_row1, const u32 in_row2) const
01122   {
01123   arma_extra_debug_sigprint();
01124   
01125   arma_debug_check
01126     (
01127     (in_row1 > in_row2) || (in_row2 >= n_rows),
01128     "Mat::rows(): indices out of bounds or incorrectly used"
01129     );
01130   
01131   return subview<eT>(*this, in_row1, 0, in_row2, ((n_cols>0) ? n_cols-1 : 0) );
01132   }
01133 
01134 
01135 
01136 //! creation of subview (submatrix comprised of specified column vectors)
01137 template<typename eT>
01138 arma_inline
01139 subview<eT>
01140 Mat<eT>::cols(const u32 in_col1, const u32 in_col2)
01141   {
01142   arma_extra_debug_sigprint();
01143   
01144   arma_debug_check
01145     (
01146     (in_col1 > in_col2) || (in_col2 >= n_cols),
01147     "Mat::cols(): indices out of bounds or incorrectly used"
01148     );
01149   
01150   return subview<eT>(*this, 0, in_col1, ((n_rows>0) ? n_rows-1 : 0), in_col2);
01151   }
01152 
01153 
01154 
01155 //! creation of subview (submatrix comprised of specified column vectors)
01156 template<typename eT>
01157 arma_inline
01158 const subview<eT>
01159 Mat<eT>::cols(const u32 in_col1, const u32 in_col2) const
01160   {
01161   arma_extra_debug_sigprint();
01162   
01163   arma_debug_check
01164     (
01165     (in_col1 > in_col2) || (in_col2 >= n_cols),
01166     "Mat::cols(): indices out of bounds or incorrectly used"
01167     );
01168   
01169   return subview<eT>(*this, 0, in_col1, ((n_rows>0) ? n_rows-1 : 0), in_col2);
01170   }
01171 
01172 
01173 
01174 //! creation of subview (submatrix)
01175 template<typename eT>
01176 arma_inline
01177 subview<eT>
01178 Mat<eT>::submat(const u32 in_row1, const u32 in_col1, const u32 in_row2, const u32 in_col2)
01179   {
01180   arma_extra_debug_sigprint();
01181   
01182   arma_debug_check
01183     (
01184     (in_row1 > in_row2) || (in_col1 >  in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
01185     "Mat::submat(): indices out of bounds or incorrectly used"
01186     );
01187   
01188   return subview<eT>(*this, in_row1, in_col1, in_row2, in_col2);
01189   }
01190 
01191 
01192 
01193 //! creation of subview (generic submatrix)
01194 template<typename eT>
01195 arma_inline
01196 const subview<eT>
01197 Mat<eT>::submat(const u32 in_row1, const u32 in_col1, const u32 in_row2, const u32 in_col2) const
01198   {
01199   arma_extra_debug_sigprint();
01200   
01201   arma_debug_check
01202     (
01203     (in_row1 > in_row2) || (in_col1 >  in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
01204     "Mat::submat(): indices out of bounds or incorrectly used"
01205     );
01206     
01207   return subview<eT>(*this, in_row1, in_col1, in_row2, in_col2);
01208   }
01209 
01210 
01211 
01212 //! creation of diagview (diagonal)
01213 template<typename eT>
01214 arma_inline
01215 diagview<eT>
01216 Mat<eT>::diag(const s32 in_id)
01217   {
01218   arma_extra_debug_sigprint();
01219   
01220   const u32 row_offset = (in_id < 0) ? -in_id : 0;
01221   const u32 col_offset = (in_id > 0) ?  in_id : 0;
01222   
01223   arma_debug_check
01224     (
01225     (row_offset >= n_rows) || (col_offset >= n_cols),
01226     "Mat::diag(): requested diagonal out of bounds"
01227     );
01228   
01229   const u32 len = (std::min)(n_rows - row_offset, n_cols - col_offset);
01230   
01231   return diagview<eT>(*this, row_offset, col_offset, len);
01232   }
01233 
01234 
01235 
01236 //! creation of diagview (diagonal)
01237 template<typename eT>
01238 arma_inline
01239 const diagview<eT>
01240 Mat<eT>::diag(const s32 in_id) const
01241   {
01242   arma_extra_debug_sigprint();
01243   
01244   const u32 row_offset = (in_id < 0) ? -in_id : 0;
01245   const u32 col_offset = (in_id > 0) ?  in_id : 0;
01246   
01247   arma_debug_check
01248     (
01249     (row_offset >= n_rows) || (col_offset >= n_cols),
01250     "Mat::diag(): requested diagonal out of bounds"
01251     );
01252   
01253   
01254   const u32 len = (std::min)(n_rows - row_offset, n_cols - col_offset);
01255   
01256   return diagview<eT>(*this, row_offset, col_offset, len);
01257   }
01258 
01259 
01260 
01261 template<typename eT>
01262 inline
01263 void
01264 Mat<eT>::swap_rows(const u32 in_row1, const u32 in_row2)
01265   {
01266   arma_extra_debug_sigprint();
01267   
01268   arma_debug_check
01269     (
01270     (in_row1 >= n_rows) || (in_row2 >= n_rows),
01271     "Mat::swap_rows(): out of bounds"
01272     );
01273   
01274   for(u32 col=0; col<n_cols; ++col)
01275     {
01276     const u32 offset = col*n_rows;
01277     const u32 pos1   = in_row1 + offset;
01278     const u32 pos2   = in_row2 + offset;
01279     
01280     const eT tmp          = mem[pos1];
01281     access::rw(mem[pos1]) = mem[pos2];
01282     access::rw(mem[pos2]) = tmp;
01283     }
01284   
01285   }
01286 
01287 
01288 
01289 template<typename eT>
01290 inline
01291 void
01292 Mat<eT>::swap_cols(const u32 in_col1, const u32 in_col2)
01293   {
01294   arma_extra_debug_sigprint();
01295   
01296   arma_debug_check
01297     (
01298     (in_col1 >= n_cols) || (in_col2 >= n_cols),
01299     "Mat::swap_cols(): out of bounds"
01300     );
01301   
01302   eT* ptr1 = colptr(in_col1);
01303   eT* ptr2 = colptr(in_col2);
01304   
01305   for(u32 row=0; row<n_rows; ++row)
01306     {
01307     const eT tmp = ptr1[row];
01308     ptr1[row]    = ptr2[row];
01309     ptr2[row]    = tmp;
01310     }
01311   
01312   }
01313 
01314 
01315 
01316 //! create a matrix from Op, i.e. run the previously delayed unary operations
01317 template<typename eT>
01318 template<typename T1, typename op_type>
01319 inline
01320 Mat<eT>::Mat(const Op<T1, op_type>& X)
01321   : n_rows(0)
01322   , n_cols(0)
01323   , n_elem(0)
01324   , use_aux_mem(false)
01325   //, mem(0)
01326   , mem(mem)
01327   {
01328   arma_extra_debug_sigprint_this(this);
01329 
01330   isnt_same_type<eT, typename T1::elem_type>::check();
01331   
01332   op_type::apply(*this, X);
01333   }
01334 
01335 
01336 
01337 //! create a matrix from Op, i.e. run the previously delayed unary operations
01338 template<typename eT>
01339 template<typename T1, typename op_type>
01340 inline
01341 const Mat<eT>&
01342 Mat<eT>::operator=(const Op<T1, op_type>& X)
01343   {
01344   arma_extra_debug_sigprint();
01345 
01346   isnt_same_type<eT, typename T1::elem_type>::check();
01347   
01348   op_type::apply(*this, X);
01349   
01350   return *this;
01351   }
01352 
01353 
01354 
01355 //! in-place matrix addition, with the right-hand-side operand having delayed operations
01356 template<typename eT>
01357 template<typename T1, typename op_type>
01358 inline
01359 const Mat<eT>&
01360 Mat<eT>::operator+=(const Op<T1, op_type>& X)
01361   {
01362   arma_extra_debug_sigprint();
01363   
01364   isnt_same_type<eT, typename T1::elem_type>::check();
01365   
01366   const Mat<eT> m(X);
01367   
01368   return (*this).operator+=(m);
01369   }
01370 
01371 
01372 
01373 //! in-place matrix subtraction, with the right-hand-side operand having delayed operations
01374 template<typename eT>
01375 template<typename T1, typename op_type>
01376 inline
01377 const Mat<eT>&
01378 Mat<eT>::operator-=(const Op<T1, op_type>& X)
01379   {
01380   arma_extra_debug_sigprint();
01381   
01382   isnt_same_type<eT, typename T1::elem_type>::check();
01383   
01384   const Mat<eT> m(X);
01385   
01386   return (*this).operator-=(m);
01387   }
01388 
01389 
01390 
01391 //! in-place matrix multiplication, with the right-hand-side operand having delayed operations
01392 template<typename eT>
01393 template<typename T1, typename op_type>
01394 inline
01395 const Mat<eT>&
01396 Mat<eT>::operator*=(const Op<T1, op_type>& X)
01397   {
01398   arma_extra_debug_sigprint();
01399   
01400   isnt_same_type<eT, typename T1::elem_type>::check();
01401   
01402   glue_times::apply_inplace(*this, X);
01403   
01404   return *this;
01405   }
01406 
01407 
01408 
01409 //! in-place matrix element-wise multiplication, with the right-hand-side operand having delayed operations
01410 template<typename eT>
01411 template<typename T1, typename op_type>
01412 inline
01413 const Mat<eT>&
01414 Mat<eT>::operator%=(const Op<T1, op_type>& X)
01415   {
01416   arma_extra_debug_sigprint();
01417   
01418   isnt_same_type<eT, typename T1::elem_type>::check();
01419   
01420   const Mat<eT> m(X);
01421   
01422   return (*this).operator%=(m);
01423   }
01424 
01425 
01426 
01427 //! in-place matrix element-wise division, with the right-hand-side operand having delayed operations
01428 template<typename eT>
01429 template<typename T1, typename op_type>
01430 inline
01431 const Mat<eT>&
01432 Mat<eT>::operator/=(const Op<T1, op_type>& X)
01433   {
01434   arma_extra_debug_sigprint();
01435   
01436   isnt_same_type<eT, typename T1::elem_type>::check();
01437   
01438   const Mat<eT> m(X);
01439   
01440   return (*this).operator/=(m);
01441   }
01442 
01443 
01444 
01445 //! create a matrix from eOp, i.e. run the previously delayed unary operations
01446 template<typename eT>
01447 template<typename T1, typename eop_type>
01448 inline
01449 Mat<eT>::Mat(const eOp<T1, eop_type>& X)
01450   : n_rows(0)
01451   , n_cols(0)
01452   , n_elem(0)
01453   , use_aux_mem(false)
01454   //, mem(0)
01455   , mem(mem)
01456   {
01457   arma_extra_debug_sigprint_this(this);
01458 
01459   isnt_same_type<eT, typename T1::elem_type>::check();
01460   
01461   eop_type::apply(*this, X);
01462   }
01463 
01464 
01465 
01466 //! create a matrix from eOp, i.e. run the previously delayed unary operations
01467 template<typename eT>
01468 template<typename T1, typename eop_type>
01469 inline
01470 const Mat<eT>&
01471 Mat<eT>::operator=(const eOp<T1, eop_type>& X)
01472   {
01473   arma_extra_debug_sigprint();
01474 
01475   isnt_same_type<eT, typename T1::elem_type>::check();
01476   
01477   eop_type::apply(*this, X);
01478   
01479   return *this;
01480   }
01481 
01482 
01483 
01484 template<typename eT>
01485 template<typename T1, typename eop_type>
01486 inline
01487 const Mat<eT>&
01488 Mat<eT>::operator+=(const eOp<T1, eop_type>& X)
01489   {
01490   arma_extra_debug_sigprint();
01491 
01492   isnt_same_type<eT, typename T1::elem_type>::check();
01493   
01494   eop_type::apply_inplace_plus(*this, X);
01495   
01496   return *this;
01497   }
01498 
01499 
01500 
01501 template<typename eT>
01502 template<typename T1, typename eop_type>
01503 inline
01504 const Mat<eT>&
01505 Mat<eT>::operator-=(const eOp<T1, eop_type>& X)
01506   {
01507   arma_extra_debug_sigprint();
01508 
01509   isnt_same_type<eT, typename T1::elem_type>::check();
01510   
01511   eop_type::apply_inplace_minus(*this, X);
01512   
01513   return *this;
01514   }
01515 
01516 
01517 
01518 template<typename eT>
01519 template<typename T1, typename eop_type>
01520 inline
01521 const Mat<eT>&
01522 Mat<eT>::operator*=(const eOp<T1, eop_type>& X)
01523   {
01524   arma_extra_debug_sigprint();
01525   
01526   isnt_same_type<eT, typename T1::elem_type>::check();
01527   
01528   glue_times::apply_inplace(*this, X);
01529   
01530   return *this;
01531   }
01532 
01533 
01534 
01535 template<typename eT>
01536 template<typename T1, typename eop_type>
01537 inline
01538 const Mat<eT>&
01539 Mat<eT>::operator%=(const eOp<T1, eop_type>& X)
01540   {
01541   arma_extra_debug_sigprint();
01542 
01543   isnt_same_type<eT, typename T1::elem_type>::check();
01544   
01545   eop_type::apply_inplace_schur(*this, X);
01546   
01547   return *this;
01548   }
01549 
01550 
01551 
01552 template<typename eT>
01553 template<typename T1, typename eop_type>
01554 inline
01555 const Mat<eT>&
01556 Mat<eT>::operator/=(const eOp<T1, eop_type>& X)
01557   {
01558   arma_extra_debug_sigprint();
01559 
01560   isnt_same_type<eT, typename T1::elem_type>::check();
01561   
01562   eop_type::apply_inplace_div(*this, X);
01563   
01564   return *this;
01565   }
01566 
01567 
01568 
01569 //! create a matrix from Glue, i.e. run the previously delayed binary operations
01570 template<typename eT>
01571 template<typename T1, typename T2, typename glue_type>
01572 inline
01573 Mat<eT>::Mat(const Glue<T1, T2, glue_type>& X)
01574   : n_rows(0)
01575   , n_cols(0)
01576   , n_elem(0)
01577   , use_aux_mem(false)
01578   //, mem(0)
01579   , mem(mem)
01580   {
01581   arma_extra_debug_sigprint_this(this);
01582   
01583   isnt_same_type<eT, typename T1::elem_type>::check();
01584   isnt_same_type<eT, typename T2::elem_type>::check();
01585   
01586   glue_type::apply(*this, X);
01587   }
01588 
01589 
01590 
01591 //! create a matrix from Glue, i.e. run the previously delayed binary operations
01592 template<typename eT>
01593 template<typename T1, typename T2, typename glue_type>
01594 inline
01595 const Mat<eT>&
01596 Mat<eT>::operator=(const Glue<T1, T2, glue_type>& X)
01597   {
01598   arma_extra_debug_sigprint();
01599   
01600   isnt_same_type<eT, typename T1::elem_type>::check();
01601   isnt_same_type<eT, typename T2::elem_type>::check();
01602   
01603   glue_type::apply(*this, X);
01604   
01605   return *this;
01606   }
01607 
01608 
01609 
01610 //! in-place matrix addition, with the right-hand-side operands having delayed operations
01611 template<typename eT>
01612 template<typename T1, typename T2, typename glue_type>
01613 inline
01614 const Mat<eT>&
01615 Mat<eT>::operator+=(const Glue<T1, T2, glue_type>& X)
01616   {
01617   arma_extra_debug_sigprint();
01618   
01619   isnt_same_type<eT, typename T1::elem_type>::check();
01620   isnt_same_type<eT, typename T2::elem_type>::check();
01621   
01622   const Mat<eT> m(X);
01623   
01624   return (*this).operator+=(m);
01625   }
01626 
01627 
01628 
01629 //! in-place matrix subtraction, with the right-hand-side operands having delayed operations
01630 template<typename eT>
01631 template<typename T1, typename T2, typename glue_type>
01632 inline
01633 const Mat<eT>&
01634 Mat<eT>::operator-=(const Glue<T1, T2, glue_type>& X)
01635   {
01636   arma_extra_debug_sigprint();
01637   
01638   isnt_same_type<eT, typename T1::elem_type>::check();
01639   isnt_same_type<eT, typename T2::elem_type>::check();
01640   
01641   const Mat<eT> m(X);
01642   
01643   return (*this).operator-=(m);
01644   }
01645 
01646 
01647 
01648 //! in-place matrix multiplications, with the right-hand-side operands having delayed operations
01649 template<typename eT>
01650 template<typename T1, typename T2, typename glue_type>
01651 inline
01652 const Mat<eT>&
01653 Mat<eT>::operator*=(const Glue<T1, T2, glue_type>& X)
01654   {
01655   arma_extra_debug_sigprint();
01656   
01657   isnt_same_type<eT, typename T1::elem_type>::check();
01658   isnt_same_type<eT, typename T2::elem_type>::check();
01659   
01660   glue_times::apply_inplace(*this, X);
01661   
01662   return *this;
01663   }
01664 
01665 
01666 
01667 //! in-place matrix element-wise multiplication, with the right-hand-side operands having delayed operations
01668 template<typename eT>
01669 template<typename T1, typename T2, typename glue_type>
01670 inline
01671 const Mat<eT>&
01672 Mat<eT>::operator%=(const Glue<T1, T2, glue_type>& X)
01673   {
01674   arma_extra_debug_sigprint();
01675   
01676   isnt_same_type<eT, typename T1::elem_type>::check();
01677   isnt_same_type<eT, typename T2::elem_type>::check();
01678   
01679   const Mat<eT> m(X);
01680   
01681   return (*this).operator%=(m);
01682   }
01683 
01684 
01685 
01686 //! in-place matrix element-wise division, with the right-hand-side operands having delayed operations
01687 template<typename eT>
01688 template<typename T1, typename T2, typename glue_type>
01689 inline
01690 const Mat<eT>&
01691 Mat<eT>::operator/=(const Glue<T1, T2, glue_type>& X)
01692   {
01693   arma_extra_debug_sigprint();
01694   
01695   isnt_same_type<eT, typename T1::elem_type>::check();
01696   isnt_same_type<eT, typename T2::elem_type>::check();
01697   
01698   const Mat<eT> m(X);
01699   
01700   return (*this).operator/=(m);
01701   }
01702 
01703 
01704 
01705 template<typename eT>
01706 template<typename T1, typename T2>
01707 inline
01708 const Mat<eT>&
01709 Mat<eT>::operator+=(const Glue<T1, T2, glue_times>& X)
01710   {
01711   arma_extra_debug_sigprint();
01712   
01713   glue_times::apply_inplace_plus(*this, X, s32(+1));
01714   
01715   return *this;
01716   }
01717 
01718 
01719 
01720 template<typename eT>
01721 template<typename T1, typename T2>
01722 inline
01723 const Mat<eT>&
01724 Mat<eT>::operator-=(const Glue<T1, T2, glue_times>& X)
01725   {
01726   arma_extra_debug_sigprint();
01727   
01728   glue_times::apply_inplace_plus(*this, X, s32(-1));
01729   
01730   return *this;
01731   }
01732 
01733 
01734 
01735 //! create a matrix from eGlue, i.e. run the previously delayed binary operations
01736 template<typename eT>
01737 template<typename T1, typename T2, typename eglue_type>
01738 inline
01739 Mat<eT>::Mat(const eGlue<T1, T2, eglue_type>& X)
01740   : n_rows(0)
01741   , n_cols(0)
01742   , n_elem(0)
01743   , use_aux_mem(false)
01744   //, mem(0)
01745   , mem(mem)
01746   {
01747   arma_extra_debug_sigprint_this(this);
01748   
01749   isnt_same_type<eT, typename T1::elem_type>::check();
01750   isnt_same_type<eT, typename T2::elem_type>::check();
01751   
01752   eglue_type::apply(*this, X);
01753   }
01754 
01755 
01756 
01757 //! create a matrix from eGlue, i.e. run the previously delayed binary operations
01758 template<typename eT>
01759 template<typename T1, typename T2, typename eglue_type>
01760 inline
01761 const Mat<eT>&
01762 Mat<eT>::operator=(const eGlue<T1, T2, eglue_type>& X)
01763   {
01764   arma_extra_debug_sigprint();
01765   
01766   isnt_same_type<eT, typename T1::elem_type>::check();
01767   isnt_same_type<eT, typename T2::elem_type>::check();
01768   
01769   eglue_type::apply(*this, X);
01770   
01771   return *this;
01772   }
01773 
01774 
01775 
01776 //! in-place matrix addition, with the right-hand-side operands having delayed operations
01777 template<typename eT>
01778 template<typename T1, typename T2, typename eglue_type>
01779 inline
01780 const Mat<eT>&
01781 Mat<eT>::operator+=(const eGlue<T1, T2, eglue_type>& X)
01782   {
01783   arma_extra_debug_sigprint();
01784   
01785   isnt_same_type<eT, typename T1::elem_type>::check();
01786   isnt_same_type<eT, typename T2::elem_type>::check();
01787   
01788   eglue_type::apply_inplace_plus(*this, X);
01789   
01790   return *this;
01791   }
01792 
01793 
01794 
01795 //! in-place matrix subtraction, with the right-hand-side operands having delayed operations
01796 template<typename eT>
01797 template<typename T1, typename T2, typename eglue_type>
01798 inline
01799 const Mat<eT>&
01800 Mat<eT>::operator-=(const eGlue<T1, T2, eglue_type>& X)
01801   {
01802   arma_extra_debug_sigprint();
01803   
01804   isnt_same_type<eT, typename T1::elem_type>::check();
01805   isnt_same_type<eT, typename T2::elem_type>::check();
01806   
01807   eglue_type::apply_inplace_minus(*this, X);
01808   
01809   return *this;
01810   }
01811 
01812 
01813 
01814 template<typename eT>
01815 template<typename T1, typename T2, typename eglue_type>
01816 inline
01817 const Mat<eT>&
01818 Mat<eT>::operator*=(const eGlue<T1, T2, eglue_type>& X)
01819   {
01820   arma_extra_debug_sigprint();
01821   
01822   isnt_same_type<eT, typename T1::elem_type>::check();
01823   isnt_same_type<eT, typename T2::elem_type>::check();
01824   
01825   glue_times::apply_inplace(*this, X);
01826   return *this;
01827   }
01828 
01829 
01830 
01831 template<typename eT>
01832 template<typename T1, typename T2, typename eglue_type>
01833 inline
01834 const Mat<eT>&
01835 Mat<eT>::operator%=(const eGlue<T1, T2, eglue_type>& X)
01836   {
01837   arma_extra_debug_sigprint();
01838   
01839   isnt_same_type<eT, typename T1::elem_type>::check();
01840   isnt_same_type<eT, typename T2::elem_type>::check();
01841   
01842   eglue_type::apply_inplace_schur(*this, X);
01843   return *this;
01844   }
01845 
01846 
01847 
01848 template<typename eT>
01849 template<typename T1, typename T2, typename eglue_type>
01850 inline
01851 const Mat<eT>&
01852 Mat<eT>::operator/=(const eGlue<T1, T2, eglue_type>& X)
01853   {
01854   arma_extra_debug_sigprint();
01855   
01856   isnt_same_type<eT, typename T1::elem_type>::check();
01857   isnt_same_type<eT, typename T2::elem_type>::check();
01858   
01859   eglue_type::apply_inplace_div(*this, X);
01860   return *this;
01861   }
01862 
01863 
01864 
01865 //! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
01866 template<typename eT>
01867 arma_inline
01868 eT&
01869 Mat<eT>::operator() (const u32 i)
01870   {
01871   arma_debug_check( (i >= n_elem), "Mat::operator(): out of bounds");
01872   return access::rw(mem[i]);
01873   }
01874 
01875 
01876 
01877 //! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
01878 template<typename eT>
01879 arma_inline
01880 eT
01881 Mat<eT>::operator() (const u32 i) const
01882   {
01883   arma_debug_check( (i >= n_elem), "Mat::operator(): out of bounds");
01884   return mem[i];
01885   }
01886 
01887 
01888 //! linear element accessor (treats the matrix as a vector); no bounds check.  
01889 template<typename eT>
01890 arma_inline
01891 eT&
01892 Mat<eT>::operator[] (const u32 i)
01893   {
01894   return access::rw(mem[i]);
01895   }
01896 
01897 
01898 
01899 //! linear element accessor (treats the matrix as a vector); no bounds check
01900 template<typename eT>
01901 arma_inline
01902 eT
01903 Mat<eT>::operator[] (const u32 i) const
01904   {
01905   return mem[i];
01906   }
01907 
01908 
01909 
01910 //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
01911 template<typename eT>
01912 arma_inline
01913 eT&
01914 Mat<eT>::operator() (const u32 in_row, const u32 in_col)
01915   {
01916   arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): out of bounds");
01917   return access::rw(mem[in_row + in_col*n_rows]);
01918   }
01919 
01920 
01921 
01922 //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
01923 template<typename eT>
01924 arma_inline
01925 eT
01926 Mat<eT>::operator() (const u32 in_row, const u32 in_col) const
01927   {
01928   arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): out of bounds");
01929   return mem[in_row + in_col*n_rows];
01930   }
01931 
01932 
01933 
01934 //! element accessor; no bounds check
01935 template<typename eT>
01936 arma_inline
01937 eT&
01938 Mat<eT>::at(const u32 in_row, const u32 in_col)
01939   {
01940   return access::rw( mem[in_row + in_col*n_rows] );
01941   }
01942 
01943 
01944 
01945 //! element accessor; no bounds check
01946 template<typename eT>
01947 arma_inline
01948 eT
01949 Mat<eT>::at(const u32 in_row, const u32 in_col) const
01950   {
01951   return mem[in_row + in_col*n_rows];
01952   }
01953 
01954 
01955 
01956 //! prefix ++
01957 template<typename eT>
01958 arma_inline
01959 const Mat<eT>&
01960 Mat<eT>::operator++()
01961   {
01962   Mat_aux::prefix_pp(*this);
01963   return *this;
01964   }
01965 
01966 
01967 
01968 //! postfix ++  (must not return the object by reference)
01969 template<typename eT>
01970 arma_inline
01971 void
01972 Mat<eT>::operator++(int)
01973   {
01974   Mat_aux::postfix_pp(*this);
01975   }
01976 
01977 
01978 
01979 //! prefix --
01980 template<typename eT>
01981 arma_inline
01982 const Mat<eT>&
01983 Mat<eT>::operator--()
01984   {
01985   Mat_aux::prefix_mm(*this);
01986   return *this;
01987   }
01988 
01989 
01990 
01991 //! postfix --  (must not return the object by reference)
01992 template<typename eT>
01993 arma_inline
01994 void
01995 Mat<eT>::operator--(int)
01996   {
01997   Mat_aux::postfix_mm(*this);
01998   }
01999 
02000 
02001 
02002 //! returns true if the object can be interpreted as a column or row vector
02003 template<typename eT>
02004 arma_inline
02005 bool
02006 Mat<eT>::is_vec() const
02007   {
02008   return ( (n_rows == 1) || (n_cols == 1) );
02009   }
02010 
02011 
02012 
02013 //! returns true if the object has the same number of non-zero rows and columnns
02014 template<typename eT>
02015 arma_inline
02016 bool
02017 Mat<eT>::is_square() const
02018   {
02019   return ( (n_rows == n_cols) && (n_elem > 0) );
02020   }
02021 
02022 
02023 
02024 //! returns true if all of the elements are finite
02025 template<typename eT>
02026 arma_inline
02027 bool
02028 Mat<eT>::is_finite() const
02029   {
02030   for(u32 i=0; i<n_elem; ++i)
02031     {
02032     if(arma_isfinite(mem[i]) == false)
02033       {
02034       return false;
02035       }
02036     }
02037 
02038   return true;
02039   }
02040 
02041 
02042 
02043 //! returns a pointer to array of eTs for a specified column; no bounds check
02044 template<typename eT>
02045 arma_inline
02046 eT*
02047 Mat<eT>::colptr(const u32 in_col)
02048   {
02049   return & access::rw(mem[in_col*n_rows]);
02050   }
02051 
02052 
02053 
02054 //! returns a pointer to array of eTs for a specified column; no bounds check
02055 template<typename eT>
02056 arma_inline
02057 const eT*
02058 Mat<eT>::colptr(const u32 in_col) const
02059   {
02060   return & mem[in_col*n_rows];
02061   }
02062 
02063 
02064 
02065 //! returns a pointer to array of eTs used by the matrix
02066 template<typename eT>
02067 arma_inline
02068 eT*
02069 Mat<eT>::memptr()
02070   {
02071   return const_cast<eT*>(mem);
02072   }
02073 
02074 
02075 
02076 //! returns a pointer to array of eTs used by the matrix
02077 template<typename eT>
02078 arma_inline
02079 const eT*
02080 Mat<eT>::memptr() const
02081   {
02082   return mem;
02083   }
02084 
02085 
02086 
02087 //! print contents of the matrix (to the cout stream),
02088 //! optionally preceding with a user specified line of text.
02089 //! the precision and cell width are modified.
02090 //! on return, the stream's flags are restored to their original values.
02091 template<typename eT>
02092 inline
02093 void
02094 Mat<eT>::print(const std::string extra_text) const
02095   {
02096   arma_extra_debug_sigprint();
02097   
02098   if(extra_text.length() != 0)
02099     {
02100     const std::streamsize orig_width = cout.width();
02101     
02102     cout << extra_text << '\n';
02103   
02104     cout.width(orig_width);
02105     }
02106   
02107   arma_ostream::print(cout, *this, true);
02108   }
02109 
02110 
02111 
02112 //! print contents of the matrix to a user specified stream,
02113 //! optionally preceding with a user specified line of text.
02114 //! the precision and cell width are modified.
02115 //! on return, the stream's flags are restored to their original values.
02116 template<typename eT>
02117 inline
02118 void
02119 Mat<eT>::print(std::ostream& user_stream, const std::string extra_text) const
02120   {
02121   arma_extra_debug_sigprint();
02122   
02123   if(extra_text.length() != 0)
02124     {
02125     const std::streamsize orig_width = user_stream.width();
02126     
02127     user_stream << extra_text << '\n';
02128     
02129     user_stream.width(orig_width);
02130     }
02131   
02132   arma_ostream::print(user_stream, *this, true);
02133   }
02134 
02135 
02136 
02137 //! print contents of the transposed version of the matrix (to the cout stream),
02138 //! optionally preceding with a user specified line of text.
02139 //! the precision and cell width are modified.
02140 //! on return, the stream's flags are restored to their original values.
02141 template<typename eT>
02142 inline
02143 void
02144 Mat<eT>::print_trans(const std::string extra_text) const
02145   {
02146   arma_extra_debug_sigprint();
02147   
02148   Mat<eT> tmp;
02149   op_trans::apply_noalias(tmp, *this);
02150   
02151   tmp.print(extra_text);
02152   }
02153 
02154 
02155 
02156 //! print contents of the transposed version of matrix to a user specified stream,
02157 //! optionally preceding with a user specified line of text.
02158 //! the precision and cell width are modified.
02159 //! on return, the stream's flags are restored to their original values.
02160 template<typename eT>
02161 inline
02162 void
02163 Mat<eT>::print_trans(std::ostream& user_stream, const std::string extra_text) const
02164   {
02165   arma_extra_debug_sigprint();
02166   
02167   Mat<eT> tmp;
02168   op_trans::apply_noalias(tmp, *this);
02169   
02170   tmp.print(user_stream, extra_text);
02171   }
02172 
02173 
02174 
02175 //! print contents of the matrix (to the cout stream),
02176 //! optionally preceding with a user specified line of text.
02177 //! the stream's flags are used as is and are not modified
02178 //! (i.e. the precision and cell width are not modified).
02179 template<typename eT>
02180 inline
02181 void
02182 Mat<eT>::raw_print(const std::string extra_text) const
02183   {
02184   arma_extra_debug_sigprint();
02185   
02186   if(extra_text.length() != 0)
02187     {
02188     const std::streamsize orig_width = cout.width();
02189     
02190     cout << extra_text << '\n';
02191   
02192     cout.width(orig_width);
02193     }
02194   
02195   arma_ostream::print(cout, *this, false);
02196   }
02197 
02198 
02199 
02200 //! print contents of the matrix to a user specified stream,
02201 //! optionally preceding with a user specified line of text.
02202 //! the stream's flags are used as is and are not modified.
02203 //! (i.e. the precision and cell width are not modified).
02204 template<typename eT>
02205 inline
02206 void
02207 Mat<eT>::raw_print(std::ostream& user_stream, const std::string extra_text) const
02208   {
02209   arma_extra_debug_sigprint();
02210   
02211   if(extra_text.length() != 0)
02212     {
02213     const std::streamsize orig_width = user_stream.width();
02214   
02215     user_stream << extra_text << '\n';
02216   
02217     user_stream.width(orig_width);
02218     }
02219   
02220   arma_ostream::print(user_stream, *this, false);
02221   }
02222 
02223 
02224 
02225 //! print contents of the transposed version of the matrix (to the cout stream),
02226 //! optionally preceding with a user specified line of text.
02227 //! the stream's flags are used as is and are not modified
02228 //! (i.e. the precision and cell width are not modified).
02229 template<typename eT>
02230 inline
02231 void
02232 Mat<eT>::raw_print_trans(const std::string extra_text) const
02233   {
02234   arma_extra_debug_sigprint();
02235   
02236   Mat<eT> tmp;
02237   op_trans::apply_noalias(tmp, *this);
02238   
02239   tmp.raw_print(extra_text);
02240   }
02241 
02242 
02243 
02244 //! print contents of the transposed version of the matrix to a user specified stream,
02245 //! optionally preceding with a user specified line of text.
02246 //! the stream's flags are used as is and are not modified.
02247 //! (i.e. the precision and cell width are not modified).
02248 template<typename eT>
02249 inline
02250 void
02251 Mat<eT>::raw_print_trans(std::ostream& user_stream, const std::string extra_text) const
02252   {
02253   arma_extra_debug_sigprint();
02254   
02255   Mat<eT> tmp;
02256   op_trans::apply_noalias(tmp, *this);
02257   
02258   tmp.raw_print(user_stream, extra_text);
02259   }
02260 
02261 
02262 
02263 //! change the matrix to have user specified dimensions (data is not preserved)
02264 template<typename eT>
02265 inline
02266 void
02267 Mat<eT>::set_size(const u32 in_n_rows, const u32 in_n_cols)
02268   {
02269   arma_extra_debug_sigprint();
02270   
02271   init(in_n_rows, in_n_cols);
02272   }
02273 
02274 
02275 
02276 //! change the matrix (without preserving data) to have the same dimensions as the given matrix 
02277 template<typename eT>
02278 template<typename eT2>
02279 inline
02280 void
02281 Mat<eT>::copy_size(const Mat<eT2>& m)
02282   {
02283   arma_extra_debug_sigprint();
02284   
02285   init(m.n_rows, m.n_cols);
02286   }
02287 
02288 
02289 
02290 //! fill the matrix with the specified value
02291 template<typename eT>
02292 arma_hot
02293 inline
02294 void
02295 Mat<eT>::fill(const eT val)
02296   {
02297   arma_extra_debug_sigprint();
02298   
02299         eT* local_ptr    = memptr();
02300   const u32 local_n_elem = n_elem;
02301   
02302   u32 i,j;
02303   
02304   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
02305     {
02306     local_ptr[i] = val;
02307     local_ptr[j] = val;
02308     }
02309   
02310   if(i < local_n_elem)
02311     {
02312     local_ptr[i] = val;
02313     }
02314   }
02315 
02316 
02317 
02318 template<typename eT>
02319 inline
02320 void
02321 Mat<eT>::zeros()
02322   {
02323   arma_extra_debug_sigprint();
02324   
02325   fill(eT(0));
02326   }
02327 
02328 
02329 
02330 template<typename eT>
02331 inline
02332 void
02333 Mat<eT>::zeros(const u32 in_rows, const u32 in_cols)
02334   {
02335   arma_extra_debug_sigprint( arma_boost::format("in_rows = %d, in_cols = %d") % in_rows % in_cols );
02336 
02337   set_size(in_rows, in_cols);
02338   fill(eT(0));
02339   }
02340 
02341 
02342 
02343 template<typename eT>
02344 inline
02345 void
02346 Mat<eT>::ones()
02347   {
02348   arma_extra_debug_sigprint();
02349   
02350   fill(eT(1));
02351   }
02352 
02353 
02354 
02355 template<typename eT>
02356 inline
02357 void
02358 Mat<eT>::ones(const u32 in_rows, const u32 in_cols)
02359   {
02360   arma_extra_debug_sigprint( arma_boost::format("in_rows = %d, in_cols = %d") % in_rows % in_cols );
02361 
02362   set_size(in_rows, in_cols);
02363   fill(eT(1));
02364   }
02365 
02366 
02367 
02368 template<typename eT>
02369 inline
02370 void
02371 Mat<eT>::reset()
02372   {
02373   arma_extra_debug_sigprint();
02374   
02375   init(0,0);
02376   }
02377 
02378 
02379 
02380 //! save the matrix to a file
02381 template<typename eT>
02382 inline
02383 void
02384 Mat<eT>::save(const std::string name, const file_type type) const
02385   {
02386   arma_extra_debug_sigprint();
02387   
02388   switch(type)
02389     {
02390     case raw_ascii:
02391       diskio::save_raw_ascii(*this, name);
02392       break;
02393     
02394     case arma_ascii:
02395       diskio::save_arma_ascii(*this, name);
02396       break;
02397     
02398     case arma_binary:
02399       diskio::save_arma_binary(*this, name);
02400       break;
02401       
02402     case pgm_binary:
02403       diskio::save_pgm_binary(*this, name);
02404       break;
02405     
02406     default:
02407       arma_stop("Mat::save(): unsupported file type");
02408     }
02409   
02410   }
02411 
02412 
02413 
02414 //! save the matrix to a stream
02415 template<typename eT>
02416 inline
02417 void
02418 Mat<eT>::save(std::ostream& os, const file_type type) const
02419   {
02420   arma_extra_debug_sigprint();
02421   
02422   switch(type)
02423     {
02424     case raw_ascii:
02425       diskio::save_raw_ascii(*this, "[ostream]", os);
02426       break;
02427     
02428     case arma_ascii:
02429       diskio::save_arma_ascii(*this, "[ostream]", os);
02430       break;
02431     
02432     case arma_binary:
02433       diskio::save_arma_binary(*this, "[ostream]", os);
02434       break;
02435       
02436     case pgm_binary:
02437       diskio::save_pgm_binary(*this, "[ostream]", os);
02438       break;
02439     
02440     default:
02441       arma_stop("Mat::save(): unsupported file type");
02442     }
02443   
02444   }
02445 
02446 
02447 
02448 //! load a matrix from a file
02449 template<typename eT>
02450 inline
02451 void
02452 Mat<eT>::load(const std::string name, const file_type type)
02453   {
02454   arma_extra_debug_sigprint();
02455   
02456   switch(type)
02457     {
02458     case auto_detect:
02459       diskio::load_auto_detect(*this, name);
02460       break;
02461     
02462     case raw_ascii:
02463       diskio::load_raw_ascii(*this, name);
02464       break;
02465     
02466     case arma_ascii:
02467       diskio::load_arma_ascii(*this, name);
02468       break;
02469     
02470     case arma_binary:
02471       diskio::load_arma_binary(*this, name);
02472       break;
02473       
02474     case pgm_binary:
02475       diskio::load_pgm_binary(*this, name);
02476       break;
02477     
02478     default:
02479       arma_stop("Mat::load(): unsupported file type");
02480     }
02481   
02482   }
02483 
02484 
02485 
02486 //! load a matrix from a stream
02487 template<typename eT>
02488 inline
02489 void
02490 Mat<eT>::load(std::istream& is, const file_type type)
02491   {
02492   arma_extra_debug_sigprint();
02493   
02494   switch(type)
02495     {
02496     case auto_detect:
02497       diskio::load_auto_detect(*this, "[istream]", is);
02498       break;
02499     
02500     case raw_ascii:
02501       diskio::load_raw_ascii(*this, "[istream]", is);
02502       break;
02503     
02504     case arma_ascii:
02505       diskio::load_arma_ascii(*this, "[istream]", is);
02506       break;
02507     
02508     case arma_binary:
02509       diskio::load_arma_binary(*this, "[istream]", is);
02510       break;
02511       
02512     case pgm_binary:
02513       diskio::load_pgm_binary(*this, "[istream]", is);
02514       break;
02515     
02516     default:
02517       arma_stop("Mat::load(): unsupported file type");
02518     }
02519   
02520   }
02521 
02522 
02523 
02524 //! prefix ++
02525 template<typename eT>
02526 arma_inline
02527 void
02528 Mat_aux::prefix_pp(Mat<eT>& x)
02529   {
02530         eT* memptr = x.memptr();
02531   const u32 n_elem = x.n_elem;
02532   
02533   u32 i,j;
02534 
02535   for(i=0, j=1; j<n_elem; i+=2, j+=2)
02536     {
02537     ++(memptr[i]);
02538     ++(memptr[j]);
02539     }
02540   
02541   if(i < n_elem)
02542     {
02543     ++(memptr[i]);
02544     }
02545   }
02546 
02547 
02548 
02549 //! prefix ++ for complex numbers (work around for limitations of the std::complex class)
02550 template<typename T>
02551 arma_inline
02552 void
02553 Mat_aux::prefix_pp(Mat< std::complex<T> >& x)
02554   {
02555   x += T(1);
02556   }
02557 
02558 
02559 
02560 //! postfix ++
02561 template<typename eT>
02562 arma_inline
02563 void
02564 Mat_aux::postfix_pp(Mat<eT>& x)
02565   {
02566         eT* memptr = x.memptr();
02567   const u32 n_elem = x.n_elem;
02568   
02569   u32 i,j;
02570   
02571   for(i=0, j=1; j<n_elem; i+=2, j+=2)
02572     {
02573     (memptr[i])++;
02574     (memptr[j])++;
02575     }
02576   
02577   if(i < n_elem)
02578     {
02579     (memptr[i])++;
02580     }
02581   }
02582 
02583 
02584 
02585 //! postfix ++ for complex numbers (work around for limitations of the std::complex class)
02586 template<typename T>
02587 arma_inline
02588 void
02589 Mat_aux::postfix_pp(Mat< std::complex<T> >& x)
02590   {
02591   x += T(1);
02592   }
02593 
02594 
02595 
02596 //! prefix --
02597 template<typename eT>
02598 arma_inline
02599 void
02600 Mat_aux::prefix_mm(Mat<eT>& x)
02601   {
02602         eT* memptr = x.memptr();
02603   const u32 n_elem = x.n_elem;
02604 
02605   u32 i,j;
02606 
02607   for(i=0, j=1; j<n_elem; i+=2, j+=2)
02608     {
02609     --(memptr[i]);
02610     --(memptr[j]);
02611     }
02612   
02613   if(i < n_elem)
02614     {
02615     --(memptr[i]);
02616     }
02617   }
02618 
02619 
02620 
02621 //! prefix -- for complex numbers (work around for limitations of the std::complex class)
02622 template<typename T>
02623 arma_inline
02624 void
02625 Mat_aux::prefix_mm(Mat< std::complex<T> >& x)
02626   {
02627   x -= T(1);
02628   }
02629 
02630 
02631 
02632 //! postfix --
02633 template<typename eT>
02634 arma_inline
02635 void
02636 Mat_aux::postfix_mm(Mat<eT>& x)
02637   {
02638         eT* memptr = x.memptr();
02639   const u32 n_elem = x.n_elem;
02640 
02641   u32 i,j;
02642 
02643   for(i=0, j=1; j<n_elem; i+=2, j+=2)
02644     {
02645     (memptr[i])--;
02646     (memptr[j])--;
02647     }
02648   
02649   if(i < n_elem)
02650     {
02651     (memptr[i])--;
02652     }
02653   }
02654 
02655 
02656 
02657 //! postfix ++ for complex numbers (work around for limitations of the std::complex class)
02658 template<typename T>
02659 arma_inline
02660 void
02661 Mat_aux::postfix_mm(Mat< std::complex<T> >& x)
02662   {
02663   x -= T(1);
02664   }
02665 
02666 
02667 
02668 //! @}