13#ifndef OPTIMIST_ROOTFINDER_ALGO748_HH
14#define OPTIMIST_ROOTFINDER_ALGO748_HH
41 template <
typename Real>
72 return a != b && a != c && a != d && b != c && b != d && c != d;
86 template <
typename FunctionLambda>
89 #define CMD "Optimist::ScalarRootfinder::Algo748::bracketing(...): "
93 Real hba{(this->
m_b - this->
m_a)/2.0};
102 CMD "function evaluation failed during bracketing.");
103 if (this->
m_fc == 0) {
105 this->
m_d = 0.0; this->
m_fd = 0.0;
132 Real d_1{this->
m_b - this->
m_a};
133 Real d_2{this->
m_d - this->
m_a};
134 Real d_3{this->
m_e - this->
m_a};
136 Real dd_0{d_1/(this->
m_fb - this->
m_fa)};
137 Real dd_1{(d_1-d_2)/(this->
m_fb - this->
m_fd)};
138 Real dd_2{(d_2-d_3)/(this->
m_fd - this->
m_fe)};
140 Real ddd_0 {(dd_0 - dd_1)/(this->
m_fa - this->
m_fd)};
141 Real ddd_1 {(dd_1 - dd_2)/(this->
m_fb - this->
m_fe)};
143 Real dddd_0{(ddd_0-ddd_1)/(this->
m_fa-this->
m_fe)};
146 Real root{this->
m_a - this->
m_fa*(dd_0 - this->
m_fb*(ddd_0 - this->
m_fd*dddd_0))};
149 root = (this->
m_a + this->
m_b)/2.0;
164 Real a_0{this->
m_fa};
169 if (a_2 == 0) {
return this->
m_a - a_0/a_1;}
172 Real c{a_2*this->
m_fa > 0.0 ? this->
m_a : this->
m_b};
175 bool is_nonzero{
true};
176 Real pc{0.0}, pdc{0.0};
177 for (
Integer i{0}; i < n && is_nonzero ; ++i ) {
178 pc = a_0 + (a_1 + a_2*(c - this->
m_b))*(c - this->
m_a);
179 pdc = a_1 + a_2*((2.0 * c) - (this->
m_a + this->
m_b));
180 is_nonzero = pdc != 0;
181 if (is_nonzero) {c -= pc/pdc;}
184 if (is_nonzero) {
return c;}
185 else {
return this->
m_a - a_0/a_1;}
202 template <
typename FunctionLambda>
205 #define CMD "Optimist::ScalarRootfinder::Algo748::find_root_impl(...): "
216 this->
m_e = QUIET_NAN;
217 this->
m_fe = QUIET_NAN;
220 while (!(std::isfinite(this->
m_fa) && std::isfinite(this->
m_fb))) {
225 CMD "function evaluation failed at iteration " << this->
m_iterations <<
".");
237 Real abs_fa{std::abs(this->
m_fa)};
238 Real abs_fb{std::abs(this->
m_fb)};
240 abs_fa < tolerance_function ||abs_fb < tolerance_function;
246 Real b_a{this->
m_b - this->
m_a};
247 Real r{b_a/(this->
m_fb - this->
m_fa)};
248 this->
m_c = std::abs(this->
m_fb) < std::abs(this->
m_fa) ?
251 if (this->
m_c < (a_min = this->
m_a + delta)) {this->
m_c = a_min;}
252 else if (this->
m_c > (b_max = this->
m_b - delta)) {this->
m_c = b_max;}
263 Real a0_b0{this->
m_b - this->
m_a};
267 Real abs_fa {std::abs(this->
m_fa)};
268 Real abs_fb {std::abs(this->
m_fb)};
269 this->
m_converged = abs_fa < tolerance_function || abs_fb < tolerance_function;
274 bool do_newton_quadratic{
false};
275 if (!std::isfinite(this->
m_fe)) {
276 do_newton_quadratic =
true;
278 do_newton_quadratic =
true;
281 do_newton_quadratic = (this->
m_c-this->
m_a)*(this->
m_c-this->
m_b) >= 0.0;
291 return std::abs(this->
m_fa) < std::abs(this->
m_fb) ? this->
m_a : this->
m_b;
294 do_newton_quadratic =
true;
297 do_newton_quadratic = (this->
m_c - this->
m_a)*(this->
m_c - this->
m_b) >= 0.0;
304 Real abs_fa{std::abs(this->
m_fa)};
305 Real abs_fb{std::abs(this->
m_fb)};
313 if (abs_fa < abs_fb) {u = this->
m_a; fu = this->
m_fa;}
314 else {u = this->
m_b; fu = this->
m_fb;}
315 Real hba{(this->
m_b - this->
m_a)/2.0};
316 this->
m_c = u - 4.0*(fu/(this->
m_fb - this->
m_fa))*hba;
317 if (std::abs(this->
m_c - u) > hba) {this->
m_c = this->
m_a + hba;}
323 return std::abs(this->
m_fa) < std::abs(this->
m_fb) ? this->
m_a : this->
m_b;
327 if ((this->
m_b-this->
m_a) < this->
m_mu*a0_b0) {
continue;}
334 Real b_a{this->
m_b-this->
m_a};
335 this->
m_c = this->
m_a + b_a/2.0;
340 return std::abs(this->
m_fa) < std::abs(this->
m_fb) ? this->
m_a : this->
m_b;
#define OPTIMIST_ASSERT_WARNING(COND, MSG)
Definition Optimist.hh:61
#define OPTIMIST_BASIC_CONSTANTS(Real)
Definition Optimist.hh:71
Real cubic_interpolation()
Definition Algo748.hh:129
static constexpr bool requires_second_derivative
Definition Algo748.hh:47
Real find_root_impl(FunctionLambda &&function)
Definition Algo748.hh:203
Algo748()
Definition Algo748.hh:54
std::string name_impl() const
Definition Algo748.hh:60
bool all_different(Real a, Real b, Real c, Real d) const
Definition Algo748.hh:71
static constexpr bool requires_function
Definition Algo748.hh:45
static constexpr bool requires_first_derivative
Definition Algo748.hh:46
Real newton_quadratic(Integer n)
Definition Algo748.hh:161
bool bracketing(FunctionLambda &&function)
Definition Algo748.hh:87
Real m_b
Definition Bracketing.hh:51
Real m_e
Definition Bracketing.hh:54
Real m_fd
Definition Bracketing.hh:53
Real m_d
Definition Bracketing.hh:53
Real m_a
Definition Bracketing.hh:50
Bracketing()
Definition Bracketing.hh:60
Real m_mu
Definition Bracketing.hh:47
Real m_fe
Definition Bracketing.hh:54
Real m_interval_shink
Definition Bracketing.hh:48
Real m_fa
Definition Bracketing.hh:50
Real m_tolerance_bracketing
Definition Bracketing.hh:46
Real m_fc
Definition Bracketing.hh:52
Real m_fb
Definition Bracketing.hh:51
Real m_c
Definition Bracketing.hh:52
Integer m_iterations
Definition SolverBase.hh:84
Integer m_max_iterations
Definition SolverBase.hh:85
Real tolerance() const
Definition SolverBase.hh:392
bool m_converged
Definition SolverBase.hh:98
bool evaluate_function(FunctionLambda &&function, InputType const &x, OutputType &out)
Definition SolverBase.hh:768
Real m_tolerance
Definition SolverBase.hh:91
Namespace for the Optimist library.
Definition Optimist.hh:88
OPTIMIST_DEFAULT_INTEGER_TYPE Integer
The Integer type as used for the API.
Definition Optimist.hh:96