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
2622namespace 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