Coverage Report

Created: 2026-01-25 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/math/solvers1d/halley.hpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2024 Klaus Spanderen
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
 <https://www.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 halley.hpp
21
    \brief Halley 1-D solver
22
*/
23
24
#ifndef quantlib_solver1d_halley_hpp
25
#define quantlib_solver1d_halley_hpp
26
27
#include <ql/math/solvers1d/newtonsafe.hpp>
28
29
namespace QuantLib {
30
31
    //! %Halley 1-D solver
32
    /*! \note This solver requires that the passed function object
33
              implement a method <tt>Real derivative(Real)</tt>
34
              and <tt> Real secondDerivative(Real></tt>
35
36
        \test the correctness of the returned values is tested by
37
              checking them against known good results.
38
39
        \ingroup solvers
40
    */
41
    class Halley : public Solver1D<Halley> {
42
      public:
43
        template <class F>
44
        Real solveImpl(const F& f,
45
0
                       Real xAccuracy) const {
46
47
0
            while (++evaluationNumber_ <= maxEvaluations_) {
48
0
                const Real fx = f(root_);
49
0
                const Real fPrime = f.derivative(root_);
50
0
                const Real lf = fx*f.secondDerivative(root_)/(fPrime*fPrime);
51
0
                const Real step = 1.0/(1.0 - 0.5*lf)*fx/fPrime;
52
0
                root_ -= step;
53
54
                // jumped out of brackets, switch to NewtonSafe
55
0
                if ((xMin_-root_)*(root_-xMax_) < 0.0) {
56
0
                    NewtonSafe s;
57
0
                    s.setMaxEvaluations(maxEvaluations_-evaluationNumber_);
58
0
                    return s.solve(f, xAccuracy, root_+step, xMin_, xMax_);
59
0
                }
60
61
0
                if (std::abs(step) < xAccuracy) {
62
0
                    f(root_);
63
0
                    ++evaluationNumber_;
64
0
                    return root_;
65
0
                }
66
67
0
            }
68
69
0
            QL_FAIL("maximum number of function evaluations ("
70
0
                    << maxEvaluations_ << ") exceeded");
71
0
        }
72
    };
73
}
74
75
#endif