subview_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 subview
00017 //! @{
00018 
00019 
00020 template<typename eT>
00021 inline
00022 subview<eT>::~subview()
00023   {
00024   arma_extra_debug_sigprint();
00025   }
00026 
00027 
00028 template<typename eT>
00029 arma_inline
00030 subview<eT>::subview(const Mat<eT>& in_m, const u32 in_row1, const u32 in_col1, const u32 in_row2,  const u32 in_col2)
00031   : m(in_m)
00032   , m_ptr(0)
00033   , aux_row1(in_row1)
00034   , aux_col1(in_col1)
00035   , aux_row2(in_row2)
00036   , aux_col2(in_col2)
00037   , n_rows(1 + in_row2 - in_row1)
00038   , n_cols(1 + in_col2 - in_col1)
00039   , n_elem(n_rows*n_cols)
00040   {
00041   arma_extra_debug_sigprint();
00042   }
00043 
00044 
00045 
00046 template<typename eT>
00047 arma_inline
00048 subview<eT>::subview(Mat<eT>& in_m, const u32 in_row1, const u32 in_col1, const u32 in_row2,  const u32 in_col2)
00049   : m(in_m)
00050   , m_ptr(&in_m)
00051   , aux_row1(in_row1)
00052   , aux_col1(in_col1)
00053   , aux_row2(in_row2)
00054   , aux_col2(in_col2)
00055   , n_rows(1 + in_row2 - in_row1)
00056   , n_cols(1 + in_col2 - in_col1)
00057   , n_elem(n_rows*n_cols)
00058   {
00059   arma_extra_debug_sigprint();
00060   }
00061 
00062 
00063 
00064 template<typename eT>
00065 inline
00066 void
00067 subview<eT>::fill(const eT val)
00068   {
00069   arma_extra_debug_sigprint();
00070   
00071   for(u32 col = 0; col<n_cols; ++col)
00072     {
00073     eT* coldata = colptr(col);
00074     
00075     for(u32 row = 0; row<n_rows; ++row)
00076       {
00077       coldata[row] = val;
00078       }
00079     }
00080   
00081   
00082   }
00083 
00084 
00085 
00086 template<typename eT>
00087 inline
00088 void
00089 subview<eT>::operator+= (const eT val)
00090   {
00091   arma_extra_debug_sigprint();
00092   
00093   for(u32 col = 0; col<n_cols; ++col)
00094     {
00095     eT* coldata = colptr(col);
00096     
00097     for(u32 row = 0; row<n_rows; ++row)
00098       {
00099       coldata[row] += val;
00100       }
00101     
00102     }
00103   
00104   }
00105 
00106 
00107 
00108 template<typename eT>
00109 inline
00110 void
00111 subview<eT>::operator-= (const eT val)
00112   {
00113   arma_extra_debug_sigprint();
00114   
00115   for(u32 col = 0; col<n_cols; ++col)
00116     {
00117     eT* coldata = colptr(col);
00118     
00119     for(u32 row = 0; row<n_rows; ++row)
00120       {
00121       coldata[row] -= val;
00122       }
00123     
00124     }
00125   
00126   }
00127 
00128 
00129 
00130 template<typename eT>
00131 inline
00132 void
00133 subview<eT>::operator*= (const eT val)
00134   {
00135   arma_extra_debug_sigprint();
00136   
00137   for(u32 col = 0; col<n_cols; ++col)
00138     {
00139     eT* coldata = colptr(col);
00140     
00141     for(u32 row = 0; row<n_rows; ++row)
00142       {
00143       coldata[row] *= val;
00144       }
00145     
00146     }
00147   
00148   }
00149 
00150 
00151 
00152 template<typename eT>
00153 inline
00154 void
00155 subview<eT>::operator/= (const eT val)
00156   {
00157   arma_extra_debug_sigprint();
00158   
00159   for(u32 col = 0; col<n_cols; ++col)
00160     {
00161     eT* coldata = colptr(col);
00162     
00163     for(u32 row = 0; row<n_rows; ++row)
00164       {
00165       coldata[row] /= val;
00166       }
00167     
00168     }
00169   
00170   }
00171 
00172 
00173 
00174 template<typename eT>
00175 template<typename T1>
00176 inline
00177 void
00178 subview<eT>::operator= (const Base<eT,T1>& in)
00179   {
00180   arma_extra_debug_sigprint();
00181   
00182   const unwrap<T1> tmp(in.get_ref());
00183   
00184   const Mat<eT>&     x = tmp.M;
00185         subview<eT>& t = *this;
00186   
00187   arma_debug_assert_same_size(t, x, "insert into submatrix");
00188   
00189   
00190   for(u32 col = 0; col<t.n_cols; ++col)
00191     {
00192           eT* t_coldata = t.colptr(col);
00193     const eT* x_coldata = x.colptr(col);
00194     
00195     for(u32 row = 0; row<t.n_rows; ++row)
00196       {
00197       t_coldata[row] = x_coldata[row];
00198       }
00199       
00200     }
00201   }
00202 
00203 
00204 
00205 template<typename eT>
00206 template<typename T1>
00207 inline
00208 void
00209 subview<eT>::operator+= (const Base<eT,T1>& in)
00210   {
00211   arma_extra_debug_sigprint();
00212   
00213   const unwrap<T1> tmp(in.get_ref());
00214   
00215   const Mat<eT>&     x = tmp.M;
00216         subview<eT>& t = *this;
00217   
00218   arma_debug_assert_same_size(t, x, "matrix addition");
00219   
00220   
00221   for(u32 col = 0; col<t.n_cols; ++col)
00222     {
00223           eT* t_coldata = t.colptr(col);
00224     const eT* x_coldata = x.colptr(col);
00225     
00226     for(u32 row = 0; row<t.n_rows; ++row)
00227       {
00228       t_coldata[row] += x_coldata[row];
00229       }
00230     }
00231   
00232   }
00233 
00234 
00235 
00236 template<typename eT>
00237 template<typename T1>
00238 inline
00239 void
00240 subview<eT>::operator-= (const Base<eT,T1>& in)
00241   {
00242   arma_extra_debug_sigprint();
00243   
00244   const unwrap<T1> tmp(in.get_ref());
00245   
00246   const Mat<eT>&     x = tmp.M;
00247         subview<eT>& t = *this;
00248   
00249   arma_debug_assert_same_size(t, x, "matrix subtraction");
00250   
00251   
00252   for(u32 col = 0; col<t.n_cols; ++col)
00253     {
00254           eT* t_coldata = t.colptr(col);
00255     const eT* x_coldata = x.colptr(col);
00256     
00257     for(u32 row = 0; row<t.n_rows; ++row)
00258       {
00259       t_coldata[row] -= x_coldata[row];
00260       }
00261     }
00262   
00263   }
00264 
00265 
00266 
00267 template<typename eT>
00268 template<typename T1>
00269 inline
00270 void
00271 subview<eT>::operator%= (const Base<eT,T1>& in)
00272   {
00273   arma_extra_debug_sigprint();
00274   
00275   const unwrap<T1> tmp(in.get_ref());
00276   
00277   const Mat<eT>&     x = tmp.M;
00278         subview<eT>& t = *this;
00279   
00280   arma_debug_assert_same_size(t, x, "matrix schur product");
00281   
00282   
00283   for(u32 col = 0; col<t.n_cols; ++col)
00284     {
00285           eT* t_coldata = t.colptr(col);
00286     const eT* x_coldata = x.colptr(col);
00287     
00288     for(u32 row = 0; row<t.n_rows; ++row)
00289       {
00290       t_coldata[row] *= x_coldata[row];
00291       }
00292     }
00293   
00294   }
00295 
00296 
00297 
00298 template<typename eT>
00299 template<typename T1>
00300 inline
00301 void
00302 subview<eT>::operator/= (const Base<eT,T1>& in)
00303   {
00304   arma_extra_debug_sigprint();
00305   
00306   const unwrap<T1> tmp(in.get_ref());
00307   
00308   const Mat<eT>&     x = tmp.M;
00309         subview<eT>& t = *this;
00310   
00311   arma_debug_assert_same_size(t, x, "element-wise matrix division");
00312   
00313   
00314   for(u32 col = 0; col<t.n_cols; ++col)
00315     {
00316           eT* t_coldata = t.colptr(col);
00317     const eT* x_coldata = x.colptr(col);
00318     
00319     for(u32 row = 0; row<t.n_rows; ++row)
00320       {
00321       t_coldata[row] /= x_coldata[row];
00322       }
00323     }
00324   
00325   }
00326 
00327 
00328 
00329 //! x.submat(...) = y.submat(...)
00330 template<typename eT>
00331 inline
00332 void
00333 subview<eT>::operator= (const subview<eT>& x_in)
00334   {
00335   arma_extra_debug_sigprint();
00336   
00337   const bool overlap = check_overlap(x_in);
00338   
00339         Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
00340   const subview<eT>* tmp_subview = overlap ? new subview<eT>(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.aux_row2, x_in.aux_col2) : 0;
00341   const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
00342   
00343   subview<eT>& t = *this;
00344   
00345   arma_debug_assert_same_size(t, x, "insert into submatrix");
00346   
00347   
00348   for(u32 col = 0; col<t.n_cols; ++col)
00349     {
00350           eT* t_coldata = t.colptr(col);
00351     const eT* x_coldata = x.colptr(col);
00352     
00353     for(u32 row = 0; row<t.n_rows; ++row)
00354       {
00355       t_coldata[row] = x_coldata[row];
00356       }
00357     
00358     }
00359     
00360   if(overlap)
00361     {
00362     delete tmp_subview;
00363     delete tmp_mat;
00364     }
00365   
00366   }
00367 
00368 
00369 
00370 template<typename eT>
00371 inline
00372 void
00373 subview<eT>::operator+= (const subview<eT>& x_in)
00374   {
00375   arma_extra_debug_sigprint();
00376   
00377   const bool overlap = check_overlap(x_in);
00378   
00379         Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
00380   const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.aux_row2, x_in.aux_col2) : 0;
00381   const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
00382   
00383   
00384   subview<eT>& t = *this;
00385   
00386   arma_debug_assert_same_size(t, x, "matrix addition");
00387   
00388   
00389   for(u32 col = 0; col<t.n_cols; ++col)
00390     {
00391           eT* t_coldata = t.colptr(col);
00392     const eT* x_coldata = x.colptr(col);
00393     
00394     for(u32 row = 0; row<t.n_rows; ++row)
00395       {
00396       t_coldata[row] += x_coldata[row];
00397       }
00398     
00399     }
00400   
00401   }
00402 
00403 
00404 
00405 template<typename eT>
00406 inline
00407 void
00408 subview<eT>::operator-= (const subview<eT>& x_in)
00409   {
00410   arma_extra_debug_sigprint();
00411   
00412   const bool overlap = check_overlap(x_in);
00413   
00414         Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
00415   const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.aux_row2, x_in.aux_col2) : 0;
00416   const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
00417   
00418   subview<eT>& t = *this;
00419   
00420   arma_debug_assert_same_size(t, x, "matrix subtraction");
00421   
00422   
00423   for(u32 col = 0; col<t.n_cols; ++col)
00424     {
00425           eT* t_coldata = t.colptr(col);
00426     const eT* x_coldata = x.colptr(col);
00427     
00428     for(u32 row = 0; row<t.n_rows; ++row)
00429       {
00430       t_coldata[row] -= x_coldata[row];
00431       }
00432     }
00433     
00434   if(overlap)
00435     {
00436     delete tmp_subview;
00437     delete tmp_mat;
00438     }
00439   
00440   }
00441 
00442 
00443 
00444 template<typename eT>
00445 inline
00446 void
00447 subview<eT>::operator%= (const subview& x_in)
00448   {
00449   arma_extra_debug_sigprint();
00450   
00451   const bool overlap = check_overlap(x_in);
00452   
00453         Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
00454   const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.aux_row2, x_in.aux_col2) : 0;
00455   const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
00456   
00457   subview<eT>& t = *this;
00458   
00459   arma_debug_assert_same_size(t, x, "matrix schur product");
00460   
00461   
00462   for(u32 col = 0; col<t.n_cols; ++col)
00463     {
00464           eT* t_coldata = t.colptr(col);
00465     const eT* x_coldata = x.colptr(col);
00466     
00467     for(u32 row = 0; row<t.n_rows; ++row)
00468       {
00469       t_coldata[row] *= x_coldata[row];
00470       }
00471     }
00472   
00473   if(overlap)
00474     {
00475     delete tmp_subview;
00476     delete tmp_mat;
00477     }
00478   
00479   }
00480 
00481 
00482 
00483 template<typename eT>
00484 inline
00485 void
00486 subview<eT>::operator/= (const subview& x_in)
00487   {
00488   arma_extra_debug_sigprint();
00489   
00490   const bool overlap = check_overlap(x_in);
00491   
00492         Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
00493   const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.aux_row2, x_in.aux_col2) : 0;
00494   const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
00495   
00496   subview<eT>& t = *this;
00497   
00498   arma_debug_assert_same_size(t, x, "element-wise matrix division");
00499   
00500   
00501   for(u32 col = 0; col<t.n_cols; ++col)
00502     {
00503           eT* t_coldata = t.colptr(col);
00504     const eT* x_coldata = x.colptr(col);
00505     
00506     for(u32 row = 0; row<t.n_rows; ++row)
00507       {
00508       t_coldata[row] /= x_coldata[row];
00509       }
00510     }
00511     
00512   if(overlap)
00513     {
00514     delete tmp_subview;
00515     delete tmp_mat;
00516     }
00517   
00518   }
00519 
00520 
00521 
00522 template<typename eT>
00523 inline
00524 void
00525 subview<eT>::zeros()
00526   {
00527   arma_extra_debug_sigprint();
00528   
00529   subview<eT>& t = *this;
00530   
00531   for(u32 col = 0; col<t.n_cols; ++col)
00532     {
00533     eT* t_coldata = t.colptr(col);
00534     
00535     for(u32 row = 0; row<t.n_rows; ++row)
00536       {
00537       t_coldata[row] = eT(0);
00538       }
00539     
00540     }
00541   
00542   }
00543 
00544 
00545 
00546 template<typename eT>
00547 arma_inline
00548 eT&
00549 subview<eT>::operator[](const u32 i)
00550   {
00551   arma_check( (m_ptr == 0), "subview::operator[]: matrix is read-only");
00552   
00553   const u32 in_col = i / n_rows;
00554   const u32 in_row = i % n_rows;
00555     
00556   const u32 index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00557   return access::rw( (*m_ptr).mem[index] );
00558   }
00559 
00560 
00561 
00562 template<typename eT>
00563 arma_inline
00564 eT
00565 subview<eT>::operator[](const u32 i) const
00566   {
00567   const u32 in_col = i / n_rows;
00568   const u32 in_row = i % n_rows;
00569   
00570   const u32 index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00571   return m.mem[index];
00572   }
00573 
00574 
00575 
00576 template<typename eT>
00577 arma_inline
00578 eT&
00579 subview<eT>::operator()(const u32 i)
00580   {
00581   arma_check( (m_ptr == 0), "subview::operator(): matrix is read-only");
00582   arma_debug_check( (i >= n_elem), "subview::operator(): index out of bounds");
00583     
00584   const u32 in_col = i / n_rows;
00585   const u32 in_row = i % n_rows;
00586   
00587   const u32 index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00588   return access::rw( (*m_ptr).mem[index] );
00589   }
00590 
00591 
00592 
00593 template<typename eT>
00594 arma_inline
00595 eT
00596 subview<eT>::operator()(const u32 i) const
00597   {
00598   arma_debug_check( (i >= n_elem), "subview::operator(): index out of bounds");
00599   
00600   const u32 in_col = i / n_rows;
00601   const u32 in_row = i % n_rows;
00602   
00603   const u32 index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00604   return m.mem[index];
00605   }
00606 
00607 
00608 
00609 template<typename eT>
00610 arma_inline
00611 eT&
00612 subview<eT>::operator()(const u32 in_row, const u32 in_col)
00613   {
00614   arma_check( (m_ptr == 0), "subview::operator(): matrix is read-only");
00615   arma_debug_check( ( (n_elem == 0) || (in_row >= n_rows) || (in_col >= n_cols)), "subview::operator(): index out of bounds");
00616   
00617   const u32 index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00618   return access::rw( (*m_ptr).mem[index] );
00619   }
00620 
00621 
00622 
00623 template<typename eT>
00624 arma_inline
00625 eT
00626 subview<eT>::operator()(const u32 in_row, const u32 in_col) const
00627   {
00628   arma_debug_check( ( (n_elem == 0) || (in_row >= n_rows) || (in_col >= n_cols)), "subview::operator(): index out of bounds");
00629   
00630   const u32 index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00631   return m.mem[index];
00632   }
00633 
00634 
00635 
00636 template<typename eT>
00637 arma_inline
00638 eT&
00639 subview<eT>::at(const u32 in_row, const u32 in_col)
00640   {
00641   arma_check( (m_ptr == 0), "subview::at(): matrix is read-only");
00642   
00643   const u32 index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00644   return access::rw( (*m_ptr).mem[index] );
00645   }
00646 
00647 
00648 
00649 template<typename eT>
00650 arma_inline
00651 eT
00652 subview<eT>::at(const u32 in_row, const u32 in_col) const
00653   {
00654   const u32 index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00655   return m.mem[index];
00656   }
00657 
00658 
00659 
00660 template<typename eT>
00661 arma_inline
00662 eT*
00663 subview<eT>::colptr(const u32 in_col)
00664   {
00665   arma_check( (m_ptr == 0), "subview::colptr(): matrix is read-only");
00666     
00667   return & access::rw((*m_ptr).mem[ (in_col + aux_col1)*m.n_rows + aux_row1 ]);
00668   }
00669 
00670 
00671 
00672 template<typename eT>
00673 arma_inline
00674 const eT*
00675 subview<eT>::colptr(const u32 in_col) const
00676   {
00677   return & m.mem[ (in_col + aux_col1)*m.n_rows + aux_row1 ];
00678   }
00679 
00680 
00681 
00682 template<typename eT>
00683 inline
00684 bool
00685 subview<eT>::check_overlap(const subview<eT>& x) const
00686   {
00687   const subview<eT>& t = *this;
00688   
00689   if(&t.m != &x.m)
00690     {
00691     return false;
00692     }
00693   else
00694     {
00695     const bool row_overlap =
00696       (
00697       ( (x.aux_row1 >= t.aux_row1) && (x.aux_row1 <= t.aux_row2) )
00698       || 
00699       ( (x.aux_row2 >= t.aux_row1) && (x.aux_row2 <= t.aux_row2) )
00700       );
00701     
00702     const bool col_overlap =
00703       (
00704       ( (x.aux_col1 >= t.aux_col1) && (x.aux_col1 <= t.aux_col2) )
00705       || 
00706       ( (x.aux_col2 >= t.aux_col1) && (x.aux_col2 <= t.aux_col2) )
00707       );
00708     
00709     
00710     return (row_overlap & col_overlap);
00711     }
00712   }
00713 
00714 
00715 
00716 template<typename eT>
00717 inline
00718 bool
00719 subview<eT>::is_vec() const
00720   {
00721   return ( (n_rows == 1) || (n_cols == 1) );
00722   }
00723 
00724 
00725 
00726 //! X = Y.submat(...)
00727 template<typename eT>
00728 inline
00729 void
00730 subview<eT>::extract(Mat<eT>& actual_out, const subview<eT>& in)
00731   {
00732   arma_extra_debug_sigprint();
00733   
00734   //
00735   const bool alias = (&actual_out == &in.m);
00736   
00737   Mat<eT>* tmp = (alias) ? new Mat<eT> : 0;
00738   Mat<eT>& out = (alias) ? (*tmp)      : actual_out;
00739   
00740   //
00741   
00742   const u32 n_rows = in.n_rows;  // number of rows in the subview
00743   const u32 n_cols = in.n_cols;  // number of columns in the subview
00744   
00745   out.set_size(n_rows, n_cols);
00746   
00747   arma_extra_debug_print(arma_boost::format("out.n_rows = %d   out.n_cols = %d    in.m.n_rows = %d  in.m.n_cols = %d") % out.n_rows % out.n_cols % in.m.n_rows % in.m.n_cols );
00748   
00749 
00750   if(in.is_vec() == true)
00751     {
00752     if(n_cols == 1)   // a column vector
00753       {
00754       arma_extra_debug_print("subview::extract(): copying col (going across rows)");
00755       
00756             eT* out_mem    = out.memptr();
00757       const eT* in_coldata = in.colptr(0);  // the first column of the subview, taking into account any row offset
00758       
00759       for(u32 row=0; row<n_rows; ++row)
00760         {
00761         out_mem[row] = in_coldata[row];
00762         }
00763       }
00764     else   // a row vector
00765       {
00766       arma_extra_debug_print("subview::extract(): copying row (going across columns)");
00767       
00768       const Mat<eT>& X = in.m;
00769       
00770             eT* out_mem   = out.memptr();
00771       const u32 row       = in.aux_row1;
00772       const u32 start_col = in.aux_col1;
00773       
00774       for(u32 i=0; i<n_cols; ++i)
00775         {
00776         out_mem[i] = X.at(row, i+start_col);
00777         }
00778       }
00779     }
00780   else   // general submatrix
00781     {
00782     arma_extra_debug_print("subview::extract(): general submatrix");
00783     
00784     for(u32 col = 0; col<n_cols; ++col)   
00785       {
00786             eT* out_coldata = out.colptr(col);
00787       const eT*  in_coldata =  in.colptr(col);
00788       
00789       for(u32 row = 0; row<n_rows; ++row)
00790         {
00791         out_coldata[row] = in_coldata[row];
00792         }
00793       }
00794     }
00795   
00796   
00797   if(alias)
00798     {
00799     actual_out = out;
00800     delete tmp;
00801     }
00802   
00803   }
00804 
00805 
00806 
00807 //! X += Y.submat(...)
00808 template<typename eT>
00809 inline
00810 void
00811 subview<eT>::plus_inplace(Mat<eT>& out, const subview<eT>& in)
00812   {
00813   arma_extra_debug_sigprint();
00814   
00815   arma_debug_assert_same_size(out, in, "matrix addition");
00816   
00817   if(&out != &in.m)
00818     {
00819     const u32 n_rows = out.n_rows;
00820     const u32 n_cols = out.n_cols;
00821     
00822     for(u32 col = 0; col<n_cols; ++col)
00823       {
00824             eT* out_coldata = out.colptr(col);
00825       const eT*  in_coldata =  in.colptr(col);
00826       
00827       for(u32 row = 0; row<n_rows; ++row)
00828         {
00829         out_coldata[row] += in_coldata[row];
00830         }
00831       }
00832     }
00833   else
00834     {
00835     // X += X.submat(...)
00836     // this only makes sense if X and X.submat(...) are the same size
00837     
00838     eT* out_mem = out.memptr();
00839     
00840     for(u32 i=0; i<out.n_elem; ++i)
00841       {
00842       out_mem[i] *= eT(2);
00843       }
00844     }
00845   
00846   }
00847 
00848 
00849 
00850 //! X -= Y.submat(...)
00851 template<typename eT>
00852 inline
00853 void
00854 subview<eT>::minus_inplace(Mat<eT>& out, const subview<eT>& in)
00855   {
00856   arma_extra_debug_sigprint();
00857   
00858   arma_debug_assert_same_size(out, in, "matrix subtraction");
00859   
00860   if(&out != &in.m)
00861     {
00862     const u32 n_rows = out.n_rows;
00863     const u32 n_cols = out.n_cols;
00864     
00865     for(u32 col = 0; col<n_cols; ++col)
00866       {
00867             eT* out_coldata = out.colptr(col);
00868       const eT*  in_coldata =  in.colptr(col);
00869       
00870       for(u32 row = 0; row<n_rows; ++row)
00871         {
00872         out_coldata[row] -= in_coldata[row];
00873         }
00874       }
00875     }
00876   else
00877     {
00878     out.zeros();
00879     }
00880   
00881   }
00882 
00883 
00884 
00885 //! X *= Y.submat(...)
00886 template<typename eT>
00887 inline
00888 void
00889 subview<eT>::times_inplace(Mat<eT>& out, const subview<eT>& in)
00890   {
00891   arma_extra_debug_sigprint();
00892   
00893   arma_debug_assert_mul_size(out, in, "matrix multiply");
00894 
00895   if(&out != &in.m)
00896     {
00897     glue_times::apply_inplace(out, Mat<eT>(in));
00898     }
00899   else
00900     {
00901     glue_times::apply_inplace(out, out);
00902     }
00903   
00904   }
00905 
00906 
00907 
00908 //! X %= Y.submat(...)
00909 template<typename eT>
00910 inline
00911 void
00912 subview<eT>::schur_inplace(Mat<eT>& out, const subview<eT>& in)
00913   {
00914   arma_extra_debug_sigprint();
00915   
00916   arma_debug_assert_same_size(out, in, "matrix schur product");
00917   
00918   if(&out != &in.m)
00919     {
00920     const u32 n_rows = out.n_rows;
00921     const u32 n_cols = out.n_cols;
00922     
00923     for(u32 col = 0; col<n_cols; ++col)
00924       {
00925             eT* out_coldata = out.colptr(col);
00926       const eT*  in_coldata =  in.colptr(col);
00927       
00928       for(u32 row = 0; row<n_rows; ++row)
00929         {
00930         out_coldata[row] *= in_coldata[row];
00931         }
00932       }
00933     }
00934   else
00935     {
00936     eT* out_mem = out.memptr();
00937     
00938     for(u32 i=0; i<out.n_elem; ++i)
00939       {
00940       const eT tmp = out_mem[i];
00941       out_mem[i] = tmp*tmp;
00942       }
00943     }
00944   
00945   }
00946 
00947 
00948 
00949 //! X /= Y.submat(...)
00950 template<typename eT>
00951 inline
00952 void
00953 subview<eT>::div_inplace(Mat<eT>& out, const subview<eT>& in)
00954   {
00955   arma_extra_debug_sigprint();
00956   
00957   arma_debug_assert_same_size(out, in, "element-wise matrix division");
00958   
00959   if(&out != &in.m)
00960     {
00961     const u32 n_rows = out.n_rows;
00962     const u32 n_cols = out.n_cols;
00963     
00964     for(u32 col = 0; col<n_cols; ++col)
00965       {
00966             eT* out_coldata = out.colptr(col);
00967       const eT*  in_coldata =  in.colptr(col);
00968       
00969       for(u32 row = 0; row<n_rows; ++row)
00970         {
00971         out_coldata[row] /= in_coldata[row];
00972         }
00973       }
00974     }
00975   else
00976     {
00977     eT* out_mem = out.memptr();
00978     
00979     for(u32 i=0; i<out.n_elem; ++i)
00980       {
00981       const eT tmp = out_mem[i];
00982       out_mem[i] = tmp/tmp;  // using tmp/tmp as tmp might be zero
00983       }
00984     }
00985   
00986   }
00987 
00988 
00989 
00990 //
00991 //
00992 //
00993 
00994 
00995 
00996 template<typename eT>
00997 arma_inline
00998 subview_col<eT>::subview_col(const Mat<eT>& in_m, const u32 in_col)
00999   : subview<eT>(in_m, 0, in_col, in_m.n_rows-1, in_col)
01000   {
01001   arma_extra_debug_sigprint();
01002   }
01003 
01004 
01005 
01006 template<typename eT>
01007 arma_inline
01008 subview_col<eT>::subview_col(Mat<eT>& in_m, const u32 in_col)
01009   : subview<eT>(in_m, 0, in_col, in_m.n_rows-1, in_col)
01010   {
01011   arma_extra_debug_sigprint();
01012   }
01013 
01014 
01015 
01016 template<typename eT>
01017 arma_inline
01018 subview_col<eT>::subview_col(const Mat<eT>& in_m, const u32 in_col, const u32 in_row1, const u32 in_row2)
01019   : subview<eT>(in_m, in_row1, in_col, in_row2, in_col)
01020   {
01021   arma_extra_debug_sigprint();
01022   }
01023 
01024 
01025 
01026 template<typename eT>
01027 arma_inline
01028 subview_col<eT>::subview_col(Mat<eT>& in_m, const u32 in_col, const u32 in_row1, const u32 in_row2)
01029   : subview<eT>(in_m, in_row1, in_col, in_row2, in_col)
01030   {
01031   arma_extra_debug_sigprint();
01032   }
01033 
01034 
01035 
01036 template<typename eT>
01037 inline
01038 void
01039 subview_col<eT>::operator=(const subview<eT>& X)
01040   {
01041   arma_extra_debug_sigprint();
01042   
01043   subview<eT>::operator=(X);
01044   arma_debug_check( (subview<eT>::n_cols > 1), "subview_col(): incompatible dimensions" );
01045   }
01046 
01047 
01048 
01049 template<typename eT>
01050 inline
01051 void
01052 subview_col<eT>::operator=(const subview_col<eT>& X)
01053   {
01054   arma_extra_debug_sigprint();
01055   
01056   subview<eT>::operator=(X); // interprets 'subview_col' as 'subview'
01057   arma_debug_check( (subview<eT>::n_cols > 1), "subview_col(): incompatible dimensions" );
01058   }
01059 
01060 
01061 
01062 template<typename eT>
01063 template<typename T1>
01064 inline
01065 void
01066 subview_col<eT>::operator=(const Base<eT,T1>& X)
01067   {
01068   arma_extra_debug_sigprint();
01069   
01070   subview<eT>::operator=(X);
01071   arma_debug_check( (subview<eT>::n_cols > 1), "subview_col(): incompatible dimensions" );
01072   }
01073 
01074 
01075 
01076 
01077 //
01078 //
01079 //
01080 
01081 
01082 
01083 template<typename eT>
01084 arma_inline
01085 subview_row<eT>::subview_row(const Mat<eT>& in_m, const u32 in_row)
01086   : subview<eT>(in_m, in_row, 0, in_row, in_m.n_cols-1)
01087   {
01088   arma_extra_debug_sigprint();
01089   }
01090 
01091 
01092 
01093 template<typename eT>
01094 arma_inline
01095 subview_row<eT>::subview_row(Mat<eT>& in_m, const u32 in_row)
01096   : subview<eT>(in_m, in_row, 0, in_row, in_m.n_cols-1)
01097   {
01098   arma_extra_debug_sigprint();
01099   }
01100 
01101 
01102 
01103 template<typename eT>
01104 arma_inline
01105 subview_row<eT>::subview_row(const Mat<eT>& in_m, const u32 in_row, const u32 in_col1, const u32 in_col2)
01106   : subview<eT>(in_m, in_row, in_col1, in_row, in_col2)
01107   {
01108   arma_extra_debug_sigprint();
01109   }
01110 
01111 
01112 
01113 template<typename eT>
01114 arma_inline
01115 subview_row<eT>::subview_row(Mat<eT>& in_m, const u32 in_row, const u32 in_col1, const u32 in_col2)
01116   : subview<eT>(in_m, in_row, in_col1, in_row, in_col2)
01117   {
01118   arma_extra_debug_sigprint();
01119   }
01120 
01121 
01122 
01123 template<typename eT>
01124 inline
01125 void
01126 subview_row<eT>::operator=(const subview<eT>& X)
01127   {
01128   arma_extra_debug_sigprint();
01129   
01130   subview<eT>::operator=(X);
01131   arma_debug_check( (subview<eT>::n_rows > 1), "subview_row(): incompatible dimensions" );
01132   }
01133 
01134 
01135 
01136 template<typename eT>
01137 inline
01138 void
01139 subview_row<eT>::operator=(const subview_row<eT>& X)
01140   {
01141   arma_extra_debug_sigprint();
01142   
01143   subview<eT>::operator=(X); // interprets 'subview_row' as 'subview'
01144   arma_debug_check( (subview<eT>::n_rows > 1), "subview_row(): incompatible dimensions" );
01145   }
01146 
01147 
01148 
01149 template<typename eT>
01150 template<typename T1>
01151 inline
01152 void
01153 subview_row<eT>::operator=(const Base<eT,T1>& X)
01154   {
01155   arma_extra_debug_sigprint();
01156   
01157   subview<eT>::operator=(X);
01158   arma_debug_check( (subview<eT>::n_rows > 1), "subview_row(): incompatible dimensions" );
01159   }
01160 
01161 
01162 
01163 //! @}