blob: af75fce512e48d1b8f7395e9304d6a25ec677428 [file] [log] [blame]
Howard Hinnant54305402010-05-25 00:27:34 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00005// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
Howard Hinnant54305402010-05-25 00:27:34 +00007//
8//===----------------------------------------------------------------------===//
Jonathan Roelofsd9144e82014-12-11 18:35:36 +00009//
10// REQUIRES: long_tests
Howard Hinnant54305402010-05-25 00:27:34 +000011
12// <random>
13
14// template<class RealType = double>
15// class piecewise_linear_distribution
16
17// template<class _URNG> result_type operator()(_URNG& g);
18
19#include <iostream>
20
21#include <random>
Howard Hinnant54305402010-05-25 00:27:34 +000022#include <vector>
23#include <iterator>
24#include <numeric>
25#include <cassert>
26
27template <class T>
28inline
29T
30sqr(T x)
31{
32 return x*x;
33}
34
35double
36f(double x, double a, double m, double b, double c)
37{
38 return a + m*(sqr(x) - sqr(b))/2 + c*(x-b);
39}
40
41int main()
42{
43 {
44 typedef std::piecewise_linear_distribution<> D;
45 typedef D::param_type P;
46 typedef std::mt19937_64 G;
47 G g;
48 double b[] = {10, 14, 16, 17};
49 double p[] = {0, 1, 1, 0};
50 const size_t Np = sizeof(p) / sizeof(p[0]) - 1;
51 D d(b, b+Np+1, p);
52 const int N = 1000000;
53 std::vector<D::result_type> u;
54 for (int i = 0; i < N; ++i)
55 {
56 D::result_type v = d(g);
57 assert(d.min() <= v && v < d.max());
58 u.push_back(v);
59 }
60 std::sort(u.begin(), u.end());
61 int kp = -1;
Dan Albert1d4a1ed2016-05-25 22:36:09 -070062 double a;
63 double m;
64 double bk;
65 double c;
Howard Hinnant54305402010-05-25 00:27:34 +000066 std::vector<double> areas(Np);
67 double S = 0;
68 for (int i = 0; i < areas.size(); ++i)
69 {
70 areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2;
71 S += areas[i];
72 }
73 for (int i = 0; i < areas.size(); ++i)
74 areas[i] /= S;
75 for (int i = 0; i < Np+1; ++i)
76 p[i] /= S;
77 for (int i = 0; i < N; ++i)
78 {
79 int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1;
80 if (k != kp)
81 {
82 a = 0;
83 for (int j = 0; j < k; ++j)
84 a += areas[j];
85 m = (p[k+1] - p[k]) / (b[k+1] - b[k]);
86 bk = b[k];
87 c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]);
88 kp = k;
89 }
90 assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001);
91 }
92 }
93 {
94 typedef std::piecewise_linear_distribution<> D;
95 typedef D::param_type P;
96 typedef std::mt19937_64 G;
97 G g;
98 double b[] = {10, 14, 16, 17};
99 double p[] = {0, 0, 1, 0};
100 const size_t Np = sizeof(p) / sizeof(p[0]) - 1;
101 D d(b, b+Np+1, p);
102 const int N = 1000000;
103 std::vector<D::result_type> u;
104 for (int i = 0; i < N; ++i)
105 {
106 D::result_type v = d(g);
107 assert(d.min() <= v && v < d.max());
108 u.push_back(v);
109 }
110 std::sort(u.begin(), u.end());
111 int kp = -1;
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700112 double a;
113 double m;
114 double bk;
115 double c;
Howard Hinnant54305402010-05-25 00:27:34 +0000116 std::vector<double> areas(Np);
117 double S = 0;
118 for (int i = 0; i < areas.size(); ++i)
119 {
120 areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2;
121 S += areas[i];
122 }
123 for (int i = 0; i < areas.size(); ++i)
124 areas[i] /= S;
125 for (int i = 0; i < Np+1; ++i)
126 p[i] /= S;
127 for (int i = 0; i < N; ++i)
128 {
129 int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1;
130 if (k != kp)
131 {
132 a = 0;
133 for (int j = 0; j < k; ++j)
134 a += areas[j];
135 m = (p[k+1] - p[k]) / (b[k+1] - b[k]);
136 bk = b[k];
137 c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]);
138 kp = k;
139 }
140 assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001);
141 }
142 }
143 {
144 typedef std::piecewise_linear_distribution<> D;
145 typedef D::param_type P;
146 typedef std::mt19937_64 G;
147 G g;
148 double b[] = {10, 14, 16, 17};
149 double p[] = {1, 0, 0, 0};
150 const size_t Np = sizeof(p) / sizeof(p[0]) - 1;
151 D d(b, b+Np+1, p);
152 const int N = 1000000;
153 std::vector<D::result_type> u;
154 for (int i = 0; i < N; ++i)
155 {
156 D::result_type v = d(g);
157 assert(d.min() <= v && v < d.max());
158 u.push_back(v);
159 }
160 std::sort(u.begin(), u.end());
161 int kp = -1;
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700162 double a;
163 double m;
164 double bk;
165 double c;
Howard Hinnant54305402010-05-25 00:27:34 +0000166 std::vector<double> areas(Np);
167 double S = 0;
168 for (int i = 0; i < areas.size(); ++i)
169 {
170 areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2;
171 S += areas[i];
172 }
173 for (int i = 0; i < areas.size(); ++i)
174 areas[i] /= S;
175 for (int i = 0; i < Np+1; ++i)
176 p[i] /= S;
177 for (int i = 0; i < N; ++i)
178 {
179 int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1;
180 if (k != kp)
181 {
182 a = 0;
183 for (int j = 0; j < k; ++j)
184 a += areas[j];
185 m = (p[k+1] - p[k]) / (b[k+1] - b[k]);
186 bk = b[k];
187 c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]);
188 kp = k;
189 }
190 assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001);
191 }
192 }
193 {
194 typedef std::piecewise_linear_distribution<> D;
195 typedef D::param_type P;
196 typedef std::mt19937_64 G;
197 G g;
198 double b[] = {10, 14, 16};
199 double p[] = {0, 1, 0};
200 const size_t Np = sizeof(p) / sizeof(p[0]) - 1;
201 D d(b, b+Np+1, p);
202 const int N = 1000000;
203 std::vector<D::result_type> u;
204 for (int i = 0; i < N; ++i)
205 {
206 D::result_type v = d(g);
207 assert(d.min() <= v && v < d.max());
208 u.push_back(v);
209 }
210 std::sort(u.begin(), u.end());
211 int kp = -1;
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700212 double a;
213 double m;
214 double bk;
215 double c;
Howard Hinnant54305402010-05-25 00:27:34 +0000216 std::vector<double> areas(Np);
217 double S = 0;
218 for (int i = 0; i < areas.size(); ++i)
219 {
220 areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2;
221 S += areas[i];
222 }
223 for (int i = 0; i < areas.size(); ++i)
224 areas[i] /= S;
225 for (int i = 0; i < Np+1; ++i)
226 p[i] /= S;
227 for (int i = 0; i < N; ++i)
228 {
229 int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1;
230 if (k != kp)
231 {
232 a = 0;
233 for (int j = 0; j < k; ++j)
234 a += areas[j];
235 m = (p[k+1] - p[k]) / (b[k+1] - b[k]);
236 bk = b[k];
237 c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]);
238 kp = k;
239 }
240 assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001);
241 }
242 }
243 {
244 typedef std::piecewise_linear_distribution<> D;
245 typedef D::param_type P;
246 typedef std::mt19937_64 G;
247 G g;
248 double b[] = {10, 14};
249 double p[] = {1, 1};
250 const size_t Np = sizeof(p) / sizeof(p[0]) - 1;
251 D d(b, b+Np+1, p);
252 const int N = 1000000;
253 std::vector<D::result_type> u;
254 for (int i = 0; i < N; ++i)
255 {
256 D::result_type v = d(g);
257 assert(d.min() <= v && v < d.max());
258 u.push_back(v);
259 }
260 std::sort(u.begin(), u.end());
261 int kp = -1;
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700262 double a;
263 double m;
264 double bk;
265 double c;
Howard Hinnant54305402010-05-25 00:27:34 +0000266 std::vector<double> areas(Np);
267 double S = 0;
268 for (int i = 0; i < areas.size(); ++i)
269 {
270 areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2;
271 S += areas[i];
272 }
273 for (int i = 0; i < areas.size(); ++i)
274 areas[i] /= S;
275 for (int i = 0; i < Np+1; ++i)
276 p[i] /= S;
277 for (int i = 0; i < N; ++i)
278 {
279 int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1;
280 if (k != kp)
281 {
282 a = 0;
283 for (int j = 0; j < k; ++j)
284 a += areas[j];
285 m = (p[k+1] - p[k]) / (b[k+1] - b[k]);
286 bk = b[k];
287 c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]);
288 kp = k;
289 }
290 assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001);
291 }
292 }
293 {
294 typedef std::piecewise_linear_distribution<> D;
295 typedef D::param_type P;
296 typedef std::mt19937_64 G;
297 G g;
298 double b[] = {10, 14, 16, 17};
299 double p[] = {25, 62.5, 12.5, 0};
300 const size_t Np = sizeof(p) / sizeof(p[0]) - 1;
301 D d(b, b+Np+1, p);
302 const int N = 1000000;
303 std::vector<D::result_type> u;
304 for (int i = 0; i < N; ++i)
305 {
306 D::result_type v = d(g);
307 assert(d.min() <= v && v < d.max());
308 u.push_back(v);
309 }
310 std::sort(u.begin(), u.end());
311 int kp = -1;
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700312 double a;
313 double m;
314 double bk;
315 double c;
Howard Hinnant54305402010-05-25 00:27:34 +0000316 std::vector<double> areas(Np);
317 double S = 0;
318 for (int i = 0; i < areas.size(); ++i)
319 {
320 areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2;
321 S += areas[i];
322 }
323 for (int i = 0; i < areas.size(); ++i)
324 areas[i] /= S;
325 for (int i = 0; i < Np+1; ++i)
326 p[i] /= S;
327 for (int i = 0; i < N; ++i)
328 {
329 int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1;
330 if (k != kp)
331 {
332 a = 0;
333 for (int j = 0; j < k; ++j)
334 a += areas[j];
335 m = (p[k+1] - p[k]) / (b[k+1] - b[k]);
336 bk = b[k];
337 c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]);
338 kp = k;
339 }
340 assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001);
341 }
342 }
343}