xref: /llvm-project/libcxx/test/std/numerics/rand/rand.dist/rand.dist.samp/rand.dist.samp.plinear/eval.pass.cpp (revision e99c4906e44ae3f921fa05356909d006cda8d954)
1eb1c5037SNikolas Klauser //===----------------------------------------------------------------------===//
2eb1c5037SNikolas Klauser //
3eb1c5037SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4eb1c5037SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
5eb1c5037SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6eb1c5037SNikolas Klauser //
7eb1c5037SNikolas Klauser //===----------------------------------------------------------------------===//
8eb1c5037SNikolas Klauser //
9eb1c5037SNikolas Klauser // REQUIRES: long_tests
10eb1c5037SNikolas Klauser 
11eb1c5037SNikolas Klauser // <random>
12eb1c5037SNikolas Klauser 
13eb1c5037SNikolas Klauser // template<class RealType = double>
14eb1c5037SNikolas Klauser // class piecewise_linear_distribution
15eb1c5037SNikolas Klauser 
16eb1c5037SNikolas Klauser // template<class _URNG> result_type operator()(_URNG& g);
17eb1c5037SNikolas Klauser 
18eb1c5037SNikolas Klauser #include <algorithm>
19eb1c5037SNikolas Klauser #include <cassert>
2009e3a360SLouis Dionne #include <cmath>
21*e99c4906SNikolas Klauser #include <cstddef>
22eb1c5037SNikolas Klauser #include <limits>
23*e99c4906SNikolas Klauser #include <random>
2409e3a360SLouis Dionne #include <vector>
25eb1c5037SNikolas Klauser 
26eb1c5037SNikolas Klauser #include "test_macros.h"
27eb1c5037SNikolas Klauser 
28eb1c5037SNikolas Klauser template <class T>
29eb1c5037SNikolas Klauser inline
30eb1c5037SNikolas Klauser T
31eb1c5037SNikolas Klauser sqr(T x)
32eb1c5037SNikolas Klauser {
33eb1c5037SNikolas Klauser     return x*x;
34eb1c5037SNikolas Klauser }
35eb1c5037SNikolas Klauser 
36eb1c5037SNikolas Klauser double
37eb1c5037SNikolas Klauser f(double x, double a, double m, double b, double c)
38eb1c5037SNikolas Klauser {
39eb1c5037SNikolas Klauser     return a + m*(sqr(x) - sqr(b))/2 + c*(x-b);
40eb1c5037SNikolas Klauser }
41eb1c5037SNikolas Klauser 
42eb1c5037SNikolas Klauser void
43eb1c5037SNikolas Klauser test1()
44eb1c5037SNikolas Klauser {
45eb1c5037SNikolas Klauser     typedef std::piecewise_linear_distribution<> D;
46eb1c5037SNikolas Klauser     typedef std::mt19937_64 G;
47eb1c5037SNikolas Klauser     G g;
48eb1c5037SNikolas Klauser     double b[] = {10, 14, 16, 17};
49eb1c5037SNikolas Klauser     double p[] = {0, 1, 1, 0};
50fb855eb9SMark de Wever     const std::size_t Np = sizeof(p) / sizeof(p[0]) - 1;
51eb1c5037SNikolas Klauser     D d(b, b+Np+1, p);
52eb1c5037SNikolas Klauser     const int N = 1000000;
53eb1c5037SNikolas Klauser     std::vector<D::result_type> u;
54fb855eb9SMark de Wever     for (std::size_t i = 0; i < N; ++i)
55eb1c5037SNikolas Klauser     {
56eb1c5037SNikolas Klauser         D::result_type v = d(g);
57eb1c5037SNikolas Klauser         assert(d.min() <= v && v < d.max());
58eb1c5037SNikolas Klauser         u.push_back(v);
59eb1c5037SNikolas Klauser     }
60eb1c5037SNikolas Klauser     std::sort(u.begin(), u.end());
6176aa042dSMatt Stephanson     std::ptrdiff_t kp = -1;
62eb1c5037SNikolas Klauser     double a = std::numeric_limits<double>::quiet_NaN();
63eb1c5037SNikolas Klauser     double m = std::numeric_limits<double>::quiet_NaN();
64eb1c5037SNikolas Klauser     double bk = std::numeric_limits<double>::quiet_NaN();
65eb1c5037SNikolas Klauser     double c = std::numeric_limits<double>::quiet_NaN();
66eb1c5037SNikolas Klauser     std::vector<double> areas(Np);
67eb1c5037SNikolas Klauser     double S = 0;
68fb855eb9SMark de Wever     for (std::size_t i = 0; i < areas.size(); ++i)
69eb1c5037SNikolas Klauser     {
70eb1c5037SNikolas Klauser         areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2;
71eb1c5037SNikolas Klauser         S += areas[i];
72eb1c5037SNikolas Klauser     }
73fb855eb9SMark de Wever     for (std::size_t i = 0; i < areas.size(); ++i)
74eb1c5037SNikolas Klauser         areas[i] /= S;
75fb855eb9SMark de Wever     for (std::size_t i = 0; i < Np+1; ++i)
76eb1c5037SNikolas Klauser         p[i] /= S;
77fb855eb9SMark de Wever     for (std::size_t i = 0; i < N; ++i)
78eb1c5037SNikolas Klauser     {
7976aa042dSMatt Stephanson       std::ptrdiff_t k = std::lower_bound(b, b + Np + 1, u[i]) - b - 1;
8076aa042dSMatt Stephanson       if (k != kp) {
81eb1c5037SNikolas Klauser         a = 0;
82eb1c5037SNikolas Klauser         for (int j = 0; j < k; ++j)
83eb1c5037SNikolas Klauser           a += areas[j];
84eb1c5037SNikolas Klauser         m  = (p[k + 1] - p[k]) / (b[k + 1] - b[k]);
85eb1c5037SNikolas Klauser         bk = b[k];
86eb1c5037SNikolas Klauser         c  = (b[k + 1] * p[k] - b[k] * p[k + 1]) / (b[k + 1] - b[k]);
87eb1c5037SNikolas Klauser         kp = k;
88eb1c5037SNikolas Klauser         }
8976aa042dSMatt Stephanson       assert(std::abs(f(u[i], a, m, bk, c) - double(i) / N) < .0013);
90eb1c5037SNikolas Klauser     }
91eb1c5037SNikolas Klauser }
92eb1c5037SNikolas Klauser 
93eb1c5037SNikolas Klauser void
94eb1c5037SNikolas Klauser test2()
95eb1c5037SNikolas Klauser {
96eb1c5037SNikolas Klauser     typedef std::piecewise_linear_distribution<> D;
97eb1c5037SNikolas Klauser     typedef std::mt19937_64 G;
98eb1c5037SNikolas Klauser     G g;
99eb1c5037SNikolas Klauser     double b[] = {10, 14, 16, 17};
100eb1c5037SNikolas Klauser     double p[] = {0, 0, 1, 0};
101fb855eb9SMark de Wever     const std::size_t Np = sizeof(p) / sizeof(p[0]) - 1;
102eb1c5037SNikolas Klauser     D d(b, b+Np+1, p);
103eb1c5037SNikolas Klauser     const int N = 1000000;
104eb1c5037SNikolas Klauser     std::vector<D::result_type> u;
105fb855eb9SMark de Wever     for (std::size_t i = 0; i < N; ++i)
106eb1c5037SNikolas Klauser     {
107eb1c5037SNikolas Klauser         D::result_type v = d(g);
108eb1c5037SNikolas Klauser         assert(d.min() <= v && v < d.max());
109eb1c5037SNikolas Klauser         u.push_back(v);
110eb1c5037SNikolas Klauser     }
111eb1c5037SNikolas Klauser     std::sort(u.begin(), u.end());
11276aa042dSMatt Stephanson     std::ptrdiff_t kp = -1;
113eb1c5037SNikolas Klauser     double a = std::numeric_limits<double>::quiet_NaN();
114eb1c5037SNikolas Klauser     double m = std::numeric_limits<double>::quiet_NaN();
115eb1c5037SNikolas Klauser     double bk = std::numeric_limits<double>::quiet_NaN();
116eb1c5037SNikolas Klauser     double c = std::numeric_limits<double>::quiet_NaN();
117eb1c5037SNikolas Klauser     std::vector<double> areas(Np);
118eb1c5037SNikolas Klauser     double S = 0;
119fb855eb9SMark de Wever     for (std::size_t i = 0; i < areas.size(); ++i)
120eb1c5037SNikolas Klauser     {
121eb1c5037SNikolas Klauser         areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2;
122eb1c5037SNikolas Klauser         S += areas[i];
123eb1c5037SNikolas Klauser     }
124fb855eb9SMark de Wever     for (std::size_t i = 0; i < areas.size(); ++i)
125eb1c5037SNikolas Klauser         areas[i] /= S;
126fb855eb9SMark de Wever     for (std::size_t i = 0; i < Np+1; ++i)
127eb1c5037SNikolas Klauser         p[i] /= S;
128fb855eb9SMark de Wever     for (std::size_t i = 0; i < N; ++i)
129eb1c5037SNikolas Klauser     {
13076aa042dSMatt Stephanson       std::ptrdiff_t k = std::lower_bound(b, b + Np + 1, u[i]) - b - 1;
13176aa042dSMatt Stephanson       if (k != kp) {
132eb1c5037SNikolas Klauser         a = 0;
133eb1c5037SNikolas Klauser         for (int j = 0; j < k; ++j)
134eb1c5037SNikolas Klauser           a += areas[j];
135eb1c5037SNikolas Klauser         m  = (p[k + 1] - p[k]) / (b[k + 1] - b[k]);
136eb1c5037SNikolas Klauser         bk = b[k];
137eb1c5037SNikolas Klauser         c  = (b[k + 1] * p[k] - b[k] * p[k + 1]) / (b[k + 1] - b[k]);
138eb1c5037SNikolas Klauser         kp = k;
139eb1c5037SNikolas Klauser         }
14076aa042dSMatt Stephanson       assert(std::abs(f(u[i], a, m, bk, c) - double(i) / N) < .0013);
141eb1c5037SNikolas Klauser     }
142eb1c5037SNikolas Klauser }
143eb1c5037SNikolas Klauser 
144eb1c5037SNikolas Klauser void
145eb1c5037SNikolas Klauser test3()
146eb1c5037SNikolas Klauser {
147eb1c5037SNikolas Klauser     typedef std::piecewise_linear_distribution<> D;
148eb1c5037SNikolas Klauser     typedef std::mt19937_64 G;
149eb1c5037SNikolas Klauser     G g;
150eb1c5037SNikolas Klauser     double b[] = {10, 14, 16, 17};
151eb1c5037SNikolas Klauser     double p[] = {1, 0, 0, 0};
152fb855eb9SMark de Wever     const std::size_t Np = sizeof(p) / sizeof(p[0]) - 1;
153eb1c5037SNikolas Klauser     D d(b, b+Np+1, p);
154fb855eb9SMark de Wever     const std::size_t N = 1000000;
155eb1c5037SNikolas Klauser     std::vector<D::result_type> u;
156fb855eb9SMark de Wever     for (std::size_t i = 0; i < N; ++i)
157eb1c5037SNikolas Klauser     {
158eb1c5037SNikolas Klauser         D::result_type v = d(g);
159eb1c5037SNikolas Klauser         assert(d.min() <= v && v < d.max());
160eb1c5037SNikolas Klauser         u.push_back(v);
161eb1c5037SNikolas Klauser     }
162eb1c5037SNikolas Klauser     std::sort(u.begin(), u.end());
16376aa042dSMatt Stephanson     std::ptrdiff_t kp = -1;
164eb1c5037SNikolas Klauser     double a = std::numeric_limits<double>::quiet_NaN();
165eb1c5037SNikolas Klauser     double m = std::numeric_limits<double>::quiet_NaN();
166eb1c5037SNikolas Klauser     double bk = std::numeric_limits<double>::quiet_NaN();
167eb1c5037SNikolas Klauser     double c = std::numeric_limits<double>::quiet_NaN();
168eb1c5037SNikolas Klauser     std::vector<double> areas(Np);
169eb1c5037SNikolas Klauser     double S = 0;
170fb855eb9SMark de Wever     for (std::size_t i = 0; i < areas.size(); ++i)
171eb1c5037SNikolas Klauser     {
172eb1c5037SNikolas Klauser         areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2;
173eb1c5037SNikolas Klauser         S += areas[i];
174eb1c5037SNikolas Klauser     }
175fb855eb9SMark de Wever     for (std::size_t i = 0; i < areas.size(); ++i)
176eb1c5037SNikolas Klauser         areas[i] /= S;
177fb855eb9SMark de Wever     for (std::size_t i = 0; i < Np+1; ++i)
178eb1c5037SNikolas Klauser         p[i] /= S;
179fb855eb9SMark de Wever     for (std::size_t i = 0; i < N; ++i)
180eb1c5037SNikolas Klauser     {
18176aa042dSMatt Stephanson       std::ptrdiff_t k = std::lower_bound(b, b + Np + 1, u[i]) - b - 1;
18276aa042dSMatt Stephanson       if (k != kp) {
183eb1c5037SNikolas Klauser         a = 0;
184eb1c5037SNikolas Klauser         for (int j = 0; j < k; ++j)
185eb1c5037SNikolas Klauser           a += areas[j];
186eb1c5037SNikolas Klauser         m  = (p[k + 1] - p[k]) / (b[k + 1] - b[k]);
187eb1c5037SNikolas Klauser         bk = b[k];
188eb1c5037SNikolas Klauser         c  = (b[k + 1] * p[k] - b[k] * p[k + 1]) / (b[k + 1] - b[k]);
189eb1c5037SNikolas Klauser         kp = k;
190eb1c5037SNikolas Klauser         }
19176aa042dSMatt Stephanson       assert(std::abs(f(u[i], a, m, bk, c) - double(i) / N) < .0013);
192eb1c5037SNikolas Klauser     }
193eb1c5037SNikolas Klauser }
194eb1c5037SNikolas Klauser 
195eb1c5037SNikolas Klauser void
196eb1c5037SNikolas Klauser test4()
197eb1c5037SNikolas Klauser {
198eb1c5037SNikolas Klauser     typedef std::piecewise_linear_distribution<> D;
199eb1c5037SNikolas Klauser     typedef std::mt19937_64 G;
200eb1c5037SNikolas Klauser     G g;
201eb1c5037SNikolas Klauser     double b[] = {10, 14, 16};
202eb1c5037SNikolas Klauser     double p[] = {0, 1, 0};
203fb855eb9SMark de Wever     const std::size_t Np = sizeof(p) / sizeof(p[0]) - 1;
204eb1c5037SNikolas Klauser     D d(b, b+Np+1, p);
205eb1c5037SNikolas Klauser     const int N = 1000000;
206eb1c5037SNikolas Klauser     std::vector<D::result_type> u;
207fb855eb9SMark de Wever     for (std::size_t i = 0; i < N; ++i)
208eb1c5037SNikolas Klauser     {
209eb1c5037SNikolas Klauser         D::result_type v = d(g);
210eb1c5037SNikolas Klauser         assert(d.min() <= v && v < d.max());
211eb1c5037SNikolas Klauser         u.push_back(v);
212eb1c5037SNikolas Klauser     }
213eb1c5037SNikolas Klauser     std::sort(u.begin(), u.end());
21476aa042dSMatt Stephanson     std::ptrdiff_t kp = -1;
215eb1c5037SNikolas Klauser     double a = std::numeric_limits<double>::quiet_NaN();
216eb1c5037SNikolas Klauser     double m = std::numeric_limits<double>::quiet_NaN();
217eb1c5037SNikolas Klauser     double bk = std::numeric_limits<double>::quiet_NaN();
218eb1c5037SNikolas Klauser     double c = std::numeric_limits<double>::quiet_NaN();
219eb1c5037SNikolas Klauser     std::vector<double> areas(Np);
220eb1c5037SNikolas Klauser     double S = 0;
221fb855eb9SMark de Wever     for (std::size_t i = 0; i < areas.size(); ++i)
222eb1c5037SNikolas Klauser     {
223eb1c5037SNikolas Klauser         areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2;
224eb1c5037SNikolas Klauser         S += areas[i];
225eb1c5037SNikolas Klauser     }
226fb855eb9SMark de Wever     for (std::size_t i = 0; i < areas.size(); ++i)
227eb1c5037SNikolas Klauser         areas[i] /= S;
228fb855eb9SMark de Wever     for (std::size_t i = 0; i < Np+1; ++i)
229eb1c5037SNikolas Klauser         p[i] /= S;
230fb855eb9SMark de Wever     for (std::size_t i = 0; i < N; ++i)
231eb1c5037SNikolas Klauser     {
23276aa042dSMatt Stephanson       std::ptrdiff_t k = std::lower_bound(b, b + Np + 1, u[i]) - b - 1;
23376aa042dSMatt Stephanson       if (k != kp) {
234eb1c5037SNikolas Klauser         a = 0;
235eb1c5037SNikolas Klauser         for (int j = 0; j < k; ++j)
236eb1c5037SNikolas Klauser           a += areas[j];
237eb1c5037SNikolas Klauser         assert(k < static_cast<int>(Np));
238eb1c5037SNikolas Klauser         m  = (p[k + 1] - p[k]) / (b[k + 1] - b[k]);
239eb1c5037SNikolas Klauser         bk = b[k];
240eb1c5037SNikolas Klauser         c  = (b[k + 1] * p[k] - b[k] * p[k + 1]) / (b[k + 1] - b[k]);
241eb1c5037SNikolas Klauser         kp = k;
242eb1c5037SNikolas Klauser         }
24376aa042dSMatt Stephanson       assert(std::abs(f(u[i], a, m, bk, c) - double(i) / N) < .0013);
244eb1c5037SNikolas Klauser     }
245eb1c5037SNikolas Klauser }
246eb1c5037SNikolas Klauser 
247eb1c5037SNikolas Klauser void
248eb1c5037SNikolas Klauser test5()
249eb1c5037SNikolas Klauser {
250eb1c5037SNikolas Klauser     typedef std::piecewise_linear_distribution<> D;
251eb1c5037SNikolas Klauser     typedef std::mt19937_64 G;
252eb1c5037SNikolas Klauser     G g;
253eb1c5037SNikolas Klauser     double b[] = {10, 14};
254eb1c5037SNikolas Klauser     double p[] = {1, 1};
255fb855eb9SMark de Wever     const std::size_t Np = sizeof(p) / sizeof(p[0]) - 1;
256eb1c5037SNikolas Klauser     D d(b, b+Np+1, p);
257eb1c5037SNikolas Klauser     const int N = 1000000;
258eb1c5037SNikolas Klauser     std::vector<D::result_type> u;
259fb855eb9SMark de Wever     for (std::size_t i = 0; i < N; ++i)
260eb1c5037SNikolas Klauser     {
261eb1c5037SNikolas Klauser         D::result_type v = d(g);
262eb1c5037SNikolas Klauser         assert(d.min() <= v && v < d.max());
263eb1c5037SNikolas Klauser         u.push_back(v);
264eb1c5037SNikolas Klauser     }
265eb1c5037SNikolas Klauser     std::sort(u.begin(), u.end());
26676aa042dSMatt Stephanson     std::ptrdiff_t kp = -1;
267eb1c5037SNikolas Klauser     double a = std::numeric_limits<double>::quiet_NaN();
268eb1c5037SNikolas Klauser     double m = std::numeric_limits<double>::quiet_NaN();
269eb1c5037SNikolas Klauser     double bk = std::numeric_limits<double>::quiet_NaN();
270eb1c5037SNikolas Klauser     double c = std::numeric_limits<double>::quiet_NaN();
271eb1c5037SNikolas Klauser     std::vector<double> areas(Np);
272eb1c5037SNikolas Klauser     double S = 0;
273fb855eb9SMark de Wever     for (std::size_t i = 0; i < areas.size(); ++i)
274eb1c5037SNikolas Klauser     {
275eb1c5037SNikolas Klauser         assert(i < Np);
276eb1c5037SNikolas Klauser         areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2;
277eb1c5037SNikolas Klauser         S += areas[i];
278eb1c5037SNikolas Klauser     }
279fb855eb9SMark de Wever     for (std::size_t i = 0; i < areas.size(); ++i)
280eb1c5037SNikolas Klauser         areas[i] /= S;
281fb855eb9SMark de Wever     for (std::size_t i = 0; i < Np+1; ++i)
282eb1c5037SNikolas Klauser         p[i] /= S;
283fb855eb9SMark de Wever     for (std::size_t i = 0; i < N; ++i)
284eb1c5037SNikolas Klauser     {
28576aa042dSMatt Stephanson       std::ptrdiff_t k = std::lower_bound(b, b + Np + 1, u[i]) - b - 1;
28676aa042dSMatt Stephanson       if (k != kp) {
287eb1c5037SNikolas Klauser         a = 0;
288eb1c5037SNikolas Klauser         for (int j = 0; j < k; ++j)
289eb1c5037SNikolas Klauser           a += areas[j];
290eb1c5037SNikolas Klauser         assert(k < static_cast<int>(Np));
291eb1c5037SNikolas Klauser         m  = (p[k + 1] - p[k]) / (b[k + 1] - b[k]);
292eb1c5037SNikolas Klauser         bk = b[k];
293eb1c5037SNikolas Klauser         c  = (b[k + 1] * p[k] - b[k] * p[k + 1]) / (b[k + 1] - b[k]);
294eb1c5037SNikolas Klauser         kp = k;
295eb1c5037SNikolas Klauser         }
29676aa042dSMatt Stephanson       assert(std::abs(f(u[i], a, m, bk, c) - double(i) / N) < .0013);
297eb1c5037SNikolas Klauser     }
298eb1c5037SNikolas Klauser }
299eb1c5037SNikolas Klauser 
300eb1c5037SNikolas Klauser void
301eb1c5037SNikolas Klauser test6()
302eb1c5037SNikolas Klauser {
303eb1c5037SNikolas Klauser     typedef std::piecewise_linear_distribution<> D;
304eb1c5037SNikolas Klauser     typedef std::mt19937_64 G;
305eb1c5037SNikolas Klauser     G g;
306eb1c5037SNikolas Klauser     double b[] = {10, 14, 16, 17};
307eb1c5037SNikolas Klauser     double p[] = {25, 62.5, 12.5, 0};
308fb855eb9SMark de Wever     const std::size_t Np = sizeof(p) / sizeof(p[0]) - 1;
309eb1c5037SNikolas Klauser     D d(b, b+Np+1, p);
310eb1c5037SNikolas Klauser     const int N = 1000000;
311eb1c5037SNikolas Klauser     std::vector<D::result_type> u;
312fb855eb9SMark de Wever     for (std::size_t i = 0; i < N; ++i)
313eb1c5037SNikolas Klauser     {
314eb1c5037SNikolas Klauser         D::result_type v = d(g);
315eb1c5037SNikolas Klauser         assert(d.min() <= v && v < d.max());
316eb1c5037SNikolas Klauser         u.push_back(v);
317eb1c5037SNikolas Klauser     }
318eb1c5037SNikolas Klauser     std::sort(u.begin(), u.end());
31976aa042dSMatt Stephanson     std::ptrdiff_t kp = -1;
320eb1c5037SNikolas Klauser     double a = std::numeric_limits<double>::quiet_NaN();
321eb1c5037SNikolas Klauser     double m = std::numeric_limits<double>::quiet_NaN();
322eb1c5037SNikolas Klauser     double bk = std::numeric_limits<double>::quiet_NaN();
323eb1c5037SNikolas Klauser     double c = std::numeric_limits<double>::quiet_NaN();
324eb1c5037SNikolas Klauser     std::vector<double> areas(Np);
325eb1c5037SNikolas Klauser     double S = 0;
326fb855eb9SMark de Wever     for (std::size_t i = 0; i < areas.size(); ++i)
327eb1c5037SNikolas Klauser     {
328eb1c5037SNikolas Klauser         areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2;
329eb1c5037SNikolas Klauser         S += areas[i];
330eb1c5037SNikolas Klauser     }
331fb855eb9SMark de Wever     for (std::size_t i = 0; i < areas.size(); ++i)
332eb1c5037SNikolas Klauser         areas[i] /= S;
333fb855eb9SMark de Wever     for (std::size_t i = 0; i < Np+1; ++i)
334eb1c5037SNikolas Klauser         p[i] /= S;
335fb855eb9SMark de Wever     for (std::size_t i = 0; i < N; ++i)
336eb1c5037SNikolas Klauser     {
33776aa042dSMatt Stephanson       std::ptrdiff_t k = std::lower_bound(b, b + Np + 1, u[i]) - b - 1;
33876aa042dSMatt Stephanson       if (k != kp) {
339eb1c5037SNikolas Klauser         a = 0;
340eb1c5037SNikolas Klauser         for (int j = 0; j < k; ++j)
341eb1c5037SNikolas Klauser           a += areas[j];
342eb1c5037SNikolas Klauser         m  = (p[k + 1] - p[k]) / (b[k + 1] - b[k]);
343eb1c5037SNikolas Klauser         bk = b[k];
344eb1c5037SNikolas Klauser         c  = (b[k + 1] * p[k] - b[k] * p[k + 1]) / (b[k + 1] - b[k]);
345eb1c5037SNikolas Klauser         kp = k;
346eb1c5037SNikolas Klauser         }
34776aa042dSMatt Stephanson       assert(std::abs(f(u[i], a, m, bk, c) - double(i) / N) < .0013);
348eb1c5037SNikolas Klauser     }
349eb1c5037SNikolas Klauser }
350eb1c5037SNikolas Klauser 
351eb1c5037SNikolas Klauser int main(int, char**)
352eb1c5037SNikolas Klauser {
353eb1c5037SNikolas Klauser     test1();
354eb1c5037SNikolas Klauser     test2();
355eb1c5037SNikolas Klauser     test3();
356eb1c5037SNikolas Klauser     test4();
357eb1c5037SNikolas Klauser     test5();
358eb1c5037SNikolas Klauser     test6();
359eb1c5037SNikolas Klauser 
360eb1c5037SNikolas Klauser   return 0;
361eb1c5037SNikolas Klauser }
362