Optimist
0.0.0
A C++ library for optimization
|
Class container for the Broyden's method. More...
#include <Broyden.hh>
Inherits Optimist::RootFinder::QuasiNewton< Real, N, Broyden< Real, N > >.
Public Types | |
using | Method = enum class Method : Integer {GOOD = 0, BAD = 1, COMBINED = 2} |
using | Vector = typename QuasiNewton<Real, N, Broyden<Real, N>>::Vector |
using | Matrix = typename QuasiNewton<Real, N, Broyden<Real, N>>::Matrix |
using | FunctionWrapper = typename QuasiNewton<Real, N, Broyden<Real, N>>::FunctionWrapper |
using | JacobianWrapper = typename QuasiNewton<Real, N, Broyden<Real, N>>::JacobianWrapper |
![]() | |
using | Method |
using | Vector |
using | Matrix |
using | FunctionWrapper |
using | JacobianWrapper |
![]() | |
using | Vector |
using | Matrix |
using | Tensor |
using | FunctionWrapper |
using | JacobianWrapper |
using | HessianWrapper |
Public Member Functions | |
Broyden () | |
std::string | name_impl () const |
Method | method () const |
void | method (Method t_method) |
void | enable_good_method () |
void | enable_bad_method () |
void | enable_combined_method () |
void | set_method (Method t_method) |
void | update_impl (Vector const &delta_x_old, Vector const &delta_function_old, Matrix const &jacobian_old, Vector const &delta_x_new, Vector const &delta_function_new, Vector const &, Matrix &jacobian_new) |
![]() | |
QuasiNewton () | |
std::string | name_impl () const |
bool | solve_impl (FunctionWrapper function, JacobianWrapper jacobian, Vector const &x_ini, Vector &x_sol) |
void | update (Vector const &delta_x_old, Vector const &delta_function_old, Matrix const &jacobian_old, Vector const &delta_x_new, Vector const &delta_function_new, Vector const &function_new, Matrix &jacobian_new) |
![]() | |
RootFinder () | |
std::string | name () const |
Integer | jacobian_evaluations () const |
Integer | max_jacobian_evaluations () const |
void | max_jacobian_evaluations (Integer t_jacobian_evaluations) |
Integer | hessian_evaluations () const |
Integer | max_hessian_evaluations () const |
void | max_hessian_evaluations (Integer t_hessian_evaluations) |
bool | solve (FunctionWrapper function, Vector const &x_ini, Vector &x_sol) |
bool | solve (FunctionWrapper function, JacobianWrapper jacobian, Vector const &x_ini, Vector &x_sol) |
bool | solve (FunctionWrapper function, JacobianWrapper jacobian, HessianWrapper hessian, Vector const &x_ini, Vector &x_sol) |
![]() | |
Solver () | |
Solver (FunctionWrapper function, const InputType &x_ini, InputType &x_sol) | |
Solver (FunctionWrapper function, FirstDerivativeWrapper first_derivative, const InputType &x_ini, InputType &x_sol) | |
Solver (FunctionWrapper function, FirstDerivativeWrapper first_derivative, SecondDerivativeWrapper second_derivative, const InputType &x_ini, InputType &x_sol) | |
const InputType & | lower_bound () const |
void | lower_bound (const InputType &t_lower_bound) |
const InputType & | upper_bound () const |
void | upper_bound (const InputType &t_upper_bound) |
void | bounds (const InputType &t_lower_bound, const InputType &t_upper_bound) |
constexpr Integer | input_dimension () const |
constexpr Integer | output_dimension () const |
Integer | function_evaluations () const |
void | max_function_evaluations (Integer t_max_function_evaluations) |
Integer | max_function_evaluations () const |
Integer | iterations () const |
Integer | max_iterations () const |
void | max_iterations (Integer t_max_iterations) |
Real | alpha () const |
void | alpha (Real t_alpha) |
Integer | relaxations () const |
Integer | max_relaxations () const |
void | max_relaxations (Integer t_max_relaxations) |
Real | tolerance () const |
void | tolerance (Real t_tolerance) |
void | verbose_mode (bool t_verbose) |
bool | verbose_mode () const |
void | enable_verbose_mode () |
void | disable_verbose_mode () |
void | damped_mode (bool t_damped) |
bool | damped_mode () const |
void | enable_damped_mode () |
void | disable_damped_mode () |
std::string | task () const |
void | task (std::string t_task) |
bool | converged () const |
const TraceType & | trace () const |
std::ostream & | ostream () const |
void | ostream (std::ostream &t_ostream) |
bool | solve (FunctionWrapper function, const InputType &x_ini, InputType &x_sol) |
bool | solve (FunctionWrapper function, FirstDerivativeWrapper first_derivative, const InputType &x_ini, InputType &x_sol) |
bool | solve (FunctionWrapper function, FirstDerivativeWrapper first_derivative, SecondDerivativeWrapper second_derivative, const InputType &x_ini, InputType &x_sol) |
bool | rootfind (Function< Real, FunInDim, FunOutDim, DerivedFunction > const &function, const InputType &x_ini, InputType &x_sol) |
bool | optimize (Function< Real, FunInDim, FunOutDim, DerivedFunction > const &function, const InputType &x_ini, InputType &x_sol) |
std::string | name () const |
Static Public Attributes | |
static constexpr bool | requires_function {true} |
static constexpr bool | requires_first_derivative {true} |
static constexpr bool | requires_second_derivative {false} |
![]() | |
static constexpr bool | requires_function |
static constexpr bool | requires_first_derivative |
static constexpr bool | requires_second_derivative |
![]() | |
static constexpr bool | is_rootfinder |
static constexpr bool | is_optimizer |
static constexpr bool | requires_function |
static constexpr bool | requires_first_derivative |
static constexpr bool | requires_second_derivative |
Private Attributes | |
Method | m_method {Method::COMBINED} |
The Broyden family includes the good, bad, and combined methods. These methods are quasi-Newton approaches that approximate the Jacobian matrix or its inverse. The combined method integrates the updates of the good and bad methods, offering an alternative approach to the classical Newton's method. The Broyden's methods are based on the linearization of the function \mathbf{f}(\mathbf{x}) around the current iterate \mathbf{x}_k, which leads to the linear system
\mathbf{Jf}_{\mathbf{x}}(\mathbf{x}_k) \mathbf{h}_k = -\mathbf{f}(\mathbf{x}_k) \text{.}
Here, the Jacobian matrix \mathbf{Jf}_{\mathbf{x}} is supposed not to be explicitly available or computationally expensive to compute. For this reason, Broyden's methods approximate the Jacobian matrix iteratively. The Broyden's method is defined as
\mathbf{H}_k(\mathbf{x}_k) \mathbf{h}_k = -\mathbf{f}(\mathbf{x}_k) \text{,}
where \mathbf{H}_k is the (inverse) Jacobian approximation at the k-th iteration. The generic advancing step is then defined as
\mathbf{x}_{k+1} = \mathbf{x}_k + \alpha_k \mathbf{h}_k \text{.}
where \alpha_k is a damping coefficient that ensures affine-invariant criteria is satisfied.
What distinguishes Broyden's combined method from the generic Broyden's method is the update of the Jacobian approximation. The Broyden's combined method uses the following update rule
\begin{cases} \mathbf{H}_{k+1}^{-1} = \mathbf{H}_k^{-1} - \displaystyle\frac{\mathbf{H}_k^{-1} \Delta\mathbf{f}_k - \Delta\mathbf{x}_k}{\mathbf{C}_g \Delta\mathbf{f}_k} \mathbf{C}_g & \left\| \displaystyle\frac{\Delta\mathbf{x}_k^\top \Delta\mathbf{x}_{k-1}}{\Delta\mathbf{x}_k^\top \mathbf{H}_k^{-1} \Delta\mathbf{f}_k} \right\| < \left\| \displaystyle\frac{\Delta\mathbf{f}_k^\top \Delta\mathbf{f}_{k-1}}{\Delta\mathbf{f}_k^\top\Delta\mathbf{f}_k} \right\| \\ \mathbf{H}_{k+1}^{-1} = \mathbf{H}_k^{-1} - \displaystyle\frac{\mathbf{H}_k^{-1} \Delta\mathbf{f}_k-\Delta\mathbf{x}_k}{\mathbf{C}_b \Delta\mathbf{f}_k} \mathbf{C}_b & \text{otherwise} \end{cases} \text{,}
with \mathbf{C}_g = \Delta\mathbf{x}_k^\top \mathbf{H}_k^{-1}, \mathbf{C}_b = \Delta\mathbf{f}_k^\top, \Delta\mathbf{x}_k = \mathbf{x}_{k+1} - \mathbf{x}_k, and \Delta\mathbf{f}_k = \mathbf{f}(\mathbf{x}_{k+1}) - \mathbf{f}(\mathbf{x}_k). Such a rule allows Broyden's combined method to adapt to the problem's behavior, switching between the good and bad methods based on the convergence history.
For more details on the Broyden's methods refer to the references: Broyden C.G., A class of methods for solving nonlinear simultaneous equations, Mathematics of Computation, 19 (1965), pp. 577-593, 10.1090/s0025-5718-1965-0198670-6, and Martinez J., Ochi L., Sobre dois métodos de broyden, Matemática Aplicada e Computacional, IV Congresso Nacional de Matemática Aplicada e Computacional, Rio de Janeiro, Brasil, setembro de 1981.
NOTE: In
Optimist
, the implemented Broyden's class for the combined method can be used as a good or bad solver by setting the appropriate parameters.
N | Dimension of the root-finding problem. |
Real | Scalar number type. |
using Optimist::RootFinder::Broyden< Real, N >::FunctionWrapper = typename QuasiNewton<Real, N, Broyden<Real, N>>::FunctionWrapper |
using Optimist::RootFinder::Broyden< Real, N >::JacobianWrapper = typename QuasiNewton<Real, N, Broyden<Real, N>>::JacobianWrapper |
using Optimist::RootFinder::Broyden< Real, N >::Matrix = typename QuasiNewton<Real, N, Broyden<Real, N>>::Matrix |
using Optimist::RootFinder::Broyden< Real, N >::Method = enum class Method : Integer {GOOD = 0, BAD = 1, COMBINED = 2} |
Broyden solver type.
using Optimist::RootFinder::Broyden< Real, N >::Vector = typename QuasiNewton<Real, N, Broyden<Real, N>>::Vector |
|
inline |
Class constructor for the Broyden solver.
|
inline |
Enable the bad Broyden solver method.
|
inline |
Enable the combined Broyden solver method.
|
inline |
Enable the good Broyden solver method.
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
Jacobian approximation update rule for the Broyden's method.
[in] | delta_x_old | Old difference between points. |
[in] | delta_function_old | Old difference between function values. |
[in] | jacobian_old | Old jacobian approximation. |
[in] | delta_x_new | New difference between points. |
[in] | delta_function_new | New difference between function values. |
[in] | function_new | New function value. |
[out] | jacobian_new | New jacobian approximation. |
|
private |
Broyden solver type.
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
Basic constants.