27 void initialize(
size_t numberOfSamples,
double a,
double b, Function f)
34 if (numberOfSamples < 3) {
35 samples.push_back({a, 0.0, 0.0});
36 samples.push_back({b, 1.0, 1.0});
41 const double domainSize = b - a;
42 const double intervalSize = domainSize /
static_cast<double>(numberOfSamples - 1);
44 double lastX, lastY, lastSum;
45 size_t effectiveNumberOfSamples = numberOfSamples;
50 for (
size_t i = 0; i < numberOfSamples; ++i) {
51 const double x = a + intervalSize *
static_cast<double>(i);
52 const double y = f(x);
55 a += intervalSize *
static_cast<double>(i - 1);
56 effectiveNumberOfSamples -= i - 1;
60 if (i == numberOfSamples - 1) {
66 for (
size_t i = 0; i < numberOfSamples; ++i) {
67 const double x = b - intervalSize *
static_cast<double>(i);
68 const double y = f(x);
71 b -= intervalSize *
static_cast<double>(i - 1);
72 effectiveNumberOfSamples -= i - 1;
80 samples.push_back({a, 0.0, 0.0});
89 constexpr double maximumAngleDeviationToSkip{
M_PI / 1000.0};
90 double referenceAngle = 0.0;
91 bool mustCheckAngle =
false;
92 int skippedPoints = 0;
94 for (
size_t i = 1; i < effectiveNumberOfSamples; ++i) {
95 const double x = a + intervalSize *
static_cast<double>(i);
96 const double y = f(x);
98 sum += (x - lastX) * (y + lastY) / 2.0;
108 mustCheckAngle =
false;
112 if (skippedPoints > 0) {
113 samples.push_back({lastX, lastSum, 0.0});
115 mustCheckAngle =
false;
120 if (i > 1 && mustCheckAngle) {
121 const int nPoints =
samples.size();
122 const double angle = std::atan2(sum -
samples[nPoints - 2].cdfAtX, x -
samples[nPoints - 2].x);
123 if (std::abs(angle - referenceAngle) <= maximumAngleDeviationToSkip) {
130 samples.push_back({x, sum, 0.0});
131 referenceAngle = std::atan2(sum - lastSum, x - lastX);
132 mustCheckAngle =
true;
142 for (
size_t i = 1; i <
samples.size() - 1; ++i) {