"Fossies" - the Fresh Open Source Software Archive

Member "armadillo-9.800.3/include/armadillo_bits/MapMat_meat.hpp" (16 Jun 2016, 34555 Bytes) of package /linux/misc/armadillo-9.800.3.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "MapMat_meat.hpp" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.600.4_vs_9.600.5.

    1 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
    2 // Copyright 2008-2016 National ICT Australia (NICTA)
    3 // 
    4 // Licensed under the Apache License, Version 2.0 (the "License");
    5 // you may not use this file except in compliance with the License.
    6 // You may obtain a copy of the License at
    7 // http://www.apache.org/licenses/LICENSE-2.0
    8 // 
    9 // Unless required by applicable law or agreed to in writing, software
   10 // distributed under the License is distributed on an "AS IS" BASIS,
   11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12 // See the License for the specific language governing permissions and
   13 // limitations under the License.
   14 // ------------------------------------------------------------------------
   15 
   16 
   17 //! \addtogroup MapMat
   18 //! @{
   19 
   20 
   21 
   22 template<typename eT>
   23 inline
   24 MapMat<eT>::~MapMat()
   25   {
   26   arma_extra_debug_sigprint_this(this);
   27   
   28   if(map_ptr)  { (*map_ptr).clear();  delete map_ptr; }
   29   
   30   // try to expose buggy user code that accesses deleted objects
   31   if(arma_config::debug)  { map_ptr = NULL; }
   32   
   33   arma_type_check(( is_supported_elem_type<eT>::value == false ));
   34   }
   35 
   36 
   37 
   38 template<typename eT>
   39 inline
   40 MapMat<eT>::MapMat()
   41   : n_rows (0)
   42   , n_cols (0)
   43   , n_elem (0)
   44   , map_ptr(NULL)
   45   {
   46   arma_extra_debug_sigprint_this(this);
   47   
   48   init_cold();
   49   }
   50 
   51 
   52 
   53 template<typename eT>
   54 inline
   55 MapMat<eT>::MapMat(const uword in_n_rows, const uword in_n_cols)
   56   : n_rows (in_n_rows)
   57   , n_cols (in_n_cols)
   58   , n_elem (in_n_rows * in_n_cols)
   59   , map_ptr(NULL)
   60   {
   61   arma_extra_debug_sigprint_this(this);
   62   
   63   init_cold();
   64   }
   65 
   66 
   67 
   68 template<typename eT>
   69 inline
   70 MapMat<eT>::MapMat(const SizeMat& s)
   71   : n_rows (s.n_rows)
   72   , n_cols (s.n_cols)
   73   , n_elem (s.n_rows * s.n_cols)
   74   , map_ptr(NULL)
   75   {
   76   arma_extra_debug_sigprint_this(this);
   77   
   78   init_cold();
   79   }
   80 
   81 
   82 
   83 template<typename eT>
   84 inline
   85 MapMat<eT>::MapMat(const MapMat<eT>& x)
   86   : n_rows (0)
   87   , n_cols (0)
   88   , n_elem (0)
   89   , map_ptr(NULL)
   90   {
   91   arma_extra_debug_sigprint_this(this);
   92   
   93   init_cold();
   94   
   95   (*this).operator=(x);
   96   }
   97 
   98 
   99 
  100 template<typename eT>
  101 inline
  102 void
  103 MapMat<eT>::operator=(const MapMat<eT>& x)
  104   {
  105   arma_extra_debug_sigprint();
  106   
  107   if(this == &x)  { return; }
  108   
  109   access::rw(n_rows) = x.n_rows;
  110   access::rw(n_cols) = x.n_cols;
  111   access::rw(n_elem) = x.n_elem;
  112   
  113   (*map_ptr) = *(x.map_ptr);
  114   }
  115 
  116 
  117 
  118 template<typename eT>
  119 inline
  120 MapMat<eT>::MapMat(const SpMat<eT>& x)
  121   : n_rows (0)
  122   , n_cols (0)
  123   , n_elem (0)
  124   , map_ptr(NULL)
  125   {
  126   arma_extra_debug_sigprint_this(this);
  127   
  128   init_cold();
  129   
  130   (*this).operator=(x);
  131   }
  132 
  133 
  134 
  135 template<typename eT>
  136 inline
  137 void
  138 MapMat<eT>::operator=(const SpMat<eT>& x)
  139   {
  140   arma_extra_debug_sigprint();
  141   
  142   const uword x_n_rows = x.n_rows;
  143   const uword x_n_cols = x.n_cols;
  144   
  145   (*this).zeros(x_n_rows, x_n_cols);
  146   
  147   if(x.n_nonzero == 0)  { return; }
  148   
  149   const    eT* x_values      = x.values;
  150   const uword* x_row_indices = x.row_indices;
  151   const uword* x_col_ptrs    = x.col_ptrs;
  152   
  153   map_type& map_ref = (*map_ptr);
  154   
  155   for(uword col = 0; col < x_n_cols; ++col)
  156     {
  157     const uword start = x_col_ptrs[col    ];
  158     const uword end   = x_col_ptrs[col + 1];
  159     
  160     for(uword i = start; i < end; ++i)
  161       {
  162       const uword row = x_row_indices[i];
  163       const eT    val = x_values[i];
  164       
  165       const uword index = (x_n_rows * col) + row;
  166       
  167       #if defined(ARMA_USE_CXX11)
  168         map_ref.emplace_hint(map_ref.cend(), index, val);
  169       #else
  170         map_ref.operator[](index) = val;
  171       #endif
  172       }
  173     }
  174   }
  175 
  176 
  177 
  178 #if defined(ARMA_USE_CXX11)
  179 
  180   template<typename eT>
  181   inline
  182   MapMat<eT>::MapMat(MapMat<eT>&& x)
  183     : n_rows (x.n_rows )
  184     , n_cols (x.n_cols )
  185     , n_elem (x.n_elem )
  186     , map_ptr(x.map_ptr)
  187     {
  188     arma_extra_debug_sigprint_this(this);
  189     
  190     access::rw(x.n_rows)  = 0;
  191     access::rw(x.n_cols)  = 0;
  192     access::rw(x.n_elem)  = 0;
  193     access::rw(x.map_ptr) = NULL;
  194     }
  195   
  196   
  197   
  198   template<typename eT>
  199   inline
  200   void
  201   MapMat<eT>::operator=(MapMat<eT>&& x)
  202     {
  203     arma_extra_debug_sigprint();
  204     
  205     reset();
  206     
  207     if(map_ptr)  { delete map_ptr; }
  208     
  209     access::rw(n_rows)  = x.n_rows;
  210     access::rw(n_cols)  = x.n_cols;
  211     access::rw(n_elem)  = x.n_elem;
  212     access::rw(map_ptr) = x.map_ptr;
  213     
  214     access::rw(x.n_rows)  = 0;
  215     access::rw(x.n_cols)  = 0;
  216     access::rw(x.n_elem)  = 0;
  217     access::rw(x.map_ptr) = NULL;
  218     }
  219 
  220 #endif
  221 
  222 
  223 
  224 template<typename eT>
  225 inline
  226 void
  227 MapMat<eT>::reset()
  228   {
  229   arma_extra_debug_sigprint();
  230   
  231   access::rw(n_rows) = 0;
  232   access::rw(n_cols) = 0;
  233   access::rw(n_elem) = 0;
  234   
  235   if((*map_ptr).empty() == false)  { (*map_ptr).clear(); }
  236   }
  237 
  238 
  239 
  240 template<typename eT>
  241 inline
  242 void
  243 MapMat<eT>::set_size(const uword in_n_rows)
  244   {
  245   arma_extra_debug_sigprint();
  246   
  247   init_warm(in_n_rows, 1);
  248   }
  249 
  250 
  251 
  252 template<typename eT>
  253 inline
  254 void
  255 MapMat<eT>::set_size(const uword in_n_rows, const uword in_n_cols)
  256   {
  257   arma_extra_debug_sigprint();
  258   
  259   init_warm(in_n_rows, in_n_cols);
  260   }
  261 
  262 
  263 
  264 template<typename eT>
  265 inline
  266 void
  267 MapMat<eT>::set_size(const SizeMat& s)
  268   {
  269   arma_extra_debug_sigprint();
  270   
  271   init_warm(s.n_rows, s.n_cols);
  272   }
  273 
  274 
  275 
  276 template<typename eT>
  277 inline
  278 void
  279 MapMat<eT>::zeros()
  280   {
  281   arma_extra_debug_sigprint();
  282   
  283   (*map_ptr).clear();
  284   }
  285 
  286 
  287 
  288 template<typename eT>
  289 inline
  290 void
  291 MapMat<eT>::zeros(const uword in_n_rows)
  292   {
  293   arma_extra_debug_sigprint();
  294   
  295   init_warm(in_n_rows, 1);
  296   
  297   (*map_ptr).clear();
  298   }
  299 
  300 
  301 
  302 template<typename eT>
  303 inline
  304 void
  305 MapMat<eT>::zeros(const uword in_n_rows, const uword in_n_cols)
  306   {
  307   arma_extra_debug_sigprint();
  308   
  309   init_warm(in_n_rows, in_n_cols);
  310   
  311   (*map_ptr).clear();
  312   }
  313 
  314 
  315 
  316 template<typename eT>
  317 inline
  318 void
  319 MapMat<eT>::zeros(const SizeMat& s)
  320   {
  321   arma_extra_debug_sigprint();
  322   
  323   init_warm(s.n_rows, s.n_cols);
  324   
  325   (*map_ptr).clear();
  326   }
  327 
  328 
  329 
  330 template<typename eT>
  331 inline
  332 void
  333 MapMat<eT>::eye()
  334   {
  335   arma_extra_debug_sigprint();
  336   
  337   (*this).eye(n_rows, n_cols);
  338   }
  339 
  340 
  341 
  342 template<typename eT>
  343 inline
  344 void
  345 MapMat<eT>::eye(const uword in_n_rows, const uword in_n_cols)
  346   {
  347   arma_extra_debug_sigprint();
  348   
  349   zeros(in_n_rows, in_n_cols);
  350   
  351   const uword N = (std::min)(in_n_rows, in_n_cols);
  352   
  353   map_type& map_ref = (*map_ptr);
  354   
  355   for(uword i=0; i<N; ++i)
  356     {
  357     const uword index = (in_n_rows * i) + i;
  358     
  359     #if defined(ARMA_USE_CXX11)
  360       map_ref.emplace_hint(map_ref.cend(), index, eT(1));
  361     #else
  362       map_ref.operator[](index) = eT(1);
  363     #endif
  364     }
  365   }
  366 
  367 
  368 
  369 template<typename eT>
  370 inline
  371 void
  372 MapMat<eT>::eye(const SizeMat& s)
  373   {
  374   arma_extra_debug_sigprint();
  375   
  376   (*this).eye(s.n_rows, s.n_cols);
  377   }
  378 
  379 
  380 
  381 template<typename eT>
  382 inline
  383 void
  384 MapMat<eT>::speye()
  385   {
  386   arma_extra_debug_sigprint();
  387   
  388   (*this).eye();
  389   }
  390 
  391 
  392 
  393 template<typename eT>
  394 inline
  395 void
  396 MapMat<eT>::speye(const uword in_n_rows, const uword in_n_cols)
  397   {
  398   arma_extra_debug_sigprint();
  399   
  400   (*this).eye(in_n_rows, in_n_cols);
  401   }
  402 
  403 
  404 
  405 template<typename eT>
  406 inline
  407 void
  408 MapMat<eT>::speye(const SizeMat& s)
  409   {
  410   arma_extra_debug_sigprint();
  411   
  412   (*this).eye(s);
  413   }
  414 
  415 
  416 
  417 template<typename eT>
  418 arma_inline
  419 arma_warn_unused
  420 MapMat_val<eT>
  421 MapMat<eT>::operator[](const uword index)
  422   {
  423   return MapMat_val<eT>(*this, index);
  424   }
  425 
  426 
  427 
  428 template<typename eT>
  429 inline
  430 arma_warn_unused
  431 eT
  432 MapMat<eT>::operator[](const uword index) const
  433   {
  434   map_type& map_ref = (*map_ptr);
  435   
  436   typename map_type::const_iterator it     = map_ref.find(index);
  437   typename map_type::const_iterator it_end = map_ref.end();
  438   
  439   return (it != it_end) ? eT((*it).second) : eT(0);
  440   }
  441 
  442 
  443 
  444 template<typename eT>
  445 arma_inline
  446 arma_warn_unused
  447 MapMat_val<eT>
  448 MapMat<eT>::operator()(const uword index)
  449   {
  450   arma_debug_check( (index >= n_elem), "MapMat::operator(): index out of bounds" );
  451   
  452   return MapMat_val<eT>(*this, index);
  453   }
  454 
  455 
  456 
  457 template<typename eT>
  458 inline
  459 arma_warn_unused
  460 eT
  461 MapMat<eT>::operator()(const uword index) const
  462   {
  463   arma_debug_check( (index >= n_elem), "MapMat::operator(): index out of bounds" );
  464   
  465   map_type& map_ref = (*map_ptr);
  466   
  467   typename map_type::const_iterator it     = map_ref.find(index);
  468   typename map_type::const_iterator it_end = map_ref.end();
  469   
  470   return (it != it_end) ? eT((*it).second) : eT(0);
  471   }
  472 
  473 
  474 
  475 template<typename eT>
  476 arma_inline
  477 arma_warn_unused
  478 MapMat_val<eT>
  479 MapMat<eT>::at(const uword in_row, const uword in_col)
  480   {
  481   const uword index = (n_rows * in_col) + in_row;
  482   
  483   return MapMat_val<eT>(*this, index);
  484   }
  485 
  486 
  487 
  488 template<typename eT>
  489 inline
  490 arma_warn_unused
  491 eT
  492 MapMat<eT>::at(const uword in_row, const uword in_col) const
  493   {
  494   const uword index = (n_rows * in_col) + in_row;
  495   
  496   map_type& map_ref = (*map_ptr);
  497   
  498   typename map_type::const_iterator it     = map_ref.find(index);
  499   typename map_type::const_iterator it_end = map_ref.end();
  500   
  501   return (it != it_end) ? eT((*it).second) : eT(0);
  502   }
  503 
  504 
  505 
  506 template<typename eT>
  507 arma_inline
  508 arma_warn_unused
  509 MapMat_val<eT>
  510 MapMat<eT>::operator()(const uword in_row, const uword in_col)
  511   {
  512   arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "MapMat::operator(): index out of bounds" );
  513   
  514   const uword index = (n_rows * in_col) + in_row;
  515   
  516   return MapMat_val<eT>(*this, index);
  517   }
  518 
  519 
  520 
  521 template<typename eT>
  522 inline
  523 arma_warn_unused
  524 eT
  525 MapMat<eT>::operator()(const uword in_row, const uword in_col) const
  526   {
  527   arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "MapMat::operator(): index out of bounds" );
  528   
  529   const uword index = (n_rows * in_col) + in_row;
  530   
  531   map_type& map_ref = (*map_ptr);
  532   
  533   typename map_type::const_iterator it     = map_ref.find(index);
  534   typename map_type::const_iterator it_end = map_ref.end();
  535   
  536   return (it != it_end) ? eT((*it).second) : eT(0);
  537   }
  538 
  539 
  540 
  541 template<typename eT>
  542 inline
  543 arma_warn_unused
  544 bool
  545 MapMat<eT>::is_empty() const
  546   {
  547   return (n_elem == 0);
  548   }
  549 
  550 
  551 
  552 template<typename eT>
  553 inline
  554 arma_warn_unused
  555 bool
  556 MapMat<eT>::is_vec() const
  557   {
  558   return ( (n_rows == 1) || (n_cols == 1) );
  559   }
  560 
  561 
  562 
  563 template<typename eT>
  564 inline
  565 arma_warn_unused
  566 bool
  567 MapMat<eT>::is_rowvec() const
  568   {
  569   return (n_rows == 1);
  570   }
  571 
  572 
  573 
  574 //! returns true if the object can be interpreted as a column vector
  575 template<typename eT>
  576 inline
  577 arma_warn_unused
  578 bool
  579 MapMat<eT>::is_colvec() const
  580   {
  581   return (n_cols == 1);
  582   }
  583 
  584 
  585 
  586 template<typename eT>
  587 inline
  588 arma_warn_unused
  589 bool
  590 MapMat<eT>::is_square() const
  591   {
  592   return (n_rows == n_cols);
  593   }
  594 
  595 
  596 
  597 // this function is for debugging purposes only
  598 template<typename eT>
  599 inline
  600 void
  601 MapMat<eT>::sprandu(const uword in_n_rows, const uword in_n_cols, const double density)
  602   {
  603   arma_extra_debug_sigprint();
  604   
  605   zeros(in_n_rows, in_n_cols);
  606   
  607   const uword N = uword(density * double(n_elem));
  608   
  609   const Col<eT>    vals(N, fill::randu);
  610   const Col<uword> indx = linspace< Col<uword> >(0, ((n_elem > 0) ? uword(n_elem-1) : uword(0)) , N);
  611   
  612   const eT*    vals_mem = vals.memptr();
  613   const uword* indx_mem = indx.memptr();
  614   
  615   map_type& map_ref = (*map_ptr);
  616   
  617   for(uword i=0; i < N; ++i)
  618     {
  619     const uword index = indx_mem[i];
  620     const eT    val   = vals_mem[i];
  621     
  622     #if defined(ARMA_USE_CXX11)
  623       map_ref.emplace_hint(map_ref.cend(), index, val);
  624     #else
  625       map_ref.operator[](index) = val;
  626     #endif
  627     }
  628   }
  629 
  630 
  631 
  632 // this function is for debugging purposes only
  633 template<typename eT>
  634 inline
  635 void
  636 MapMat<eT>::print(const std::string& extra_text) const
  637   {
  638   arma_extra_debug_sigprint();
  639   
  640   if(extra_text.length() != 0)
  641     {
  642     const std::streamsize orig_width = get_cout_stream().width();
  643     
  644     get_cout_stream() << extra_text << '\n';
  645     
  646     get_cout_stream().width(orig_width);
  647     }
  648   
  649   map_type& map_ref = (*map_ptr);
  650   
  651   const uword n_nonzero = uword(map_ref.size());
  652   
  653   const double density = (n_elem > 0) ? ((double(n_nonzero) / double(n_elem))*double(100)) : double(0);
  654   
  655   get_cout_stream()
  656     << "[matrix size: " << n_rows << 'x' << n_cols << "; n_nonzero: " << n_nonzero
  657     << "; density: " << density << "%]\n\n";
  658   
  659   if(n_nonzero > 0)
  660     {
  661     typename map_type::const_iterator it = map_ref.begin();
  662 
  663     for(uword i=0; i < n_nonzero; ++i)
  664       {
  665       const std::pair<uword, eT>& entry = (*it);
  666       
  667       const uword index = entry.first;
  668       const eT    val   = entry.second;
  669       
  670       const uword row = index % n_rows;
  671       const uword col = index / n_rows;
  672       
  673       get_cout_stream() << '(' << row << ", " << col << ") ";
  674       get_cout_stream() << val << '\n';
  675       
  676       ++it;
  677       }
  678     }
  679   
  680   get_cout_stream().flush();
  681   }
  682 
  683 
  684 
  685 template<typename eT>
  686 inline
  687 uword
  688 MapMat<eT>::get_n_nonzero() const
  689   {
  690   arma_extra_debug_sigprint();
  691   
  692   return uword((*map_ptr).size());
  693   }
  694 
  695 
  696 
  697 template<typename eT>
  698 inline
  699 void
  700 MapMat<eT>::get_locval_format(umat& locs, Col<eT>& vals) const
  701   {
  702   arma_extra_debug_sigprint();
  703   
  704   map_type& map_ref = (*map_ptr);
  705   
  706   typename map_type::const_iterator it = map_ref.begin();
  707   
  708   const uword N = uword(map_ref.size());
  709   
  710   locs.set_size(2,N);
  711   vals.set_size(N);
  712   
  713   eT* vals_mem = vals.memptr();
  714   
  715   for(uword i=0; i<N; ++i)
  716     {
  717     const std::pair<uword, eT>& entry = (*it);
  718     
  719     const uword index = entry.first;
  720     const eT    val   = entry.second;
  721     
  722     const uword row = index % n_rows;
  723     const uword col = index / n_rows;
  724     
  725     uword* locs_colptr = locs.colptr(i);
  726     
  727     locs_colptr[0] = row;
  728     locs_colptr[1] = col;
  729     
  730     vals_mem[i] = val;
  731     
  732     ++it;
  733     }
  734   }
  735 
  736 
  737 
  738 template<typename eT>
  739 inline
  740 void
  741 MapMat<eT>::init_cold()
  742   {
  743   arma_extra_debug_sigprint();
  744   
  745   // ensure that n_elem can hold the result of (n_rows * n_cols)
  746   
  747   #if (defined(ARMA_USE_CXX11) || defined(ARMA_64BIT_WORD))
  748     const char* error_message = "MapMat(): requested size is too large";
  749   #else
  750     const char* error_message = "MapMat(): requested size is too large; suggest to compile in C++11 mode or enable ARMA_64BIT_WORD";
  751   #endif
  752   
  753   arma_debug_check
  754     (
  755       (
  756       ( (n_rows > ARMA_MAX_UHWORD) || (n_cols > ARMA_MAX_UHWORD) )
  757         ? ( (double(n_rows) * double(n_cols)) > double(ARMA_MAX_UWORD) )
  758         : false
  759       ),
  760     error_message
  761     );
  762   
  763   map_ptr = new (std::nothrow) map_type;
  764   
  765   arma_check_bad_alloc( (map_ptr == NULL), "MapMat(): out of memory" );
  766   }
  767 
  768 
  769 
  770 template<typename eT>
  771 inline
  772 void
  773 MapMat<eT>::init_warm(const uword in_n_rows, const uword in_n_cols)
  774   {
  775   arma_extra_debug_sigprint();
  776   
  777   if( (n_rows == in_n_rows) && (n_cols == in_n_cols))  { return; }
  778   
  779   // ensure that n_elem can hold the result of (n_rows * n_cols)
  780   
  781   #if (defined(ARMA_USE_CXX11) || defined(ARMA_64BIT_WORD))
  782     const char* error_message = "MapMat(): requested size is too large";
  783   #else
  784     const char* error_message = "MapMat(): requested size is too large; suggest to compile in C++11 mode or enable ARMA_64BIT_WORD";
  785   #endif
  786   
  787   arma_debug_check
  788     (
  789       (
  790       ( (in_n_rows > ARMA_MAX_UHWORD) || (in_n_cols > ARMA_MAX_UHWORD) )
  791         ? ( (double(in_n_rows) * double(in_n_cols)) > double(ARMA_MAX_UWORD) )
  792         : false
  793       ),
  794     error_message
  795     );
  796   
  797   const uword new_n_elem = in_n_rows * in_n_cols;
  798   
  799   access::rw(n_rows) = in_n_rows;
  800   access::rw(n_cols) = in_n_cols;
  801   access::rw(n_elem) = new_n_elem;
  802   
  803   if(new_n_elem == 0)  { (*map_ptr).clear(); }
  804   }
  805 
  806 
  807 
  808 template<typename eT>
  809 arma_inline
  810 void
  811 MapMat<eT>::set_val(const uword index, const eT& in_val)
  812   {
  813   arma_extra_debug_sigprint();
  814   
  815   if(in_val != eT(0))
  816     {
  817     #if defined(ARMA_USE_CXX11)
  818       {
  819       map_type& map_ref = (*map_ptr);
  820       
  821       if( (map_ref.empty() == false) && (index > uword(map_ref.crbegin()->first)) )
  822         {
  823         map_ref.emplace_hint(map_ref.cend(), index, in_val);
  824         }
  825       else
  826         {
  827         map_ref.operator[](index) = in_val;
  828         }
  829       }
  830     #else
  831       {
  832       (*map_ptr).operator[](index) = in_val;
  833       }
  834     #endif
  835     }
  836   else
  837     {
  838     (*this).erase_val(index);
  839     }
  840   }
  841 
  842 
  843 
  844 template<typename eT>
  845 inline
  846 void
  847 MapMat<eT>::erase_val(const uword index)
  848   {
  849   arma_extra_debug_sigprint();
  850   
  851   map_type& map_ref = (*map_ptr);
  852   
  853   typename map_type::iterator it     = map_ref.find(index);
  854   typename map_type::iterator it_end = map_ref.end();
  855   
  856   if(it != it_end)  { map_ref.erase(it); }
  857   }
  858 
  859 
  860 
  861 
  862 
  863 
  864 // MapMat_val
  865 
  866 
  867 
  868 template<typename eT>
  869 arma_inline
  870 MapMat_val<eT>::MapMat_val(MapMat<eT>& in_parent, const uword in_index)
  871   : parent(in_parent)
  872   , index (in_index )
  873   {
  874   arma_extra_debug_sigprint();
  875   }
  876 
  877 
  878 
  879 template<typename eT>
  880 arma_inline
  881 MapMat_val<eT>::operator eT() const
  882   {
  883   arma_extra_debug_sigprint();
  884   
  885   const MapMat<eT>& const_parent = parent;
  886   
  887   return const_parent.operator[](index);
  888   }
  889 
  890 
  891 
  892 template<typename eT>
  893 arma_inline
  894 typename get_pod_type<eT>::result
  895 MapMat_val<eT>::real() const
  896   {
  897   arma_extra_debug_sigprint();
  898   
  899   typedef typename get_pod_type<eT>::result T;
  900   
  901   const MapMat<eT>& const_parent = parent;
  902   
  903   return T( access::tmp_real( const_parent.operator[](index) ) );
  904   }
  905 
  906 
  907 
  908 template<typename eT>
  909 arma_inline
  910 typename get_pod_type<eT>::result
  911 MapMat_val<eT>::imag() const
  912   {
  913   arma_extra_debug_sigprint();
  914   
  915   typedef typename get_pod_type<eT>::result T;
  916   
  917   const MapMat<eT>& const_parent = parent;
  918   
  919   return T( access::tmp_imag( const_parent.operator[](index) ) );
  920   }
  921 
  922 
  923 
  924 template<typename eT>
  925 arma_inline
  926 void
  927 MapMat_val<eT>::operator=(const MapMat_val<eT>& x)
  928   {
  929   arma_extra_debug_sigprint();
  930   
  931   const eT in_val = eT(x);
  932   
  933   parent.set_val(index, in_val);
  934   }
  935 
  936 
  937 
  938 template<typename eT>
  939 arma_inline
  940 void
  941 MapMat_val<eT>::operator=(const eT in_val)
  942   {
  943   arma_extra_debug_sigprint();
  944   
  945   parent.set_val(index, in_val);
  946   }
  947 
  948 
  949 
  950 template<typename eT>
  951 arma_inline
  952 void
  953 MapMat_val<eT>::operator+=(const eT in_val)
  954   {
  955   arma_extra_debug_sigprint();
  956   
  957   typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr);
  958   
  959   if(in_val != eT(0))
  960     {
  961     eT& val = map_ref.operator[](index);  // creates the element if it doesn't exist
  962     
  963     val += in_val;
  964     
  965     if(val == eT(0))  { map_ref.erase(index); }
  966     }
  967   }
  968 
  969 
  970 
  971 template<typename eT>
  972 arma_inline
  973 void
  974 MapMat_val<eT>::operator-=(const eT in_val)
  975   {
  976   arma_extra_debug_sigprint();
  977   
  978   typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr);
  979   
  980   if(in_val != eT(0))
  981     {
  982     eT& val = map_ref.operator[](index);  // creates the element if it doesn't exist
  983     
  984     val -= in_val;
  985     
  986     if(val == eT(0))  { map_ref.erase(index); }
  987     }
  988   }
  989 
  990 
  991 
  992 template<typename eT>
  993 arma_inline
  994 void
  995 MapMat_val<eT>::operator*=(const eT in_val)
  996   {
  997   arma_extra_debug_sigprint();
  998   
  999   typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr);
 1000   
 1001   typename MapMat<eT>::map_type::iterator it     = map_ref.find(index);
 1002   typename MapMat<eT>::map_type::iterator it_end = map_ref.end();
 1003   
 1004   if(it != it_end)
 1005     {
 1006     if(in_val != eT(0))
 1007       {
 1008       eT& val = (*it).second;
 1009       
 1010       val *= in_val;
 1011       
 1012       if(val == eT(0))  { map_ref.erase(it); }
 1013       }
 1014     else
 1015       {
 1016       map_ref.erase(it);
 1017       }
 1018     }
 1019   }
 1020 
 1021 
 1022 
 1023 template<typename eT>
 1024 arma_inline
 1025 void
 1026 MapMat_val<eT>::operator/=(const eT in_val)
 1027   {
 1028   arma_extra_debug_sigprint();
 1029   
 1030   typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr);
 1031   
 1032   typename MapMat<eT>::map_type::iterator it     = map_ref.find(index);
 1033   typename MapMat<eT>::map_type::iterator it_end = map_ref.end();
 1034   
 1035   if(it != it_end)
 1036     {
 1037     eT& val = (*it).second;
 1038     
 1039     val /= in_val;
 1040     
 1041     if(val == eT(0))  { map_ref.erase(it); }
 1042     }
 1043   else
 1044     {
 1045     // silly operation, but included for completness
 1046     
 1047     const eT val = eT(0) / in_val;
 1048     
 1049     if(val != eT(0))  { parent.set_val(index, val); }
 1050     }
 1051   }
 1052 
 1053 
 1054 
 1055 template<typename eT>
 1056 arma_inline
 1057 void
 1058 MapMat_val<eT>::operator++()
 1059   {
 1060   arma_extra_debug_sigprint();
 1061   
 1062   typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr);
 1063   
 1064   eT& val = map_ref.operator[](index);  // creates the element if it doesn't exist
 1065   
 1066   val += eT(1);  // can't use ++,  as eT can be std::complex
 1067   
 1068   if(val == eT(0))  { map_ref.erase(index); }
 1069   }
 1070 
 1071 
 1072 
 1073 template<typename eT>
 1074 arma_inline
 1075 void
 1076 MapMat_val<eT>::operator++(int)
 1077   {
 1078   arma_extra_debug_sigprint();
 1079   
 1080   (*this).operator++();
 1081   }
 1082 
 1083 
 1084 
 1085 template<typename eT>
 1086 arma_inline
 1087 void
 1088 MapMat_val<eT>::operator--()
 1089   {
 1090   arma_extra_debug_sigprint();
 1091   
 1092   typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr);
 1093   
 1094   eT& val = map_ref.operator[](index);  // creates the element if it doesn't exist
 1095   
 1096   val -= eT(1);  // can't use --,  as eT can be std::complex
 1097   
 1098   if(val == eT(0))  { map_ref.erase(index); }
 1099   }
 1100 
 1101 
 1102 
 1103 template<typename eT>
 1104 arma_inline
 1105 void
 1106 MapMat_val<eT>::operator--(int)
 1107   {
 1108   arma_extra_debug_sigprint();
 1109   
 1110   (*this).operator--();
 1111   }
 1112 
 1113 
 1114 
 1115 
 1116 
 1117 // SpMat_MapMat_val
 1118 
 1119 
 1120 
 1121 template<typename eT>
 1122 arma_inline
 1123 SpMat_MapMat_val<eT>::SpMat_MapMat_val(SpMat<eT>& in_s_parent, MapMat<eT>& in_m_parent, const uword in_row, const uword in_col)
 1124   : s_parent(in_s_parent)
 1125   , m_parent(in_m_parent)
 1126   , row     (in_row     )
 1127   , col     (in_col     )
 1128   {
 1129   arma_extra_debug_sigprint();
 1130   }
 1131 
 1132 
 1133 
 1134 template<typename eT>
 1135 inline
 1136 SpMat_MapMat_val<eT>::operator eT() const
 1137   {
 1138   arma_extra_debug_sigprint();
 1139   
 1140   const SpMat<eT>& const_s_parent = s_parent;  // declare as const for clarity of intent
 1141   
 1142   return const_s_parent.get_value(row,col);
 1143   }
 1144 
 1145 
 1146 
 1147 template<typename eT>
 1148 inline
 1149 typename get_pod_type<eT>::result
 1150 SpMat_MapMat_val<eT>::real() const
 1151   {
 1152   arma_extra_debug_sigprint();
 1153   
 1154   typedef typename get_pod_type<eT>::result T;
 1155   
 1156   const SpMat<eT>& const_s_parent = s_parent;  // declare as const for clarity of intent
 1157   
 1158   return T( access::tmp_real( const_s_parent.get_value(row,col) ) );
 1159   }
 1160 
 1161 
 1162 
 1163 template<typename eT>
 1164 inline
 1165 typename get_pod_type<eT>::result
 1166 SpMat_MapMat_val<eT>::imag() const
 1167   {
 1168   arma_extra_debug_sigprint();
 1169   
 1170   typedef typename get_pod_type<eT>::result T;
 1171   
 1172   const SpMat<eT>& const_s_parent = s_parent;  // declare as const for clarity of intent
 1173   
 1174   return T( access::tmp_imag( const_s_parent.get_value(row,col) ) );
 1175   }
 1176 
 1177 
 1178 
 1179 template<typename eT>
 1180 inline
 1181 SpMat_MapMat_val<eT>&
 1182 SpMat_MapMat_val<eT>::operator=(const SpMat_MapMat_val<eT>& x)
 1183   {
 1184   arma_extra_debug_sigprint();
 1185   
 1186   const eT in_val = eT(x);
 1187   
 1188   return (*this).operator=(in_val);
 1189   }
 1190 
 1191 
 1192 
 1193 template<typename eT>
 1194 inline
 1195 SpMat_MapMat_val<eT>&
 1196 SpMat_MapMat_val<eT>::operator=(const eT in_val)
 1197   {
 1198   arma_extra_debug_sigprint();
 1199   
 1200   #if defined(ARMA_USE_OPENMP)
 1201     {
 1202     #pragma omp critical (arma_SpMat_cache)
 1203       {
 1204       (*this).set(in_val);
 1205       }
 1206     }
 1207   #elif defined(ARMA_USE_CXX11)
 1208     {
 1209     s_parent.cache_mutex.lock();
 1210     
 1211     (*this).set(in_val);
 1212     
 1213     s_parent.cache_mutex.unlock();
 1214     }
 1215   #else
 1216     {
 1217     (*this).set(in_val);
 1218     }
 1219   #endif
 1220   
 1221   return *this;
 1222   }
 1223 
 1224 
 1225 
 1226 template<typename eT>
 1227 inline
 1228 SpMat_MapMat_val<eT>&
 1229 SpMat_MapMat_val<eT>::operator+=(const eT in_val)
 1230   {
 1231   arma_extra_debug_sigprint();
 1232   
 1233   if(in_val == eT(0))  { return *this; }
 1234   
 1235   #if defined(ARMA_USE_OPENMP)
 1236     {
 1237     #pragma omp critical (arma_SpMat_cache)
 1238       {
 1239       (*this).add(in_val);
 1240       }
 1241     }
 1242   #elif defined(ARMA_USE_CXX11)
 1243     {
 1244     s_parent.cache_mutex.lock();
 1245     
 1246     (*this).add(in_val);
 1247     
 1248     s_parent.cache_mutex.unlock();
 1249     }
 1250   #else
 1251     {
 1252     (*this).add(in_val);
 1253     }
 1254   #endif
 1255   
 1256   return *this;
 1257   }
 1258 
 1259 
 1260 
 1261 template<typename eT>
 1262 inline
 1263 SpMat_MapMat_val<eT>&
 1264 SpMat_MapMat_val<eT>::operator-=(const eT in_val)
 1265   {
 1266   arma_extra_debug_sigprint();
 1267   
 1268   if(in_val == eT(0))  { return *this; }
 1269   
 1270   #if defined(ARMA_USE_OPENMP)
 1271     {
 1272     #pragma omp critical (arma_SpMat_cache)
 1273       {
 1274       (*this).sub(in_val);
 1275       }
 1276     }
 1277   #elif defined(ARMA_USE_CXX11)
 1278     {
 1279     s_parent.cache_mutex.lock();
 1280     
 1281     (*this).sub(in_val);
 1282     
 1283     s_parent.cache_mutex.unlock();
 1284     }
 1285   #else
 1286     {
 1287     (*this).sub(in_val);
 1288     }
 1289   #endif
 1290   
 1291   return *this;
 1292   }
 1293 
 1294 
 1295 
 1296 template<typename eT>
 1297 inline
 1298 SpMat_MapMat_val<eT>&
 1299 SpMat_MapMat_val<eT>::operator*=(const eT in_val)
 1300   {
 1301   arma_extra_debug_sigprint();
 1302   
 1303   #if defined(ARMA_USE_OPENMP)
 1304     {
 1305     #pragma omp critical (arma_SpMat_cache)
 1306       {
 1307       (*this).mul(in_val);
 1308       }
 1309     }
 1310   #elif defined(ARMA_USE_CXX11)
 1311     {
 1312     s_parent.cache_mutex.lock();
 1313     
 1314     (*this).mul(in_val);
 1315     
 1316     s_parent.cache_mutex.unlock();
 1317     }
 1318   #else
 1319     {
 1320     (*this).mul(in_val);
 1321     }
 1322   #endif
 1323   
 1324   return *this;
 1325   }
 1326 
 1327 
 1328 
 1329 template<typename eT>
 1330 inline
 1331 SpMat_MapMat_val<eT>&
 1332 SpMat_MapMat_val<eT>::operator/=(const eT in_val)
 1333   {
 1334   arma_extra_debug_sigprint();
 1335   
 1336   #if defined(ARMA_USE_OPENMP)
 1337     {
 1338     #pragma omp critical (arma_SpMat_cache)
 1339       {
 1340       (*this).div(in_val);
 1341       }
 1342     }
 1343   #elif defined(ARMA_USE_CXX11)
 1344     {
 1345     s_parent.cache_mutex.lock();
 1346     
 1347     (*this).div(in_val);
 1348     
 1349     s_parent.cache_mutex.unlock();
 1350     }
 1351   #else
 1352     {
 1353     (*this).div(in_val);
 1354     }
 1355   #endif
 1356   
 1357   return *this;
 1358   }
 1359 
 1360 
 1361 
 1362 template<typename eT>
 1363 inline
 1364 SpMat_MapMat_val<eT>&
 1365 SpMat_MapMat_val<eT>::operator++()
 1366   {
 1367   arma_extra_debug_sigprint();
 1368   
 1369   return (*this).operator+=( eT(1) );
 1370   }
 1371 
 1372 
 1373 
 1374 template<typename eT>
 1375 inline
 1376 arma_warn_unused
 1377 eT
 1378 SpMat_MapMat_val<eT>::operator++(int)
 1379   {
 1380   arma_extra_debug_sigprint();
 1381   
 1382   const eT old_val = eT(*this);
 1383   
 1384   (*this).operator+=( eT(1) );
 1385   
 1386   return old_val;
 1387   }
 1388 
 1389 
 1390 
 1391 template<typename eT>
 1392 inline
 1393 SpMat_MapMat_val<eT>&
 1394 SpMat_MapMat_val<eT>::operator--()
 1395   {
 1396   arma_extra_debug_sigprint();
 1397   
 1398   return (*this).operator-=( eT(1) );
 1399   }
 1400 
 1401 
 1402 
 1403 template<typename eT>
 1404 inline
 1405 arma_warn_unused
 1406 eT
 1407 SpMat_MapMat_val<eT>::operator--(int)
 1408   {
 1409   arma_extra_debug_sigprint();
 1410   
 1411   const eT old_val = eT(*this);
 1412   
 1413   (*this).operator-=( eT(1) );
 1414   
 1415   return old_val;
 1416   }
 1417 
 1418 
 1419 
 1420 template<typename eT>
 1421 inline
 1422 void
 1423 SpMat_MapMat_val<eT>::set(const eT in_val)
 1424   {
 1425   arma_extra_debug_sigprint();
 1426   
 1427   const bool done = (s_parent.sync_state == 0) ? s_parent.try_set_value_csc(row, col, in_val) : false;
 1428   
 1429   if(done == false)
 1430     {
 1431     s_parent.sync_cache_simple();
 1432     
 1433     const uword index = (m_parent.n_rows * col) + row;
 1434     
 1435     m_parent.set_val(index, in_val);
 1436     
 1437     s_parent.sync_state = 1;
 1438     
 1439     access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero();
 1440     }
 1441   }
 1442 
 1443 
 1444 
 1445 template<typename eT>
 1446 inline
 1447 void
 1448 SpMat_MapMat_val<eT>::add(const eT in_val)
 1449   {
 1450   arma_extra_debug_sigprint();
 1451   
 1452   const bool done = (s_parent.sync_state == 0) ? s_parent.try_add_value_csc(row, col, in_val) : false;
 1453     
 1454   if(done == false)
 1455     {
 1456     s_parent.sync_cache_simple();
 1457     
 1458     const uword index = (m_parent.n_rows * col) + row;
 1459     
 1460     typename MapMat<eT>::map_type& map_ref = *(m_parent.map_ptr);
 1461     
 1462     eT& val = map_ref.operator[](index);  // creates the element if it doesn't exist
 1463     
 1464     val += in_val;
 1465     
 1466     if(val == eT(0))  { map_ref.erase(index); }
 1467     
 1468     s_parent.sync_state = 1;
 1469     
 1470     access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero();
 1471     }
 1472   }
 1473 
 1474 
 1475 
 1476 template<typename eT>
 1477 inline
 1478 void
 1479 SpMat_MapMat_val<eT>::sub(const eT in_val)
 1480   {
 1481   arma_extra_debug_sigprint();
 1482   
 1483   const bool done = (s_parent.sync_state == 0) ? s_parent.try_sub_value_csc(row, col, in_val) : false;
 1484   
 1485   if(done == false)
 1486     {
 1487     s_parent.sync_cache_simple();
 1488     
 1489     const uword index = (m_parent.n_rows * col) + row;
 1490     
 1491     typename MapMat<eT>::map_type& map_ref = *(m_parent.map_ptr);
 1492     
 1493     eT& val = map_ref.operator[](index);  // creates the element if it doesn't exist
 1494     
 1495     val -= in_val;
 1496     
 1497     if(val == eT(0))  { map_ref.erase(index); }
 1498     
 1499     s_parent.sync_state = 1;
 1500     
 1501     access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero();
 1502     }
 1503   }
 1504 
 1505 
 1506 
 1507 template<typename eT>
 1508 inline
 1509 void
 1510 SpMat_MapMat_val<eT>::mul(const eT in_val)
 1511   {
 1512   arma_extra_debug_sigprint();
 1513   
 1514   const bool done = (s_parent.sync_state == 0) ? s_parent.try_mul_value_csc(row, col, in_val) : false;
 1515   
 1516   if(done == false)
 1517     {
 1518     s_parent.sync_cache_simple();
 1519     
 1520     const uword index = (m_parent.n_rows * col) + row;
 1521     
 1522     typename MapMat<eT>::map_type& map_ref = *(m_parent.map_ptr);
 1523     
 1524     typename MapMat<eT>::map_type::iterator it     = map_ref.find(index);
 1525     typename MapMat<eT>::map_type::iterator it_end = map_ref.end();
 1526     
 1527     if(it != it_end)
 1528       {
 1529       if(in_val != eT(0))
 1530         {
 1531         eT& val = (*it).second;
 1532         
 1533         val *= in_val;
 1534         
 1535         if(val == eT(0))  { map_ref.erase(it); }
 1536         }
 1537       else
 1538         {
 1539         map_ref.erase(it);
 1540         }
 1541       
 1542       s_parent.sync_state = 1;
 1543       
 1544       access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero();
 1545       }
 1546     else
 1547       {
 1548       // element not found, ie. it's zero; zero multiplied by anything is zero, except for nan and inf
 1549       if(arma_isfinite(in_val) == false)
 1550         {
 1551         const eT result = eT(0) * in_val;
 1552         
 1553         if(result != eT(0))  // paranoia, in case compiling with -ffast-math
 1554           {
 1555           m_parent.set_val(index, result);
 1556           
 1557           s_parent.sync_state = 1;
 1558           
 1559           access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero();
 1560           }
 1561         }
 1562       }
 1563     }
 1564   }
 1565 
 1566 
 1567 
 1568 template<typename eT>
 1569 inline
 1570 void
 1571 SpMat_MapMat_val<eT>::div(const eT in_val)
 1572   {
 1573   arma_extra_debug_sigprint();
 1574   
 1575   const bool done = (s_parent.sync_state == 0) ? s_parent.try_div_value_csc(row, col, in_val) : false;
 1576   
 1577   if(done == false)
 1578     {
 1579     s_parent.sync_cache_simple();
 1580     
 1581     const uword index = (m_parent.n_rows * col) + row;
 1582     
 1583     typename MapMat<eT>::map_type& map_ref = *(m_parent.map_ptr);
 1584     
 1585     typename MapMat<eT>::map_type::iterator it     = map_ref.find(index);
 1586     typename MapMat<eT>::map_type::iterator it_end = map_ref.end();
 1587     
 1588     if(it != it_end)
 1589       {
 1590       eT& val = (*it).second;
 1591       
 1592       val /= in_val;
 1593       
 1594       if(val == eT(0))  { map_ref.erase(it); }
 1595       
 1596       s_parent.sync_state = 1;
 1597       
 1598       access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero();
 1599       }
 1600     else
 1601       {
 1602       // element not found, ie. it's zero; zero divided by anything is zero, except for zero and nan
 1603       if( (in_val == eT(0)) || (arma_isnan(in_val)) )
 1604         {
 1605         const eT result = eT(0) / in_val;
 1606         
 1607         if(result != eT(0))  // paranoia, in case compiling with -ffast-math
 1608           {
 1609           m_parent.set_val(index, result);
 1610           
 1611           s_parent.sync_state = 1;
 1612           
 1613           access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero();
 1614           }
 1615         }
 1616       }
 1617     }
 1618   }
 1619 
 1620 
 1621 
 1622 
 1623 // SpSubview_MapMat_val
 1624 
 1625 
 1626 
 1627 template<typename eT>
 1628 arma_inline
 1629 SpSubview_MapMat_val<eT>::SpSubview_MapMat_val(SpSubview<eT>& in_sv_parent, MapMat<eT>& in_m_parent, const uword in_row, const uword in_col)
 1630   : SpMat_MapMat_val<eT>(access::rw(in_sv_parent.m), in_m_parent, in_row, in_col)
 1631   , sv_parent(in_sv_parent)
 1632   {
 1633   arma_extra_debug_sigprint();
 1634   }
 1635 
 1636 
 1637 
 1638 template<typename eT>
 1639 inline
 1640 SpSubview_MapMat_val<eT>&
 1641 SpSubview_MapMat_val<eT>::operator=(const SpSubview_MapMat_val<eT>& x)
 1642   {
 1643   arma_extra_debug_sigprint();
 1644   
 1645   const eT in_val = eT(x);
 1646   
 1647   return (*this).operator=(in_val);
 1648   }
 1649 
 1650 
 1651 
 1652 template<typename eT>
 1653 inline
 1654 SpSubview_MapMat_val<eT>&
 1655 SpSubview_MapMat_val<eT>::operator=(const eT in_val)
 1656   {
 1657   arma_extra_debug_sigprint();
 1658   
 1659   const uword old_n_nonzero = sv_parent.m.n_nonzero;
 1660   
 1661   SpMat_MapMat_val<eT>::operator=(in_val);
 1662   
 1663   if(sv_parent.m.n_nonzero > old_n_nonzero)  { access::rw(sv_parent.n_nonzero)++; }
 1664   if(sv_parent.m.n_nonzero < old_n_nonzero)  { access::rw(sv_parent.n_nonzero)--; }
 1665   
 1666   return *this;
 1667   }
 1668 
 1669 
 1670 
 1671 template<typename eT>
 1672 inline
 1673 SpSubview_MapMat_val<eT>&
 1674 SpSubview_MapMat_val<eT>::operator+=(const eT in_val)
 1675   {
 1676   arma_extra_debug_sigprint();
 1677   
 1678   const uword old_n_nonzero = sv_parent.m.n_nonzero;
 1679   
 1680   SpMat_MapMat_val<eT>::operator+=(in_val);
 1681   
 1682   if(sv_parent.m.n_nonzero > old_n_nonzero)  { access::rw(sv_parent.n_nonzero)++; }
 1683   if(sv_parent.m.n_nonzero < old_n_nonzero)  { access::rw(sv_parent.n_nonzero)--; }
 1684   
 1685   return *this;
 1686   }
 1687 
 1688 
 1689 
 1690 template<typename eT>
 1691 inline
 1692 SpSubview_MapMat_val<eT>&
 1693 SpSubview_MapMat_val<eT>::operator-=(const eT in_val)
 1694   {
 1695   arma_extra_debug_sigprint();
 1696   
 1697   const uword old_n_nonzero = sv_parent.m.n_nonzero;
 1698   
 1699   SpMat_MapMat_val<eT>::operator-=(in_val);
 1700   
 1701   if(sv_parent.m.n_nonzero > old_n_nonzero)  { access::rw(sv_parent.n_nonzero)++; }
 1702   if(sv_parent.m.n_nonzero < old_n_nonzero)  { access::rw(sv_parent.n_nonzero)--; }
 1703   
 1704   return *this;
 1705   }
 1706 
 1707 
 1708 
 1709 template<typename eT>
 1710 inline
 1711 SpSubview_MapMat_val<eT>&
 1712 SpSubview_MapMat_val<eT>::operator*=(const eT in_val)
 1713   {
 1714   arma_extra_debug_sigprint();
 1715   
 1716   const uword old_n_nonzero = sv_parent.m.n_nonzero;
 1717   
 1718   SpMat_MapMat_val<eT>::operator*=(in_val);
 1719   
 1720   if(sv_parent.m.n_nonzero > old_n_nonzero)  { access::rw(sv_parent.n_nonzero)++; }
 1721   if(sv_parent.m.n_nonzero < old_n_nonzero)  { access::rw(sv_parent.n_nonzero)--; }
 1722   
 1723   return *this;
 1724   }
 1725 
 1726 
 1727 
 1728 template<typename eT>
 1729 inline
 1730 SpSubview_MapMat_val<eT>&
 1731 SpSubview_MapMat_val<eT>::operator/=(const eT in_val)
 1732   {
 1733   arma_extra_debug_sigprint();
 1734   
 1735   const uword old_n_nonzero = sv_parent.m.n_nonzero;
 1736   
 1737   SpMat_MapMat_val<eT>::operator/=(in_val);
 1738   
 1739   if(sv_parent.m.n_nonzero > old_n_nonzero)  { access::rw(sv_parent.n_nonzero)++; }
 1740   if(sv_parent.m.n_nonzero < old_n_nonzero)  { access::rw(sv_parent.n_nonzero)--; }
 1741   
 1742   return *this;
 1743   }
 1744 
 1745 
 1746 
 1747 template<typename eT>
 1748 inline
 1749 SpSubview_MapMat_val<eT>&
 1750 SpSubview_MapMat_val<eT>::operator++()
 1751   {
 1752   arma_extra_debug_sigprint();
 1753   
 1754   const uword old_n_nonzero = sv_parent.m.n_nonzero;
 1755   
 1756   SpMat_MapMat_val<eT>::operator++();
 1757   
 1758   if(sv_parent.m.n_nonzero > old_n_nonzero)  { access::rw(sv_parent.n_nonzero)++; }
 1759   if(sv_parent.m.n_nonzero < old_n_nonzero)  { access::rw(sv_parent.n_nonzero)--; }
 1760   
 1761   return *this;
 1762   }
 1763 
 1764 
 1765 
 1766 template<typename eT>
 1767 inline
 1768 arma_warn_unused
 1769 eT
 1770 SpSubview_MapMat_val<eT>::operator++(int)
 1771   {
 1772   arma_extra_debug_sigprint();
 1773   
 1774   const uword old_n_nonzero = sv_parent.m.n_nonzero;
 1775   
 1776   const eT old_val = SpMat_MapMat_val<eT>::operator++(int(0));
 1777   
 1778   if(sv_parent.m.n_nonzero > old_n_nonzero)  { access::rw(sv_parent.n_nonzero)++; }
 1779   if(sv_parent.m.n_nonzero < old_n_nonzero)  { access::rw(sv_parent.n_nonzero)--; }
 1780   
 1781   return old_val;
 1782   }
 1783 
 1784 
 1785 
 1786 template<typename eT>
 1787 inline
 1788 SpSubview_MapMat_val<eT>&
 1789 SpSubview_MapMat_val<eT>::operator--()
 1790   {
 1791   arma_extra_debug_sigprint();
 1792   
 1793   const uword old_n_nonzero = sv_parent.m.n_nonzero;
 1794   
 1795   SpMat_MapMat_val<eT>::operator--();
 1796   
 1797   if(sv_parent.m.n_nonzero > old_n_nonzero)  { access::rw(sv_parent.n_nonzero)++; }
 1798   if(sv_parent.m.n_nonzero < old_n_nonzero)  { access::rw(sv_parent.n_nonzero)--; }
 1799   
 1800   return *this;
 1801   }
 1802 
 1803 
 1804 
 1805 template<typename eT>
 1806 inline
 1807 arma_warn_unused
 1808 eT
 1809 SpSubview_MapMat_val<eT>::operator--(int)
 1810   {
 1811   arma_extra_debug_sigprint();
 1812   
 1813   const uword old_n_nonzero = sv_parent.m.n_nonzero;
 1814   
 1815   const eT old_val = SpMat_MapMat_val<eT>::operator--(int(0));
 1816   
 1817   if(sv_parent.m.n_nonzero > old_n_nonzero)  { access::rw(sv_parent.n_nonzero)++; }
 1818   if(sv_parent.m.n_nonzero < old_n_nonzero)  { access::rw(sv_parent.n_nonzero)--; }
 1819   
 1820   return old_val;
 1821   }
 1822 
 1823 
 1824 
 1825 //! @}