Coverage Report

Created: 2026-02-03 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/math/integrals/trapezoidintegral.hpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2003 Roman Gitlin
5
 Copyright (C) 2003 StatPro Italia srl
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
 <https://www.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
/*! \file trapezoidintegral.hpp
22
    \brief integral of a one-dimensional function using the trapezoid formula
23
*/
24
25
#ifndef quantlib_trapezoid_integral_hpp
26
#define quantlib_trapezoid_integral_hpp
27
28
#include <ql/math/integrals/integral.hpp>
29
#include <ql/utilities/null.hpp>
30
#include <ql/errors.hpp>
31
32
namespace QuantLib {
33
34
    //! Integral of a one-dimensional function
35
    /*! Given a target accuracy \f$ \epsilon \f$, the integral of
36
        a function \f$ f \f$ between \f$ a \f$ and \f$ b \f$ is
37
        calculated by means of the trapezoid formula
38
        \f[
39
        \int_{a}^{b} f \mathrm{d}x =
40
        \frac{1}{2} f(x_{0}) + f(x_{1}) + f(x_{2}) + \dots
41
        + f(x_{N-1}) + \frac{1}{2} f(x_{N})
42
        \f]
43
        where \f$ x_0 = a \f$, \f$ x_N = b \f$, and
44
        \f$ x_i = a+i \Delta x \f$ with
45
        \f$ \Delta x = (b-a)/N \f$. The number \f$ N \f$ of intervals
46
        is repeatedly increased until the target accuracy is reached.
47
48
        \test the correctness of the result is tested by checking it
49
              against known good values.
50
    */
51
    template <class IntegrationPolicy>
52
    class TrapezoidIntegral : public Integrator {
53
      public:
54
        TrapezoidIntegral(Real accuracy,
55
                          Size maxIterations)
56
0
        : Integrator(accuracy, maxIterations){}
57
58
      protected:
59
0
        Real integrate(const std::function<Real(Real)>& f, Real a, Real b) const override {
60
61
            // start from the coarsest trapezoid...
62
0
            Size N = 1;
63
0
            Real I = (f(a)+f(b))*(b-a)/2.0, newI;
64
0
            increaseNumberOfEvaluations(2);
65
            // ...and refine it
66
0
            Size i = 1;
67
0
            do {
68
0
                newI = IntegrationPolicy::integrate(f,a,b,I,N);
69
0
                increaseNumberOfEvaluations(N*(IntegrationPolicy::nbEvalutions()-1));
70
0
                N *= IntegrationPolicy::nbEvalutions();
71
                // good enough? Also, don't run away immediately
72
0
                if (std::fabs(I-newI) <= absoluteAccuracy() && i > 5)
73
                    // ok, exit
74
0
                    return newI;
75
                // oh well. Another step.
76
0
                I = newI;
77
0
                i++;
78
0
            } while (i < maxEvaluations());
79
0
            QL_FAIL("max number of iterations reached");
80
0
        }
81
    };
82
83
    // Integration policies
84
    struct Default {
85
        static Real integrate(const std::function<Real (Real)>& f, 
86
                                     Real a, 
87
                                     Real b, 
88
                                     Real I, 
89
                                     Size N)
90
0
        {
91
0
            Real sum = 0.0;
92
0
            Real dx = (b-a)/N;
93
0
            Real x = a + dx/2.0;
94
0
            for (Size i=0; i<N; x += dx, ++i)
95
0
                sum += f(x);
96
0
            return (I + dx*sum)/2.0;
97
0
        }
98
0
        static Size nbEvalutions(){ return 2;}
99
    };
100
101
    struct MidPoint {
102
        static Real integrate(const std::function<Real (Real)>& f,
103
                                     Real a, 
104
                                     Real b, 
105
                                     Real I, 
106
                                     Size N)
107
0
        {
108
0
            Real sum = 0.0;
109
0
            Real dx = (b-a)/N;
110
0
            Real x = a + dx/6.0;
111
0
            Real D = 2.0*dx/3.0;
112
0
            for (Size i=0; i<N; x += dx, ++i)
113
0
                sum += f(x) + f(x+D);
114
0
            return (I + dx*sum)/3.0;
115
0
        }
116
0
        static Size nbEvalutions(){ return 3;}
117
    };
118
119
}
120
121
#endif