Optimist  0.0.0
A C++ library for optimization
Loading...
Searching...
No Matches
Chebyshev.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_CHEBYSHEV_HH
14#define OPTIMIST_SCALAR_ROOT_FINDER_CHEBYSHEV_HH
15
17
18namespace Optimist
19{
20 namespace ScalarRootFinder
21 {
22
23 /*\
24 | ____ _ _ _
25 | / ___| |__ ___| |__ _ _ ___| |__ _____ __
26 | | | | '_ \ / _ \ '_ \| | | / __| '_ \ / _ \ \ / /
27 | | |___| | | | __/ |_) | |_| \__ \ | | | __/\ V /
28 | \____|_| |_|\___|_.__/ \__, |___/_| |_|\___| \_/
29 | |___/
30 \*/
31
39 template <typename Real>
40 class Chebyshev : public ScalarRootFinder<Real, Chebyshev<Real>>
41 {
42 public:
43 static constexpr bool requires_function{true};
44 static constexpr bool requires_first_derivative{true};
45 static constexpr bool requires_second_derivative{true};
46
48
49 // Function types
53
58
63 std::string name_impl() const {return "Chebyshev";}
64
74 bool solve_impl(FunctionWrapper function, FirstDerivativeWrapper first_derivative,
75 SecondDerivativeWrapper second_derivative, Real x_ini, Real & x_sol)
76 {
77 #define CMD "Optimist::ScalarRootFinder::Chebyshev::solve(...): "
78
79 // Setup internal variables
80 this->reset();
81
82 // Print header
83 if (this->m_verbose) {this->header();}
84
85 // Initialize variables
86 bool damped;
87 Real residuals, step_norm;
88 Real x_old, x_new, function_old, function_new, step_old, step_new;
89 Real first_derivative_old, second_derivative_old;
90
91 // Set initial iteration
92 x_old = x_ini;
93 this->evaluate_function(function, x_old, function_old);
94
95 // Algorithm iterations
96 Real tolerance_residuals{this->m_tolerance};
97 Real tolerance_step_norm{this->m_tolerance * this->m_tolerance};
98 for (this->m_iterations = static_cast<Integer>(1); this->m_iterations < this->m_max_iterations; ++this->m_iterations)
99 {
100 // Store trace
101 this->store_trace(x_old);
102
103 // Evaluate derivatives
104 this->evaluate_first_derivative(first_derivative, x_old, first_derivative_old);
105 this->evaluate_second_derivative(second_derivative, x_old, second_derivative_old);
106
107 // Calculate step
108 if (std::abs(first_derivative_old) < EPSILON_LOW) {
109 OPTIMIST_WARNING( CMD "singular first derivative detected.");
110 first_derivative_old = (first_derivative_old > 0.0) ? EPSILON_LOW : -EPSILON_LOW;
111 }
112 if (std::abs(second_derivative_old) < EPSILON_LOW) {
113 OPTIMIST_WARNING( CMD "singular second derivative detected.");
114 second_derivative_old = (second_derivative_old > 0.0) ? EPSILON_LOW : -EPSILON_LOW;
115 }
116 step_old = -(function_old / first_derivative_old) * (1.0 + (function_old * second_derivative_old) /
117 (first_derivative_old * first_derivative_old));
118 OPTIMIST_ASSERT(std::isfinite(step_old), CMD "step " << this->m_iterations << " is not finite.");
119
120 // Check convergence
121 residuals = std::abs(function_old);
122 step_norm = std::abs(step_old);
123 if (this->m_verbose) {this->info(residuals);}
124 if (residuals < tolerance_residuals || step_norm < tolerance_step_norm) {
125 this->m_converged = true;
126 break;
127 }
128
129 if (this->m_damped) {
130 // Relax the iteration process
131 damped = this->damp(function, x_old, function_old, step_old, x_new, function_new, step_new);
132 OPTIMIST_ASSERT_WARNING(damped, CMD "damping failed.");
133 } else {
134 // Update point
135 x_new = x_old + step_old;
136 this->evaluate_function(function, x_new, function_new);
137 }
138
139 // Update internal variables
140 x_old = x_new;
141 function_old = function_new;
142 step_old = step_new;
143 }
144
145 // Print bottom
146 if (this->m_verbose) {this->bottom();}
147
148 // Convergence data
149 x_sol = x_old;
150 return this->m_converged;
151
152 #undef CMD
153 }
154
155 }; // class Chebyshev
156
157 } // namespace ScalarRootFinder
158
159} // namespace Optimist
160
161#endif // OPTIMIST_SCALAR_ROOT_FINDER_CHEBYSHEV_HH
#define OPTIMIST_WARNING(MSG)
Definition Optimist.hh:52
#define OPTIMIST_ASSERT_WARNING(COND, MSG)
Definition Optimist.hh:60
#define OPTIMIST_BASIC_CONSTANTS(Real)
Definition Optimist.hh:70
#define OPTIMIST_ASSERT(COND, MSG)
Definition Optimist.hh:43
#define CMD
typename ScalarRootFinder< Real, Chebyshev< Real > >::FunctionWrapper FunctionWrapper
Definition Chebyshev.hh:50
typename ScalarRootFinder< Real, Chebyshev< Real > >::FirstDerivativeWrapper FirstDerivativeWrapper
Definition Chebyshev.hh:51
static constexpr bool requires_first_derivative
Definition Chebyshev.hh:44
typename ScalarRootFinder< Real, Chebyshev< Real > >::SecondDerivativeWrapper SecondDerivativeWrapper
Definition Chebyshev.hh:52
static constexpr bool requires_second_derivative
Definition Chebyshev.hh:45
bool solve_impl(FunctionWrapper function, FirstDerivativeWrapper first_derivative, SecondDerivativeWrapper second_derivative, Real x_ini, Real &x_sol)
Definition Chebyshev.hh:74
std::string name_impl() const
Definition Chebyshev.hh:63
Chebyshev()
Definition Chebyshev.hh:57
static constexpr bool requires_function
Definition Chebyshev.hh:43
void store_trace(const InputType &x)
Definition Solver.hh:750
bool damp(FunctionWrapper function, InputType const &x_old, InputType const &function_old, InputType const &step_old, InputType &x_new, InputType &function_new, InputType &step_new)
Definition Solver.hh:763
void evaluate_first_derivative(FirstDerivativeWrapper function, const InputType &x, FirstDerivativeType &out)
Definition Solver.hh:724
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_iterations
Definition Solver.hh:85
Integer m_max_iterations
Definition Solver.hh:86
void evaluate_second_derivative(SecondDerivativeWrapper function, const InputType &x, SecondDerivativeType &out)
Definition Solver.hh:738
Namespace for the Optimist library.
Definition Optimist.hh:87
OPTIMIST_DEFAULT_INTEGER_TYPE Integer
The Integer type as used for the API.
Definition Optimist.hh:95