25#ifndef __ANDERSON_STABLE_MIXER_HPP__
26#define __ANDERSON_STABLE_MIXER_HPP__
64template <
typename... FUNCS>
70 std::size_t history_size_;
74 :
Mixer<FUNCS...>(max_history)
76 , R_(max_history - 1, max_history - 1),
82 void mix_impl()
override
84 const auto idx_step = this->idx_hist(this->step_);
85 const auto idx_next_step = this->idx_hist(this->step_ + 1);
86 const auto idx_step_prev = this->idx_hist(this->step_ - 1);
88 const bool normalize =
false;
90 const auto history_size =
static_cast<int>(this->history_size_);
97 this->copy(this->output_history_[idx_step], this->input_);
100 this->axpy(this->beta_, this->residual_history_[idx_step], this->input_);
102 if (history_size > 0) {
106 this->scale(-1.0, this->residual_history_[idx_step_prev]);
107 this->axpy(1.0, this->residual_history_[idx_step], this->residual_history_[idx_step_prev]);
110 this->scale(-1.0, this->output_history_[idx_step_prev]);
111 this->axpy(1.0, this->output_history_[idx_step], this->output_history_[idx_step_prev]);
114 for (
int i = 1; i <= history_size - 1; ++i) {
115 auto j = this->idx_hist(this->step_ - i - 1);
116 auto sz = this->
template inner_product<normalize>(
117 this->residual_history_[j],
118 this->residual_history_[idx_step_prev]
120 this->R_(history_size - 1 - i, history_size - 1) = sz;
121 this->axpy(-sz, this->residual_history_[j], this->residual_history_[idx_step_prev]);
125 for (
int i = 1; i <= history_size - 1; ++i) {
126 auto j = this->idx_hist(this->step_ - i - 1);
127 auto sz = this->
template inner_product<normalize>(
128 this->residual_history_[j],
129 this->residual_history_[idx_step_prev]
131 this->R_(history_size - 1 - i, history_size - 1) += sz;
132 this->axpy(-sz, this->residual_history_[j], this->residual_history_[idx_step_prev]);
136 auto nrm2 = this->
template inner_product<normalize>(
137 this->residual_history_[idx_step_prev],
138 this->residual_history_[idx_step_prev]
142 auto sz = std::sqrt(nrm2);
143 this->R_(history_size - 1, history_size - 1) = sz;
144 this->scale(1.0 / sz, this->residual_history_[idx_step_prev]);
150 for (
int i = 1; i <= history_size; ++i) {
151 auto j = this->idx_hist(this->step_ - i);
152 h(history_size - i) = this->
template inner_product<normalize>(this->residual_history_[j], this->residual_history_[idx_step]);
157 for (
int i = 0; i < history_size; ++i) {
161 for (
int j = history_size - 1; j >= 0; --j) {
162 k(j) /= this->R_(j, j);
163 for (
int i = j - 1; i >= 0; --i) {
164 k(i) -= this->R_(i, j) * k(j);
169 for (
int i = 1; i <= history_size; ++i) {
170 auto j = this->idx_hist(this->step_ - i);
171 this->axpy(-this->beta_ * h(history_size - i), this->residual_history_[j], this->input_);
175 for (
int i = 1; i <= history_size; ++i) {
176 auto j = this->idx_hist(this->step_ - i);
177 this->axpy(-k(history_size - i), this->output_history_[j], this->input_);
183 this->history_size_ = 0;
194 if (this->history_size_ == this->max_history_ - 1) {
196 for (
int row = 1; row <= history_size - 1; ++row) {
198 auto c = std::get<0>(rotation);
199 auto s = std::get<1>(rotation);
200 auto nrm = std::get<2>(rotation);
203 this->R_(row - 1, row) = nrm;
204 this->R_(row , row) = 0;
207 for (
int col = row + 1; col < history_size; ++col) {
208 auto r1 = this->R_(row - 1, col);
209 auto r2 = this->R_(row , col);
211 this->R_(row - 1, col) = c * r1 + s * r2;
212 this->R_(row , col) = -s * r1 + c * r2;
216 int i1 = this->idx_hist(this->step_ - history_size + row - 1);
217 int i2 = this->idx_hist(this->step_ - history_size + row);
218 this->rotate(c, s, this->residual_history_[i1], this->residual_history_[i2]);
222 for (
int i = 1; i <= history_size - 1; ++i) {
223 int i1 = this->idx_hist(this->step_ - i - 1);
224 int i2 = this->idx_hist(this->step_ - i);
225 std::swap(this->residual_history_[i2], this->residual_history_[i1]);
229 for (
int col = 0; col <= history_size - 2; ++col) {
230 for (
int row = 0; row <= col; ++row) {
231 this->R_(row, col) = this->R_(row, col + 1);
236 this->copy(this->input_, this->output_history_[idx_next_step]);
237 this->history_size_ = std::min(this->history_size_ + 1, this->max_history_ - 1);
Abstract mixer for variadic number of Function objects, which are described by FunctionProperties.
void zero(memory_t mem__, size_t idx0__, size_t n__)
Zero n elements starting from idx0.
Linear algebra interface.
Memory management functions and classes.
Contains definition and implementation of sirius::Mixer base class.
Namespace of the SIRIUS library.