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