ivl 679
|
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