Optimist  0.0.0
A C++ library for optimization
Loading...
Searching...
No Matches
Newton.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_ROOTFINDER_NEWTON_HH
14#define OPTIMIST_ROOTFINDER_NEWTON_HH
15
17
18namespace Optimist
19{
20 namespace RootFinder
21 {
22
23 /*\
24 | _ _ _
25 | | \ | | _____ _| |_ ___ _ __
26 | | \| |/ _ \ \ /\ / / __/ _ \| '_ \
27 | | |\ | __/\ V V /| || (_) | | | |
28 | |_| \_|\___| \_/\_/ \__\___/|_| |_|
29 |
30 \*/
31
40 template <typename Real, Integer N>
41 class Newton : public RootFinder<Real, N, Newton<Real, N>>
42 {
43 public:
44 static constexpr bool requires_function{true};
45 static constexpr bool requires_first_derivative{true};
46 static constexpr bool requires_second_derivative{false};
47
49
50 using Vector = typename RootFinder<Real, N, Newton<Real, N>>::Vector;
51 using Matrix = typename RootFinder<Real, N, Newton<Real, N>>::Matrix;
52 using FunctionWrapper = typename RootFinder<Real, N, Newton<Real, N>>::FunctionWrapper;
53 using JacobianWrapper = typename RootFinder<Real, N, Newton<Real, N>>::JacobianWrapper;
54 using RootFinder<Real, N, Newton<Real, N>>::solve;
55
56 private:
57 Eigen::FullPivLU<Matrix> m_lu;
58
59 public:
63 Newton() {}
64
69 std::string name_impl() const {return "Newton";}
70
80 bool solve_impl(FunctionWrapper function, JacobianWrapper jacobian, Vector const & x_ini, Vector & x_sol)
81 {
82 // Setup internal variables
83 this->reset();
84
85 // Print header
86 if (this->m_verbose) {this->header();}
87
88 // Initialize variables
89 bool damped;
90 Real residuals, step_norm;
91 Vector x_old, x_new, function_old, function_new, step_old, step_new;
92 Matrix jacobian_old;
93
94 // Set initial iteration
95 x_old = x_ini;
96 this->evaluate_function(function, x_old, function_old);
97
98 // Algorithm iterations
99 Real tolerance_residuals{this->m_tolerance};
100 Real tolerance_step_norm{this->m_tolerance * this->m_tolerance};
101 for (this->m_iterations = static_cast<Integer>(1); this->m_iterations < this->m_max_iterations; ++this->m_iterations)
102 {
103 // Store trace
104 this->store_trace(x_old);
105
106 // Calculate step
107 this->evaluate_jacobian(jacobian, x_old, jacobian_old);
108 this->m_lu.compute(jacobian_old);
109 OPTIMIST_ASSERT(this->m_lu.rank() == N,
110 "Optimist::RootFinder::Newton::solve(...): singular Jacobian detected.");
111 step_old = -this->m_lu.solve(function_old);
112
113 // Check convergence
114 residuals = function_old.norm();
115 step_norm = step_old.norm();
116 if (this->m_verbose) {this->info(residuals);}
117 if (residuals < tolerance_residuals || step_norm < tolerance_step_norm) {
118 this->m_converged = true;
119 break;
120 }
121
122 if (this->m_damped)
123 {
124 // Relax the iteration process
125 damped = this->damp(function, x_old, function_old, step_old, x_new, function_new, step_new);
127 "Optimist::RootFinder::Newton::solve(...): damping failed.");
128 } else {
129 // Update point
130 x_new = x_old + step_old;
131 this->evaluate_function(function, x_new, function_new);
132 }
133
134 // Update internal variables
135 x_old = x_new;
136 function_old = function_new;
137 step_old = step_new;
138 }
139
140 // Print bottom
141 if (this->m_verbose) {this->bottom();}
142
143 // Convergence data
144 x_sol = x_old;
145 return this->m_converged;
146 }
147
148 }; // class Newton
149
150 } // namespace RootFinder
151
152} // namespace Optimist
153
154#endif // OPTIMIST_ROOTFINDER_NEWTON_HH
#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
Newton()
Definition Newton.hh:63
typename RootFinder< Real, N, Newton< Real, N > >::FunctionWrapper FunctionWrapper
Definition Newton.hh:52
static constexpr bool requires_function
Definition Newton.hh:44
typename RootFinder< Real, N, Newton< Real, N > >::JacobianWrapper JacobianWrapper
Definition Newton.hh:53
typename RootFinder< Real, N, Newton< Real, N > >::Vector Vector
Definition Newton.hh:50
static constexpr bool requires_first_derivative
Definition Newton.hh:45
bool solve_impl(FunctionWrapper function, JacobianWrapper jacobian, Vector const &x_ini, Vector &x_sol)
Definition Newton.hh:80
std::string name_impl() const
Definition Newton.hh:69
Eigen::FullPivLU< Matrix > m_lu
Definition Newton.hh:57
static constexpr bool requires_second_derivative
Definition Newton.hh:46
typename RootFinder< Real, N, Newton< Real, N > >::Matrix Matrix
Definition Newton.hh:51
void evaluate_jacobian(JacobianWrapper jacobian, const Vector &x, Matrix &out)
Definition RootFinder.hh:140
bool solve(FunctionWrapper function, Vector const &x_ini, Vector &x_sol)
Definition RootFinder.hh:164
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_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
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