op_shuffle_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_shuffle
00020 //! @{
00021 
00022 
00023 
00024 template<typename T1>
00025 inline
00026 void
00027 op_shuffle::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_shuffle>& in)
00028   {
00029   arma_extra_debug_sigprint();
00030   
00031   typedef typename T1::elem_type eT;
00032   
00033   const unwrap<T1>   tmp(in.m);
00034   const Mat<eT>& X = tmp.M;
00035   
00036   const u32 dim = in.aux_u32_a;
00037   const u32 N   = (dim == 0) ? X.n_rows : X.n_cols;
00038   
00039   // see "fn_sort_index.hpp" for the definition of "arma_sort_index_packet_ascend"
00040   // and the associated "operator<"
00041   std::vector< arma_sort_index_packet_ascend<int,u32> > packet_vec(N);
00042   
00043   for(u32 i=0; i<N; ++i)
00044     {
00045     packet_vec[i].val   = std::rand();
00046     packet_vec[i].index = i;
00047     }
00048   
00049   std::sort( packet_vec.begin(), packet_vec.end() );
00050   
00051   if(X.is_vec() == false)
00052     {
00053     if(&out != &X)
00054       {
00055       arma_extra_debug_print("op_shuffle::apply(): matrix");
00056       
00057       out.copy_size(X);
00058       
00059       if(dim == 0)
00060         {
00061         for(u32 i=0; i<N; ++i)
00062           {
00063           out.row(i) = X.row(packet_vec[i].index);
00064           }
00065         }
00066       else
00067         {
00068         for(u32 i=0; i<N; ++i)
00069           {
00070           out.col(i) = X.col(packet_vec[i].index);
00071           }
00072         }
00073       }
00074     else  // in-place shuffle
00075       {
00076       arma_extra_debug_print("op_shuffle::apply(): in-place matrix");
00077       
00078       // reuse the val member variable of packet_vec
00079       // to indicate whether a particular row or column
00080       // has already been shuffled
00081       
00082       for(u32 i=0; i<N; ++i)
00083         {
00084         packet_vec[i].val = 0;
00085         }
00086         
00087       if(dim == 0)
00088         {
00089         for(u32 i=0; i<N; ++i)
00090           {
00091           if(packet_vec[i].val == 0)
00092             {
00093             const u32 j = packet_vec[i].index;
00094             
00095             out.swap_rows(i, j);
00096             
00097             packet_vec[j].val = 1;
00098             }
00099           }
00100         }
00101       else
00102         {
00103         for(u32 i=0; i<N; ++i)
00104           {
00105           if(packet_vec[i].val == 0)
00106             {
00107             const u32 j = packet_vec[i].index;
00108             
00109             out.swap_cols(i, j);
00110             
00111             packet_vec[j].val = 1;
00112             }
00113           }
00114         }
00115       }
00116     }
00117   else  // we're dealing with a vector
00118     {
00119     if(&out != &X)
00120       {
00121       arma_extra_debug_print("op_shuffle::apply(): vector");
00122       
00123       out.copy_size(X);
00124       
00125       if(dim == 0)
00126         {
00127         if(X.n_rows > 1)  // i.e. column vector
00128           {
00129           for(u32 i=0; i<N; ++i)
00130             {
00131             out[i] = X[ packet_vec[i].index ];
00132             }
00133           }
00134         else
00135           {
00136           out = X;
00137           }
00138         }
00139       else
00140         {
00141         if(X.n_cols > 1)  // i.e. row vector
00142           {
00143           for(u32 i=0; i<N; ++i)
00144             {
00145             out[i] = X[ packet_vec[i].index ];
00146             }
00147           }
00148         else
00149           {
00150           out = X;
00151           }
00152         }
00153       }
00154     else  // in-place shuffle
00155       {
00156       arma_extra_debug_print("op_shuffle::apply(): in-place vector");
00157       
00158       // reuse the val member variable of packet_vec
00159       // to indicate whether a particular row or column
00160       // has already been shuffled
00161       
00162       for(u32 i=0; i<N; ++i)
00163         {
00164         packet_vec[i].val = 0;
00165         }
00166         
00167       if(dim == 0)
00168         {
00169         if(X.n_rows > 1)  // i.e. column vector
00170           {
00171           for(u32 i=0; i<N; ++i)
00172             {
00173             if(packet_vec[i].val == 0)
00174               {
00175               const u32 j = packet_vec[i].index;
00176               
00177               std::swap(out[i], out[j]);
00178               
00179               packet_vec[j].val = 1;
00180               }
00181             }
00182           }
00183         }
00184       else
00185         {
00186         if(X.n_cols > 1)  // i.e. row vector
00187           {
00188           for(u32 i=0; i<N; ++i)
00189             {
00190             if(packet_vec[i].val == 0)
00191               {
00192               const u32 j = packet_vec[i].index;
00193               
00194               std::swap(out[i], out[j]);
00195               
00196               packet_vec[j].val = 1;
00197               }
00198             }
00199           }
00200         }
00201       }
00202     }
00203   
00204   }
00205 
00206 
00207 //! @}