Program Listing for File linesearch.cpp#
↰ Return to documentation for file (source/linesearch.cpp)
#include "pele/linesearch.hpp"
#include <iostream>
#include <limits>
#include <memory>
namespace pele {
double OldLineSearch::line_search(Array<double> &x, Array<double> step) {
double fnew;
x_ = x;
f_ = opt_->get_f();
// This basically makes sure the f_ is assigned from linesearch and not
// from before
// Always point the step in the direction of the gradient:
// May fail if the convergence is quadratic
if (dot(step, g_) > 0.) {
if (verbosity_ > 1) {
std::cout << "warning: step direction was uphill. inverting"
<< std::endl;
}
#pragma simd
for (size_t j2 = 0; j2 < step.size(); ++j2) {
step[j2] *= -1;
}
}
double factor = 1.;
int nred;
double stepnorm = opt_->compute_pot_norm(step);
// make sure the stepnorm is no larger than maxstepnorm
if (factor * stepnorm > max_stepnorm_) {
factor = max_stepnorm_ / stepnorm;
}
for (nred = 0; nred < nred_max_; ++nred) {
#pragma simd
for (size_t j2 = 0; j2 < x_.size(); ++j2) {
x_[j2] = xold_[j2] + factor * step[j2];
}
opt_->compute_func_gradient(x_, fnew, g_);
double df = fnew - f_;
if (use_relative_f_) {
double absf = 1e-100;
if (f_ != 0) {
absf = std::abs(f_);
}
df /= absf;
}
if (df < max_f_rise_) {
break;
} else {
factor *= 0.5;
if (verbosity_ > 2) {
std::cout << "energy increased by " << df << " to " << fnew << " from "
<< f_ << " reducing step norm to " << factor * stepnorm
<< std::endl;
}
}
}
if (nred >= nred_max_) {
// possibly raise an error here
if (verbosity_ > 0) {
std::cout << "warning: the line search backtracked too many times"
<< std::endl;
}
}
opt_->set_f(fnew);
// rms_ = norm(g_) * inv_sqrt_size;
opt_->set_rms(norm(g_) / sqrt(x_.size()));
return stepnorm * factor;
};
} // namespace pele