40 [[nodiscard]]
const std::vector<DenseMatrix<Complex>>&
42 direction_ = conjugated(gradients, restart);
43 previous_gradients_ = gradients;
48 [[nodiscard]] std::vector<DenseMatrix<Complex>>
50 const std::vector<DenseMatrix<Complex>> steepest_descent = negated(gradients);
51 if (restart || previous_gradients_.empty() || direction_.empty()) {
52 return steepest_descent;
56 Real denominator = 0.0;
57 for (std::size_t kpoint = 0; kpoint < gradients.size(); kpoint++) {
58 DenseMatrix<Complex> change = gradients[kpoint];
59 change.add_scaled(-1.0, previous_gradients_[kpoint]);
60 numerator += gradients[kpoint].real_inner_product(change);
61 denominator += previous_gradients_[kpoint].frobenius_norm_squared();
63 if (denominator <= 0.0) {
64 return steepest_descent;
66 const Real beta = std::max(0.0, numerator / denominator);
68 return steepest_descent;
71 std::vector<DenseMatrix<Complex>> direction = steepest_descent;
73 for (std::size_t kpoint = 0; kpoint < gradients.size(); kpoint++) {
74 direction[kpoint].add_scaled(beta, direction_[kpoint]);
75 slope += gradients[kpoint].real_inner_product(direction[kpoint]);
77 return slope >= 0.0 ? steepest_descent : direction;
81 [[nodiscard]]
static std::vector<DenseMatrix<Complex>>
82 negated(
const std::vector<DenseMatrix<Complex>>& gradients) {
83 std::vector<DenseMatrix<Complex>> result;
84 result.reserve(gradients.size());
85 for (
const DenseMatrix<Complex>& gradient : gradients) {
86 result.push_back(gradient.scaled(-1.0));
91 std::vector<DenseMatrix<Complex>> previous_gradients_;
92 std::vector<DenseMatrix<Complex>> direction_;