op_find_meat.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2010 NICTA and the authors listed below
00002 // http://nicta.com.au
00003 // 
00004 // Authors:
00005 // - Conrad Sanderson (conradsand at ieee dot org)
00006 // - Dimitrios Bouzas (dimitris dot mpouzas at gmail dot com)
00007 // 
00008 // This file is part of the Armadillo C++ library.
00009 // It is provided without any warranty of fitness
00010 // for any purpose. You can redistribute this file
00011 // and/or modify it under the terms of the GNU
00012 // Lesser General Public License (LGPL) as published
00013 // by the Free Software Foundation, either version 3
00014 // of the License or (at your option) any later version.
00015 // (see http://www.opensource.org/licenses for more info)
00016 
00017 
00018 
00019 //! \addtogroup op_find
00020 //! @{
00021 
00022 
00023 
00024 template<typename T1>
00025 inline
00026 u32
00027 op_find::helper
00028   (
00029   Mat<u32>& indices,
00030   const Base<typename T1::elem_type, T1>& X
00031   )
00032   {
00033   arma_extra_debug_sigprint();
00034   
00035   typedef typename T1::elem_type eT;
00036   
00037   const Proxy<T1> P(X.get_ref());
00038   
00039   const u32 n_elem = P.n_elem;
00040   
00041   indices.set_size(n_elem, 1);
00042   
00043   u32* indices_mem = indices.memptr();
00044   u32  n_nz        = 0;
00045   
00046   for(u32 i=0; i<n_elem; ++i)
00047     {
00048     if(P[i] != eT(0))
00049       {
00050       indices_mem[n_nz] = i;
00051       ++n_nz;
00052       }
00053     }
00054    
00055   return n_nz;
00056   }
00057 
00058 
00059 
00060 template<typename T1, typename op_type>
00061 inline
00062 u32
00063 op_find::helper
00064   (
00065   Mat<u32>& indices,
00066   const mtOp<u32, T1, op_type>& X,
00067   const typename arma_op_rel_only<op_type>::result junk1,
00068   const typename arma_not_cx<typename T1::elem_type>::result junk2
00069   )
00070   {
00071   arma_extra_debug_sigprint();
00072   
00073   typedef typename T1::elem_type eT;
00074   
00075   const eT val = X.aux;
00076   
00077   const Proxy<T1> P(X.m);
00078   
00079   const u32 n_elem = P.n_elem;
00080   
00081   indices.set_size(n_elem, 1);
00082   
00083   u32* indices_mem = indices.memptr();
00084   u32  n_nz        = 0;
00085   
00086   for(u32 i=0; i<n_elem; ++i)
00087     {
00088     const eT tmp = P[i];
00089     
00090     bool not_zero;
00091     
00092          if(is_same_type<op_type, op_rel_lt_pre   >::value == true)  { not_zero = (val <  tmp); }
00093     else if(is_same_type<op_type, op_rel_lt_post  >::value == true)  { not_zero = (tmp <  val); }
00094     else if(is_same_type<op_type, op_rel_gt_pre   >::value == true)  { not_zero = (val >  tmp); }
00095     else if(is_same_type<op_type, op_rel_gt_post  >::value == true)  { not_zero = (tmp >  val); }
00096     else if(is_same_type<op_type, op_rel_lteq_pre >::value == true)  { not_zero = (val <= tmp); }
00097     else if(is_same_type<op_type, op_rel_lteq_post>::value == true)  { not_zero = (tmp <= val); }
00098     else if(is_same_type<op_type, op_rel_gteq_pre >::value == true)  { not_zero = (val >= tmp); }
00099     else if(is_same_type<op_type, op_rel_gteq_post>::value == true)  { not_zero = (tmp >= val); }
00100     else if(is_same_type<op_type, op_rel_eq       >::value == true)  { not_zero = (tmp == val); }
00101     else if(is_same_type<op_type, op_rel_noteq    >::value == true)  { not_zero = (tmp != val); }
00102     else not_zero = false;
00103     
00104     if(not_zero == true)
00105       {
00106       indices_mem[n_nz] = i;
00107       ++n_nz;
00108       }
00109     }
00110   
00111   return n_nz;
00112   }
00113 
00114 
00115 
00116 template<typename T1, typename op_type>
00117 inline
00118 u32
00119 op_find::helper
00120   (
00121   Mat<u32>& indices,
00122   const mtOp<u32, T1, op_type>& X,
00123   const typename arma_op_rel_only<op_type>::result junk1,
00124   const typename arma_cx_only<typename T1::elem_type>::result junk2
00125   )
00126   {
00127   arma_extra_debug_sigprint();
00128   
00129   typedef typename T1::elem_type eT;
00130   
00131   const eT val = X.aux;
00132   
00133   const Proxy<T1> P(X.m);
00134   
00135   const u32 n_elem = P.n_elem;
00136   
00137   indices.set_size(n_elem, 1);
00138   
00139   u32* indices_mem = indices.memptr();
00140   u32  n_nz        = 0;
00141   
00142   for(u32 i=0; i<n_elem; ++i)
00143     {
00144     const eT tmp = P[i];
00145     
00146     bool not_zero;
00147     
00148          if(is_same_type<op_type, op_rel_eq   >::value == true)  { not_zero = (tmp == val); }
00149     else if(is_same_type<op_type, op_rel_noteq>::value == true)  { not_zero = (tmp != val); }
00150     else not_zero = false;
00151     
00152     if(not_zero == true)
00153       {
00154       indices_mem[n_nz] = i;
00155       ++n_nz;
00156       }
00157     }
00158   
00159   return n_nz;
00160   }
00161 
00162 
00163 
00164 template<typename T1, typename T2, typename glue_type>
00165 inline
00166 u32
00167 op_find::helper
00168   (
00169   Mat<u32>& indices,
00170   const mtGlue<u32, T1, T2, glue_type>& X,
00171   const typename arma_glue_rel_only<glue_type>::result junk1,
00172   const typename arma_not_cx<typename T1::elem_type>::result junk2,
00173   const typename arma_not_cx<typename T2::elem_type>::result junk3
00174   )
00175   {
00176   arma_extra_debug_sigprint();
00177   
00178   typedef typename T1::elem_type eT1;
00179   typedef typename T2::elem_type eT2;
00180   
00181   const Proxy<T1> A(X.A);
00182   const Proxy<T2> B(X.B);
00183   
00184   arma_debug_assert_same_size(A, B, "relational operator");
00185   
00186   const u32 n_elem = A.n_elem;
00187   
00188   indices.set_size(n_elem, 1);
00189   
00190   u32* indices_mem = indices.memptr();
00191   u32  n_nz        = 0;
00192   
00193   for(u32 i=0; i<n_elem; ++i)
00194     {
00195     const eT1 tmp1 = A[i];
00196     const eT1 tmp2 = B[i];
00197     
00198     bool not_zero;
00199     
00200          if(is_same_type<glue_type, glue_rel_lt    >::value == true)  { not_zero = (tmp1 <  tmp2); }
00201     else if(is_same_type<glue_type, glue_rel_gt    >::value == true)  { not_zero = (tmp1 >  tmp2); }
00202     else if(is_same_type<glue_type, glue_rel_lteq  >::value == true)  { not_zero = (tmp1 <= tmp2); }
00203     else if(is_same_type<glue_type, glue_rel_gteq  >::value == true)  { not_zero = (tmp1 >= tmp2); }
00204     else if(is_same_type<glue_type, glue_rel_eq    >::value == true)  { not_zero = (tmp1 == tmp2); }
00205     else if(is_same_type<glue_type, glue_rel_noteq >::value == true)  { not_zero = (tmp1 != tmp2); }
00206     else not_zero = false;
00207     
00208     if(not_zero == true)
00209       {
00210       indices_mem[n_nz] = i;
00211       ++n_nz;
00212       }
00213     }
00214   
00215   return n_nz;
00216   }
00217 
00218 
00219 
00220 template<typename T1, typename T2, typename glue_type>
00221 inline
00222 u32
00223 op_find::helper
00224   (
00225   Mat<u32>& indices,
00226   const mtGlue<u32, T1, T2, glue_type>& X,
00227   const typename arma_glue_rel_only<glue_type>::result junk1,
00228   const typename arma_cx_only<typename T1::elem_type>::result junk2,
00229   const typename arma_cx_only<typename T2::elem_type>::result junk3
00230   )
00231   {
00232   arma_extra_debug_sigprint();
00233   
00234   const Proxy<T1> A(X.A);
00235   const Proxy<T2> B(X.B);
00236   
00237   arma_debug_assert_same_size(A, B, "relational operator");
00238   
00239   const u32 n_elem = A.n_elem;
00240   
00241   indices.set_size(n_elem, 1);
00242   
00243   u32* indices_mem = indices.memptr();
00244   u32  n_nz        = 0;
00245   
00246   for(u32 i=0; i<n_elem; ++i)
00247     {
00248     bool not_zero;
00249     
00250          if(is_same_type<glue_type, glue_rel_eq    >::value == true)  { not_zero = (A[i] == B[i]); }
00251     else if(is_same_type<glue_type, glue_rel_noteq >::value == true)  { not_zero = (A[i] != B[i]); }
00252     else not_zero = false;
00253     
00254     if(not_zero == true)
00255       {
00256       indices_mem[n_nz] = i;
00257       ++n_nz;
00258       }
00259     }
00260   
00261   return n_nz;
00262   }
00263 
00264 
00265 
00266 template<typename T1>
00267 inline
00268 void
00269 op_find::apply(Mat<u32>& out, const mtOp<u32, T1, op_find>& X)
00270   {
00271   arma_extra_debug_sigprint();
00272   
00273   const u32 k    = X.aux_u32_a;
00274   const u32 type = X.aux_u32_b;
00275   
00276   Mat<u32> indices;
00277   const u32 n_nz = op_find::helper(indices, X.m);
00278   
00279   if(n_nz > 0)
00280     {
00281     if(type == 0)   // "first"
00282       {
00283       out = (k > 0 && k <= n_nz) ? indices.rows(0,      k-1   ) : indices.rows(0, n_nz-1);
00284       }
00285     else   // "last"
00286       {
00287       out = (k > 0 && k <= n_nz) ? indices.rows(n_nz-k, n_nz-1) : indices.rows(0, n_nz-1);
00288       }
00289     }
00290   else
00291     {
00292     out.reset();
00293     }
00294   }
00295 
00296 
00297 
00298 //! @}