[go: up one dir, main page]

1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2003 RiskMap srl
5 Copyright (C) 2015 Peter Caspers
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21#include "integrals.hpp"
22#include "utilities.hpp"
23#include <ql/math/integrals/exponentialintegrals.hpp>
24#include <ql/math/integrals/filonintegral.hpp>
25#include <ql/math/integrals/segmentintegral.hpp>
26#include <ql/math/integrals/simpsonintegral.hpp>
27#include <ql/math/integrals/trapezoidintegral.hpp>
28#include <ql/math/integrals/kronrodintegral.hpp>
29#include <ql/math/integrals/gausslobattointegral.hpp>
30#include <ql/math/integrals/discreteintegrals.hpp>
31#include <ql/math/integrals/tanhsinhintegral.hpp>
32#include <ql/math/integrals/gaussianquadratures.hpp>
33#include <ql/math/interpolations/bilinearinterpolation.hpp>
34#include <ql/math/distributions/normaldistribution.hpp>
35#include <ql/termstructures/volatility/abcd.hpp>
36#include <ql/math/integrals/twodimensionalintegral.hpp>
37#include <ql/experimental/math/piecewisefunction.hpp>
38#include <ql/experimental/math/piecewiseintegral.hpp>
39
40using namespace QuantLib;
41using boost::unit_test_framework::test_suite;
42
43namespace integrals_test {
44
45 Real tolerance = 1.0e-6;
46
47 template <class T>
48 void testSingle(const T& I, const std::string& tag,
49 const ext::function<Real (Real)>& f,
50 Real xMin, Real xMax, Real expected) {
51 Real calculated = I(f,xMin,xMax);
52 if (std::fabs(x: calculated-expected) > integrals_test::tolerance) {
53 BOOST_FAIL(std::setprecision(10)
54 << "integrating " << tag
55 << " calculated: " << calculated
56 << " expected: " << expected);
57 }
58 }
59
60 template <class T>
61 void testSeveral(const T& I) {
62 testSingle(I, "f(x) = 0", [](Real x) -> Real { return 0.0; }, 0.0, 1.0, 0.0);
63 testSingle(I, "f(x) = 1", [](Real x) -> Real { return 1.0; }, 0.0, 1.0, 1.0);
64 testSingle(I, "f(x) = x", [](Real x) -> Real { return x; }, 0.0, 1.0, 0.5);
65 testSingle(I, "f(x) = x^2",
66 [](Real x) -> Real { return x * x; }, 0.0, 1.0, 1.0/3.0);
67 testSingle(I, "f(x) = sin(x)",
68 [](Real x) -> Real { return std::sin(x: x); }, 0.0, M_PI, 2.0);
69 testSingle(I, "f(x) = cos(x)",
70 [](Real x) -> Real { return std::cos(x: x); }, 0.0, M_PI, 0.0);
71
72 testSingle(I, "f(x) = Gaussian(x)",
73 NormalDistribution(), -10.0, 10.0, 1.0);
74 testSingle(I, "f(x) = Abcd2(x)",
75 AbcdSquared(0.07, 0.07, 0.5, 0.1, 8.0, 10.0), 5.0, 6.0,
76 AbcdFunction(0.07, 0.07, 0.5, 0.1).covariance(t1: 5.0, t2: 6.0, T: 8.0, S: 10.0));
77 }
78
79 template <class T>
80 void testDegeneratedDomain(const T& I) {
81 testSingle(I, "f(x) = 0 over [1, 1 + macheps]", [](Real x) -> Real { return 0.0; }, 1.0,
82 1.0 + QL_EPSILON, 0.0);
83 }
84
85}
86
87
88void IntegralTest::testSegment() {
89 BOOST_TEST_MESSAGE("Testing segment integration...");
90
91 using namespace integrals_test;
92
93 testSeveral(I: SegmentIntegral(10000));
94 testDegeneratedDomain(I: SegmentIntegral(10000));
95}
96
97void IntegralTest::testTrapezoid() {
98 BOOST_TEST_MESSAGE("Testing trapezoid integration...");
99
100 using namespace integrals_test;
101
102 testSeveral(I: TrapezoidIntegral<Default>(integrals_test::tolerance, 10000));
103 testDegeneratedDomain(I: TrapezoidIntegral<Default>(integrals_test::tolerance, 10000));
104}
105
106void IntegralTest::testMidPointTrapezoid() {
107 BOOST_TEST_MESSAGE("Testing mid-point trapezoid integration...");
108
109 using namespace integrals_test;
110
111 testSeveral(I: TrapezoidIntegral<MidPoint>(integrals_test::tolerance, 10000));
112 testDegeneratedDomain(I: TrapezoidIntegral<MidPoint>(integrals_test::tolerance, 10000));
113}
114
115void IntegralTest::testSimpson() {
116 BOOST_TEST_MESSAGE("Testing Simpson integration...");
117
118 using namespace integrals_test;
119
120 testSeveral(I: SimpsonIntegral(integrals_test::tolerance, 10000));
121 testDegeneratedDomain(I: SimpsonIntegral(integrals_test::tolerance, 10000));
122}
123
124void IntegralTest::testGaussKronrodAdaptive() {
125 BOOST_TEST_MESSAGE("Testing adaptive Gauss-Kronrod integration...");
126
127 using namespace integrals_test;
128
129 Size maxEvaluations = 1000;
130 testSeveral(I: GaussKronrodAdaptive(integrals_test::tolerance, maxEvaluations));
131 testDegeneratedDomain(I: GaussKronrodAdaptive(integrals_test::tolerance, maxEvaluations));
132}
133
134void IntegralTest::testGaussLobatto() {
135 BOOST_TEST_MESSAGE("Testing adaptive Gauss-Lobatto integration...");
136
137 using namespace integrals_test;
138
139 Size maxEvaluations = 1000;
140 testSeveral(I: GaussLobattoIntegral(maxEvaluations, integrals_test::tolerance));
141 // on degenerated domain [1,1+macheps] an exception is thrown
142 // which is also ok, but not tested here
143}
144
145void IntegralTest::testTanhSinh() {
146 BOOST_TEST_MESSAGE("Testing tanh-sinh integration...");
147
148 using namespace integrals_test;
149 testSeveral(I: TanhSinhIntegral());
150}
151
152void IntegralTest::testGaussLegendreIntegrator() {
153 BOOST_TEST_MESSAGE("Testing Gauss-Legendre integrator...");
154
155 using namespace integrals_test;
156
157 const GaussLegendreIntegrator integrator(64);
158 testSeveral(I: integrator);
159 testDegeneratedDomain(I: integrator);
160}
161
162void IntegralTest::testGaussChebyshevIntegrator() {
163 BOOST_TEST_MESSAGE("Testing Gauss-Chebyshev integrator...");
164
165 using namespace integrals_test;
166
167 const GaussChebyshevIntegrator integrator(64);
168 testSingle(I: integrator, tag: "f(x) = Gaussian(x)",
169 f: NormalDistribution(), xMin: -10.0, xMax: 10.0, expected: 1.0);
170 testDegeneratedDomain(I: integrator);
171}
172
173void IntegralTest::testGaussChebyshev2ndIntegrator() {
174 BOOST_TEST_MESSAGE("Testing Gauss-Chebyshev 2nd integrator...");
175
176 using namespace integrals_test;
177
178 const GaussChebyshev2ndIntegrator integrator(64);
179 testSingle(I: integrator, tag: "f(x) = Gaussian(x)",
180 f: NormalDistribution(), xMin: -10.0, xMax: 10.0, expected: 1.0);
181 testDegeneratedDomain(I: integrator);
182}
183
184
185
186void IntegralTest::testGaussKronrodNonAdaptive() {
187 BOOST_TEST_MESSAGE("Testing non-adaptive Gauss-Kronrod integration...");
188
189 using namespace integrals_test;
190
191 Real precision = integrals_test::tolerance;
192 Size maxEvaluations = 100;
193 Real relativeAccuracy = integrals_test::tolerance;
194 GaussKronrodNonAdaptive gaussKronrodNonAdaptive(precision, maxEvaluations,
195 relativeAccuracy);
196 testSeveral(I: gaussKronrodNonAdaptive);
197 testDegeneratedDomain(I: gaussKronrodNonAdaptive);
198}
199
200void IntegralTest::testTwoDimensionalIntegration() {
201 BOOST_TEST_MESSAGE("Testing two dimensional adaptive "
202 "Gauss-Lobatto integration...");
203
204 using namespace integrals_test;
205
206 const Size maxEvaluations = 1000;
207 const Real calculated = TwoDimensionalIntegral(
208 ext::shared_ptr<Integrator>(
209 new TrapezoidIntegral<Default>(integrals_test::tolerance, maxEvaluations)),
210 ext::shared_ptr<Integrator>(
211 new TrapezoidIntegral<Default>(integrals_test::tolerance, maxEvaluations)))(
212 std::multiplies<>(),
213 std::make_pair(x: 0.0, y: 0.0), std::make_pair(x: 1.0, y: 2.0));
214
215 const Real expected = 1.0;
216 if (std::fabs(x: calculated-expected) > integrals_test::tolerance) {
217 BOOST_FAIL(std::setprecision(10)
218 << "two dimensional integration: "
219 << "\n calculated: " << calculated
220 << "\n expected: " << expected);
221 }
222}
223
224namespace integrals_test {
225
226 class sineF {
227 public:
228 Real operator()(Real x) const {
229 return std::exp(x: -0.5*(x - M_PI_2/100));
230 }
231 };
232
233 class cosineF {
234 public:
235 Real operator()(Real x) const {
236 return std::exp(x: -0.5*x);
237 }
238 };
239
240}
241
242void IntegralTest::testFolinIntegration() {
243 BOOST_TEST_MESSAGE("Testing Folin's integral formulae...");
244
245 using namespace integrals_test;
246
247 // Examples taken from
248 // http://www.tat.physik.uni-tuebingen.de/~kokkotas/Teaching/Num_Methods_files/Comp_Phys5.pdf
249 const Size nr[] = { 4, 8, 16, 128, 256, 1024, 2048 };
250 const Real expected[] = { 4.55229440e-5,4.72338540e-5, 4.72338540e-5,
251 4.78308678e-5,4.78404787e-5, 4.78381120e-5,
252 4.78381084e-5};
253
254 const Real t = 100;
255 const Real o = M_PI_2/t;
256
257 const Real tol = 1e-12;
258
259 for (Size i=0; i < LENGTH(nr); ++i) {
260 const Size n = nr[i];
261 const Real calculatedCosine
262 = FilonIntegral(FilonIntegral::Cosine, t, n)(cosineF(),0,2*M_PI);
263 const Real calculatedSine
264 = FilonIntegral(FilonIntegral::Sine, t, n)
265 (sineF(), o,2*M_PI + o);
266
267 if (std::fabs(x: calculatedCosine-expected[i]) > tol) {
268 BOOST_FAIL(std::setprecision(10)
269 << "Filon Cosine integration failed: "
270 << "\n calculated: " << calculatedCosine
271 << "\n expected: " << expected[i]);
272 }
273 if (std::fabs(x: calculatedSine-expected[i]) > tol) {
274 BOOST_FAIL(std::setprecision(10)
275 << "Filon Sine integration failed: "
276 << "\n calculated: " << calculatedCosine
277 << "\n expected: " << expected[i]);
278 }
279 }
280}
281
282namespace integrals_test {
283
284 Real f1(Real x) {
285 return 1.2*x*x+3.2*x+3.1;
286 }
287
288 Real f2(Real x) {
289 return 4.3*(x-2.34)*(x-2.34)-6.2*(x-2.34) + f1(x: 2.34);
290 }
291
292}
293
294void IntegralTest::testDiscreteIntegrals() {
295 BOOST_TEST_MESSAGE("Testing discrete integral formulae...");
296
297 using namespace integrals_test;
298
299 Array x(6), f(6);
300 x[0] = 1.0; x[1] = 2.02; x[2] = 2.34; x[3] = 3.3; x[4] = 4.2; x[5] = 4.6;
301
302 std::transform(first: x.begin(), last: x.begin()+3, result: f.begin(), unary_op: f1);
303 std::transform(first: x.begin()+3, last: x.end(), result: f.begin()+3, unary_op: f2);
304
305 const Real expectedSimpson =
306 16.0401216 + 30.4137528 + 0.2*f2(x: 4.2) + 0.2*f2(x: 4.6);
307 const Real expectedTrapezoid =
308 0.5*(f1(x: 1.0) + f1(x: 2.02))*1.02
309 + 0.5*(f1(x: 2.02) + f1(x: 2.34))*0.32
310 + 0.5*(f2(x: 2.34) + f2(x: 3.3) )*0.96
311 + 0.5*(f2(x: 3.3) + f2(x: 4.2) )*0.9
312 + 0.5*(f2(x: 4.2) + f2(x: 4.6) )*0.4;
313
314 const Real calculatedSimpson = DiscreteSimpsonIntegral()(x, f);
315 const Real calculatedTrapezoid = DiscreteTrapezoidIntegral()(x, f);
316
317 const Real tol = 1e-12;
318 if (std::fabs(x: calculatedSimpson-expectedSimpson) > tol) {
319 BOOST_FAIL(std::setprecision(16)
320 << "discrete Simpson integration failed: "
321 << "\n calculated: " << calculatedSimpson
322 << "\n expected: " << expectedSimpson);
323 }
324
325 if (std::fabs(x: calculatedTrapezoid-expectedTrapezoid) > tol) {
326 BOOST_FAIL(std::setprecision(16)
327 << "discrete Trapezoid integration failed: "
328 << "\n calculated: " << calculatedTrapezoid
329 << "\n expected: " << expectedTrapezoid);
330 }
331}
332
333void IntegralTest::testDiscreteIntegrator() {
334 BOOST_TEST_MESSAGE("Testing discrete integrator formulae...");
335
336 using namespace integrals_test;
337
338 testSeveral(I: DiscreteSimpsonIntegrator(300));
339 testSeveral(I: DiscreteTrapezoidIntegrator(3000));
340}
341
342namespace integrals_test{
343
344std::vector<Real> x, y;
345
346Real pw_fct(const Real t) { return QL_PIECEWISE_FUNCTION(x, y, t); }
347
348void pw_check(const Integrator &in, const Real a, const Real b,
349 const Real expected) {
350 Real calculated = in(pw_fct, a, b);
351 if (!close(x: calculated, y: expected))
352 BOOST_FAIL(std::setprecision(16)
353 << "piecewise integration over [" << a << "," << b
354 << "] failed: "
355 << "\n calculated: " << calculated
356 << "\n expected: " << expected
357 << "\n difference: " << (calculated - expected));
358}
359} // empty namespace
360
361void IntegralTest::testPiecewiseIntegral() {
362 BOOST_TEST_MESSAGE("Testing piecewise integral...");
363
364 using namespace integrals_test;
365
366 x = { 1.0, 2.0, 3.0, 4.0, 5.0 };
367 y = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
368 ext::shared_ptr<Integrator> segment =
369 ext::make_shared<SegmentIntegral>(args: 1);
370 ext::shared_ptr<Integrator> piecewise =
371 ext::make_shared<PiecewiseIntegral>(args&: segment, args&: x);
372 pw_check(in: *piecewise, a: -1.0, b: 0.0, expected: 1.0);
373 pw_check(in: *piecewise, a: 0.0, b: 1.0, expected: 1.0);
374 pw_check(in: *piecewise, a: 0.0, b: 1.5, expected: 2.0);
375 pw_check(in: *piecewise, a: 0.0, b: 2.0, expected: 3.0);
376 pw_check(in: *piecewise, a: 0.0, b: 2.5, expected: 4.5);
377 pw_check(in: *piecewise, a: 0.0, b: 3.0, expected: 6.0);
378 pw_check(in: *piecewise, a: 0.0, b: 4.0, expected: 10.0);
379 pw_check(in: *piecewise, a: 0.0, b: 5.0, expected: 15.0);
380 pw_check(in: *piecewise, a: 0.0, b: 6.0, expected: 21.0);
381 pw_check(in: *piecewise, a: 0.0, b: 7.0, expected: 27.0);
382 pw_check(in: *piecewise, a: 3.5, b: 4.5, expected: 4.5);
383 pw_check(in: *piecewise, a: 5.0, b: 10.0, expected: 30.0);
384 pw_check(in: *piecewise, a: 9.0, b: 10.0, expected: 6.0);
385}
386
387namespace integrals_test {
388 template <class T>
389 void reportSiCiFail(
390 const std::string& name, T z, T c, T e, Real diff, Real tol) {
391 BOOST_FAIL(std::setprecision(16)
392 << name << " calculation failed for " << z
393 << "\n calculated: " << c
394 << "\n expected: " << e
395 << "\n difference: " << diff
396 << "\n tolerance: " << tol);
397 }
398}
399
400void IntegralTest::testExponentialIntegral() {
401 BOOST_TEST_MESSAGE("Testing exponential integrals...");
402
403 using namespace ExponentialIntegral;
404
405 // reference values are calculated with Mathematica or Python/mpmath
406 const Real data[][10] = {
407 {0.0010000000000000000208, 0.0, 0.00099999994444444613193, 0.0, -6.330539864080593754, 0.0, -6.3295393640250381967, 0.0, 6.3315393641361493112, 0.0},
408 {0.00070710678118654756077, 0.00070710678118654751747, 0.00070710682047025644818, 0.00070710674190283627304, -6.3305396140806145873, 0.785397913397448279, -6.329832507338711751, 0.7861055202179185354, 6.3312467208225174236, -0.78469130657697802259},
409 {6.1232339957367660136e-20, 0.0010000000000000000208, 6.1232350162201617204e-20, 0.001000000055555557243, -6.330539364080593754, 1.570796326794896558, -6.3305398640805937539, 1.5717963267393410041, 6.330539864080593754, -1.5697963268504521119},
410 {-0.00070710678118654747417, 0.00070710678118654760407, -0.00070710682047025636158, 0.00070710674190283635964, -6.3305396140806145873, 2.356194740192344837, -6.3312467208225174235, 2.3569013470128150935, 6.3298325073387117511, -2.3554871333718745805},
411 {-0.0010000000000000000208, 1.2246467991473532027e-19, -0.00099999994444444613193, 1.2246465950321797194e-19, -6.330539864080593754, 3.141592653589793116, -6.3315393641361493112, 3.1415926535897931161, 6.3295393640250381967, -3.1415926535897931159},
412 {-0.00070710678118654764736, -0.00070710678118654743088, -0.00070710682047025653477, -0.00070710674190283618645, -6.3305396140806145873, -2.3561947401923450819, -6.3312467208225174237, -2.3569013470128153382, 6.3298325073387117509, 2.3554871333718748256},
413 {-1.8369701987210298041e-19, -0.0010000000000000000208, -1.8369705049015472569e-19, -0.001000000055555557243, -6.330539364080593754, -1.5707963267948968029, -6.3305398640805937541, -1.5717963267393412491, 6.3305398640805937538, 1.5697963268504523568},
414 {0.00070710678118654738758, -0.00070710678118654769066, 0.00070710682047025627499, -0.00070710674190283644623, -6.3305396140806145873, -0.78539791339744852393, -6.3298325073387117512, -0.78610552021791878051, 6.3312467208225174234, 0.78469130657697826735},
415 {0.10000000000000000555, 0.0, 0.099944461108276955702, 0.0, -1.7278683866572965838, 0.0, -1.6228128139692766136, 0.0, 1.8229239584193906159, 0.0},
416 {0.07071067811865475853, 0.0707106781186547542, 0.070749950041603603669, 0.070671382625480302524, -1.7253704697591484327, 0.78289816362892975745, -1.6546990871336681256, 0.8586481132075703999, 1.7960418523846287393, -0.7171482131243632012},
417 {6.123233995736766226e-18, 0.10000000000000000555, 6.1334444895968712791e-18, 0.10005557222505700112, -1.7228683861943336147, 1.5707963267948965577, -1.7278683866572965777, 1.670740787903173514, 1.7278683866572965899, -1.4708518656866196026},
418 {-0.070710678118654749871, 0.07071067811865476286, -0.070749950041603595024, 0.070671382625480311198, -1.7253704697591484321, 2.3586944899608633586, -1.7960418523846287312, 2.4244444404654299234, 1.6546990871336681349, -2.2829445403822227075},
419 {-0.10000000000000000555, 1.2246467991473532452e-17, -0.099944461108276955702, 1.2226067414369268591e-17, -1.7278683866572965838, 3.1415926535897931166, -1.8229239584193906159, 3.1415926535897931277, 1.6228128139692766136, -3.1415926535897931031},
420 {-0.07071067811865476719, -0.070710678118654745541, -0.070749950041603612314, -0.07067138262548029385, -1.7253704697591484333, -2.3586944899608636035, -1.7960418523846287474, -2.4244444404654301511, 1.6546990871336681163, 2.2829445403822229697},
421 {-1.8369701987210298678e-17, -0.10000000000000000555, -1.8400333469093536425e-17, -0.10005557222505700112, -1.7228683861943336147, -1.5707963267948968038, -1.7278683866572966021, -1.6707407879031737577, 1.7278683866572965654, 1.4708518656866198463},
422 {0.070710678118654741211, -0.07071067811865477152, 0.070749950041603586379, -0.070671382625480319872, -1.7253704697591484315, -0.78289816362893000238, -1.6546990871336681441, -0.85864811320757066212, 1.7960418523846287232, 0.71714821312436342884},
423 {0.25, 0.0, 0.2491335703197571641, 0.0, -0.82466306258094565309, 0.0, -0.54254326466191372953, 0.0, 1.0442826344437381945, 0.0},
424 {0.17677669529663688651, 0.17677669529663687569, 0.17738935115398995617, 0.17616173766104897661, -0.80911938627521916259, 0.76977321991145556311, -0.63295764861417017313, 0.97841245803743094036, 0.98528112393626814822, -0.62363375572945104943},
425 {1.5308084989341914715e-17, 0.25, 1.5468043259937507815e-17, 0.2508696848909122325, -0.79341294955282596203, 1.5707963267948965561, -0.82466306258094563794, 1.819929897114653724, 0.82466306258094566823, -1.3216627564751393958},
426 {-0.17677669529663686486, 0.17677669529663689734, -0.17738935115398993475, 0.17616173766104899848, -0.80911938627521915876, 2.3718194336783375529, -0.98528112393626813018, 2.517958897860342088, 0.63295764861417019883, -2.1631801955523621542},
427 {-0.25, 3.0616169978683829431e-17, -0.2491335703197571641, 3.0298246679137807606e-17, -0.82466306258094565309, 3.1415926535897931198, -1.0442826344437381945, 3.1415926535897931431, 0.54254326466191372953, -3.1415926535897930812},
428 {-0.17677669529663690816, -0.17677669529663685404, -0.1773893511539899776, -0.17616173766104895473, -0.80911938627521916642, -2.3718194336783377978, -0.98528112393626816627, -2.5179588978603422901, 0.63295764861417014743, 2.163180195552362442},
429 {-4.5924254968025744146e-17, -0.25, -4.6404129781529084775e-17, -0.2508696848909122325, -0.79341294955282596203, -1.5707963267948968087, -0.82466306258094569853, -1.8199298971146539613, 0.82466306258094560764, 1.3216627564751396331},
430 {0.17677669529663684321, -0.17677669529663691899, 0.17738935115398991333, -0.17616173766104902036, -0.80911938627521915494, -0.769773219911455808, -0.63295764861417022453, -0.97841245803743122809, 0.98528112393626811213, 0.62363375572945125148},
431 {0.5, 0.0, 0.49310741804306668916, 0.0, -0.17778407880661290134, 0.0, 0.45421990486317357992, 0.0, 0.55977359477616081175, 0.0},
432 {0.35355339059327377302, 0.35355339059327375138, 0.3584268697133189464, 0.34860625536259795411, -0.11658254521497154353, 0.72290178026868503268, 0.23202371014762644078, 1.2063214162395304511, 0.46518880057756951253, -0.48946767681289259981},
433 {3.0616169978683829431e-17, 0.5, 3.190788489546069124e-17, 0.50699674981966719583, -0.052776844956493615913, 1.5707963267948965502, -0.17778407880661287198, 2.0639037448379632547, 0.17778407880661293069, -1.0776889087518298763},
434 {-0.35355339059327372973, 0.35355339059327379467, -0.35842686971331890493, 0.34860625536259799919, -0.11658254521497152822, 2.4186908733211080836, -0.46518880057756948275, 2.652124976776900558, -0.2320237101476263804, -1.9352712373502626237},
435 {-0.5, 6.1232339957367658861e-17, -0.49310741804306668916, 5.8712695126944314728e-17, -0.17778407880661290134, 3.141592653589793131, -0.55977359477616081175, 3.1415926535897931642, -0.45421990486317357992, -3.1415926535897930366},
436 {-0.35355339059327381632, -0.35355339059327370808, -0.35842686971331898787, -0.34860625536259790903, -0.11658254521497155883, -2.4186908733211083279, -0.4651888005775695423, -2.6521249767769007193, -0.23202371014762650116, 1.9352712373502629509},
437 {-9.1848509936051488292e-17, -0.5, -9.5723654690421041556e-17, -0.50699674981966719583, -0.052776844956493615913, -1.5707963267948968264, -0.1777840788066129894, -2.0639037448379634696, 0.17778407880661281327, 1.0776889087518300913},
438 {0.35355339059327368643, -0.35355339059327383797, 0.35842686971331886346, -0.34860625536259804427, -0.11658254521497151291, -0.72290178026868527697, 0.23202371014762632001, -1.2063214162395307784, 0.46518880057756945298, 0.48946767681289276116},
439 {1.0, 0.0, 0.94608307036718301494, 0.0, 0.33740392290096813466, 0.0, 1.8951178163559367555, 0.0, 0.21938393439552027368, 0.0},
440 {0.70710678118654754605, 0.70710678118654750275, 0.74519215535365930209, 0.66666481741950631398, 0.56680209825930888934, 0.53562961732242986806, 1.233466915678815284, 1.7803588648261259588, 0.099862719160197444251, -0.28997455411880742612},
441 {6.1232339957367658861e-17, 1.0, 7.1960319005373041642e-17, 1.0572508753757285146, 0.83786694098020824089, 1.5707963267948965247, 0.33740392290096818619, 2.5168793971620796011, -0.33740392290096808314, -0.62471325642771357121},
442 {-0.70710678118654745945, 0.70710678118654758935, -0.74519215535365923063, 0.66666481741950641427, 0.5668020982593089504, 2.605963036267363253, -0.099862719160197405024, 2.8516180994709857664, -1.2334669156788151226, -1.3612337887636670908},
443 {-1.0, 1.2246467991473531772e-16, -0.94608307036718301494, 1.0305047480945999774e-16, 0.33740392290096813466, 3.1415926535897931723, -0.21938393439552027368, 3.1415926535897931934, -1.8951178163559367555, -3.1415926535897929056},
444 {-0.70710678118654763265, -0.70710678118654741616, -0.74519215535365937355, -0.66666481741950621369, 0.56680209825930882828, -2.6059630362673634878, -0.099862719160197483478, -2.8516180994709858582, -1.2334669156788154453, 1.3612337887636674684},
445 {-1.8369701987210297658e-16, -1.0, -2.158809570266204413e-16, -1.0572508753757285146, 0.83786694098020824089, -1.5707963267948969027, 0.33740392290096798009, -2.5168793971620797334, -0.33740392290096828924, 0.62471325642771370354},
446 {0.70710678118654737286, -0.70710678118654767594, 0.74519215535365915917, -0.66666481741950651456, 0.56680209825930901147, -0.53562961732243010279, 1.2334669156788149613, -1.7803588648261263365, 0.099862719160197365796, 0.28997455411880751794},
447 {1.5, 0.0, 1.3246835311721196804, 0.0, 0.47035631719539988668, 0.0, 3.301285449129797838, 0.0, 0.1000195824066326519, 0.0},
448 {1.0606601717798213191, 1.0606601717798212541, 1.1839593855572855609, 0.9194789610047786165, 0.93002583013377829907, 0.22553329329273497242, 1.8495047911385570699, 2.5292224190594471214, -0.010546869128999664075, -0.16130364794487607552},
449 {9.1848509936051488292e-17, 1.5, 1.3038076345658281264e-16, 1.7006525157682152449, 1.600632933361582593, 1.5707963267948964752, 0.47035631719539994775, 2.8954798579670162953, -0.4703563171953998256, -0.24611279562277693453},
450 {-1.0606601717798211892, 1.060660171779821384, -1.1839593855572854849, 0.91947896100477878934, 0.93002583013377843491, 2.9160593602970581693, 0.010546869128999701077, 2.9802890056449171422, -1.8495047911385567612, -0.61237023453034594437},
451 {-1.5, 1.8369701987210297658e-16, -1.3246835311721196804, 1.2215790424776667532e-16, 0.47035631719539988668, 3.1415926535897932298, -0.1000195824066326519, 3.1415926535897932111, -3.301285449129797838, -3.1415926535897926896},
452 {-1.060660171779821449, -1.0606601717798211242, -1.1839593855572856369, -0.91947896100477844366, 0.93002583013377816324, -2.9160593602970583627, 0.010546869128999627072, -2.9802890056449171836, -1.8495047911385573786, 0.6123702345303462898},
453 {-2.7554552980815446488e-16, -1.5, -3.9114229038065365107e-16, -1.7006525157682152449, 1.600632933361582593, -1.5707963267948970514, 0.47035631719539970344, -2.8954798579670163126, -0.47035631719540006991, 0.24611279562277695186},
454 {1.0606601717798210593, -1.0606601717798215139, 1.1839593855572854089, -0.91947896100477896218, 0.93002583013377857075, -0.22553329329273516584, 1.8495047911385564526, -2.5292224190594474668, -0.010546869128999738079, 0.16130364794487611693},
455 {2.0, 0.0, 1.6054129768026948486, 0.0, 0.4229808287748649957, 0.0, 4.9542343560018901634, 0.0, 0.048900510708061119567, 0.0},
456 {1.4142135623730950921, 1.4142135623730950055, 1.6883194933582990243, 1.0649044719839209475, 1.1044891171909028954, -0.19981522706084708457, 2.1693935891748240916, 3.4589310472140426889, -0.039584645206981933184, -0.08229206049744467714},
457 {1.2246467991473531772e-16, 2.0, 2.2208114946641807464e-16, 2.5015674333549756415, 2.4526669226469145219, 1.5707963267948963889, 0.42298082877486505138, 3.1762093035975914933, -0.42298082877486494002, 0.034616650007798203864},
458 {-1.4142135623730949189, 1.4142135623730951787, -1.6883194933582989874, 1.0649044719839212109, 1.1044891171909031294, 3.3414078806506402814, 0.039584645206981962593, 3.0593005930923485567, -2.169393589174823594, 0.31733839362424952895},
459 {-2.0, 2.4492935982947063545e-16, -1.6054129768026948486, 1.1135681831696612616e-16, 0.4229808287748649957, 3.1415926535897932894, -0.048900510708061119567, 3.1415926535897932219, -4.9542343560018901634, -3.1415926535897923336},
460 {-1.4142135623730952653, -1.4142135623730948323, -1.6883194933582990613, -1.064904471983920684, 1.1044891171909026613, -3.3414078806506403646, 0.039584645206981903775, -3.059300593092348566, -2.1693935891748245892, -0.31733839362424937184},
461 {-3.6739403974420595317e-16, -2.0, -6.6624344842268023737e-16, -2.5015674333549756415, 2.4526669226469145219, -1.5707963267948973103, 0.42298082877486482866, -3.1762093035975913914, -0.42298082877486516273, -0.03461665000779830579},
462 {1.4142135623730947457, -1.4142135623730953519, 1.6883194933582989504, -1.0649044719839214744, 1.1044891171909033635, 0.19981522706084700137, 2.1693935891748230965, -3.458931047214042846, -0.039584645206981992002, 0.082292060497444686426},
463 {5.0, 0.0, 1.5499312449446741373, 0.0, -0.19002974965664387862, 0.0, 40.185275355803177455, 0.0, 0.0011482955912753257973, 0.0},
464 {3.5355339059327377302, 3.5355339059327375138, 3.6871508611543429709, -3.157181373909001357, -3.1547681046716106125, -2.1118502909279661892, -6.311949478580612776, 7.3697974788772077195, -0.0024132692373907452624, 0.0045042434314801607547},
465 {3.0616169978683829431e-16, 5.0, 4.5436362172750887551e-15, 20.09321182569722639, 20.092063530105951065, 1.5707963267948920752, -0.19002974965664393734, 3.1207275717395707391, 0.1900297496566438199, -0.020865081850222464588},
466 {-3.5355339059327372973, 3.5355339059327379467, -3.6871508611543449094, -3.1571813739090021642, -3.1547681046716114182, 5.2534429445177613695, 0.0024132692373907438925, 3.1460968970212734025, 6.3119494785806111631, 4.2282048252874106008},
467 {-5.0, 6.1232339957367658861e-16, -1.5499312449446741373, -1.174343542809398959e-16, -0.19002974965664387862, 3.1415926535897932037, -0.0011482955912753257973, 3.1415926535897932376, -40.185275355803177455, -3.1415926535897750631},
468 {-3.5355339059327381632, -3.5355339059327370808, -3.6871508611543410324, 3.1571813739090005499, -3.1547681046716098067, -5.2534429445177574859, 0.0024132692373907466323, -3.1460968970212733959, 6.3119494785806143889, -4.2282048252874183613},
469 {-9.1848509936051488292e-16, -5.0, -1.3630908648516543815e-14, -20.09321182569722639, 20.092063530105951065, -1.5707963267949102514, -0.19002974965664370247, -3.1207275717395708086, 0.19002974965664405477, 0.020865081850222534065},
470 {3.5355339059327368643, -3.5355339059327383797, 3.6871508611543468479, 3.1571813739090029713, -3.154768104671612224, 2.1118502909279700728, -6.3119494785806095501, -7.3697974788771999589, -0.0024132692373907425226, -0.004504243431480167346},
471 {10.0, 0.0, 1.6583475942188740493, 0.0, -0.045456433004455372635, 0.0, 2492.2289762418777591, 0.0, 4.1569689296853242774e-6, 0.0},
472 {7.0710678118654754605, 7.0710678118654750275, -3.7745175303432929615, 62.642575559232345941, 62.642571122904060317, 5.3452347019798827768, 125.28514668213645736, -7.5489559055283299711, 4.4363282856236060522e-6, -0.000079155158306803868409},
473 {6.1232339957367658861e-16, 10.0, 6.7436601941373126554e-13, 1246.1144901994233444, 1246.1144860424544147, 1.5707963267942222532, -0.045456433004455405946, 3.2291439210137707199, 0.045456433004455339323, 0.087551267423977378721},
474 {-7.0710678118654745945, 7.0710678118654758935, 3.7745175303433438135, 62.642575559232397046, 62.642571122904111422, -2.2036420483901403904, -4.4363282856235323221e-6, 3.1415134984314864345, -125.28514668213635515, -10.690548559118021506},
475 {-10.0, 1.2246467991473531772e-15, -1.6583475942188740493, -6.6623371218859982286e-17, -0.045456433004455372635, 3.1415926535897933412, -4.1569689296853242774e-6, 3.1415926535897932385, -2492.2289762418777591, -3.1415926535870957744},
476 {-7.0710678118654763265, -7.0710678118654741616, 3.7745175303432421091, -62.642575559232294835, 62.642571122904009212, 2.2036420483900386859, -4.4363282856236797822e-6, -3.1415134984314864347, -125.28514668213655957, 10.690548559118224914},
477 {-1.8369701987210297658e-15, -10.0, -2.0230980582411937966e-12, -1246.1144901994233444, 1246.1144860424544147, -1.5707963267969197173, -0.045456433004455272699, -3.2291439210137705144, 0.04545643300445547257, -0.087551267423977584235},
478 {7.0710678118654737286, -7.0710678118654767594, -3.7745175303433946658, -62.642575559232448152, 62.642571122904162528, -5.3452347019799844813, 125.28514668213625294, 7.5489559055281265623, 4.4363282856234585915e-6, 0.000079155158306804015139},
479 {15.0, 0.0, 1.6181944437083687391, 0.0, 0.046278677674360439604, 0.0, 234955.85249076830358, 0.0, 1.9186278921478669771e-8, 0.0},
480 {10.606601717798213191, 10.606601717798212541, -471.05515346873571713, -1328.2594907541181068, -1328.2594913017652105, 472.62595127241629118, -2656.5189820558856064, -942.11030841435617353, 5.4764710367805069957e-7, 1.4768856774331466472e-6},
481 {9.1848509936051488292e-16, 15.0, 1.0008479153886857898e-10, 117477.92624539374493, 117477.92624537455865, 1.5707963266948118277, 0.046278677674360479423, 3.1889907705032654049, -0.046278677674360399786, 0.047398116913472073375},
482 {-10.606601717798211892, 10.60660171779821384, 471.05515346873477896, -1328.2594907541203959, -1328.2594913017674995, -469.48435861882555978, -5.4764710367805350438e-7, 3.1415941304754706716, 2656.5189820558810283, -945.2519010679478431},
483 {-15.0, 1.8369701987210297658e-15, -1.6181944437083687391, 7.9637292204322254463e-17, 0.046278677674360439604, 3.1415926535897933315, -1.9186278921478669771e-8, 3.1415926535897932385, -234955.85249076830358, -3.1415926531894540723},
484 {-10.60660171779821449, -10.606601717798211242, 471.05515346873665531, 1328.2594907541158178, -1328.2594913017629215, 469.48435861882743613, -5.4764710367804789476e-7, -3.1415941304754706716, 2656.5189820558901845, 945.25190106794409045},
485 {-2.7554552980815446488e-15, -15.0, -3.0025437461660077385e-10, -117477.92624539374493, 117477.92624537455865, -1.5707963270951509938, 0.046278677674360320148, -3.1889907705032652188, -0.04627867767436055906, -0.047398116913472259445},
486 {10.606601717798210593, -10.606601717798215139, -471.05515346873384079, 1328.2594907541226849, -1328.2594913017697886, -472.62595127241441484, -2656.5189820558764503, 942.11030841435992621, 5.4764710367805630921e-7, -1.4768856774331489463e-6},
487 {20.0, 0.0, 1.5482417010434398402, 0.0, 0.04441982084535331654, 0.0, 25615652.66405658882, 0.0, 9.8355252906498816904e-11, 0.0},
488 {14.142135623730950921, 14.142135623730950055, 24486.68965358318626, 26235.092183360235647, 26235.092183384186671, -24485.118857281672279, 52470.184366744507202, 48973.379307191653857, -2.3951024244493564362e-8, -2.5280915398646225218e-8},
489 {1.2246467991473531772e-15, 20.0, 1.4853900090407493933e-8, 12807826.332028294459, 12807826.332028294361, 1.5707963119409965288, 0.044419820845353372442, 3.1190380278383364344, -0.044419820845353260638, -0.02255462575145675408},
490 {-14.142135623730949189, 14.142135623730951787, -24486.689653583186682, 26235.092183360320531, 26235.092183384271555, 24488.260449935262494, 2.3951024244493652701e-8, 3.1415926283088778398, -52470.184366744337435, 48970.23771453806322},
491 {-20.0, 2.4492935982947063545e-15, -1.5482417010434398402, 1.1180354790034662799e-16, 0.04441982084535331654, 3.1415926535897931885, -9.8355252906498816904e-11, 3.1415926535897932385, -25615652.66405658882, -3.1415925941741928768},
492 {-14.142135623730952653, -14.142135623730948323, -24486.689653583185838, -26235.092183360150763, 26235.092183384101787, -24488.26044993526165, 2.3951024244493476023e-8, -3.1415926283088778398, -52470.184366744676971, -48970.237714538064908},
493 {-3.6739403974420595317e-15, -20.0, -4.4561700271222483452e-8, -12807826.332028294459, 12807826.332028294361, -1.5707963713565968905, 0.044419820845353148834, -3.1190380278383365344, -0.044419820845353484245, 0.022554625751456854031},
494 {14.142135623730947457, -14.142135623730953519, 24486.689653583187103, -26235.092183360405415, 26235.09218338435644, 24485.118857281673122, 52470.184366744167666, -48973.37930719165217, -2.3951024244493741041e-8, 2.528091539864622434e-8},
495 {24.989999999999998437, 0.0, 1.5315374843262580141, 0.0, -0.0072448862399538447391, 0.0, 2977286754.0962403117, 0.0, 5.4047414055481939457e-13, 0.0},
496 {17.67059846185182207, 17.670598461851820988, -885673.16331345207799, -400248.00540652140574, -400248.00540652215797, 885674.7341097792085, -800496.01081304623667, -1771346.3266269055961, 7.5223231588352466724e-10, 3.3560562518531656391e-10},
497 {1.5301961755346176992e-15, 24.989999999999998437, 2.1825789542468514196e-6, 1488643377.0481201559, 1488643377.0481201559, 1.5707941442159423724, -0.0072448862399538534498, 3.1023338111211545727, 0.0072448862399538360284, -0.039258842468638544566},
498 {-17.670598461851819906, 17.670598461851823152, 885673.16331345318248, -400248.0054065240787, -400248.00540652483093, -885671.59251712672318, -7.5223231588352706351e-10, 3.1415926539253988636, 800496.01081304089075, -1771349.4682195569769},
499 {-24.989999999999998437, 3.0603923510692353985e-15, -1.5315374843262580141, -1.7421457417638512695e-17, -0.0072448862399538447391, 3.1415926535897931172, -5.4047414055481939457e-13, 3.1415926535897932385, -2977286754.0962403117, -3.1415839232739762511},
500 {-17.670598461851824234, -17.670598461851818824, 885673.16331345097349, 400248.00540651873277, -400248.005406519485, 885671.5925171245142, -7.5223231588352227096e-10, -3.1415926539253988636, 800496.01081305158263, 1771349.4682195613948},
501 {-4.5905885266038530977e-15, -24.989999999999998437, -6.5477368627405542588e-6, -1488643377.0481201559, 1488643377.0481201559, -1.5708028745317593598, -0.0072448862399538186069, -3.1023338111211548151, 0.0072448862399538708713, 0.039258842468638787005},
502 {17.670598461851817742, -17.670598461851825316, -885673.16331345428695, 400248.00540652675168, -400248.00540652750391, -885674.73410978141745, -800496.01081303554482, 1771346.3266269011781, 7.5223231588352945979e-10, -3.3560562518531458362e-10}
503 };
504
505 const Real tol = 1e-10;
506
507 for (const auto& i : data) {
508 const Real x = i[0];
509 const Real y = (std::abs(x: i[1]) < 1e-12) ? 0.0 : i[1];
510 const std::complex<Real> z(x, y);
511
512
513 const std::complex<Real> si = Si(z);
514 std::complex<Real> ref(i[2], i[3]);
515 Real diff = std::abs(z: si-ref)/std::abs(z: ref);
516 if (diff > tol
517 || (std::abs(x: ref.real()) < tol && std::abs(x: si.real()) > tol)
518 || (std::abs(x: ref.imag()) < tol && std::abs(x: si.imag()) > tol)) {
519 integrals_test::reportSiCiFail(name: "Si", z, c: si, e: ref, diff, tol);
520 }
521
522 const std::complex<Real> ci = Ci(z);
523 ref = std::complex<Real>(i[4], i[5]);
524 diff = std::min(a: std::abs(z: ci-ref), b: std::abs(z: ci-ref)/std::abs(z: ref));
525 if (diff > tol
526 || (std::abs(x: ref.real()) < tol && std::abs(x: ci.real()) > tol)
527 || (std::abs(x: ref.imag()) < tol && std::abs(x: ci.imag()) > tol)) {
528 integrals_test::reportSiCiFail(name: "Ci", z, c: ci, e: ref, diff, tol);
529 }
530
531 const std::complex<Real> ei = Ei(z);
532 ref = std::complex<Real>(i[6], i[7]);
533 diff = std::abs(z: ei-ref)/std::abs(z: ref);
534 if (diff > tol
535 || (std::abs(x: ref.real()) < tol && std::abs(x: ei.real()) > tol)
536 || (std::abs(x: ref.imag()) < tol && std::abs(x: ei.imag()) > tol)) {
537 integrals_test::reportSiCiFail(name: "Ei", z, c: ei, e: ref, diff, tol);
538 }
539
540 const std::complex<Real> e1 = E1(z);
541 ref = std::complex<Real>(i[8], i[9]);
542 diff = std::min(a: std::abs(z: e1-ref), b: std::abs(z: e1-ref)/std::abs(z: ref));
543 if (std::abs(z: z) < 10.0)
544 if (diff > tol
545 || (std::abs(x: ref.real()) < tol && std::abs(x: e1.real()) > tol)
546 || (std::abs(x: ref.imag()) < tol && std::abs(x: e1.imag()) > tol)) {
547 integrals_test::reportSiCiFail(name: "E1", z, c: e1, e: ref, diff, tol);
548 }
549 }
550}
551
552
553
554void IntegralTest::testRealSiCiIntegrals() {
555 BOOST_TEST_MESSAGE("Testing real Ci and Si...");
556
557 using namespace ExponentialIntegral;
558
559 // reference values are calculated with Mathematica or Python/mpmath
560 const Real data[][3] = {
561 {1e-12, 1e-12, -27.0538054510270153677},
562 {0.1, 0.09994446110827695570, -1.7278683866572965838},
563 {1.0, 0.9460830703671830149, 0.3374039229009681347},
564 {1.9999, 1.6053675097543679041, 0.4230016343635392},
565 {3.9999, 1.758222058430840841, -0.140965355646150101},
566 {4.0001, 1.758184218306157867, -0.140998037827177150},
567 {5.0, 1.5499312449446741373, -0.19002974965664387862},
568 {7.0, 1.4545966142480935906, 0.076695278482184518383,},
569 {10.0, 1.6583475942188740493, -0.045456433004455372635},
570 {15.0, 1.6181944437083687391, 0.046278677674360439604},
571 {20.0, 1.5482417010434398402, 0.04441982084535331654},
572 {24.9, 1.532210740207620024, -0.010788215638781789846},
573 {25.1, 1.5311526281483412938, -0.0028719014454227088097},
574 {30.0, 1.566756540030351111, -0.033032417282071143779},
575 {40.0, 1.5869851193547845068, 0.019020007896208766962},
576 {400.0, 1.5721148692738117518, -0.00212398883084634893},
577 {4000.0, 1.5709788562309441985, -0.00017083030544201591130}
578 };
579
580
581 const Real tol = 1e-12;
582
583 for (const auto& i : data) {
584 Real x = i[0];
585 Real si = Si(x);
586
587 Real diff = std::fabs(x: si - i[1]);
588 if (diff > tol) {
589 integrals_test::reportSiCiFail(name: "SineIntegral", z: x, c: si, e: i[1], diff, tol);
590 }
591
592 const Real ci = Ci(x);
593 diff = std::fabs(x: ci - i[2]);
594 if (diff > tol) {
595 integrals_test::reportSiCiFail(name: "CosineIntegral", z: x, c: ci, e: i[2], diff, tol);
596 }
597
598 x = -i[0];
599 si = Si(x);
600 diff = std::fabs(x: si + i[1]);
601 if (diff > tol) {
602 integrals_test::reportSiCiFail(name: "SineIntegral", z: x, c: si, e: Real(-i[1]), diff, tol);
603 }
604 }
605}
606
607test_suite* IntegralTest::suite() {
608 auto* suite = BOOST_TEST_SUITE("Integration tests");
609 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testSegment));
610 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testTrapezoid));
611 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testMidPointTrapezoid));
612 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testSimpson));
613 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testGaussKronrodAdaptive));
614 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testGaussKronrodNonAdaptive));
615 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testGaussLobatto));
616 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testGaussLegendreIntegrator));
617 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testGaussChebyshevIntegrator));
618 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testGaussChebyshev2ndIntegrator));
619 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testTwoDimensionalIntegration));
620 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testFolinIntegration));
621 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testDiscreteIntegrals));
622 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testDiscreteIntegrator));
623 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testPiecewiseIntegral));
624 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testExponentialIntegral));
625 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testRealSiCiIntegrals));
626
627#ifdef QL_BOOST_HAS_TANH_SINH
628 suite->add(QUANTLIB_TEST_CASE(&IntegralTest::testTanhSinh));
629#endif
630
631 return suite;
632}
633
634

source code of quantlib/test-suite/integrals.cpp