Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ode/ode-0.9/GIMPACT/include/GIMPACT/gim_radixsort.h @ 216

Last change on this file since 216 was 216, checked in by mathiask, 16 years ago

[Physik] add ode-0.9

File size: 7.4 KB
Line 
1#ifndef GIM_RADIXSORT_H_INCLUDED
2#define GIM_RADIXSORT_H_INCLUDED
3/*! \file gim_radixsort.h
4\author Francisco León.
5Based on the work of Michael Herf : "fast floating-point radix sort"
6Avaliable on http://www.stereopsis.com/radix.html
7*/
8/*
9-----------------------------------------------------------------------------
10This source file is part of GIMPACT Library.
11
12For the latest info, see http://gimpact.sourceforge.net/
13
14Copyright (c) 2006 Francisco Leon. C.C. 80087371.
15email: projectileman@yahoo.com
16
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
27 This library is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
30 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
31
32-----------------------------------------------------------------------------
33*/
34
35#include "GIMPACT/gim_memory.h"
36
37/*! \defgroup SORTING
38\brief
39Macros for sorting.
40*/
41//! @{
42struct GIM_RSORT_TOKEN
43{
44    GUINT m_key;
45    GUINT m_value;
46};
47//typedef struct _GIM_RSORT_TOKEN GIM_RSORT_TOKEN;
48
49//comparator for sorting
50#define RSORT_TOKEN_COMPARATOR(x, y) ((int)((x.m_key) - (y.m_key)))
51
52// ---- utils for accessing 11-bit quantities
53#define D11_0(x)        (x & 0x7FF)
54#define D11_1(x)        (x >> 11 & 0x7FF)
55#define D11_2(x)        (x >> 22 )
56
57
58//COMMON FUNCTIONS FOR ACCESSING THE KEY OF AN ELEMENT
59
60
61//For the type of your array, you need to declare a macro for obtaining the key, like these:
62#define SIMPLE_GET_FLOAT32KEY(e,key) {key =(GREAL)(e);}
63
64#define SIMPLE_GET_INTKEY(e,key) {key =(GINT)(e);}
65
66#define SIMPLE_GET_UINTKEY(e,key) {key =(GUINT)(e);}
67
68//For the type of your array, you need to declare a macro for copy elements, like this:
69
70#define SIMPLE_COPY_ELEMENTS(dest,src) {dest = src;}
71
72#define kHist 2048
73
74///Radix sort for unsigned integer keys
75
76#define GIM_RADIX_SORT_RTOKENS(array,sorted,element_count)\
77{\
78        GUINT i;\
79        GUINT b0[kHist * 3];\
80        GUINT *b1 = b0 + kHist;\
81        GUINT *b2 = b1 + kHist;\
82        for (i = 0; i < kHist * 3; i++)\
83        {\
84                b0[i] = 0;\
85        }\
86        GUINT fi;\
87        GUINT pos;\
88        for (i = 0; i < element_count; i++)\
89        {\
90            fi = array[i].m_key;\
91                b0[D11_0(fi)] ++;\
92                b1[D11_1(fi)] ++;\
93                b2[D11_2(fi)] ++;\
94        }\
95        {\
96                GUINT sum0 = 0, sum1 = 0, sum2 = 0;\
97                GUINT tsum;\
98                for (i = 0; i < kHist; i++)\
99                {\
100                        tsum = b0[i] + sum0;\
101                        b0[i] = sum0 - 1;\
102                        sum0 = tsum;\
103                        tsum = b1[i] + sum1;\
104                        b1[i] = sum1 - 1;\
105                        sum1 = tsum;\
106                        tsum = b2[i] + sum2;\
107                        b2[i] = sum2 - 1;\
108                        sum2 = tsum;\
109                }\
110        }\
111        for (i = 0; i < element_count; i++)\
112        {\
113        fi = array[i].m_key;\
114                pos = D11_0(fi);\
115                pos = ++b0[pos];\
116                sorted[pos].m_key = array[i].m_key;\
117                sorted[pos].m_value = array[i].m_value;\
118        }\
119        for (i = 0; i < element_count; i++)\
120        {\
121        fi = sorted[i].m_key;\
122                pos = D11_1(fi);\
123                pos = ++b1[pos];\
124                array[pos].m_key = sorted[i].m_key;\
125                array[pos].m_value = sorted[i].m_value;\
126        }\
127        for (i = 0; i < element_count; i++)\
128        {\
129        fi = array[i].m_key;\
130                pos = D11_2(fi);\
131                pos = ++b2[pos];\
132                sorted[pos].m_key = array[i].m_key;\
133                sorted[pos].m_value = array[i].m_value;\
134        }\
135}\
136
137/// Get the sorted tokens from an array. For generic use. Tokens are GIM_RSORT_TOKEN
138#define GIM_RADIX_SORT_ARRAY_TOKENS(array, sorted_tokens, element_count, get_uintkey_macro)\
139{\
140    GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN )*element_count);\
141    GUINT _i;\
142    for (_i=0;_i<element_count;_i++)\
143    {\
144        get_uintkey_macro(array[_i],_unsorted[_i].m_key);\
145        _unsorted[_i].m_value = _i;\
146    }\
147    GIM_RADIX_SORT_RTOKENS(_unsorted,sorted_tokens,element_count);\
148    gim_free(_unsorted,sizeof(GIM_RSORT_TOKEN )*element_count);\
149}\
150
151/// Sorts array in place. For generic use
152#define GIM_RADIX_SORT(type,array,element_count,get_uintkey_macro,copy_elements_macro)\
153{\
154    GIM_RSORT_TOKEN * _sorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN )*element_count);\
155    GIM_RADIX_SORT_ARRAY_TOKENS(array,_sorted,element_count,get_uintkey_macro);\
156    type * _original_array = (type *) gim_alloc(sizeof(type)*element_count); \
157    memcpy(_original_array,array,sizeof(type)*element_count);\
158    GUINT _i;\
159    for (_i=0;_i<element_count;_i++)\
160    {\
161        copy_elements_macro(array[_i],_original_array[_sorted[_i].m_value]);\
162    }\
163    gim_free(_original_array,sizeof(type)*element_count);\
164    gim_free(_sorted,sizeof(GIM_RSORT_TOKEN )*element_count);\
165}\
166
167/// Sorts array in place using quick sort
168#define GIM_QUICK_SORT_ARRAY(type, array, array_count, comp_macro, exchange_macro) \
169{\
170  GINT   _i_, _j_, _p_, _stack_index_, _start_, _end_;\
171  GINT   _start_stack_[64]; \
172  GINT   _end_stack_[64];\
173  _start_stack_[0] = 0;\
174  _end_stack_[0] = (array_count);\
175  _stack_index_ = 1;\
176  while (_stack_index_ > 0)\
177  {\
178    _stack_index_ --;\
179    _start_ = _start_stack_[_stack_index_];\
180    _end_ = _end_stack_[_stack_index_];\
181    while (_end_ - _start_ > 2)\
182    {\
183      _p_ = _start_;\
184      _i_ = _start_ + 1;\
185      _j_ = _end_ - 1;\
186      while (_i_<_j_) \
187      {\
188        for(; _i_<=_j_ && comp_macro(((array)[_i_]),((array)[_p_]))<=0; _i_++) ;\
189        if (_i_ > _j_) \
190        {\
191          exchange_macro(type, array, _j_, _p_);\
192          _i_ = _j_;\
193        }\
194        else\
195        {\
196          for(; _i_<=_j_ && comp_macro(((array)[_j_]),((array)[_p_]))>=0; _j_--) ;\
197          if (_i_ > _j_) \
198          {\
199            exchange_macro(type, array, _j_, _p_);\
200            _i_ = _j_;\
201          }\
202          else if (_i_ < _j_)\
203          {\
204            exchange_macro(type, array, _i_, _j_);\
205            if (_i_+2 < _j_) {_i_++; _j_--;}\
206            else if (_i_+1 < _j_) _i_++;\
207          }\
208        }\
209      }\
210      if (_i_-_start_ > 1 && _end_-_j_ > 1) \
211      {\
212        if (_i_-_start_ < _end_-_j_-1) \
213        {\
214          _start_stack_[_stack_index_] = _j_+1;\
215          _end_stack_[_stack_index_] = _end_;\
216          _stack_index_ ++;\
217          _end_ = _i_;\
218        }\
219        else\
220        {\
221          _start_stack_[_stack_index_] = _start_;\
222          _end_stack_[_stack_index_] = _i_;\
223          _stack_index_ ++;\
224          _start_ = _j_+1;\
225        }\
226      }\
227      else\
228      {\
229        if (_i_-_start_ > 1)\
230        {\
231          _end_ = _i_;\
232        }\
233        else \
234        {\
235          _start_ = _j_+1;\
236        }\
237      }\
238    }\
239    if (_end_ - _start_ == 2) \
240    {\
241      if (comp_macro(((array)[_start_]),((array)[_end_-1])) > 0) \
242      {\
243        exchange_macro(type, array, _start_, _end_-1);\
244      }\
245    }\
246  }\
247}\
248
249#define GIM_DEF_EXCHANGE_MACRO(type, _array, _i, _j)\
250{\
251    type _e_tmp_ =(_array)[(_i)];\
252    (_array)[(_i)]=(_array)[(_j)];\
253    (_array)[(_j)]= _e_tmp_;\
254}\
255
256#define GIM_COMP_MACRO(x, y) ((GINT)((x) - (y)))
257//! @}
258#endif // GIM_RADIXSORT_H_INCLUDED
Note: See TracBrowser for help on using the repository browser.