Optimist  0.0.0
A C++ library for optimization
Loading...
Searching...
No Matches
Chandrupatla.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2 * Copyright (c) 2025, Davide Stocco, Mattia Piazza and Enrico Bertolazzi. *
3 * *
4 * The Optimist project is distributed under the BSD 2-Clause License. *
5 * *
6 * Davide Stocco Mattia Piazza Enrico Bertolazzi *
7 * University of Trento University of Trento University of Trento *
8 * davide.stocco@unitn.it mattia.piazza@unitn.it enrico.bertolazzi@unitn.it *
9\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
10
11#pragma once
12
13#ifndef OPTIMIST_SCALAR_ROOT_FINDER_CHANDRUPATLA_HH
14#define OPTIMIST_SCALAR_ROOT_FINDER_CHANDRUPATLA_HH
15
17
18namespace Optimist
19{
20 namespace ScalarRootFinder
21 {
22
23 /*\
24 | ____ _ _ _ _
25 | / ___| |__ __ _ _ __ __| |_ __ _ _ _ __ __ _| |_| | __ _
26 | | | | '_ \ / _` | '_ \ / _` | '__| | | | '_ \ / _` | __| |/ _` |
27 | | |___| | | | (_| | | | | (_| | | | |_| | |_) | (_| | |_| | (_| |
28 | \____|_| |_|\__,_|_| |_|\__,_|_| \__,_| .__/ \__,_|\__|_|\__,_|
29 | |_|
30 \*/
31
41 template <typename Real>
42 class Chandrupatla : public Bracketing<Real, Chandrupatla<Real>>
43 {
44 public:
45 static constexpr bool requires_function{true};
46 static constexpr bool requires_first_derivative{false};
47 static constexpr bool requires_second_derivative{false};
48
50
51 // Function types
55
60
65 std::string name_impl() const {return "Chandrupatla";}
66
74
75 #define CMD "Optimist::ScalarRootfinder::Chandrupatla::find_root_impl(...): "
76
77 Real tolerance_step{this->m_tolerance_bracketing};
78 Real tolerance_function{this->m_tolerance_bracketing};
79
80 // Check for trivial solution
81 this->m_converged = this->m_fa == 0; if (this->m_converged) {return this->m_a;}
82 this->m_converged = this->m_fb == 0; if (this->m_converged) {return this->m_b;}
83
84 // Initialize to dumb values
85 this->m_e = QUIET_NAN;
86 this->m_fe = QUIET_NAN;
87
88 // While f(left) or f(right) are infinite perform bisection
89 while (!(std::isfinite(this->m_fa) && std::isfinite(this->m_fb))) {
90 ++this->m_iterations;
91 this->m_c = (this->m_a + this->m_b)/2.0;
92 this->evaluate_function(function, this->m_c, this->m_fc);
93 this->m_converged = this->m_fc == 0;
94 if (this->m_converged) {return this->m_c;}
95 if (this->m_fa*this->m_fc < 0.0) {
96 // -> [a, c]
97 this->m_b = this->m_c; this->m_fb = this->m_fc;
98 } else {
99 // -> [c, b]
100 this->m_a = this->m_c; this->m_fa = this->m_fc;
101 }
102
103 // Check for convergence
104 Real abs_fa{std::abs(this->m_fa)};
105 Real abs_fb{std::abs(this->m_fb)};
106 this->m_converged = (this->m_b - this->m_a) < tolerance_step ||
107 abs_fa < tolerance_function ||abs_fb < tolerance_function;
108 if (this->m_converged) {return abs_fb < abs_fa ? this->m_b : this->m_a;}
109 }
110
111 Real t{0.5};
112
114
115 Real direction{this->m_b - this->m_a};
116 Real tolerance{tolerance_step/(2.0*std::abs(direction))};
117 this->m_converged = tolerance >= 0.5;
118 if (this->m_converged) {break;}
119
120 Real abs_fa{std::abs(this->m_fa)};
121 Real abs_fb{std::abs(this->m_fb)};
122 this->m_converged = abs_fa < tolerance_function || abs_fb < tolerance_function;
123 if (this->m_converged) {break;}
124
125 if (t < tolerance) {t = tolerance;}
126 else if (t > 1.0 - tolerance) {t = 1.0 - tolerance;}
127
128 Real c{this->m_a + t * direction};
129 Real fc; this->evaluate_function(function, c, fc);
130 if (this->m_verbose) {this->info(fc);}
131
132 OPTIMIST_ASSERT(std::isfinite(fc), CMD "function is not finite.");
133
134 this->m_converged = fc == 0;
135 if (this->m_converged) {
136 this->m_a = this->m_b = c; this->m_fa = this->m_fb = 0;
137 break;
138 }
139
140 // Arrange 2-1-3: 2-1 interval, 1 middle, 3 discarded point
141 Real d, fd;
142 if ((0.0 < fc) == (0.0 < this->m_fa)) {
143 // a -> d --> [d,a,b] = [a,c,b]
144 d = this->m_a; fd = this->m_fa;
145 } else {
146 // b -> d, a -> b --> [b,a,d] = [a,c,b]
147 d = this->m_b; fd = this->m_fb;
148 this->m_b = this->m_a; this->m_fb = this->m_fa;
149 }
150 // c => a
151 this->m_a = c; this->m_fa = fc;
152
153 // If inverse quadratic interpolation holds use it
154 Real ba{this->m_b - this->m_a};
155 Real fba{this->m_fb - this->m_fa};
156 Real bd{this->m_b - d};
157 Real fbd{this->m_fb - fd};
158
159 Real xi{ba/bd};
160 Real ph{fba/fbd};
161 Real fl{1.0 - std::sqrt(1.0 - xi)};
162 Real fh{std::sqrt(xi)};
163
164 if (fl < ph && ph < fh) {
165 Real da{d - this->m_a};
166 Real fda{fd - this->m_fa};
167 t = (this->m_fa/fba) * (fd/fbd) - (this->m_fa/fda) * (this->m_fb/fbd) * (da/ba);
168 } else {
169 t = 0.5;
170 }
171 }
172 if (this->m_a > this->m_b) {std::swap(this->m_a, this->m_b); std::swap(this->m_fa, this->m_fb);}
173 return std::abs(this->m_fa) < std::abs(this->m_fb) ? this->m_a : this->m_b;;
174
175 #undef CMD
176 }
177
178 }; // class Chandrupatla
179
180 } // namespace ScalarRootFinder
181
182} // namespace Optimist
183
184#endif // OPTIMIST_SCALAR_ROOT_FINDER_CHANDRUPATLA_HH
#define OPTIMIST_BASIC_CONSTANTS(Real)
Definition Optimist.hh:70
#define OPTIMIST_ASSERT(COND, MSG)
Definition Optimist.hh:43
#define CMD
std::string name_impl() const
Definition Chandrupatla.hh:65
Chandrupatla()
Definition Chandrupatla.hh:59
static constexpr bool requires_second_derivative
Definition Chandrupatla.hh:47
static constexpr bool requires_function
Definition Chandrupatla.hh:45
Real find_root_impl(FunctionWrapper function)
Definition Chandrupatla.hh:73
static constexpr bool requires_first_derivative
Definition Chandrupatla.hh:46
typename ScalarRootFinder< Real, Chandrupatla >::SecondDerivativeWrapper SecondDerivativeWrapper
Definition Chandrupatla.hh:54
typename ScalarRootFinder< Real, Chandrupatla >::FunctionWrapper FunctionWrapper
Definition Chandrupatla.hh:52
typename ScalarRootFinder< Real, Chandrupatla >::FirstDerivativeWrapper FirstDerivativeWrapper
Definition Chandrupatla.hh:53
Class container for the scalar scalar root-finder.
Definition ScalarRootFinder.hh:46
Real tolerance() const
Definition Solver.hh:377
void evaluate_function(FunctionWrapper function, const InputType &x, OutputType &out)
Definition Solver.hh:710
void info(Real residuals, std::string const &notes="-")
Definition Solver.hh:853
Integer m_max_iterations
Definition Solver.hh:86
Namespace for the Optimist library.
Definition Optimist.hh:87