1
#ifndef GIM_RADIXSORT_H_INCLUDED
2
#define GIM_RADIXSORT_H_INCLUDED
3
/*! \file gim_radixsort.h
4
\author Francisco Leon Najera.
5
Based on the work of Michael Herf : "fast floating-point radix sort"
6
Avaliable on http://www.stereopsis.com/radix.html
9
-----------------------------------------------------------------------------
10
This source file is part of GIMPACT Library.
12
For the latest info, see http://gimpact.sourceforge.net/
14
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
15
email: projectileman@yahoo.com
17
This library is free software; you can redistribute it and/or
18
modify it under the terms of EITHER:
19
(1) The GNU Lesser General Public License as published by the Free
20
Software Foundation; either version 2.1 of the License, or (at
21
your option) any later version. The text of the GNU Lesser
22
General Public License is included with this library in the
23
file GIMPACT-LICENSE-LGPL.TXT.
24
(2) The BSD-style license that is included with this library in
25
the file GIMPACT-LICENSE-BSD.TXT.
26
(3) The zlib/libpng license that is included with this library in
27
the file GIMPACT-LICENSE-ZLIB.TXT.
29
This library is distributed in the hope that it will be useful,
30
but WITHOUT ANY WARRANTY; without even the implied warranty of
31
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
32
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
34
-----------------------------------------------------------------------------
37
#include "gim_memory.h"
39
///Macros for sorting.
40
//! Prototype for comparators
45
template<class T,class Z>
46
inline int operator() ( const T& a, const Z& b )
48
return ( a<b?-1:(a>b?1:0));
52
//! Prototype for comparators
53
class integer_comparator
58
inline int operator() ( const T& a, const T& b )
64
//!Prototype for getting the integer representation of an object
69
inline GUINT operator()( const T& a)
76
//!Prototype for copying elements
77
class copy_elements_func
81
inline void operator()(T& a,T& b)
87
//!Prototype for copying elements
88
class memcopy_elements_func
92
inline void operator()(T& a,T& b)
94
gim_simd_memcpy(&a,&b,sizeof(T));
100
struct GIM_RSORT_TOKEN
107
GIM_RSORT_TOKEN(const GIM_RSORT_TOKEN& rtoken)
109
m_key = rtoken.m_key;
110
m_value = rtoken.m_value;
113
inline bool operator <(const GIM_RSORT_TOKEN& other) const
115
return (m_key < other.m_key);
118
inline bool operator >(const GIM_RSORT_TOKEN& other) const
120
return (m_key > other.m_key);
124
//! Prototype for comparators
125
class GIM_RSORT_TOKEN_COMPARATOR
129
inline int operator()( const GIM_RSORT_TOKEN& a, const GIM_RSORT_TOKEN& b )
131
return (int)((a.m_key) - (b.m_key));
138
// ---- utils for accessing 11-bit quantities
139
#define D11_0(x) (x & 0x7FF)
140
#define D11_1(x) (x >> 11 & 0x7FF)
141
#define D11_2(x) (x >> 22 )
145
///Radix sort for unsigned integer keys
146
inline void gim_radix_sort_rtokens(
147
GIM_RSORT_TOKEN * array,
148
GIM_RSORT_TOKEN * sorted, GUINT element_count)
152
GUINT *b1 = b0 + kHist;
153
GUINT *b2 = b1 + kHist;
154
for (i = 0; i < kHist * 3; ++i)
160
for (i = 0; i < element_count; ++i)
168
GUINT sum0 = 0, sum1 = 0, sum2 = 0;
170
for (i = 0; i < kHist; ++i)
183
for (i = 0; i < element_count; ++i)
188
sorted[pos].m_key = array[i].m_key;
189
sorted[pos].m_value = array[i].m_value;
191
for (i = 0; i < element_count; ++i)
193
fi = sorted[i].m_key;
196
array[pos].m_key = sorted[i].m_key;
197
array[pos].m_value = sorted[i].m_value;
199
for (i = 0; i < element_count; ++i)
204
sorted[pos].m_key = array[i].m_key;
205
sorted[pos].m_value = array[i].m_value;
212
/// Get the sorted tokens from an array. For generic use. Tokens are IRR_RSORT_TOKEN
214
*\param array Array of elements to sort
215
*\param sorted_tokens Tokens of sorted elements
216
*\param element_count element count
217
*\param uintkey_macro Functor which retrieves the integer representation of an array element
219
template<typename T, class GETKEY_CLASS>
220
void gim_radix_sort_array_tokens(
222
GIM_RSORT_TOKEN * sorted_tokens,
223
GUINT element_count,GETKEY_CLASS uintkey_macro)
225
GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count);
226
for (GUINT _i=0;_i<element_count;++_i)
228
_unsorted[_i].m_key = uintkey_macro(array[_i]);
229
_unsorted[_i].m_value = _i;
231
gim_radix_sort_rtokens(_unsorted,sorted_tokens,element_count);
236
/// Sorts array in place. For generic use
238
\param type Type of the array
241
\param get_uintkey_macro Macro for extract the Integer value of the element. Similar to SIMPLE_GET_UINTKEY
242
\param copy_elements_macro Macro for copy elements, similar to SIMPLE_COPY_ELEMENTS
244
template<typename T, class GETKEY_CLASS, class COPY_CLASS>
246
T * array, GUINT element_count,
247
GETKEY_CLASS get_uintkey_macro, COPY_CLASS copy_elements_macro)
249
GIM_RSORT_TOKEN * _sorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count);
250
gim_radix_sort_array_tokens(array,_sorted,element_count,get_uintkey_macro);
251
T * _original_array = (T *) gim_alloc(sizeof(T)*element_count);
252
gim_simd_memcpy(_original_array,array,sizeof(T)*element_count);
253
for (GUINT _i=0;_i<element_count;++_i)
255
copy_elements_macro(array[_i],_original_array[_sorted[_i].m_value]);
257
gim_free(_original_array);
261
//! Failsafe Iterative binary search,
263
If the element is not found, it returns the nearest upper element position, may be the further position after the last element.
265
\param _start_i the beginning of the array
266
\param _end_i the ending index of the array
267
\param _search_key Value to find
268
\param _comp_macro macro for comparing elements
269
\param _found If true the value has found. Boolean
270
\param _result_index the index of the found element, or if not found then it will get the index of the closest bigger value
272
template<class T, typename KEYCLASS, typename COMP_CLASS>
273
bool gim_binary_search_ex(
274
const T* _array, GUINT _start_i,
275
GUINT _end_i,GUINT & _result_index,
276
const KEYCLASS & _search_key,
277
COMP_CLASS _comp_macro)
286
_comp_result = _comp_macro(_array[_k], _search_key);
287
if (_comp_result == 0)
292
else if (_comp_result < 0)
307
//! Failsafe Iterative binary search,Template version
309
If the element is not found, it returns the nearest upper element position, may be the further position after the last element.
311
\param _start_i the beginning of the array
312
\param _end_i the ending index of the array
313
\param _search_key Value to find
314
\param _result_index the index of the found element, or if not found then it will get the index of the closest bigger value
315
\return true if found, else false
318
bool gim_binary_search(
319
const T*_array,GUINT _start_i,
320
GUINT _end_i,const T & _search_key,
321
GUINT & _result_index)
329
if(_array[_k]==_search_key)
334
else if (_array[_k]<_search_key)
349
///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/
350
template <typename T, typename COMP_CLASS>
351
void gim_down_heap(T *pArr, GUINT k, GUINT n,COMP_CLASS CompareFunc)
353
/* PRE: a[k+1..N] is a heap */
354
/* POST: a[k..N] is a heap */
356
T temp = pArr[k - 1];
362
if ((child < (int)n) && CompareFunc(pArr[child - 1] , pArr[child])<0)
366
/* pick larger child */
367
if (CompareFunc(temp , pArr[child - 1])<0)
370
pArr[k - 1] = pArr[child - 1];
382
template <typename T, typename COMP_CLASS>
383
void gim_heap_sort(T *pArr, GUINT element_count, COMP_CLASS CompareFunc)
385
/* sort a[0..N-1], N.B. 0 to N-1 */
387
GUINT n = element_count;
388
for (k = n/2; k > 0; k--)
390
gim_down_heap(pArr, k, n, CompareFunc);
393
/* a[1..N] is now a heap */
396
gim_swap_elements(pArr,0,n-1); /* largest of a[0..n-1] */
398
/* restore a[1..i-1] heap */
399
gim_down_heap(pArr, 1, n, CompareFunc);
406
#endif // GIM_RADIXSORT_H_INCLUDED