Jpp 19.3.0-rc.1
the software that should make you happy
Loading...
Searching...
No Matches
JMergeSort.cc
Go to the documentation of this file.
1
2#include <iostream>
3#include <iomanip>
4#include <functional>
5#include <limits>
6#include <vector>
7#include <algorithm>
8
9#include "TRandom3.h"
10
11#include "JTools/JMergeSort.hh"
12#include "JLang/JSTDToolkit.hh"
13
14#include "Jeep/JTimer.hh"
15#include "Jeep/JParser.hh"
16#include "Jeep/JMessage.hh"
17
18
19namespace JTOOLS {
20
21 /**
22 * Merge multiple sorted ranges.
23 *
24 * \param __begin begin of data
25 * \param N number of delimiters (equals number of ranges plus one)
26 * \param delimiter incremental delimiters
27 */
28 template<class T>
29 void inplace_merge(T __begin, const size_t N, const size_t* delimiter)
30 {
31 switch (N - 1) {
32
33 case 0:
34 case 1:
35 break;
36
37 case 2:
38
39 std::inplace_merge(__begin + delimiter[0],
40 __begin + delimiter[1],
41 __begin + delimiter[2]);
42
43 break;
44
45 default:
46
47 const size_t n = (N - 1) >> 1;
48
49 inplace_merge(__begin, n + 1, delimiter);
50 inplace_merge(__begin, N - n, delimiter + n);
51
52 std::inplace_merge(__begin + delimiter[ 0 ],
53 __begin + delimiter[ n ],
54 __begin + delimiter[N-1]);
55
56 break;
57 };
58 }
59
60
61 /**
62 * Auxiliary class to convert value to element.
63 */
64 template<class T>
65 struct JElement
66 {
67 /**
68 * Default constructor.
69 */
71 {}
72
73
74 /**
75 * Type conversion operator.
76 *
77 * \param x value
78 * \return element
79 */
80 inline T operator()(const double x) const
81 {
82 return (T) x;
83 }
84
85
86 /**
87 * Get end marker.
88 *
89 * \return element
90 */
91 static inline T getEndMarker()
92 {
93 return std::numeric_limits<T>::max();
94 }
95 };
96}
97
98
99/**
100 * \file
101 *
102 * Example program to test performance of JTOOLS::JMergeSort.
103 * \author mdejong
104 */
105int main(int argc, char **argv)
106{
107 using namespace std;
108
109 double rate_Hz;
110 int debug;
111
112 try {
113
114 JParser<> zap("Example program to test performance of merge sort.");
115
116 zap['B'] = make_field(rate_Hz);
117 zap['d'] = make_field(debug) = 0;
118
119 zap(argc, argv);
120 }
121 catch(const exception &error) {
122 FATAL(error.what() << endl);
123 }
124
125
126 using namespace JPP;
127
128 if (rate_Hz <= 0.0) {
129 FATAL("Rate " << rate_Hz << " < 0 Hz." << endl);
130 }
131
132 const double period = 1.0e9 / rate_Hz; // [ns]
133
134 const double Tmin = 0.0; // [ns]
135 const double Tmax = 1.0e8; // [ns]
136
137 const int NUMBER_OF_PMTS = 31;
138 const int NUMBER_OF_MODULES = 115 * 18;
139
140
141 //typedef int hit_type;
142 typedef double hit_type;
143 typedef JElement<hit_type> JElement_t;
144 const JElement_t getElement;
145 typedef std::vector<hit_type> JBuffer1D;
146 typedef std::vector<JBuffer1D> JBuffer2D;
147
148
149 // generate random data
150
151 JBuffer2D input(NUMBER_OF_PMTS);
152
153 size_t number_of_hits = 0;
154
155 for (int i = 0; i != NUMBER_OF_PMTS; ++i) {
156
157 for (double t1 = Tmin + gRandom->Exp(period); t1 < Tmax; t1 += gRandom->Exp(period), ++number_of_hits) {
158 input[i].push_back(getElement(t1));
159 }
160
161 NOTICE("PMT[" << setw(2) << i << "] " << input[i].size() << endl);
162
163 putEndMarker(input[i], JElement_t::getEndMarker());
164 }
165
166
167 JTimer timer[] = {
168 JTimer("std::sort"),
169 JTimer("std::inplace_merge"),
170 JTimer("JMergeSort")
171 };
172
173
174 {
175 JBuffer1D buffer;
176
177 for (int i = 0; i != NUMBER_OF_MODULES; ++i) {
178
179 timer[0].start();
180
181 buffer.clear();
182
183 for (int i = 0; i != NUMBER_OF_PMTS; ++i) {
184 copy(input[i].begin(), input[i].end(), back_inserter(buffer));
185 }
186
187 std::sort(buffer.begin(), buffer.end());
188
189 timer[0].stop();
190
191 ASSERT(buffer.size() == number_of_hits, "Test std::sort.");
192 ASSERT(is_sorted(buffer.begin(), buffer.end()), "Test std::sort.");
193 }
194 }
195
196 {
197 JBuffer1D buffer;
198
199 vector<size_t> delimiter(NUMBER_OF_PMTS + 1);
200
201 for (int i = 0; i != NUMBER_OF_MODULES; ++i) {
202
203 timer[1].start();
204
205 size_t n = 0;
206
207 for (int i = 0; i != NUMBER_OF_PMTS; ++i) {
208 n += input[i].size();
209 }
210
211 buffer.resize(n);
212
213 JBuffer1D::iterator out = buffer.begin();
214
215 delimiter[0] = 0;
216
217 for (int i = 0; i != NUMBER_OF_PMTS; ++i) {
218
219 out = copy(input[i].begin(), input[i].end(), out);
220
221 delimiter[i+1] = distance(buffer.begin(), out);
222 }
223
224 inplace_merge(buffer.begin(), delimiter.size(), delimiter.data());
225
226 timer[1].stop();
227
228 ASSERT(buffer.size() == number_of_hits, "Test std::inplace_merge.");
229 ASSERT(is_sorted(buffer.begin(), buffer.end()), "Test std::inplace_merge.");
230 }
231 }
232
233 {
234 JBuffer1D buffer;
236
237 for (int i = 0; i != NUMBER_OF_MODULES; ++i) {
238
239 timer[2].start();
240
241 buffer.clear();
242
243 merge(input, buffer);
244
245 timer[2].stop();
246
247 ASSERT(buffer.size() == number_of_hits, "Test JMergeSort.");
248 ASSERT(is_sorted(buffer.begin(), buffer.end()), "Test JMergeSort.");
249 }
250 }
251
252
253 for (int i = 0; i != sizeof(timer)/sizeof(timer[0]); ++i) {
254 timer[i].print(cout, false);
255 }
256}
int main(int argc, char **argv)
General purpose messaging.
#define ASSERT(A,...)
Assert macro.
Definition JMessage.hh:90
#define NOTICE(A)
Definition JMessage.hh:64
#define FATAL(A)
Definition JMessage.hh:67
int debug
debug level
Definition JSirene.cc:72
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2142
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Auxiliary class for CPU timing and usage.
Definition JTimer.hh:33
void print(std::ostream &out, const JScale_t scale=milli_t) const
Print timer data.
Definition JTimer.hh:172
void stop()
Stop timer.
Definition JTimer.hh:127
void start()
Start timer.
Definition JTimer.hh:106
Utility class to parse command line options.
Definition JParser.hh:1698
This class implements a merge and sort algorithm based on the divide-and-conquer concept.
Definition JMergeSort.hh:50
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for multi-dimensional interpolations and histograms.
void inplace_merge(T __begin, const size_t N, const size_t *delimiter)
Merge multiple sorted ranges.
Definition JMergeSort.cc:29
const int n
Definition JPolint.hh:791
Auxiliary class to convert value to element.
Definition JMergeSort.cc:66
T operator()(const double x) const
Type conversion operator.
Definition JMergeSort.cc:80
static T getEndMarker()
Get end marker.
Definition JMergeSort.cc:91
JElement()
Default constructor.
Definition JMergeSort.cc:70