1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_OPTIMIZEBFGS_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_OPTIMIZEBFGS_H
3#include <molpro/linalg/itsolv/CastOptions.h>
4#include <molpro/linalg/itsolv/DSpaceResetter.h>
5#include <molpro/linalg/itsolv/Interpolate.h>
6#include <molpro/linalg/itsolv/IterativeSolverTemplate.h>
7#include <molpro/linalg/itsolv/propose_rspace.h>
8#include <molpro/linalg/itsolv/subspace/SubspaceSolverOptBFGS.h>
9#include <molpro/linalg/itsolv/subspace/XSpace.h>
20template <
class R,
class Q = R,
class P = std::map<
size_t,
typename R::value_type>>
25 using typename SolverTemplate::scalar_type;
26 using typename SolverTemplate::value_type;
27 using typename SolverTemplate::value_type_abs;
31 const std::shared_ptr<Logger>& logger_ = std::make_shared<Logger>())
32 :
SolverTemplate(std::make_shared<subspace::XSpace<R, Q, P>>(handlers, logger_),
33 std::static_pointer_cast<subspace::ISubspaceSolver<R, Q, P>>(
34 std::make_shared<subspace::SubspaceSolverOptBFGS<R, Q, P>>(logger_)),
35 handlers, std::make_shared<
Statistics>(), logger_),
41 auto prof = this->
profiler()->push(
"itsolv::add_vector");
42 using namespace subspace;
44 auto& xdata = xspace->data;
45 const auto& H = xdata[EqnData::H];
46 const auto& S = xdata[EqnData::S];
47 auto& Value = xdata[EqnData::value];
52 while (xspace->size() >=
size_t(this->m_max_size_qspace)) {
54 xspace->eraseq(xspace->size() - 1);
60 auto oldValue = Value;
61 Value.resize({xspace->size() + 1, 1});
62 if (xspace->size() > 0)
63 Value.slice({1, 0}, {xspace->size() + 1, 1}) = oldValue.slice();
69 if (xspace->size() > 1) {
70 auto fprev = Value(1, 0);
71 auto fcurrent = Value(0, 0);
72 auto gprev = H(0, 1) - H(1, 1);
73 auto gcurrent = H(0, 0) - H(1, 0);
74 bool Wolfe_1 = fcurrent <= fprev +
m_Wolfe_1 * gprev;
76 auto step = S(0, 0) - S(1, 0) - S(0, 1) + S(1, 1);
78 molpro::cout <<
"Size of Q=" << xspace->size() << std::endl;
79 molpro::cout <<
"step=" << step << std::endl;
80 molpro::cout <<
"fprev=" << fprev << std::endl;
81 molpro::cout <<
"fcurrent=" << fcurrent << std::endl;
82 molpro::cout <<
" m_Wolfe_1 =" <<
m_Wolfe_1 << std::endl;
83 molpro::cout <<
" m_Wolfe_1 * gprev=" <<
m_Wolfe_1 * gprev << std::endl;
84 molpro::cout <<
"fprev + m_Wolfe_1 * gprev=" << fprev +
m_Wolfe_1 * gprev << std::endl;
85 molpro::cout <<
"gprev=" << gprev << std::endl;
86 molpro::cout <<
"gcurrent=" << gcurrent << std::endl;
88 molpro::cout <<
"Wolfe conditions: " << Wolfe_1 << Wolfe_2 << std::endl;
95 Interpolate inter({-1, fprev, gprev}, {0, fcurrent, gcurrent});
101 this->
m_handlers->rr().scal(1 + x, parameters);
102 this->
m_handlers->rq().axpy(-x, xspace->paramsq()[1], parameters);
103 auto erased = fprev < fcurrent ? 0 : 1;
106 xspace->eraseq(erased);
110 while (xspace->size() >= 2) {
111 std::cout <<
"delete Q because line searching" << std::endl;
112 xspace->eraseq(xspace->size() - 1);
124 if (std::abs(H(a, a) - H(a, a + 1) - H(a + 1, a) + H(a + 1, a + 1)) <
125 std::max(5e-14 * std::abs(H(a, a)), 1e-15)) {
126 xspace->eraseq(a + 1);
137 const auto& q = xspace->paramsq();
138 const auto& u = xspace->actionsq();
142 (H(a, a) - H(a, a + 1) - H(a + 1, a) + H(a + 1, a + 1));
149 const auto& q = xspace->paramsq();
150 const auto& u = xspace->actionsq();
153 (H(a, a) - H(a, a + 1) - H(a + 1, a) + H(a + 1, a + 1));
160 auto prof = this->
profiler()->push(
"itsolv::end_iteration");
166 if (this->
m_errors.front() < this->m_convergence_threshold) {
171 auto& z = action.front();
172 const auto& xspace = this->
m_xspace;
173 auto& xdata = xspace->data;
176 auto len_z = std::sqrt(this->
m_handlers->rr().dot(z,z));
179 this->
m_handlers->rr().axpy(-1, z, parameters.front());
181 this->
m_stats->line_search_steps++;
183 this->
m_stats->line_searches++;
184 m_last_iteration_linesearching =
true;
190 size_t end_iteration(std::vector<R>& parameters, std::vector<R>& action)
override {
196 auto wparams = std::vector<std::reference_wrapper<R>>{std::ref(parameters)};
197 auto wactions = std::vector<std::reference_wrapper<R>>{std::ref(actions)};
203 this->
m_value_errors.assign(1, std::numeric_limits<double>::max());
204 if (this->
m_xspace->size() > 1 and Value(0, 0) < Value(1, 0))
217 if (opt.max_size_qspace)
219 if (opt.strong_Wolfe)
225 if (opt.linesearch_tolerance)
227 if (opt.linesearch_grow_factor)
229 if (opt.quasinewton_maximum_step)
235 auto opt = std::make_shared<OptimizeBFGSOptions>();
247 void report(std::ostream& cout,
bool endl =
true)
const override {
249 cout <<
", value " << this->
value() << (
m_linesearch ?
", line-searching" :
", quasi-Newton step");
Class, containing a collection of array handlers used in IterativeSolver Provides a Builder sub-class...
Definition: ArrayHandlers.h:25
Definition: Interpolate.h:13
Interpolate::point minimize(double xa, double xb, size_t bracket_grid=100, size_t max_bracket_grid=100000, bool analytic=true) const
Find the minimum of the interpolant within a range.
Definition: Interpolate.cpp:136
Implements IterativeSolver interface that is common to all solvers.
Definition: IterativeSolverTemplate.h:127
void solution_params(const std::vector< int > &roots, std::vector< R > ¶meters) override
Definition: IterativeSolverTemplate.h:224
std::vector< int > m_working_set
indices of roots in the working set
Definition: IterativeSolverTemplate.h:583
scalar_type value() const override
Report the function value for the current optimum solution.
Definition: IterativeSolverTemplate.h:312
std::shared_ptr< subspace::IXSpace< R, R, std::map< size_t, typename R::value_type > > > m_xspace
manages the subspace and associated data
Definition: IterativeSolverTemplate.h:579
std::shared_ptr< ArrayHandlers< R, R, std::map< size_t, typename R::value_type > > > m_handlers
Array handlers.
Definition: IterativeSolverTemplate.h:578
std::shared_ptr< Options > get_options() const override
Definition: IterativeSolverTemplate.h:262
const std::shared_ptr< molpro::profiler::Profiler > & profiler() const override
Definition: IterativeSolverTemplate.h:320
bool m_end_iteration_needed
whether end_iteration should be called after any preconditioner
Definition: IterativeSolverTemplate.h:600
int add_vector(const VecRef< R > ¶meters, const VecRef< R > &actions) override
Definition: IterativeSolverTemplate.h:140
const std::vector< scalar_type > & errors() const override
Definition: IterativeSolverTemplate.h:269
void report() const override
Definition: IterativeSolverTemplate.h:287
double m_convergence_threshold
residual norms less than this mark a converged solution
Definition: IterativeSolverTemplate.h:585
std::shared_ptr< Logger > m_logger
logger
Definition: IterativeSolverTemplate.h:589
void set_options(const Options &options) override
Definition: IterativeSolverTemplate.h:253
std::vector< double > m_errors
errors from the most recent solution
Definition: IterativeSolverTemplate.h:581
std::shared_ptr< Statistics > m_stats
accumulates statistics of operations performed by the solver
Definition: IterativeSolverTemplate.h:588
std::vector< double > m_value_errors
value errors from the most recent solution
Definition: IterativeSolverTemplate.h:582
typename R::value_type value_type
The underlying type of elements of vectors.
Definition: IterativeSolver.h:202
A class that optimises a function using a Quasi-Newton or other method.
Definition: OptimizeBFGS.h:21
int add_vector(R ¶meters, R &residual, value_type value) override
Definition: OptimizeBFGS.h:40
bool m_strong_Wolfe
Whether to use strong or weak Wolfe conditions.
Definition: OptimizeBFGS.h:265
size_t end_iteration(R ¶meters, R &actions) override
Definition: OptimizeBFGS.h:195
double m_Wolfe_2
Acceptance parameter for function gradient; recommended value Nocedal and Wright p142.
Definition: OptimizeBFGS.h:267
double m_Wolfe_1
Acceptance parameter for function value; recommended value Nocedal and Wright p142.
Definition: OptimizeBFGS.h:266
void BFGS_update_1(R &residual, std::shared_ptr< const subspace::IXSpace< R, Q, P > > xspace, const Matrix< double > &H)
Definition: OptimizeBFGS.h:135
void report(std::ostream &cout, bool endl=true) const override
Writes a report to cout output stream.
Definition: OptimizeBFGS.h:247
double m_linesearch_tolerance
Definition: OptimizeBFGS.h:268
std::shared_ptr< Options > get_options() const override
Definition: OptimizeBFGS.h:234
bool nonlinear() const override
Report whether the class is a non-linear solver.
Definition: OptimizeBFGS.h:38
bool m_linesearch
Definition: OptimizeBFGS.h:257
std::shared_ptr< Logger > logger
Definition: OptimizeBFGS.h:253
int m_max_size_qspace
maximum size of Q space
Definition: OptimizeBFGS.h:264
double m_quasinewton_maximum_step
Definition: OptimizeBFGS.h:272
size_t end_iteration(std::vector< R > ¶meters, std::vector< R > &action) override
Definition: OptimizeBFGS.h:190
void set_options(const Options &options) override
Definition: OptimizeBFGS.h:213
void BFGS_update_2(R &z, std::shared_ptr< const subspace::IXSpace< R, Q, P > > xspace, const Matrix< double > &H)
Definition: OptimizeBFGS.h:148
std::vector< double > m_BFGS_update_alpha
Definition: OptimizeBFGS.h:256
void set_value_errors() override
Implementation class should overload this to set errors in the current values (e.g....
Definition: OptimizeBFGS.h:201
void set_max_size_qspace(int n)
Definition: OptimizeBFGS.h:210
size_t end_iteration(const VecRef< R > ¶meters, const VecRef< R > &action) override
Behaviour depends on the solver.
Definition: OptimizeBFGS.h:159
int get_max_size_qspace() const
Definition: OptimizeBFGS.h:211
void construct_residual(const std::vector< int > &roots, const CVecRef< R > ¶ms, const VecRef< R > &actions) override
Constructs residual for given roots provided their parameters and actions.
Definition: OptimizeBFGS.h:262
void report() const override
Writes a report to std::cout.
Definition: IterativeSolverTemplate.h:287
bool m_last_iteration_linesearching
Definition: OptimizeBFGS.h:258
OptimizeBFGS(const std::shared_ptr< ArrayHandlers< R, Q, P > > &handlers, const std::shared_ptr< Logger > &logger_=std::make_shared< Logger >())
Definition: OptimizeBFGS.h:30
double m_linesearch_grow_factor
If the predicted line search step is extrapolation, limit the step to this factor times the current s...
Definition: OptimizeBFGS.h:270
Matrix container that allows simple data access, slicing, copying and resizing without loosing data.
Definition: Matrix.h:28
Solves subspace problem for minimisation using the Steepest Descent algorithm.
Definition: SubspaceSolverOptBFGS.h:13
4-parameter interpolation of a 1-dimensional function given two points for which function values and ...
Definition: helper.h:10
auto wrap(ForwardIt begin, ForwardIt end)
Takes a begin and end iterators and returns a vector of references to each element.
Definition: wrap.h:32
std::vector< std::reference_wrapper< const A > > CVecRef
Definition: wrap.h:14
std::vector< std::reference_wrapper< A > > VecRef
Definition: wrap.h:11
const std::shared_ptr< const molpro::Options > options()
Get the Options object associated with iterative-solver.
Definition: options.cpp:4
static std::shared_ptr< OptimizeBFGSOptions > OptimizeBFGS(const std::shared_ptr< Options > &options)
Definition: CastOptions.h:79
@ Info
Definition: Logger.h:49
Allows setting and getting of options for OptimizeBFGS instance via IterativeSolver base class.
Definition: OptimizeBFGSOptions.h:9
Access point for different options in iterative solvers.
Definition: Options.h:20
Information about performance of IterativeSolver instance.
Definition: Statistics.h:10