"Fossies" - the Fresh Open Source Software Archive

Member "armadillo-9.800.3/include/armadillo_bits/spglue_min_meat.hpp" (16 Jun 2016, 5459 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 "spglue_min_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 spglue_min
   18 //! @{
   19 
   20 
   21 
   22 template<typename T1, typename T2>
   23 inline
   24 void
   25 spglue_min::apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_min>& X)
   26   {
   27   arma_extra_debug_sigprint();
   28   
   29   typedef typename T1::elem_type eT;
   30   
   31   const SpProxy<T1> pa(X.A);
   32   const SpProxy<T2> pb(X.B);
   33   
   34   const bool is_alias = pa.is_alias(out) || pb.is_alias(out);
   35   
   36   if(is_alias == false)
   37     {
   38     spglue_min::apply_noalias(out, pa, pb);
   39     }
   40   else
   41     {
   42     SpMat<eT> tmp;
   43     
   44     spglue_min::apply_noalias(tmp, pa, pb);
   45     
   46     out.steal_mem(tmp);
   47     }
   48   }
   49 
   50 
   51 
   52 template<typename eT, typename T1, typename T2>
   53 inline
   54 void
   55 spglue_min::apply_noalias(SpMat<eT>& out, const SpProxy<T1>& pa, const SpProxy<T2>& pb)
   56   {
   57   arma_extra_debug_sigprint();
   58   
   59   arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "element-wise minimum");
   60   
   61   if(pa.get_n_nonzero() == 0)  { out = pb.Q; return; }
   62   if(pb.get_n_nonzero() == 0)  { out = pa.Q; return; }
   63   
   64   // The plus helper works here also to get an upper bound on n_nonzero.
   65   const uword max_n_nonzero = spglue_elem_helper::max_n_nonzero_plus(pa, pb);
   66   
   67   // Resize memory to upper bound
   68   out.reserve(pa.get_n_rows(), pa.get_n_cols(), max_n_nonzero);
   69   
   70   // Now iterate across both matrices.
   71   typename SpProxy<T1>::const_iterator_type x_it  = pa.begin();
   72   typename SpProxy<T1>::const_iterator_type x_end = pa.end();
   73   
   74   typename SpProxy<T2>::const_iterator_type y_it  = pb.begin();
   75   typename SpProxy<T2>::const_iterator_type y_end = pb.end();
   76   
   77   uword count = 0;
   78   
   79   while( (x_it != x_end) || (y_it != y_end) )
   80     {
   81     eT out_val;
   82     
   83     const uword x_it_col = x_it.col();
   84     const uword x_it_row = x_it.row();
   85     
   86     const uword y_it_col = y_it.col();
   87     const uword y_it_row = y_it.row();
   88     
   89     bool use_y_loc = false;
   90     
   91     if(x_it == y_it)
   92       {
   93       out_val = elem_min(eT(*x_it), eT(*y_it));
   94       
   95       ++x_it;
   96       ++y_it;
   97       }
   98     else
   99       {
  100       if((x_it_col < y_it_col) || ((x_it_col == y_it_col) && (x_it_row < y_it_row))) // if y is closer to the end
  101         {
  102         out_val = elem_min(eT(*x_it), eT(0));
  103         
  104         ++x_it;
  105         }
  106       else
  107         {
  108         out_val = elem_min(eT(*y_it), eT(0));
  109 
  110         ++y_it;
  111         
  112         use_y_loc = true;
  113         }
  114       }
  115     
  116     if(out_val != eT(0))
  117       {
  118       access::rw(out.values[count]) = out_val;
  119       
  120       const uword out_row = (use_y_loc == false) ? x_it_row : y_it_row;
  121       const uword out_col = (use_y_loc == false) ? x_it_col : y_it_col;
  122       
  123       access::rw(out.row_indices[count]) = out_row;
  124       access::rw(out.col_ptrs[out_col + 1])++;
  125       ++count;
  126       }
  127     }
  128   
  129   const uword out_n_cols = out.n_cols;
  130   
  131   uword* col_ptrs = access::rwp(out.col_ptrs);
  132   
  133   // Fix column pointers to be cumulative.
  134   for(uword c = 1; c <= out_n_cols; ++c)
  135     {
  136     col_ptrs[c] += col_ptrs[c - 1];
  137     }
  138   
  139   if(count < max_n_nonzero)
  140     {
  141     if(count <= (max_n_nonzero/2))
  142       {
  143       out.mem_resize(count);
  144       }
  145     else
  146       {
  147       // quick resize without reallocating memory and copying data
  148       access::rw(         out.n_nonzero) = count;
  149       access::rw(     out.values[count]) = eT(0);
  150       access::rw(out.row_indices[count]) = uword(0);
  151       }
  152     }
  153   }
  154 
  155 
  156 
  157 template<typename eT>
  158 inline
  159 void
  160 spglue_min::apply_noalias(SpMat<eT>& out, const SpMat<eT>& A, const SpMat<eT>& B)
  161   {
  162   arma_extra_debug_sigprint();
  163   
  164   const SpProxy< SpMat<eT> > pa(A);
  165   const SpProxy< SpMat<eT> > pb(B);
  166   
  167   spglue_min::apply_noalias(out, pa, pb);
  168   }
  169 
  170 
  171 
  172 template<typename eT, typename T1, typename T2>
  173 inline
  174 void
  175 spglue_min::dense_sparse_min(Mat<eT>& out, const Base<eT,T1>& X, const SpBase<eT,T2>& Y)
  176   {
  177   arma_extra_debug_sigprint();
  178   
  179   // NOTE: this function assumes there is no aliasing between matrix 'out' and X
  180   
  181   const   Proxy<T1> pa(X.get_ref());
  182   const SpProxy<T2> pb(Y.get_ref());
  183   
  184   const uword n_rows = pa.get_n_rows();
  185   const uword n_cols = pa.get_n_cols();
  186   
  187   arma_debug_assert_same_size( n_rows, n_cols, pb.get_n_rows(), pb.get_n_cols(), "element-wise minimum" );
  188   
  189   out.set_size(n_rows, n_cols);
  190   
  191   for(uword c=0; c < n_cols; ++c)
  192   for(uword r=0; r < n_rows; ++r)
  193     {
  194     out.at(r,c) = elem_min(pa.at(r,c), pb.at(r,c));
  195     }
  196   }
  197 
  198 
  199 
  200 // min of non-complex elements
  201 template<typename eT>
  202 inline
  203 typename enable_if2<is_cx<eT>::no, eT>::result
  204 spglue_min::elem_min(const eT& a, const eT& b)
  205   {
  206   return (std::min)(a, b);
  207   }
  208 
  209 
  210 
  211 // min of complex elements
  212 template<typename eT>
  213 inline
  214 typename enable_if2<is_cx<eT>::yes, eT>::result
  215 spglue_min::elem_min(const eT& a, const eT& b)
  216   {
  217   return (std::abs(a) < std::abs(b)) ? a : b;
  218   }
  219 
  220 
  221 
  222 //! @}