8#include <kernel/solver/base.hpp>
9#include <kernel/solver/iterative.hpp>
10#include <kernel/solver/nlcg.hpp>
14#ifdef FEAT_HAVE_ALGLIB
16#include <optimization.h>
20#if defined(FEAT_HAVE_ALGLIB) || defined(DOXYGEN)
30 template <
typename Evaluator_,
typename T_>
31 auto derefer(T_ &
object,
typename Evaluator_::GateType *) ->
decltype(
object.local())
33 return object.local();
37 template <
typename Evaluator_,
typename T_>
38 T_& derefer(T_ &
object, ...)
60 template<
typename Functional_,
typename Filter_>
74 typedef typename Functional_::DataType
DataType;
119 Functional_& functional_, Filter_& filter_,
const alglib::ae_int_t lbfgs_dim_ = alglib::ae_int_t(0),
120 const bool keep_iterates =
false) :
121 BaseClass(
"ALGLIBMinLBFGS", functional_, filter_, nullptr),
130 iterates =
new std::deque<VectorType>;
156 Functional_& functional_, Filter_& filter_) :
157 BaseClass(
"ALGLIBMinLBFGS", section_name, section, functional_, filter_, nullptr),
165 auto lbfgs_dim_p = section->
query(
"lbfgs_dim");
166 if(lbfgs_dim_p.second)
168 _lbfgs_dim = alglib::ae_int_t(std::stoul(lbfgs_dim_p.first));
173 auto keep_iterates_p = section->
query(
"keep_iterates");
174 if(keep_iterates_p.second && std::stoul(keep_iterates_p.first) == 1)
176 iterates =
new std::deque<VectorType>;
200 _functionalt_var.setlength(alglib::ae_int_t(
201 Intern::derefer<VectorType>(
_vec_def,
nullptr).
template size<LAFEM::Perspective::pod>()));
209 alglib::minlbfgssetxrep(
_state,
true);
220 this->_vec_def.clear();
221 this->_vec_tmp.clear();
228 return "ALGLIBMinLBFGS";
282 XASSERT(lbfgs_dim > alglib::ae_int_t(0));
298 iterates =
new std::deque<VectorType>;
314 this->
_functional.eval_fval_grad(fval, this->_vec_def);
317 this->_vec_def.copy(vec_def);
318 this->
_filter.filter_def(this->_vec_def);
333 this->_vec_def.scale(this->_vec_def,
DataType(-1));
334 this->
_filter.filter_def(this->_vec_def);
358 Statistics::add_solver_expression(std::make_shared<ExpressionStartSolve>(this->
name()));
361 if(iterates !=
nullptr)
363 auto tmp = vec_sol.clone();
364 iterates->push_back(std::move(tmp));
372 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->
name(), status, this->
get_num_iter()));
377 auto vec_sol_elements = Intern::derefer<VectorType>(vec_sol,
nullptr).template elements<LAFEM::Perspective::pod>();
394 switch(
_report.terminationtype)
447 static void _log(
const alglib::real_1d_array& DOXY(x),
double DOXY(func),
void* ptr)
454 if(me->
_state.c_ptr()->repnfev> 0)
462 alglib::minlbfgsrequesttermination(me->
_state);
484 static void _func_grad(
const alglib::real_1d_array& x,
double& fval, alglib::real_1d_array&
grad,
void* ptr)
490 auto vec_tmp_elements = Intern::derefer<VectorType>(me->
_vec_tmp,
nullptr).template elements<LAFEM::Perspective::pod>();
493 for(alglib::ae_int_t i(0); i < x.length(); ++i)
494 vec_tmp_elements[i] =
DataType(x[i]);
503 fval = double(me->
_fval);
506 auto vec_def_elements = Intern::derefer<VectorType>(me->
_vec_def,
nullptr).template elements<LAFEM::Perspective::pod>();
507 for(alglib::ae_int_t i(0); i <
grad.length(); ++i)
509 grad[i] = double(vec_def_elements[i]);
534 template<
typename Functional_,
typename Filter_>
536 Functional_& functional_, Filter_& filter_,
537 alglib::ae_int_t lbfgs_dim_ = alglib::ae_int_t(0),
bool keep_iterates =
false)
539 return std::make_shared<ALGLIBMinLBFGS<Functional_, Filter_>>(functional_, filter_, lbfgs_dim_, keep_iterates);
560 template<
typename Functional_,
typename Filter_>
563 Functional_& functional_, Filter_& filter_)
565 return std::make_shared<ALGLIBMinLBFGS<Functional_, Filter_>>(section_name, section, functional_, filter_);
588 template<
typename Functional_,
typename Filter_>
648 BaseClass(
"ALGLIBMinCG", functional_, filter_, nullptr),
657 iterates =
new std::deque<VectorType>;
679 Functional_& functional_, Filter_& filter_) :
680 BaseClass(
"ALGLIBMinCG", section_name, section, functional_, filter_, nullptr),
688 auto direction_update_p = section->
query(
"direction_update");
689 if(direction_update_p.second)
692 my_update << direction_update_p.first;
697 auto keep_iterates_p = section->
query(
"keep_iterates");
698 if(keep_iterates_p.second && std::stoul(keep_iterates_p.first) == 1)
700 iterates =
new std::deque<VectorType>;
722 _functionalt_var.setlength(alglib::ae_int_t(
723 Intern::derefer<VectorType>(
_vec_def,
nullptr).
template size<LAFEM::Perspective::pod>()));
731 alglib::mincgsetxrep(
_state,
true);
748 case NLCGDirectionUpdate::DaiYuan:
749 alglib::mincgsetcgtype(
_state, 0);
751 case NLCGDirectionUpdate::DYHSHybrid:
752 alglib::mincgsetcgtype(
_state, 1);
771 iterates =
new std::deque<VectorType>;
826 this->_vec_def.clear();
827 this->_vec_tmp.clear();
834 return "ALGLIBMinCG";
847 this->_vec_def.copy(vec_def);
848 this->
_filter.filter_def(this->_vec_def);
863 this->_vec_def.scale(this->_vec_def,
DataType(-1));
864 this->
_filter.filter_def(this->_vec_def);
888 Statistics::add_solver_expression(std::make_shared<ExpressionStartSolve>(this->
name()));
891 if(iterates !=
nullptr)
893 auto tmp = vec_sol.clone();
894 iterates->push_back(std::move(tmp));
903 auto vec_sol_elements = Intern::derefer<VectorType>(vec_sol,
nullptr).template elements<LAFEM::Perspective::pod>();
919 switch(
_report.terminationtype)
972 static void _log(
const alglib::real_1d_array& DOXY(x),
double DOXY(func),
void* ptr)
978 if(me->
_state.c_ptr()->repnfev > 0)
986 alglib::mincgrequesttermination(me->
_state);
1008 static void _func_grad(
const alglib::real_1d_array& x,
double& fval, alglib::real_1d_array&
grad,
void* ptr)
1013 auto vec_tmp_elements = Intern::derefer<VectorType>(me->
_vec_tmp,
nullptr).template
1014 elements<LAFEM::Perspective::pod>();
1017 for(alglib::ae_int_t i(0); i < x.length(); ++i)
1019 vec_tmp_elements[i] =
DataType(x[i]);
1029 fval = double(me->
_fval);
1032 auto vec_def_elements = Intern::derefer<VectorType>(me->
_vec_def,
nullptr).template
1033 elements<LAFEM::Perspective::pod>();
1035 for(alglib::ae_int_t i(0); i <
grad.length(); ++i)
1037 grad[i] = double(vec_def_elements[i]);
1059 template<
typename Functional_,
typename Filter_>
1061 Functional_& functional_, Filter_& filter_,
1063 bool keep_iterates_ =
false)
1065 return std::make_shared<ALGLIBMinCG<Functional_, Filter_>>(functional_, filter_, du_, keep_iterates_);
1086 template<
typename Functional_,
typename Filter_>
1089 Functional_& functional_, Filter_& filter_)
1091 return std::make_shared<ALGLIBMinCG<Functional_, Filter_>>(section_name, section, functional_, filter_);
#define XABORTM(msg)
Abortion macro definition with custom message.
#define XASSERT(expr)
Assertion macro definition.
A class organizing a tree of key-value pairs.
std::pair< String, bool > query(String key_path) const
Queries a value by its key path.
Wrapper around ALGLIB's mincg implementation for minimising an functional's gradient.
VectorType _vec_def
defect vector
virtual Status _apply_intern(VectorType &vec_sol)
Internal function, applies the solver.
void set_direction_update(NLCGDirectionUpdate update_)
Sets the direction update method.
virtual Status apply(VectorType &vec_cor, const VectorType &vec_def) override
Solver application method.
NLCGDirectionUpdate _direction_update
Method to update the search direction, defaults to DYHSHybrid.
void set_tol_abs(DataType tol_abs)
Sets the relative tolerance for the norm of the defect vector.
void set_max_iter(Index max_iter)
Sets the maximum iteration count for the solver.
VectorType _vec_tmp
temporary vector
virtual Status correct(VectorType &vec_sol, const VectorType &vec_rhs) override
Solver correction method.
ALGLIBMinCG(const String §ion_name, const PropertyMap *section, Functional_ &functional_, Filter_ &filter_)
Constructor using a PropertyMap.
Filter_ FilterType
The filter type.
alglib::real_1d_array _functionalt_var
Optimization variable for ALGLIB.
static void _log(const alglib::real_1d_array &x, double func, void *ptr)
Internal function for logging/plotting.
alglib::mincgstate _state
This will hold the state of the optimization problem in ALGLIB.
void set_keep_iterates(bool keep_iterates)
Sets the iterates deque according to a bool.
virtual String name() const override
Returns a descriptive string.
virtual ~ALGLIBMinCG()
Virtual destructor.
std::deque< VectorType > * iterates
Can hold all iterates for debugging purposes.
virtual void set_tol_fval(DataType tol_fval) override
Sets the tolerance for function value improvement.
static constexpr NLCGDirectionUpdate direction_update_default
Default NLCG search direction update.
Functional_::DataType DataType
Underlying floating point type.
virtual void init_symbolic() override
Symbolic initialization method.
SolverBase< VectorType > PrecondType
Generic preconditioner.
Functional_::VectorTypeR VectorType
Input type for the gradient.
Functional_::GradientType GradientType
Type of the functional's gradient has.
alglib::mincgreport _report
Convergence report etc.
NLOptLS< Functional_, Filter_ > BaseClass
Our baseclass.
ALGLIBMinCG(Functional_ &functional_, Filter_ &filter_, NLCGDirectionUpdate du_=direction_update_default, bool keep_iterates=false)
Standard constructor.
Functional_ FunctionalType
The nonlinear functional type.
static void _func_grad(const alglib::real_1d_array &x, double &fval, alglib::real_1d_array &grad, void *ptr)
Internal function for computing functional value and gradient.
virtual void done_symbolic() override
Symbolic finalization method.
Wrapper around ALGLIB's lBFGS implementation for minimising an functional's gradient.
virtual ~ALGLIBMinLBFGS()
Virtual destructor.
alglib::minlbfgsstate _state
This will hold the state of the optimization problem in ALGLIB.
void set_max_iter(Index max_iter)
Sets the maximum iteration count for the solver.
VectorType _vec_tmp
temporary vector
alglib::real_1d_array _functionalt_var
Optimization variable for ALGLIB.
Filter_ FilterType
The filter type.
void set_lbfgs_dim(alglib::ae_int_t lbfgs_dim)
Sets the dimension for the LBFGS update.
VectorType _vec_def
defect vector
virtual void set_tol_fval(DataType tol_fval) override
Sets the tolerance for function value improvement.
SolverBase< VectorType > PrecondType
Generic preconditioner.
virtual Status _apply_intern(VectorType &vec_sol)
Internal function, applies the solver.
virtual void done_symbolic() override
Symbolic finalization method.
void set_keep_iterates(bool keep_iterates)
Sets the iterates deque according to a bool.
virtual Status apply(VectorType &vec_cor, const VectorType &vec_def) override
Solver application method.
std::deque< VectorType > * iterates
Can hold all iterates for debugging purposes.
virtual void init_symbolic() override
Symbolic initialization method.
Functional_::VectorTypeR VectorType
Input type for the gradient.
ALGLIBMinLBFGS(const String §ion_name, const PropertyMap *section, Functional_ &functional_, Filter_ &filter_)
Constructor using a PropertyMap.
alglib::ae_int_t _lbfgs_dim
Dimension for lBFGS Hessian update.
static void _log(const alglib::real_1d_array &x, double func, void *ptr)
Internal function for logging/plotting.
virtual String name() const override
Returns a descriptive string.
NLOptLS< Functional_, Filter_ > BaseClass
Our baseclass.
alglib::minlbfgsreport _report
Convergence report etc.
static void _func_grad(const alglib::real_1d_array &x, double &fval, alglib::real_1d_array &grad, void *ptr)
Internal function for computing functional value and gradient.
Functional_::GradientType GradientType
Type of the functional's gradient has.
Functional_ FunctionalType
The nonlinear functional type.
Functional_::DataType DataType
Underlying floating point type.
virtual Status correct(VectorType &vec_sol, const VectorType &vec_rhs) override
Solver correction method.
void set_tol_abs(DataType tol_abs)
Sets the relative tolerance for the norm of the defect vector.
ALGLIBMinLBFGS(Functional_ &functional_, Filter_ &filter_, const alglib::ae_int_t lbfgs_dim_=alglib::ae_int_t(0), const bool keep_iterates=false)
Standard constructor.
Helper class for iteration statistics collection.
void set_max_iter(Index max_iter)
Sets the maximum iteration count for the solver.
Index get_num_iter() const
Returns number of performed iterations.
void set_tol_abs(DataType tol_abs)
Sets the absolute tolerance for the solver.
Status _status
current status of the solver
virtual void plot_summary() const
Plot a summary of the last solver run.
Index _max_iter
maximum number of iterations
Base class for line search based nonlinear optimizers.
virtual Status _set_initial_defect(const VectorType &vec_def, const VectorType &vec_sol) override
Internal function: sets the initial defect vector.
DataType _fval_prev
Functional value from the previous iteration.
virtual Status _set_new_defect(const VectorType &vec_r, const VectorType &vec_sol) override
Internal function: sets the new defect norm.
DataType _fval
Current functional value.
Functional_ & _functional
Our nonlinear functional.
virtual void set_tol_fval(DataType tol_fval)
Sets the tolerance for function value improvement.
DataType _tol_fval
Tolerance for function improvement.
DataType _tol_step
Tolerance for the length of the update step.
virtual void set_ls_iter_digits(Index digits)
Sets the number of digits used to plot line search iteration numbers.
Index _ls_its
The number of iterations the linesearch performed in the last iteration of this solver.
Filter_ & _filter
The filter we apply to the gradient.
DataType _steplength
The last step length of the line search.
Polymorphic solver interface.
virtual void init_symbolic()
Symbolic initialization method.
virtual void done_symbolic()
Symbolic finalization method.
String class implementation.
T_ min(T_ a, T_ b)
Returns the minimum of two values.
NLCGDirectionUpdate
Enum for NLCG search direction updates.
Status
Solver status return codes enumeration.
@ success
solving successful (convergence criterion fulfilled)
@ progress
continue iteration (internal use only)
@ undefined
undefined status
@ stagnated
solver stagnated (stagnation criterion fulfilled)
@ max_iter
solver reached maximum iterations
@ aborted
premature abort (solver aborted due to internal errors or preconditioner failure)
std::shared_ptr< ALGLIBMinCG< Functional_, Filter_ > > new_alglib_mincg(Functional_ &functional_, Filter_ &filter_, NLCGDirectionUpdate du_=ALGLIBMinCG< Functional_, Filter_ >::direction_update_default, bool keep_iterates_=false)
Creates a new ALGLIBMinCG solver object.
std::shared_ptr< ALGLIBMinLBFGS< Functional_, Filter_ > > new_alglib_minlbfgs(Functional_ &functional_, Filter_ &filter_, alglib::ae_int_t lbfgs_dim_=alglib::ae_int_t(0), bool keep_iterates=false)
Creates a new ALGLIBMinLBFGS solver object.
String stringify(const T_ &item)
Converts an item into a String.
@ grad
specifies whether the space should supply basis function gradients
std::uint64_t Index
Index data type.