NEST main@caf0ae8
 
Loading...
Searching...
No Matches
sort.h
Go to the documentation of this file.
1/*
2 * sort.h
3 *
4 * This file is part of NEST.
5 *
6 * Copyright (C) 2004 The NEST Initiative
7 *
8 * NEST is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * NEST is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with NEST. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#ifndef SORT_H
24#define SORT_H
25
26#include <algorithm>
27#include <cstddef>
28#include <vector>
29
30// Generated includes:
31#include "config.h"
32
33#include "block_vector.h"
34
35#ifdef HAVE_BOOST
36#include "iterator_pair.h"
37#include <boost/sort/spreadsort/spreadsort.hpp>
38#endif
39
40#define INSERTION_SORT_CUTOFF 10 // use insertion sort for smaller arrays
41
42namespace nest
43{
48template < typename T >
49inline size_t
50median3_( const BlockVector< T >& vec, const size_t i, const size_t j, const size_t k )
51{
52 return ( ( vec[ i ] < vec[ j ] ) ? ( ( vec[ j ] < vec[ k ] ) ? j
53 : ( vec[ i ] < vec[ k ] ) ? k
54 : i )
55 : ( ( vec[ k ] < vec[ j ] ) ? j
56 : ( vec[ k ] < vec[ i ] ) ? k
57 : i ) );
58}
59
67template < typename T1, typename T2 >
68void
69insertion_sort( BlockVector< T1 >& vec_sort, BlockVector< T2 >& vec_perm, const size_t lo, const size_t hi )
70{
71 for ( size_t i = lo + 1; i < hi + 1; ++i )
72 {
73 for ( size_t j = i; j > lo and ( vec_sort[ j ] < vec_sort[ j - 1 ] ); --j )
74 {
75 std::swap( vec_sort[ j ], vec_sort[ j - 1 ] );
76 std::swap( vec_perm[ j ], vec_perm[ j - 1 ] );
77 }
78 }
79}
80
90template < typename T1, typename T2 >
91void
92quicksort3way( BlockVector< T1 >& vec_sort, BlockVector< T2 >& vec_perm, const size_t lo, const size_t hi )
93{
94 if ( lo >= hi )
95 {
96 return;
97 }
98
99 const size_t n = hi - lo + 1;
100
101 // switch to insertion sort for small arrays
102 if ( n <= INSERTION_SORT_CUTOFF )
103 {
104 insertion_sort( vec_sort, vec_perm, lo, hi );
105 return;
106 }
107
108 // use median-of-3 as partitioning element
109 size_t m = median3_(
110 vec_sort, lo + std::rand() % ( hi - lo ), lo + std::rand() % ( hi - lo ), lo + std::rand() % ( hi - lo ) );
111
112 // in case of many equal entries, make sure to use first entry with
113 // this value (useful for sorted arrays)
114 const T1 m_val = vec_sort[ m ];
115 while ( m > 0 and vec_sort[ m - 1 ] == m_val )
116 {
117 --m;
118 }
119
120 // move pivot to the front
121 std::swap( vec_sort[ m ], vec_sort[ lo ] );
122 std::swap( vec_perm[ m ], vec_perm[ lo ] );
123
124 // Dijkstra's three-way-sort
125 size_t lt = lo;
126 size_t i = lo + 1;
127 size_t gt = hi;
128 const T1 v = vec_sort[ lt ]; // pivot
129
130 // adjust position of i and lt (useful for sorted arrays)
131 while ( vec_sort[ i ] < v and i < vec_sort.size() - 1 )
132 {
133 ++i;
134 }
135 std::swap( vec_sort[ lo ], vec_sort[ i - 1 ] );
136 std::swap( vec_perm[ lo ], vec_perm[ i - 1 ] );
137 lt = i - 1;
138
139 // adjust position of gt (useful for sorted arrays)
140 while ( vec_sort[ gt ] > v and gt > 0 )
141 {
142 --gt;
143 }
144
145 while ( i <= gt )
146 {
147 if ( vec_sort[ i ] < v )
148 {
149 std::swap( vec_sort[ lt ], vec_sort[ i ] );
150 std::swap( vec_perm[ lt ], vec_perm[ i ] );
151 ++lt;
152 ++i;
153 }
154 else if ( vec_sort[ i ] > v )
155 {
156 std::swap( vec_sort[ i ], vec_sort[ gt ] );
157 std::swap( vec_perm[ i ], vec_perm[ gt ] );
158 --gt;
159 }
160 else
161 {
162 ++i;
163 }
164 }
165
166 quicksort3way( vec_sort, vec_perm, lo, lt - 1 );
167 quicksort3way( vec_sort, vec_perm, gt + 1, hi );
168}
169
175template < typename T1, typename T2 >
176void
178{
179#ifdef HAVE_BOOST
180 boost::sort::spreadsort::integer_sort( make_iterator_pair( vec_sort.begin(), vec_perm.begin() ),
181 make_iterator_pair( vec_sort.end(), vec_perm.end() ),
183#else
184 quicksort3way( vec_sort, vec_perm, 0, vec_sort.size() - 1 );
185#endif
186}
187
188} // namespace sort
189
190#endif /* #ifndef SORT_H */
Container with a vector-of-vectors structure.
Definition block_vector.h:156
iterator begin()
Returns a read/write iterator that points to the first element in the BlockVector.
Definition block_vector.h:380
iterator end()
Returns a read/write iterator that points one past the last element in the BlockVector.
Definition block_vector.h:394
size_t size() const
Returns the number of elements in the BlockVector.
Definition block_vector.h:456
IteratorPair< sort_iter_type_, perm_iter_type_ > make_iterator_pair(sort_iter_type_ sort_iter, perm_iter_type_ perm_iter)
Creates an IteratorPair object, deducing iterator types from the types of arguments.
Definition iterator_pair.h:163
Namespace for the NEST simulation kernel.
Definition beta_normalization_factor.h:33
size_t median3_(const BlockVector< T > &vec, const size_t i, const size_t j, const size_t k)
Calculates the median of three elements.
Definition sort.h:50
void insertion_sort(BlockVector< T1 > &vec_sort, BlockVector< T2 > &vec_perm, const size_t lo, const size_t hi)
Insertion sort, adapted from Sedgewick & Wayne (2011), Algorithms 4th edition, p251ff.
Definition sort.h:69
void sort(BlockVector< T1 > &vec_sort, BlockVector< T2 > &vec_perm)
Sorts two vectors according to elements in first vector.
Definition sort.h:177
void quicksort3way(BlockVector< T1 > &vec_sort, BlockVector< T2 > &vec_perm, const size_t lo, const size_t hi)
Quicksort with 3-way partitioning, adapted from Sedgewick & Wayne (2011), Algorithms 4th edition,...
Definition sort.h:92
#define INSERTION_SORT_CUTOFF
Definition sort.h:40
A rightshift functor for tuples to be used with Boost's sorting function.
Definition iterator_pair.h:173