Coverage Report

Created: 2025-08-11 06:28

/src/quantlib/ql/experimental/math/piecewiseintegral.hpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2015 Peter Caspers
5
6
 This file is part of QuantLib, a free-software/open-source library
7
 for financial quantitative analysts and developers - http://quantlib.org/
8
9
 QuantLib is free software: you can redistribute it and/or modify it
10
 under the terms of the QuantLib license.  You should have received a
11
 copy of the license along with this program; if not, please email
12
 <quantlib-dev@lists.sf.net>. The license is also available online at
13
 <http://quantlib.org/license.shtml>.
14
15
 This program is distributed in the hope that it will be useful, but WITHOUT
16
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
 FOR A PARTICULAR PURPOSE.  See the license for more details.
18
*/
19
20
/*! \file piecewiseintegral.hpp
21
    \brief Integral of a piecewise well behaved function using
22
           a custom integrator for the pieces. It can be forced
23
           that the function is integrated only over intervals
24
           strictly not containing the critical points
25
*/
26
27
#ifndef quantlib_piecewise_integral_hpp
28
#define quantlib_piecewise_integral_hpp
29
30
#include <ql/math/integrals/integral.hpp>
31
#include <ql/math/comparison.hpp>
32
#include <ql/shared_ptr.hpp>
33
#include <algorithm>
34
#include <vector>
35
36
namespace QuantLib {
37
38
class PiecewiseIntegral : public Integrator {
39
  public:
40
    PiecewiseIntegral(ext::shared_ptr<Integrator> integrator,
41
                      std::vector<Real> criticalPoints,
42
                      bool avoidCriticalPoints = true);
43
44
  protected:
45
    Real integrate(const std::function<Real(Real)>& f, Real a, Real b) const override;
46
47
  private:
48
    Real integrate_h(const std::function<Real(Real)> &f, Real a,
49
                     Real b) const;
50
    const ext::shared_ptr<Integrator> integrator_;
51
    std::vector<Real> criticalPoints_;
52
    const Real eps_;
53
};
54
55
// inline
56
57
inline Real PiecewiseIntegral::integrate_h(const std::function<Real(Real)> &f,
58
0
                                           Real a, Real b) const {
59
60
0
    if (!close_enough(a, b))
61
0
        return (*integrator_)(f, a, b);
62
0
    else
63
0
        return 0.0;
64
0
}
65
66
inline Real PiecewiseIntegral::integrate(const std::function<Real(Real)> &f,
67
0
                                         Real a, Real b) const {
68
69
0
    auto a0 = std::lower_bound(criticalPoints_.begin(), criticalPoints_.end(), a);
70
71
0
    auto b0 = std::lower_bound(criticalPoints_.begin(), criticalPoints_.end(), b);
72
73
0
    if (a0 == criticalPoints_.end()) {
74
0
        Real tmp = 1.0;
75
0
        if (!criticalPoints_.empty()) {
76
0
            if (close_enough(a, criticalPoints_.back())) {
77
0
                tmp = eps_;
78
0
            }
79
0
        }
80
0
        return integrate_h(f, a * tmp, b);
81
0
    }
82
83
0
    Real res = 0.0;
84
85
0
    if (!close_enough(a, *a0)) {
86
0
        res += integrate_h(f, a, std::min(*a0 / eps_, b));
87
0
    }
88
89
0
    if (b0 == criticalPoints_.end()) {
90
0
        --b0;
91
0
        if (!close_enough(*b0, b)) {
92
0
            res += integrate_h(f, (*b0) * eps_, b);
93
0
        }
94
0
    }
95
96
0
    for (auto x = a0; x < b0; ++x) {
97
0
        res += integrate_h(f, (*x) * eps_, std::min(*(x + 1) / eps_, b));
98
0
    }
99
100
0
    return res;
101
0
}
102
103
} // namespace QuantLib
104
105
#endif