SIRIUS 7.5.0
Electronic structure library and applications
Public Member Functions | Private Attributes | List of all members
sirius::mixer::Broyden2< FUNCS > Class Template Reference

Broyden mixer. More...

#include <broyden2_mixer.hpp>

Inherits sirius::mixer::Mixer< FUNCS... >.

Public Member Functions

 Broyden2 (std::size_t max_history, double beta, double beta0, double beta_scaling_factor, double linear_mix_rmse_tol)
 
void mix_impl () override
 
- Public Member Functions inherited from sirius::mixer::Mixer< FUNCS... >
 Mixer (std::size_t max_history)
 Construct a mixer. Functions have to initialized individually. More...
 
void initialize_function (const FunctionProperties< typename std::tuple_element< FUNC_INDEX, std::tuple< FUNCS... > >::type > &function_prop, const typename std::tuple_element< FUNC_INDEX, std::tuple< FUNCS... > >::type &init_value, ARGS &&... args)
 
void set_input (const typename std::tuple_element< FUNC_INDEX, std::tuple< FUNCS... > >::type &input)
 Set input for next mixing step. More...
 
void get_output (typename std::tuple_element< FUNC_INDEX, std::tuple< FUNCS... > >::type &output)
 Access last generated output. Mixing must have been performed at least once. More...
 
double mix (double rms_min__)
 Mix input and stored history. Returns the root mean square error computed by inner products of residuals. More...
 

Private Attributes

double beta_
 
double beta0_
 
double beta_scaling_factor_
 
double linear_mix_rmse_tol_
 
sddk::mdarray< double, 2 > S_
 
sddk::mdarray< double, 1 > gamma_
 

Additional Inherited Members

- Static Public Attributes inherited from sirius::mixer::Mixer< FUNCS... >
static constexpr std::size_t number_of_functions
 
- Protected Member Functions inherited from sirius::mixer::Mixer< FUNCS... >
virtual void mix_impl ()=0
 
void update_residual ()
 
void update_rms ()
 
std::size_t idx_hist (std::size_t step) const
 
double inner_product (const std::tuple< std::unique_ptr< FUNCS >... > &x, const std::tuple< std::unique_ptr< FUNCS >... > &y)
 
void scale (double alpha, std::tuple< std::unique_ptr< FUNCS >... > &x)
 
void copy (const std::tuple< std::unique_ptr< FUNCS >... > &x, std::tuple< std::unique_ptr< FUNCS >... > &y)
 
void axpy (double alpha, const std::tuple< std::unique_ptr< FUNCS >... > &x, std::tuple< std::unique_ptr< FUNCS >... > &y)
 
void rotate (double c, double s, std::tuple< std::unique_ptr< FUNCS >... > &x, std::tuple< std::unique_ptr< FUNCS >... > &y)
 
- Protected Attributes inherited from sirius::mixer::Mixer< FUNCS... >
std::size_t step_
 
std::size_t max_history_
 
std::vector< double > rmse_history_
 
std::tuple< FunctionProperties< FUNCS >... > functions_
 
std::tuple< std::unique_ptr< FUNCS >... > input_
 
std::vector< std::tuple< std::unique_ptr< FUNCS >... > > output_history_
 
std::vector< std::tuple< std::unique_ptr< FUNCS >... > > residual_history_
 

Detailed Description

template<typename... FUNCS>
class sirius::mixer::Broyden2< FUNCS >

Broyden mixer.

Quasi-Newton, limited-memory method which updates \( x_{n+1} = x_n - G_nf_n \) where \( G_n \) is an approximate inverse Jacobian. Broyden 2 is derived by recursively taking rank-1 updates to the inverse Jacobian. It requires the secant equation \( G_{n+1}\Delta f_n = \Delta x_n\) to hold for the next approximate Jacobian \( G_{n+1}\), leading to the update:

\[ G_{n+1} := G_n + (\Delta x_n - G_n \Delta f_n)(\Delta f_n^*\Delta f_n)^{-1}\Delta f_n^*. \]

By induction we can show that \( G_n \) satisfies

\[ G_n = G_1\prod_{i=1}^{n-1}\left(I - \frac{\Delta f_i \Delta f_i^*}{\Delta f_i^*\Delta f_i}\right) + \sum_{i=1}^{n-1}\frac{\Delta x_i \Delta f_i^*}{\Delta f_i^*\Delta f_i}\prod_{j=i+1}^{n-1} \left(I - \frac{\Delta f_j \Delta f_j^*}{\Delta f_j^*\Delta f_j}\right) \]

