"Fossies" - the Fresh Open Source Software Archive

Member "armadillo-9.800.3/include/armadillo_bits/spop_max_meat.hpp" (16 Jun 2016, 15656 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 "spop_max_meat.hpp" see the Fossies "Dox" file reference documentation.

    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 spop_max
   18 //! @{
   19 
   20 
   21 
   22 template<typename T1>
   23 inline
   24 void
   25 spop_max::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_max>& in)
   26   {
   27   arma_extra_debug_sigprint();
   28   
   29   const uword dim = in.aux_uword_a;
   30   arma_debug_check( (dim > 1), "max(): parameter 'dim' must be 0 or 1" );
   31   
   32   const SpProxy<T1> p(in.m);
   33   
   34   const uword p_n_rows = p.get_n_rows();
   35   const uword p_n_cols = p.get_n_cols();
   36   
   37   if( (p_n_rows == 0) || (p_n_cols == 0) || (p.get_n_nonzero() == 0) )
   38     {
   39     if(dim == 0)  { out.zeros((p_n_rows > 0) ? 1 : 0, p_n_cols); }
   40     if(dim == 1)  { out.zeros(p_n_rows, (p_n_cols > 0) ? 1 : 0); }
   41     
   42     return;
   43     }
   44   
   45   spop_max::apply_proxy(out, p, dim);
   46   }
   47 
   48 
   49 
   50 template<typename T1>
   51 inline
   52 void
   53 spop_max::apply_proxy
   54   (
   55         SpMat<typename T1::elem_type>& out,
   56   const SpProxy<T1>&                   p,
   57   const uword                          dim,
   58   const typename arma_not_cx<typename T1::elem_type>::result* junk
   59   )
   60   {
   61   arma_extra_debug_sigprint();
   62   arma_ignore(junk);
   63   
   64   typedef typename T1::elem_type eT;
   65   
   66   typename SpProxy<T1>::const_iterator_type it     = p.begin();
   67   typename SpProxy<T1>::const_iterator_type it_end = p.end();
   68   
   69   const uword p_n_cols = p.get_n_cols();
   70   const uword p_n_rows = p.get_n_rows();
   71   
   72   if(dim == 0) // find the maximum in each column
   73     {
   74     Row<eT> value(p_n_cols, fill::zeros);
   75     urowvec count(p_n_cols, fill::zeros);
   76     
   77     while(it != it_end)
   78       {
   79       const uword col = it.col();
   80       
   81       value[col] = (count[col] == 0) ? (*it) : (std::max)(value[col], (*it));
   82       count[col]++;
   83       ++it;
   84       }
   85     
   86     for(uword col=0; col<p_n_cols; ++col)
   87       {
   88       if(count[col] < p_n_rows)  { value[col] = (std::max)(value[col], eT(0)); }
   89       }
   90     
   91     out = value;
   92     }
   93   else
   94   if(dim == 1)  // find the maximum in each row
   95     {
   96     Col<eT> value(p_n_rows, fill::zeros);
   97     ucolvec count(p_n_rows, fill::zeros);
   98     
   99     while(it != it_end)
  100       {
  101       const uword row = it.row();
  102       
  103       value[row] = (count[row] == 0) ? (*it) : (std::max)(value[row], (*it));
  104       count[row]++;
  105       ++it;
  106       }
  107     
  108     for(uword row=0; row<p_n_rows; ++row)
  109       {
  110       if(count[row] < p_n_cols)  { value[row] = (std::max)(value[row], eT(0)); }
  111       }
  112     
  113     out = value;
  114     }
  115   }
  116 
  117 
  118 
  119 template<typename T1>
  120 inline
  121 typename T1::elem_type
  122 spop_max::vector_max
  123   (
  124   const T1& x,
  125   const typename arma_not_cx<typename T1::elem_type>::result* junk
  126   )
  127   {
  128   arma_extra_debug_sigprint();
  129   arma_ignore(junk);
  130   
  131   typedef typename T1::elem_type eT;
  132   
  133   const SpProxy<T1> p(x);
  134   
  135   if(p.get_n_elem() == 0)
  136     {
  137     arma_debug_check(true, "max(): object has no elements");
  138     
  139     return Datum<eT>::nan;
  140     }
  141   
  142   if(p.get_n_nonzero() == 0)  { return eT(0); }
  143   
  144   if(SpProxy<T1>::use_iterator == false)
  145     {
  146     // direct access of values
  147     if(p.get_n_nonzero() == p.get_n_elem())
  148       {
  149       return op_max::direct_max(p.get_values(), p.get_n_nonzero());
  150       }
  151     else
  152       {
  153       return std::max(eT(0), op_max::direct_max(p.get_values(), p.get_n_nonzero()));
  154       }
  155     }
  156   else
  157     {
  158     // use iterator
  159     typename SpProxy<T1>::const_iterator_type it     = p.begin();
  160     typename SpProxy<T1>::const_iterator_type it_end = p.end();
  161     
  162     eT result = (*it);
  163     ++it;
  164     
  165     while(it != it_end)
  166       {
  167       if((*it) > result)  { result = (*it); }
  168       
  169       ++it;
  170       }
  171     
  172     if(p.get_n_nonzero() == p.get_n_elem())
  173       {
  174       return result;
  175       }
  176     else
  177       {
  178       return std::max(eT(0), result);
  179       }
  180     }
  181   }
  182 
  183 
  184 
  185 template<typename T1>
  186 inline
  187 typename arma_not_cx<typename T1::elem_type>::result
  188 spop_max::max(const SpBase<typename T1::elem_type, T1>& X)
  189   {
  190   arma_extra_debug_sigprint();
  191   
  192   typedef typename T1::elem_type eT;
  193   
  194   const SpProxy<T1> P(X.get_ref());
  195   
  196   const uword n_elem    = P.get_n_elem();
  197   const uword n_nonzero = P.get_n_nonzero();
  198   
  199   if(n_elem == 0)
  200     {
  201     arma_debug_check(true, "max(): object has no elements");
  202     
  203     return Datum<eT>::nan;
  204     }
  205   
  206   eT max_val = priv::most_neg<eT>();
  207   
  208   if(SpProxy<T1>::use_iterator)
  209     {
  210     // We have to iterate over the elements.
  211     typedef typename SpProxy<T1>::const_iterator_type it_type;
  212     
  213     it_type it     = P.begin();
  214     it_type it_end = P.end();
  215     
  216     while (it != it_end)
  217       {
  218       if ((*it) > max_val)  { max_val = *it; }
  219       
  220       ++it;
  221       }
  222     }
  223   else
  224     {
  225     // We can do direct access of the values, row_indices, and col_ptrs.
  226     // We don't need the location of the max value, so we can just call out to
  227     // other functions...
  228     max_val = op_max::direct_max(P.get_values(), n_nonzero);
  229     }
  230   
  231   if(n_elem == n_nonzero)
  232     {
  233     return max_val;
  234     }
  235   else
  236     {
  237     return std::max(eT(0), max_val);
  238     }
  239   }
  240 
  241 
  242 
  243 template<typename T1>
  244 inline
  245 typename arma_not_cx<typename T1::elem_type>::result
  246 spop_max::max_with_index(const SpProxy<T1>& P, uword& index_of_max_val)
  247   {
  248   arma_extra_debug_sigprint();
  249   
  250   typedef typename T1::elem_type eT;
  251   
  252   const uword n_elem    = P.get_n_elem();
  253   const uword n_nonzero = P.get_n_nonzero();
  254   const uword n_rows    = P.get_n_rows();
  255   
  256   if(n_elem == 0)
  257     {
  258     arma_debug_check(true, "max(): object has no elements");
  259     
  260     index_of_max_val = uword(0);
  261     
  262     return Datum<eT>::nan;
  263     }
  264   
  265   eT max_val = priv::most_neg<eT>();
  266   
  267   if(SpProxy<T1>::use_iterator)
  268     {
  269     // We have to iterate over the elements.
  270     typedef typename SpProxy<T1>::const_iterator_type it_type;
  271     
  272     it_type it     = P.begin();
  273     it_type it_end = P.end();
  274     
  275     while (it != it_end)
  276       {
  277       if ((*it) > max_val)
  278         {
  279         max_val = *it;
  280         index_of_max_val = it.row() + it.col() * n_rows;
  281         }
  282       
  283       ++it;
  284       }
  285     }
  286   else
  287     {
  288     // We can do direct access.
  289     max_val = op_max::direct_max(P.get_values(), n_nonzero, index_of_max_val);
  290     
  291     // Convert to actual position in matrix.
  292     const uword row = P.get_row_indices()[index_of_max_val];
  293     uword col = 0;
  294     while (P.get_col_ptrs()[++col] <= index_of_max_val) { }
  295     index_of_max_val = (col - 1) * n_rows + row;
  296     }
  297   
  298   
  299   if(n_elem != n_nonzero)
  300     {
  301     max_val = std::max(eT(0), max_val);
  302     
  303     // If the max_val is a nonzero element, we need its actual position in the matrix.
  304     if(max_val == eT(0))
  305       {
  306       // Find first zero element.
  307       uword last_row = 0;
  308       uword last_col = 0;
  309       
  310       typedef typename SpProxy<T1>::const_iterator_type it_type;
  311       
  312       it_type it     = P.begin();
  313       it_type it_end = P.end();
  314       
  315       while (it != it_end)
  316         {
  317         // Have we moved more than one position from the last place?
  318         if ((it.col() == last_col) && (it.row() - last_row > 1))
  319           {
  320           index_of_max_val = it.col() * n_rows + last_row + 1;
  321           break;
  322           }
  323         else if ((it.col() >= last_col + 1) && (last_row < n_rows - 1))
  324           {
  325           index_of_max_val = last_col * n_rows + last_row + 1;
  326           break;
  327           }
  328         else if ((it.col() == last_col + 1) && (it.row() > 0))
  329           {
  330           index_of_max_val = it.col() * n_rows;
  331           break;
  332           }
  333         else if (it.col() > last_col + 1)
  334           {
  335           index_of_max_val = (last_col + 1) * n_rows;
  336           break;
  337           }
  338         
  339         last_row = it.row();
  340         last_col = it.col();
  341         ++it;
  342         }
  343       }
  344     }
  345   
  346   return max_val;
  347   }
  348 
  349 
  350 
  351 template<typename T1>
  352 inline
  353 void
  354 spop_max::apply_proxy
  355   (
  356         SpMat<typename T1::elem_type>& out,
  357   const SpProxy<T1>&                   p,
  358   const uword                          dim,
  359   const typename arma_cx_only<typename T1::elem_type>::result* junk
  360   )
  361   {
  362   arma_extra_debug_sigprint();
  363   arma_ignore(junk);
  364   
  365   typedef typename T1::elem_type            eT;
  366   typedef typename get_pod_type<eT>::result  T;
  367   
  368   typename SpProxy<T1>::const_iterator_type it     = p.begin();
  369   typename SpProxy<T1>::const_iterator_type it_end = p.end();
  370   
  371   const uword p_n_cols = p.get_n_cols();
  372   const uword p_n_rows = p.get_n_rows();
  373   
  374   if(dim == 0) // find the maximum in each column
  375     {
  376     Row<eT> rawval(p_n_cols, fill::zeros);
  377     Row< T> absval(p_n_cols, fill::zeros);
  378     
  379     while(it != it_end)
  380       {
  381       const uword col = it.col();
  382       
  383       const eT& v = (*it);
  384       const  T  a = std::abs(v);
  385       
  386       if(a > absval[col])
  387         {
  388         absval[col] = a;
  389         rawval[col] = v;
  390         }
  391       
  392       ++it;
  393       }
  394     
  395     out = rawval;
  396     }
  397   else
  398   if(dim == 1)  // find the maximum in each row
  399     {
  400     Col<eT> rawval(p_n_rows, fill::zeros);
  401     Col< T> absval(p_n_rows, fill::zeros);
  402     
  403     while(it != it_end)
  404       {
  405       const uword row = it.row();
  406       
  407       const eT& v = (*it);
  408       const  T  a = std::abs(v);
  409       
  410       if(a > absval[row])
  411         {
  412         absval[row] = a;
  413         rawval[row] = v;
  414         }
  415       
  416       ++it;
  417       }
  418     
  419     out = rawval;
  420     }
  421   }
  422 
  423 
  424 
  425 template<typename T1>
  426 inline
  427 typename T1::elem_type
  428 spop_max::vector_max
  429   (
  430   const T1& x,
  431   const typename arma_cx_only<typename T1::elem_type>::result* junk
  432   )
  433   {
  434   arma_extra_debug_sigprint();
  435   arma_ignore(junk);
  436   
  437   typedef typename T1::elem_type            eT;
  438   typedef typename get_pod_type<eT>::result  T;
  439   
  440   const SpProxy<T1> p(x);
  441   
  442   if(p.get_n_elem() == 0)
  443     {
  444     arma_debug_check(true, "max(): object has no elements");
  445     
  446     return Datum<eT>::nan;
  447     }
  448   
  449   if(p.get_n_nonzero() == 0)  { return eT(0); }
  450   
  451   if(SpProxy<T1>::use_iterator == false)
  452     {
  453     // direct access of values
  454     if(p.get_n_nonzero() == p.get_n_elem())
  455       {
  456       return op_max::direct_max(p.get_values(), p.get_n_nonzero());
  457       }
  458     else
  459       {
  460       const eT val1 = eT(0);
  461       const eT val2 = op_max::direct_max(p.get_values(), p.get_n_nonzero());
  462       
  463       return ( std::abs(val1) >= std::abs(val2) ) ? val1 : val2;
  464       }
  465     }
  466   else
  467     {
  468     // use iterator
  469     typename SpProxy<T1>::const_iterator_type it     = p.begin();
  470     typename SpProxy<T1>::const_iterator_type it_end = p.end();
  471 
  472     eT best_val_orig = *it;
  473      T best_val_abs  = std::abs(best_val_orig);
  474     
  475     ++it;
  476     
  477     while(it != it_end)
  478       {
  479       eT val_orig = *it;
  480        T val_abs  = std::abs(val_orig);
  481       
  482       if(val_abs > best_val_abs)
  483         {
  484         best_val_abs  = val_abs;
  485         best_val_orig = val_orig;
  486         }
  487 
  488       ++it;
  489       }
  490 
  491     if(p.get_n_nonzero() == p.get_n_elem())
  492       {
  493       return best_val_orig;
  494       }
  495     else
  496       {
  497       const eT val1 = eT(0);
  498       
  499       return ( std::abs(val1) >= best_val_abs ) ? val1 : best_val_orig;
  500       }
  501     }
  502   }
  503 
  504 
  505 
  506 template<typename T1>
  507 inline
  508 typename arma_cx_only<typename T1::elem_type>::result
  509 spop_max::max(const SpBase<typename T1::elem_type, T1>& X)
  510   {
  511   arma_extra_debug_sigprint();
  512 
  513   typedef typename T1::elem_type            eT;
  514   typedef typename get_pod_type<eT>::result  T;
  515 
  516   const SpProxy<T1> P(X.get_ref());
  517 
  518   const uword n_elem    = P.get_n_elem();
  519   const uword n_nonzero = P.get_n_nonzero();
  520 
  521   if(n_elem == 0)
  522     {
  523     arma_debug_check(true, "max(): object has no elements");
  524     
  525     return Datum<eT>::nan;
  526     }
  527   
  528    T max_val = priv::most_neg<T>();
  529   eT ret_val;
  530   
  531   if(SpProxy<T1>::use_iterator)
  532     {
  533     // We have to iterate over the elements.
  534     typedef typename SpProxy<T1>::const_iterator_type it_type;
  535     
  536     it_type it     = P.begin();
  537     it_type it_end = P.end();
  538     
  539     while (it != it_end)
  540       {
  541       const T tmp_val = std::abs(*it);
  542       
  543       if (tmp_val > max_val)
  544         {
  545         max_val = tmp_val;
  546         ret_val = *it;
  547         }
  548       
  549       ++it;
  550       }
  551     }
  552   else
  553     {
  554     // We can do direct access of the values, row_indices, and col_ptrs.
  555     // We don't need the location of the max value, so we can just call out to
  556     // other functions...
  557     ret_val = op_max::direct_max(P.get_values(), n_nonzero);
  558     max_val = std::abs(ret_val);
  559     }
  560   
  561   if(n_elem == n_nonzero)
  562     {
  563     return max_val;
  564     }
  565   else
  566     {
  567     return (T(0) > max_val) ? eT(0) : ret_val;
  568     }
  569   }
  570 
  571 
  572 
  573 template<typename T1>
  574 inline
  575 typename arma_cx_only<typename T1::elem_type>::result
  576 spop_max::max_with_index(const SpProxy<T1>& P, uword& index_of_max_val)
  577   {
  578   arma_extra_debug_sigprint();
  579   
  580   typedef typename T1::elem_type            eT;
  581   typedef typename get_pod_type<eT>::result  T;
  582   
  583   const uword n_elem    = P.get_n_elem();
  584   const uword n_nonzero = P.get_n_nonzero();
  585   const uword n_rows    = P.get_n_rows();
  586   
  587   if(n_elem == 0)
  588     {
  589     arma_debug_check(true, "max(): object has no elements");
  590     
  591     index_of_max_val = uword(0);
  592     
  593     return Datum<eT>::nan;
  594     }
  595   
  596   T max_val = priv::most_neg<T>();
  597   
  598   if(SpProxy<T1>::use_iterator)
  599     {
  600     // We have to iterate over the elements.
  601     typedef typename SpProxy<T1>::const_iterator_type it_type;
  602     
  603     it_type it     = P.begin();
  604     it_type it_end = P.end();
  605     
  606     while (it != it_end)
  607       {
  608       const T tmp_val = std::abs(*it);
  609       
  610       if (tmp_val > max_val)
  611         {
  612                  max_val = tmp_val;
  613         index_of_max_val = it.row() + it.col() * n_rows;
  614         }
  615       
  616       ++it;
  617       }
  618     }
  619   else
  620     {
  621     // We can do direct access.
  622     max_val = std::abs(op_max::direct_max(P.get_values(), n_nonzero, index_of_max_val));
  623 
  624     // Convert to actual position in matrix.
  625     const uword row = P.get_row_indices()[index_of_max_val];
  626     uword col = 0;
  627     while (P.get_col_ptrs()[++col] <= index_of_max_val) { }
  628     index_of_max_val = (col - 1) * n_rows + row;
  629     }
  630   
  631   
  632   if(n_elem != n_nonzero)
  633     {
  634     max_val = std::max(T(0), max_val);
  635 
  636     // If the max_val is a nonzero element, we need its actual position in the matrix.
  637     if(max_val == T(0))
  638       {
  639       // Find first zero element.
  640       uword last_row = 0;
  641       uword last_col = 0;
  642       
  643       typedef typename SpProxy<T1>::const_iterator_type it_type;
  644       
  645       it_type it     = P.begin();
  646       it_type it_end = P.end();
  647       
  648       while (it != it_end)
  649         {
  650         // Have we moved more than one position from the last place?
  651         if ((it.col() == last_col) && (it.row() - last_row > 1))
  652           {
  653           index_of_max_val = it.col() * n_rows + last_row + 1;
  654           break;
  655           }
  656         else if ((it.col() >= last_col + 1) && (last_row < n_rows - 1))
  657           {
  658           index_of_max_val = last_col * n_rows + last_row + 1;
  659           break;
  660           }
  661         else if ((it.col() == last_col + 1) && (it.row() > 0))
  662           {
  663           index_of_max_val = it.col() * n_rows;
  664           break;
  665           }
  666         else if (it.col() > last_col + 1)
  667           {
  668           index_of_max_val = (last_col + 1) * n_rows;
  669           break;
  670           }
  671 
  672         last_row = it.row();
  673         last_col = it.col();
  674         ++it;
  675         }
  676       }
  677     }
  678 
  679   return P[index_of_max_val];
  680   }
  681 
  682 
  683 
  684 //! @}