Skip to content

Commit c6492d0

Browse files
authored
Reduce space usage of Discrete Integrals (#1877)
2 parents 6d66cce + 19987be commit c6492d0

File tree

1 file changed

+48
-25
lines changed

1 file changed

+48
-25
lines changed

ql/math/integrals/discreteintegrals.cpp

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@
1818
*/
1919

2020
#include <ql/math/integrals/discreteintegrals.hpp>
21-
#include <boost/accumulators/accumulators.hpp>
22-
#include <boost/accumulators/statistics/sum.hpp>
23-
24-
using namespace boost::accumulators;
2521

2622
namespace QuantLib {
2723

@@ -31,13 +27,13 @@ namespace QuantLib {
3127
const Size n = f.size();
3228
QL_REQUIRE(n == x.size(), "inconsistent size");
3329

34-
accumulator_set<Real, features<tag::sum> > acc;
30+
Real sum = 0.0;
3531

3632
for (Size i=0; i < n-1; ++i) {
37-
acc((x[i+1]-x[i])*(f[i]+f[i+1]));
33+
sum += (x[i+1]-x[i])*(f[i]+f[i+1]);
3834
}
3935

40-
return 0.5*sum(acc);
36+
return 0.5*sum;
4137
}
4238

4339
Real DiscreteSimpsonIntegral::operator()(
@@ -46,45 +42,72 @@ namespace QuantLib {
4642
const Size n = f.size();
4743
QL_REQUIRE(n == x.size(), "inconsistent size");
4844

49-
accumulator_set<Real, features<tag::sum> > acc;
45+
Real sum = 0.0;
5046

5147
for (Size j=0; j < n-2; j+=2) {
5248
const Real dxj = x[j+1]-x[j];
5349
const Real dxjp1 = x[j+2]-x[j+1];
5450

55-
const Real alpha = -dxjp1*(2*x[j]-3*x[j+1]+x[j+2]);
56-
const Real dd = x[j+2]-x[j];
51+
const Real alpha = dxjp1*(2*dxj-dxjp1);
52+
const Real dd = dxj+dxjp1;
5753
const Real k = dd/(6*dxjp1*dxj);
5854
const Real beta = dd*dd;
59-
const Real gamma = dxj*(x[j]-3*x[j+1]+2*x[j+2]);
55+
const Real gamma = dxj*(2*dxjp1-dxj);
6056

61-
acc(k*alpha*f[j]+k*beta*f[j+1]+k*gamma*f[j+2]);
57+
sum += k*(alpha*f[j]+beta*f[j+1]+gamma*f[j+2]);
6258
}
6359
if ((n & 1) == 0U) {
64-
acc(0.5*(x[n-1]-x[n-2])*(f[n-1]+f[n-2]));
60+
sum += 0.5*(x[n-1]-x[n-2])*(f[n-1]+f[n-2]);
6561
}
6662

67-
return sum(acc);
63+
return sum;
6864
}
6965

70-
7166
Real DiscreteTrapezoidIntegrator::integrate(
7267
const ext::function<Real (Real)>& f, Real a, Real b) const {
73-
const Array x(maxEvaluations(), a, (b-a)/(maxEvaluations()-1));
74-
Array fv(x.size());
75-
std::transform(x.begin(), x.end(), fv.begin(), f);
76-
68+
const Size n=maxEvaluations()-1;
69+
const Real d=(b-a)/n;
70+
71+
Real sum = f(a)*0.5;
72+
73+
for(Size i=0;i<n-1;++i) {
74+
a += d;
75+
sum += f(a);
76+
}
77+
sum += f(b)*0.5;
78+
7779
increaseNumberOfEvaluations(maxEvaluations());
78-
return DiscreteTrapezoidIntegral()(x, fv);
80+
81+
return d * sum;
7982
}
8083

8184
Real DiscreteSimpsonIntegrator::integrate(
8285
const ext::function<Real (Real)>& f, Real a, Real b) const {
83-
const Array x(maxEvaluations(), a, (b-a)/(maxEvaluations()-1));
84-
Array fv(x.size());
85-
std::transform(x.begin(), x.end(), fv.begin(), f);
86-
86+
const Size n=maxEvaluations()-1;
87+
const Real d=(b-a)/n, d2=d*2;
88+
89+
Real sum = 0.0, x = a + d;
90+
for(Size i=1;i<n;i+=2) {//to time 4
91+
sum += f(x);
92+
x += d2;
93+
}
94+
sum *= 2;
95+
96+
x = a+d2;
97+
for(Size i=2;i<n-1;i+=2) {//to time 2
98+
sum += f(x);
99+
x += d2;
100+
}
101+
sum *= 2;
102+
103+
sum += f(a);
104+
if(n&1)
105+
sum += 1.5*f(b)+2.5*f(b-d);
106+
else
107+
sum += f(b);
108+
87109
increaseNumberOfEvaluations(maxEvaluations());
88-
return DiscreteSimpsonIntegral()(x, fv);
110+
111+
return d/3 * sum;
89112
}
90113
}

0 commit comments

Comments
 (0)