13#ifndef OPTIMIST_ROOTFINDER_VARONA4_HH
14#define OPTIMIST_ROOTFINDER_VARONA4_HH
19 namespace RootFinder {
35 template <
typename Scalar>
76 return this->m_method;
84 this->m_method = t_method;
91 this->m_method = Method::ORDER_4;
98 this->m_method = Method::ORDER_8;
105 this->m_method = Method::ORDER_16;
112 this->m_method = Method::ORDER_32;
120 this->m_method = t_method;
134 template <
typename FunctionLambda,
typename FirstDerivativeLambda>
136 FirstDerivativeLambda &&first_derivative,
139#define CMD "Optimist::RootFinder::Varona::solve(...): "
150 bool damped, success;
151 Scalar residuals, step_norm;
152 Scalar x_old, x_new, function_old, function_new, step_old, step_new;
153 Scalar first_derivative_old;
162 CMD "function evaluation failed at the initial point.");
172 std::forward<FirstDerivativeLambda>(first_derivative),
174 first_derivative_old);
176 CMD "first derivative evaluation failed at iteration "
180 if (std::abs(first_derivative_old) < Varona::SQRT_EPSILON) {
182 "close-to-singular first derivative detected.");
183 first_derivative_old = (first_derivative_old > 0)
184 ? Varona::SQRT_EPSILON
185 : -Varona::SQRT_EPSILON;
188 this->
compute_step(std::forward<FunctionLambda>(function),
191 first_derivative_old,
195 residuals = std::abs(function_old);
196 step_norm = std::abs(step_old);
198 this->
info(residuals);
200 if (residuals < tolerance_residuals ||
201 step_norm < tolerance_step_norm) {
208 damped = this->
damp(std::forward<FunctionLambda>(function),
218 x_new = x_old + step_old;
224 CMD "function evaluation failed at iteration "
230 function_old = function_new;
255 template <
typename FunctionLambda>
259 Scalar first_derivative_old,
261#define CMD "Optimist::RootFinder::Varona::compute_step(...): "
264 Scalar function_y, function_z, function_w, function_h, step_tmp, t, s,
269 step_old = -function_old / first_derivative_old;
272 if (this->m_method == Method::ORDER_4 ||
273 this->m_method == Method::ORDER_8 ||
274 this->m_method == Method::ORDER_16 ||
275 this->m_method == Method::ORDER_32) {
282 "function evaluation failed during order 4 step.");
283 if (std::abs(function_y) < tolerance_residuals) {
286 t = function_y / function_old;
287 step_tmp = this->
Q(t) * (function_y / first_derivative_old);
288 if (std::isfinite(step_tmp)) {
289 step_old -= step_tmp;
296 if (this->m_method == Method::ORDER_8 ||
297 this->m_method == Method::ORDER_16 ||
298 this->m_method == Method::ORDER_32) {
305 "function evaluation failed during order 8 step.");
306 if (std::abs(function_z) < tolerance_residuals) {
309 s = function_z / function_y;
310 step_tmp = this->
W(t, s) * (function_z / first_derivative_old);
311 if (std::isfinite(step_tmp)) {
312 step_old -= step_tmp;
319 if (this->m_method == Method::ORDER_16 ||
320 this->m_method == Method::ORDER_32) {
327 "function evaluation failed during order 16 step.");
328 if (std::abs(function_w) < tolerance_residuals) {
331 u = function_w / function_z;
332 step_tmp = this->
H(t, s, u) * (function_w / first_derivative_old);
333 if (std::isfinite(step_tmp)) {
334 step_old -= step_tmp;
341 if (this->m_method == Method::ORDER_32) {
348 "function evaluation failed during order 32 step.");
349 if (std::abs(function_h) < tolerance_residuals) {
352 v = (function_h / function_w);
353 step_tmp = this->
J(t, s, u, v) * (function_h / first_derivative_old);
354 if (std::isfinite(step_tmp)) {
355 step_old -= step_tmp;
372 return 1.0 + 2.0 * t;
382 return t * t * (1.0 - 4.0 * t) + (4.0 * s + 2.0) * t + s + 1.0;
398 return ((8.0 * u + 6.0 * t2 + 4.0) * s -
399 (6.0 * t8 + 4.0 * (s + u + 1.0)) * t1 + 2.0 * t8 - 4.0 * t17 +
402 t1 * (t8 + s + u + 1.0) + (1.0 - 3.0 * t2 + t23) * s + u - t17 +
424 Scalar t76{
static_cast<Scalar>(-2.0 * t22 + u + 4.0 * v + 2.0) * u};
425 return (-1.0 + 2.0 * t) * (2.0 + 5.0 * t) * u * t * t2 +
426 (4.0 * t + 1.0) * u * s * t2 +
427 (u * t22 - 2.0 * u * v - u - v - 1.0) *
428 (4.0 * t17 + 3.0 * t + 1.0) * (-1.0 + t) -
430 (t22 * (t17 / 2.0 - 1.0 / 4.0) +
431 u * (t17 * t32 - 5.0 / 8.0 * t34 - 3.0 / 4.0 * t32 +
432 3.0 / 8.0 * t37 + 3.0 / 4.0 * t17 - t / 8.0 -
434 3.0 / 4.0 * t46 * (t + 1.0 / 2.0) * (t - 2.0 / 3.0)) *
437 (t22 * (-3.0 / 2.0 * t - 1.0 / 4.0) +
438 u * (t34 - t32 - 3.0 / 2.0 * t37 + t17 / 4.0 - t -
440 t46 * (t + 1.0 / 4.0)) *
442 (1.0 + v + t65 * t17 - 4.0 * t65 * t37 - 3.0 * t65 * t32 +
443 6.0 * t65 * t34 + t76 + 4.0 * (1.0 + v + t76) * t) *
#define OPTIMIST_WARNING(MSG)
Definition Optimist.hh:55
#define OPTIMIST_BASIC_CONSTANTS(Scalar)
Definition Optimist.hh:69
#define OPTIMIST_ASSERT_WARNING(COND, MSG)
Definition Optimist.hh:61
#define OPTIMIST_ASSERT(COND, MSG)
Definition Optimist.hh:47
typename TypeTrait< Scalar >::Scalar Scalar
Definition RootFinder.hh:53
RootFinder()
Definition RootFinder.hh:66
void enable_16th_order_method()
Definition Varona.hh:104
bool solve_impl(FunctionLambda &&function, FirstDerivativeLambda &&first_derivative, Scalar x_ini, Scalar &x_sol)
Definition Varona.hh:135
static Scalar W(Scalar t, Scalar s)
Definition Varona.hh:381
Method method() const
Definition Varona.hh:75
static Scalar J(Scalar t, Scalar s, Scalar u, Scalar v)
Definition Varona.hh:414
void enable_4th_order_method()
Definition Varona.hh:90
enum class Method :Integer { ORDER_4=41, ORDER_8=8, ORDER_16=16, ORDER_32=32 } Method
Definition Varona.hh:47
void enable_8th_order_method()
Definition Varona.hh:97
static Scalar H(Scalar t, Scalar s, Scalar u)
Definition Varona.hh:392
void enable_32th_order_method()
Definition Varona.hh:111
Method m_method
Definition Varona.hh:55
constexpr std::string name_impl() const
Definition Varona.hh:67
static constexpr bool RequiresFirstDerivative
Definition Varona.hh:39
Varona()
Definition Varona.hh:61
void set_method(Method t_method)
Definition Varona.hh:119
static constexpr bool RequiresSecondDerivative
Definition Varona.hh:40
static Scalar Q(Scalar t)
Definition Varona.hh:371
void compute_step(FunctionLambda &&function, Scalar x_old, Scalar function_old, Scalar first_derivative_old, Scalar &step_old)
Definition Varona.hh:256
static constexpr bool RequiresFunction
Definition Varona.hh:38
void method(Method t_method)
Definition Varona.hh:83
bool damp(FunctionLambda &&function, const Scalar &x_old, const Scalar &function_old, const Scalar &step_old, Scalar &x_new, Scalar &function_new, Scalar &step_new)
Definition SolverBase.hh:1109
void info(Scalar residuals, const std::string ¬es="-")
Definition SolverBase.hh:1230
bool evaluate_function(FunctionLambda &&function, const Scalar &x, Scalar &out)
Definition SolverBase.hh:1040
bool evaluate_first_derivative(FirstDerivativeLambda &&function, const Scalar &x, FirstDerivative &out)
Definition SolverBase.hh:1061
bool m_damped
Definition SolverBase.hh:131
Integer m_max_iterations
Definition SolverBase.hh:121
Scalar m_tolerance
Definition SolverBase.hh:128
void header()
Definition SolverBase.hh:1168
void reset_counters()
Definition SolverBase.hh:1022
Integer m_iterations
Definition SolverBase.hh:120
bool m_verbose
Definition SolverBase.hh:130
bool m_converged
Definition SolverBase.hh:136
void bottom()
Definition SolverBase.hh:1204
Namespace for the Optimist library.
Definition Optimist.hh:89
OPTIMIST_DEFAULT_INTEGER_TYPE Integer
The Integer type as used for the API.
Definition Optimist.hh:97