Program Listing for File mxd_end_only.cpp#
↰ Return to documentation for file (source/mxd_end_only.cpp)
#include "pele/mxd_end_only.hpp"
#include <Eigen/Dense>
#include <cstddef>
#include <iostream>
#include <memory>
#include <pele/cvode.hpp>
#include "pele/array.hpp"
#include "pele/newton.hpp"
#include "pele/optimizer.hpp"
using namespace std;
namespace pele {
MixedDescentEndOnly::MixedDescentEndOnly(
std::shared_ptr<BasePotential> potential, const pele::Array<double> x0,
double tol, double newton_step_tol, double rtol, double atol,
double threshold, bool iterative)
: GradientOptimizer(potential, x0, tol),
_cvode_optimizer(potential, x0, tol, rtol, atol, DENSE,
false), // initialize the CVODE optimizer
_newton_optimizer(potential, x0, tol, threshold,
false), // initialize the Newton optimizer with the
// rattler mask option passed as true
_tol(tol),
_newton_step_tol(newton_step_tol),
use_newton_step(false),
particle_disp(potential->get_ndim()) {}
void MixedDescentEndOnly::one_iteration() {
if (use_newton_step) {
_newton_optimizer.one_iteration();
} else {
_cvode_optimizer.one_iteration();
Array<double> gradient = _cvode_optimizer.get_g();
// use standard stopping criteria to figure out when to refine the step
gradient_norm_ = norm(gradient) / sqrt(gradient.size());
if (gradient_norm_ < _tol) {
use_newton_step = true;
_newton_optimizer.reset(_cvode_optimizer.get_x());
}
}
iter_number_++;
}
// The stop criteria refines the minima so that the we're closer to the minima.
bool MixedDescentEndOnly::stop_criterion_satisfied() {
// stop criterion can only be satisfied in the Newton regime
// std::cout << _newton_optimizer.get_niter() << "niter" << std::endl;
// bool jammed;
// jammed = _newton_optimizer.is_jammed();
// // TODO: Pass these on to the python interface since we don't want to keep
// do this twice if (use_newton_step & !jammed) {
// return true; // assuming that the find rattlers function in julia will
// take care of this
// }
if (use_newton_step && _newton_optimizer.get_niter() > 0) {
// std::cout << "are we actually here" << std::endl;
size_t _ndim = potential_->get_ndim();
int nparticles = _cvode_optimizer.get_x().size() / _ndim;
Eigen::VectorXd _step = _newton_optimizer.get_step();
particle_disp.assign(0.0);
double max_disp = 0.0;
for (size_t particle_index = 0; particle_index < nparticles;
particle_index++) {
for (size_t dim = 0; dim < _ndim; dim++) {
particle_disp[dim] = _step(particle_index * _ndim + dim);
}
double disp = norm(particle_disp);
if (disp > max_disp) {
max_disp = disp;
}
}
if (max_disp < _newton_step_tol) {
// std::cout << "max_disp: " << max_disp << std::endl;
x_ = _newton_optimizer.get_x();
succeeded_ = true;
return true;
} else {
return false;
}
} else {
return false;
}
// std::cout << "should not be here" << std::endl;
}
} // namespace pele