gim_radixsort.h
Go to the documentation of this file.
00001 #ifndef GIM_RADIXSORT_H_INCLUDED
00002 #define GIM_RADIXSORT_H_INCLUDED
00003 
00008 /*
00009 -----------------------------------------------------------------------------
00010 This source file is part of GIMPACT Library.
00011 
00012 For the latest info, see http://gimpact.sourceforge.net/
00013 
00014 Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
00015 email: projectileman@yahoo.com
00016 
00017  This library is free software; you can redistribute it and/or
00018  modify it under the terms of EITHER:
00019    (1) The GNU Lesser General Public License as published by the Free
00020        Software Foundation; either version 2.1 of the License, or (at
00021        your option) any later version. The text of the GNU Lesser
00022        General Public License is included with this library in the
00023        file GIMPACT-LICENSE-LGPL.TXT.
00024    (2) The BSD-style license that is included with this library in
00025        the file GIMPACT-LICENSE-BSD.TXT.
00026    (3) The zlib/libpng license that is included with this library in
00027        the file GIMPACT-LICENSE-ZLIB.TXT.
00028 
00029  This library is distributed in the hope that it will be useful,
00030  but WITHOUT ANY WARRANTY; without even the implied warranty of
00031  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
00032  GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
00033 
00034 -----------------------------------------------------------------------------
00035 */
00036 
00037 #include "gim_memory.h"
00038 
00041 class less_comparator
00042 {
00043         public:
00044 
00045         template<class T,class Z>
00046         inline int operator() ( const T& a, const Z& b )
00047         {
00048                 return ( a<b?-1:(a>b?1:0));
00049         }
00050 };
00051 
00053 class integer_comparator
00054 {
00055         public:
00056 
00057         template<class T>
00058         inline int operator() ( const T& a, const T& b )
00059         {
00060                 return (int)(a-b);
00061         }
00062 };
00063 
00065 class uint_key_func
00066 {
00067 public:
00068         template<class T>
00069         inline GUINT operator()( const T& a)
00070         {
00071                 return (GUINT)a;
00072         }
00073 };
00074 
00075 
00077 class copy_elements_func
00078 {
00079 public:
00080         template<class T>
00081         inline void operator()(T& a,T& b)
00082         {
00083                 a = b;
00084         }
00085 };
00086 
00088 class memcopy_elements_func
00089 {
00090 public:
00091         template<class T>
00092         inline void operator()(T& a,T& b)
00093         {
00094                 gim_simd_memcpy(&a,&b,sizeof(T));
00095         }
00096 };
00097 
00098 
00100 struct GIM_RSORT_TOKEN
00101 {
00102     GUINT m_key;
00103     GUINT m_value;
00104     GIM_RSORT_TOKEN()
00105     {
00106     }
00107     GIM_RSORT_TOKEN(const GIM_RSORT_TOKEN& rtoken)
00108     {
00109         m_key = rtoken.m_key;
00110         m_value = rtoken.m_value;
00111     }
00112 
00113     inline bool operator <(const GIM_RSORT_TOKEN& other) const
00114         {
00115                 return (m_key < other.m_key);
00116         }
00117 
00118         inline bool operator >(const GIM_RSORT_TOKEN& other) const
00119         {
00120                 return (m_key > other.m_key);
00121         }
00122 };
00123 
00125 class GIM_RSORT_TOKEN_COMPARATOR
00126 {
00127         public:
00128 
00129         inline int operator()( const GIM_RSORT_TOKEN& a, const GIM_RSORT_TOKEN& b )
00130         {
00131                 return (int)((a.m_key) - (b.m_key));
00132         }
00133 };
00134 
00135 
00136 
00137 #define kHist 2048
00138 // ---- utils for accessing 11-bit quantities
00139 #define D11_0(x)        (x & 0x7FF)
00140 #define D11_1(x)        (x >> 11 & 0x7FF)
00141 #define D11_2(x)        (x >> 22 )
00142 
00143 
00144 
00146 inline void gim_radix_sort_rtokens(
00147                                 GIM_RSORT_TOKEN * array,
00148                                 GIM_RSORT_TOKEN * sorted, GUINT element_count)
00149 {
00150         GUINT i;
00151         GUINT b0[kHist * 3];
00152         GUINT *b1 = b0 + kHist;
00153         GUINT *b2 = b1 + kHist;
00154         for (i = 0; i < kHist * 3; ++i)
00155         {
00156                 b0[i] = 0;
00157         }
00158         GUINT fi;
00159         GUINT pos;
00160         for (i = 0; i < element_count; ++i)
00161         {
00162             fi = array[i].m_key;
00163                 b0[D11_0(fi)] ++;
00164                 b1[D11_1(fi)] ++;
00165                 b2[D11_2(fi)] ++;
00166         }
00167         {
00168                 GUINT sum0 = 0, sum1 = 0, sum2 = 0;
00169                 GUINT tsum;
00170                 for (i = 0; i < kHist; ++i)
00171                 {
00172                         tsum = b0[i] + sum0;
00173                         b0[i] = sum0 - 1;
00174                         sum0 = tsum;
00175                         tsum = b1[i] + sum1;
00176                         b1[i] = sum1 - 1;
00177                         sum1 = tsum;
00178                         tsum = b2[i] + sum2;
00179                         b2[i] = sum2 - 1;
00180                         sum2 = tsum;
00181                 }
00182         }
00183         for (i = 0; i < element_count; ++i)
00184         {
00185         fi = array[i].m_key;
00186                 pos = D11_0(fi);
00187                 pos = ++b0[pos];
00188                 sorted[pos].m_key = array[i].m_key;
00189                 sorted[pos].m_value = array[i].m_value;
00190         }
00191         for (i = 0; i < element_count; ++i)
00192         {
00193         fi = sorted[i].m_key;
00194                 pos = D11_1(fi);
00195                 pos = ++b1[pos];
00196                 array[pos].m_key = sorted[i].m_key;
00197                 array[pos].m_value = sorted[i].m_value;
00198         }
00199         for (i = 0; i < element_count; ++i)
00200         {
00201         fi = array[i].m_key;
00202                 pos = D11_2(fi);
00203                 pos = ++b2[pos];
00204                 sorted[pos].m_key = array[i].m_key;
00205                 sorted[pos].m_value = array[i].m_value;
00206         }
00207 }
00208 
00209 
00210 
00211 
00213 
00219 template<typename T, class GETKEY_CLASS>
00220 void gim_radix_sort_array_tokens(
00221                         T* array ,
00222                         GIM_RSORT_TOKEN * sorted_tokens,
00223                         GUINT element_count,GETKEY_CLASS uintkey_macro)
00224 {
00225         GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count);
00226     for (GUINT _i=0;_i<element_count;++_i)
00227     {
00228         _unsorted[_i].m_key = uintkey_macro(array[_i]);
00229         _unsorted[_i].m_value = _i;
00230     }
00231     gim_radix_sort_rtokens(_unsorted,sorted_tokens,element_count);
00232     gim_free(_unsorted);
00233     gim_free(_unsorted);
00234 }
00235 
00237 
00244 template<typename T, class GETKEY_CLASS, class COPY_CLASS>
00245 void gim_radix_sort(
00246         T * array, GUINT element_count,
00247         GETKEY_CLASS get_uintkey_macro, COPY_CLASS copy_elements_macro)
00248 {
00249         GIM_RSORT_TOKEN * _sorted = (GIM_RSORT_TOKEN  *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count);
00250     gim_radix_sort_array_tokens(array,_sorted,element_count,get_uintkey_macro);
00251     T * _original_array = (T *) gim_alloc(sizeof(T)*element_count);
00252     gim_simd_memcpy(_original_array,array,sizeof(T)*element_count);
00253     for (GUINT _i=0;_i<element_count;++_i)
00254     {
00255         copy_elements_macro(array[_i],_original_array[_sorted[_i].m_value]);
00256     }
00257     gim_free(_original_array);
00258     gim_free(_sorted);
00259 }
00260 
00262 
00272 template<class T, typename KEYCLASS, typename COMP_CLASS>
00273 bool  gim_binary_search_ex(
00274                 const T* _array, GUINT _start_i,
00275                 GUINT _end_i,GUINT & _result_index,
00276                 const KEYCLASS & _search_key,
00277                 COMP_CLASS _comp_macro)
00278 {
00279         GUINT _k;
00280         int _comp_result;
00281         GUINT _i = _start_i;
00282         GUINT _j = _end_i+1;
00283         while (_i < _j)
00284         {
00285                 _k = (_j+_i-1)/2;
00286                 _comp_result = _comp_macro(_array[_k], _search_key);
00287                 if (_comp_result == 0)
00288                 {
00289                         _result_index = _k;
00290                         return true;
00291                 }
00292                 else if (_comp_result < 0)
00293                 {
00294                         _i = _k+1;
00295                 }
00296                 else
00297                 {
00298                         _j = _k;
00299                 }
00300         }
00301         _result_index = _i;
00302         return false;
00303 }
00304 
00305 
00306 
00308 
00317 template<class T>
00318 bool gim_binary_search(
00319         const T*_array,GUINT _start_i,
00320         GUINT _end_i,const T & _search_key,
00321         GUINT & _result_index)
00322 {
00323         GUINT _i = _start_i;
00324         GUINT _j = _end_i+1;
00325         GUINT _k;
00326         while(_i < _j)
00327         {
00328                 _k = (_j+_i-1)/2;
00329                 if(_array[_k]==_search_key)
00330                 {
00331                         _result_index = _k;
00332                         return true;
00333                 }
00334                 else if (_array[_k]<_search_key)
00335                 {
00336                         _i = _k+1;
00337                 }
00338                 else
00339                 {
00340                         _j = _k;
00341                 }
00342         }
00343         _result_index = _i;
00344         return false;
00345 }
00346 
00347 
00348 
00350 template <typename T, typename COMP_CLASS>
00351 void gim_down_heap(T *pArr, GUINT k, GUINT n,COMP_CLASS CompareFunc)
00352 {
00353         /*  PRE: a[k+1..N] is a heap */
00354         /* POST:  a[k..N]  is a heap */
00355 
00356         T temp = pArr[k - 1];
00357         /* k has child(s) */
00358         while (k <= n/2)
00359         {
00360                 int child = 2*k;
00361 
00362                 if ((child < (int)n) && CompareFunc(pArr[child - 1] , pArr[child])<0)
00363                 {
00364                         child++;
00365                 }
00366                 /* pick larger child */
00367                 if (CompareFunc(temp , pArr[child - 1])<0)
00368                 {
00369                         /* move child up */
00370                         pArr[k - 1] = pArr[child - 1];
00371                         k = child;
00372                 }
00373                 else
00374                 {
00375                         break;
00376                 }
00377         }
00378         pArr[k - 1] = temp;
00379 } /*downHeap*/
00380 
00381 
00382 template <typename T, typename COMP_CLASS>
00383 void gim_heap_sort(T *pArr, GUINT element_count, COMP_CLASS CompareFunc)
00384 {
00385         /* sort a[0..N-1],  N.B. 0 to N-1 */
00386         GUINT k;
00387         GUINT n = element_count;
00388         for (k = n/2; k > 0; k--)
00389         {
00390                 gim_down_heap(pArr, k, n, CompareFunc);
00391         }
00392 
00393         /* a[1..N] is now a heap */
00394         while ( n>=2 )
00395         {
00396                 gim_swap_elements(pArr,0,n-1); /* largest of a[0..n-1] */
00397                 --n;
00398                 /* restore a[1..i-1] heap */
00399                 gim_down_heap(pArr, 1, n, CompareFunc);
00400         }
00401 }
00402 
00403 
00404 
00405 
00406 #endif // GIM_RADIXSORT_H_INCLUDED
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


bullet
Author(s): Erwin Coumans, ROS package maintained by Tully Foote
autogenerated on Wed Oct 31 2012 07:54:31