42 "AndersonAcceleration::init expects non-zero sizes");
51 current_u_.resize(dimension_);
52 current_F_.resize(dimension_);
53 prev_dG_.setZero(dimension_, history_length_);
54 prev_dF_.setZero(dimension_, history_length_);
55 normal_eq_matrix_.setZero(history_length_, history_length_);
56 theta_.setZero(history_length_);
57 dF_scale_.setZero(history_length_);
59 current_u_ = Eigen::Map<const Eigen::VectorXd>(initial_state, dimension_);
109 "AndersonAcceleration::compute called before init");
112 Eigen::Map<const Eigen::VectorXd> G(next_state, dimension_);
113 current_F_ = G - current_u_;
115 constexpr double eps = 1e-14;
117 if (iteration_ == 0) {
118 prev_dF_.col(0) = -current_F_;
119 prev_dG_.col(0) = -G;
123 prev_dF_.col(column_index_) += current_F_;
124 prev_dG_.col(column_index_) += G;
126 double scale = std::max(eps, prev_dF_.col(column_index_).norm());
127 dF_scale_(column_index_) = scale;
128 prev_dF_.col(column_index_) /= scale;
130 const std::size_t m_k = std::min(history_length_, iteration_);
134 const double dF_norm = prev_dF_.col(column_index_).norm();
135 normal_eq_matrix_(0, 0) = dF_norm * dF_norm;
137 theta_(0) = (prev_dF_.col(column_index_) / dF_norm).dot(current_F_ / dF_norm);
142 const Eigen::RowVectorXd new_inner_prod =
143 prev_dF_.col(column_index_).transpose() *
144 prev_dF_.block(0, 0, dimension_, m_k);
145 normal_eq_matrix_.block(column_index_, 0, 1, m_k) = new_inner_prod;
146 normal_eq_matrix_.block(0, column_index_, m_k, 1) = new_inner_prod.transpose();
148 cod_.compute(normal_eq_matrix_.block(0, 0, m_k, m_k));
150 cod_.solve(prev_dF_.block(0, 0, dimension_, m_k).transpose() * current_F_);
153 const Eigen::ArrayXd scaled_theta =
154 theta_.head(m_k).array() / dF_scale_.head(m_k).array();
155 current_u_ = G - prev_dG_.block(0, 0, dimension_, m_k) * scaled_theta.matrix();
157 column_index_ = (column_index_ + 1) % history_length_;
158 prev_dF_.col(column_index_) = -current_F_;
159 prev_dG_.col(column_index_) = -G;