ivl 679
ivl/details/array/functions/radixsort.hpp
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>.
00002    A C++ template library extending syntax towards mathematical notation.
00003 
00004    Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr>
00005    Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr>
00006 
00007    ivl is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU Lesser General Public License 
00009    version 3 as published by the Free Software Foundation.
00010 
00011    Alternatively, you can redistribute it and/or modify it under the terms 
00012    of the GNU General Public License version 2 as published by the Free 
00013    Software Foundation.
00014 
00015    ivl is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00018    See the GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License 
00021    and a copy of the GNU Lesser General Public License along 
00022    with ivl. If not, see <http://www.gnu.org/licenses/>. */
00023 
00024 #ifndef IVL_ARRAY_DETAILS_RADIXSORT_HPP
00025 #define IVL_ARRAY_DETAILS_RADIXSORT_HPP
00026 
00027 //-------------------------------------------------------------------------------------
00028 namespace ivl {
00029 
00030 namespace array_details {
00031 
00034 template<class T> inline
00035 void radix (size_t b, ivl::array<T> &source, ivl::array<T> &dest, ivl::size_array &ind)
00036 {
00037         ivl::size_array t_ind(ind);
00038         size_t N = source.size();
00039         T count[256];
00040         T index[256];
00041         for(size_t i=0;i<256;i++) count[i]=0;
00042 
00043         for ( size_t i=0; i<(size_t)N; i++ )   //count occurences of  each possible element
00044                 count[((source[i])>>(b*8))&0xff]++;
00045 
00046         index[0]=0;
00047         for ( size_t i=1; i<256; i++ )  //build a index-list for each possible element
00048                 index[i]=index[i-1]+count[i-1];
00049         for ( size_t i=0; i<(size_t)N; i++ )  //place elements in another array with the sorted order
00050         {
00051                 size_t pos = (size_t)( ((source[i])>>(b*8))&0xff);
00052                 dest[(size_t)index[pos]] = (T)source[i];
00053                 ind[(size_t)index[pos]] = t_ind[i];
00054                 index[pos]++;
00055         }
00056 }
00057 
00058 }; // namespace array_details
00059 
00060 //-------------------------------------------------------------------------------------
00063 template<class T> inline
00064 void radixsort(ivl::array<T> &source, ivl::size_array &ind)
00065 {
00066         using namespace array_details;
00067 
00068         ind = ivl::size_range(0,source.size()-1);
00069         size_t nb = sizeof(source[0]) / sizeof(char);  //number of bytes used
00070         ivl::array<T> temp(source.size()); //temporary array
00071 
00072         for(size_t i=0; i<nb/2; i++) // sort based on each byte starting from the LSD
00073         {
00074                 radix (i*2, source, temp, ind);
00075                 radix (i*2+1, temp, source, ind);
00076         }
00077 }
00078 
00079 namespace array_details {
00080 
00081 //-------------------------------------------------------------------------------------
00083 template<class T> inline
00084 void radix (size_t b, ivl::array<T> &source, ivl::array<T> &dest)
00085 {
00086         size_t N = source.size();
00087         T count[256];
00088         T index[256];
00089         for (size_t i=0; i<256; i++) count[i] = 0;
00090 
00091         for ( size_t i=0; i<(size_t)N; i++ )   //count occurences of  each possible element
00092                 count[((source[i])>>(b*8))&0xff]++;
00093 
00094         index[0]=0;
00095         for ( size_t i=1; i<256; i++ )  //build a index-list for each possible element
00096                 index[i]=index[i-1]+count[i-1];
00097         for ( size_t i=0; i<(size_t)N; i++ )  //place elements in another array with the sorted order
00098         {
00099                 size_t pos = ((source[i])>>(b*8))&0xff;
00100                 dest[index[pos]++] = source[i];
00101         }
00102 }
00103 
00104 }; // namespace array_details
00105 
00106 //-------------------------------------------------------------------------------------
00108 template<class T> inline
00109 void radixsort(ivl::array<T> &source)
00110 {
00111         using namespace array_details;
00112 
00113         size_t nb = sizeof(source[0]) / sizeof(char);  //number of bytes used
00114         ivl::array<T> temp(source.size()); //temporary array
00115 
00116         for(size_t i=0; i<nb/2; i++) // sort based on each byte starting from the LSD
00117         {
00118                 radix (i*2, source, temp);
00119                 radix (i*2+1, temp, source);
00120         }
00121 }
00122 
00123 namespace array_details {
00124 
00125 //-------------------------------------------------------------------------------------
00127 template<class T> inline
00128 void radix(size_t b, ivl::array<ivl::array<T> > &source, ivl::array<ivl::array<T> > &dest, size_t n)
00129 {
00130         size_t N = source.size();
00131         T count[256];
00132         T index[256];
00133         for(size_t i=0;i<256;i++) count[i]=0;
00134 
00135         for ( size_t i=0; i<(size_t)N; i++ )   //count occurences of  each possible element
00136                 count[((source[i][n])>>(b*8))&0xff]++;
00137 
00138         index[0]=0;
00139         for ( size_t i=1; i<256; i++ )  //build a index-list for each possible element
00140                 index[i]=index[i-1]+count[i-1];
00141         for ( size_t i=0; i<(size_t)N; i++ )  //place elements in another array with the sorted order
00142         {
00143                 size_t pos = ((source[i][n])>>(b*8))&0xff;
00144                 dest[index[pos]++] = source[i];
00145         }
00146 }
00147 
00148 }; //namespace array_details
00149 
00150 //-------------------------------------------------------------------------------------
00152 template<class T> inline
00153 void radixsort(ivl::array<ivl::array<T> > &source)
00154 {
00155         using namespace array_details;
00156 
00157         size_t nb = sizeof(source[0][0]) / sizeof(char);  //number of bytes used
00158         ivl::array<ivl::array<T> > temp(source.size()); //temporary array
00159 
00160         size_t s = source[0].size();
00161         for(int j=(int)s-1; j>-1; j--)
00162                 for(size_t i=0; i<nb/2; i++) // sort based on each byte starting from the LSD
00163                 {
00164                         radix (i*2, source, temp,(size_t)j);
00165                         radix (i*2+1, temp, source,(size_t)j);
00166                 }
00167 }
00168 
00169 namespace array_details {
00170 
00171 //-------------------------------------------------------------------------------------
00173 template<class T> inline
00174 void radix(size_t b, ivl::array<ivl::array<T> > &source, ivl::array<ivl::array<T> > &dest, size_t n,  ivl::size_array& ind)
00175 {
00176         ivl::size_array t_ind(ind);
00177         size_t N = source.size();
00178         T count[256];
00179         T index[256];
00180         for(size_t i=0;i<256;i++) count[i]=0;
00181 
00182         for ( size_t i=0; i<(size_t)N; i++ )   //count occurences of  each possible element
00183                 count[((source[i][n])>>(b*8))&0xff]++;
00184 
00185         index[0]=0;
00186         for ( size_t i=1; i<256; i++ )  //build a index-list for each possible element
00187                 index[i]=index[i-1]+count[i-1];
00188         for ( size_t i=0; i<(size_t)N; i++ )  //place elements in another array with the sorted order
00189         {
00190                 size_t pos = ((source[i][n])>>(b*8))&0xff;
00191                 dest[index[pos]] = source[i];
00192                 ind[index[pos]] = t_ind[i];
00193                 index[pos]++;
00194         }
00195 }
00196 
00197 }; // namespace array_details
00198 
00199 //-------------------------------------------------------------------------------------
00201 template<class T> inline
00202 void radixsort(ivl::array<ivl::array<T> > &source, ivl::size_array& ind)
00203 {
00204         using namespace array_details;
00205 
00206         ind = ivl::size_range(0,source.size()-1);
00207         size_t nb = sizeof(source[0][0]) / sizeof(char);  //number of bytes used
00208         ivl::array<ivl::array<T> > temp(source.size()); //temporary array
00209 
00210         size_t s = source[0].size();
00211         for(int j=(int)s-1; j>-1; j--)
00212                 for(size_t i=0; i<nb/2; i++) // sort based on each byte starting from the LSD
00213                 {
00214                         radix (i*2, source, temp,(size_t)j, ind);
00215                         radix (i*2+1, temp, source,(size_t)j, ind);
00216                 }
00217 }
00218 
00219 } /* namespace ivl */
00220 
00221 #endif // IVL_ARRAY_DETAILS_RADIXSORT_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations