13#ifndef OPTIMIST_ROOTFINDER_CHEBYSHEV_HH
14#define OPTIMIST_ROOTFINDER_CHEBYSHEV_HH
19 namespace RootFinder {
37 template <
typename Scalar>
72 template <
typename FunctionLambda,
73 typename FirstDerivativeLambda,
74 typename SecondDerivativeLambda>
76 FirstDerivativeLambda &&first_derivative,
77 SecondDerivativeLambda &&second_derivative,
80#define CMD "Optimist::RootFinder::Chebyshev::solve(...): "
92 Scalar residuals, step_norm;
93 Scalar x_old, x_new, function_old, function_new, step_old, step_new;
94 Scalar first_derivative_old, second_derivative_old;
103 CMD "function evaluation failed at iteration "
114 std::forward<FirstDerivativeLambda>(first_derivative),
116 first_derivative_old);
118 CMD "first derivative evaluation failed at iteration "
121 std::forward<SecondDerivativeLambda>(second_derivative),
123 second_derivative_old);
126 CMD "second derivative evaluation failed at iteration "
130 if (std::abs(first_derivative_old) < Chebyshev::SQRT_EPSILON) {
132 "close-to-singular first derivative detected.");
133 first_derivative_old = (first_derivative_old > 0)
134 ? Chebyshev::SQRT_EPSILON
135 : -Chebyshev::SQRT_EPSILON;
137 if (std::abs(second_derivative_old) < Chebyshev::SQRT_EPSILON) {
139 "close-to-singular second derivative detected.");
140 second_derivative_old = (second_derivative_old > 0)
141 ? Chebyshev::SQRT_EPSILON
142 : -Chebyshev::SQRT_EPSILON;
144 step_old = -(function_old / first_derivative_old) *
145 (1.0 + (function_old * second_derivative_old) /
146 (first_derivative_old * first_derivative_old));
148 std::isfinite(step_old),
152 residuals = std::abs(function_old);
153 step_norm = std::abs(step_old);
155 this->
info(residuals);
157 if (residuals < tolerance_residuals ||
158 step_norm < tolerance_step_norm) {
165 damped = this->
damp(std::forward<FunctionLambda>(function),
175 x_new = x_old + step_old;
181 CMD "function evaluation failed at iteration "
187 function_old = function_new;
#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
static constexpr bool RequiresFunction
Definition Chebyshev.hh:40
static constexpr bool RequiresSecondDerivative
Definition Chebyshev.hh:42
Chebyshev()
Definition Chebyshev.hh:49
constexpr std::string name_impl() const
Definition Chebyshev.hh:55
bool solve_impl(FunctionLambda &&function, FirstDerivativeLambda &&first_derivative, SecondDerivativeLambda &&second_derivative, Scalar x_ini, Scalar &x_sol)
Definition Chebyshev.hh:75
static constexpr bool RequiresFirstDerivative
Definition Chebyshev.hh:41
typename TypeTrait< Scalar >::Scalar Scalar
Definition RootFinder.hh:53
RootFinder()
Definition RootFinder.hh:66
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
bool evaluate_second_derivative(SecondDerivativeLambda &&function, const Scalar &x, SecondDerivative &out)
Definition SolverBase.hh:1082
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