which shows orthogonalization with respect to the \( \Delta f_i \) vectors. A practical implementation can be derived from the identity

\[ G_n = G_1 + \sum_{i=1}^{n-1}\left(\Delta x_i - G_1\Delta f_i\right)\gamma_{i,n}^* \]

where

\[ \gamma_{i,n}^* = \frac{\Delta f_i^*}{\Delta f_i^*\Delta f_i}\prod_{j=i+1}^{n-1} \left(I - \frac{\Delta f_j\Delta f_j^*}{\Delta f_j^*\Delta f_j}\right). \]

The \( \gamma_{i,n}\) vector satisfies the following recursion relation:

\[ \gamma_{i,n}^* = \frac{\Delta f_i^*}{\Delta f_i^*\Delta f_i}\left(I - \sum_{j=i+1}^{n-1} \Delta f_j \gamma_{j,n}^*\right) \]

When updating \( x_{n+1} = x_n - G_nf_n\) we only have to compute:

\[ \alpha_i := \gamma_i^*f_n = \frac{1}{\Delta f_i^*\Delta f_i}\left[\Delta f_i^*f_n - \sum_{j=i+1}^{n-1}\alpha_j\Delta f_i^* \Delta f_j \right] \]

for \( i \) from \( n-1\) down to \( 1 \) so that

\[\begin{aligned} x_{n+1} &= x_n - G_nf_n \\ &= x_n - G_1f_n + \sum_{i=1}^{n-1}\alpha_iG_1\Delta f_i - \sum_{i=1}^{n-1}\alpha_i\Delta x_i. \end{aligned}\]

In particular when \( G_1 = -\beta I\) we get the following update:

\[ x_{n+1} = x_n + \beta f_n - \sum_{i=1}^{n-1}\alpha_i \beta \Delta f_i - \sum_{i=1}^{n-1}\alpha_i\Delta x_i. \]

Finally, we store the vectors \( f_1, \cdots, f_n \) and \( x_1, \dots, x_n \) and update the Gram-matrix \( S_{ij} = f_i^*f_j \) in every iteration. The \( \alpha_i \) coefficients can be easily computed from \( S \).

Note
This class does not do anything to improve the stability of the Gram-Schmidt procedure (clearly visible in the first explicit expression for \( G_n \)) and can therefore be very unstable for larger history sizes.

Definition at line 99 of file broyden2_mixer.hpp.

Constructor & Destructor Documentation

◆ Broyden2()

template<typename... FUNCS>
sirius::mixer::Broyden2< FUNCS >::Broyden2 ( std::size_t  max_history,
double  beta,
double  beta0,
double  beta_scaling_factor,
double  linear_mix_rmse_tol 
)
inline

Definition at line 102 of file broyden2_mixer.hpp.

Member Function Documentation

◆ mix_impl()

template<typename... FUNCS>
void sirius::mixer::Broyden2< FUNCS >::mix_impl ( )
inlineoverridevirtual

Implements sirius::mixer::Mixer< FUNCS... >.

Definition at line 113 of file broyden2_mixer.hpp.

Member Data Documentation

◆ beta_

template<typename... FUNCS>
double sirius::mixer::Broyden2< FUNCS >::beta_
private

Definition at line 188 of file broyden2_mixer.hpp.

◆ beta0_

template<typename... FUNCS>
double sirius::mixer::Broyden2< FUNCS >::beta0_
private

Definition at line 189 of file broyden2_mixer.hpp.

◆ beta_scaling_factor_

template<typename... FUNCS>
double sirius::mixer::Broyden2< FUNCS >::beta_scaling_factor_
private

Definition at line 190 of file broyden2_mixer.hpp.

◆ linear_mix_rmse_tol_

template<typename... FUNCS>
double sirius::mixer::Broyden2< FUNCS >::linear_mix_rmse_tol_
private

Definition at line 191 of file broyden2_mixer.hpp.

◆ S_

template<typename... FUNCS>
sddk::mdarray<double, 2> sirius::mixer::Broyden2< FUNCS >::S_
private

Definition at line 192 of file broyden2_mixer.hpp.

◆ gamma_

template<typename... FUNCS>
sddk::mdarray<double, 1> sirius::mixer::Broyden2< FUNCS >::gamma_
private

Definition at line 193 of file broyden2_mixer.hpp.


The documentation for this class was generated from the following file: