27 #ifndef CDPL_MATH_BFGSMINIMIZER_HPP
28 #define CDPL_MATH_BFGSMINIMIZER_HPP
52 template <typename VA, typename VT = typename MinimizerVariableArrayTraits<VA>::ValueType,
typename FVT = VT>
93 rho(0.01), tau1(9), tau2(0.05), tau3(0.5), order(3), sigma(0.1), func(func), gradFunc(grad_func), status(
SUCCESS) {}
158 for (std::size_t i = 0; max_iter == 0 || i < max_iter; i++) {
159 status =
iterate(fValue, x, g);
164 if (g_norm >=
ValueType(0) && g0Norm <= g_norm)
167 if (delta_f >=
ValueType(0) && deltaF <= delta_f)
192 startF = gradFunc(x, g);
201 multiply(p, -1 / g0Norm);
240 alpha1 = std::min(
ValueType(1), 2 * del / -fp0);
252 updatePosition(alpha, x, f, g);
284 A = -(1 + dgnorm * dgnorm / dxdg) *
B + dgg / dxdg;
302 multiply(p, dir / pNorm);
316 void initFuncEvalCache()
351 return MinimizerVariableArrayTraits<VA>::template norm2<ValueType>(v);
356 return MinimizerVariableArrayTraits<VA>::template dot<ValueType>(v1, v2);
366 return dot(gAlpha, p);
371 if (alpha == xCacheKey)
378 axpy(alpha, p, xAlpha);
385 if (alpha == fCacheKey)
390 fAlpha = func(xAlpha);
398 if (alpha == dfCacheKey)
403 if (alpha != gCacheKey) {
404 fAlpha = gradFunc(xAlpha, gAlpha);
419 if (alpha == fCacheKey && alpha == dfCacheKey) {
425 if (alpha == fCacheKey || alpha == dfCacheKey) {
433 fAlpha = gradFunc(xAlpha, gAlpha);
450 getFDF(alpha, f_alpha, df_alpha);
457 void changeDirection()
540 ValueType fl = f0 + zl * (fp0 + zl * (f1 - f0 - fp0));
541 ValueType fh = f0 + zh * (fp0 + zh * (f1 - f0 - fp0));
554 if (z > zl && z < zh) {
555 ValueType f = f0 + z * (fp0 + z * (f1 - f0 - fp0));
581 return c0 + z * (c1 + z * (c2 + z * c3));
601 ValueType eta = 3 * (f1 - f0) - 2 * fp0 - fp1;
602 ValueType xi = fp0 + fp1 - 2 * (f1 - f0);
603 ValueType c0 = f0, c1 = fp0, c2 = eta, c3 = xi;
606 ValueType fmin = cubic(c0, c1, c2, c3, zl);
608 checkExtremum(c0, c1, c2, c3, zh, zmin, fmin);
611 std::size_t n = solveQuadratic(3 * c3, 2 * c2, c1, z0, z1);
614 if (z0 > zl && z0 < zh)
615 checkExtremum(c0, c1, c2, c3, z0, zmin, fmin);
617 if (z1 > zl && z1 < zh)
618 checkExtremum(c0, c1, c2, c3, z1, zmin, fmin);
621 if (z0 > zl && z0 < zh)
622 checkExtremum(c0, c1, c2, c3, z0, zmin, fmin);
645 if (order > 2 && std::isfinite(fpb))
646 z = interpolateCubic(fa, fpa * (b - a), fb, fpb * (b - a), zmin, zmax);
648 z = interpolateQuadratic(fa, fpa * (b - a), fb, zmin, zmax);
657 ValueType falpha, fpalpha, delta, alpha_next;
674 const std::size_t num_brack_iter = 100, section_iters = 100;
677 while (i++ < num_brack_iter) {
678 falpha = getF(alpha);
682 if (falpha > f0 + alpha * rho * fp0 || falpha >= falpha_prev) {
688 fpb = std::numeric_limits<ValueType>::quiet_NaN();
692 fpalpha = getDF(alpha);
711 delta = alpha - alpha_prev;
716 alpha_next = interpolate(alpha_prev, falpha_prev, fpalpha_prev,
717 alpha, falpha, fpalpha, lower, upper);
720 falpha_prev = falpha;
721 fpalpha_prev = fpalpha;
727 while (i++ < section_iters) {
733 alpha = interpolate(a, fa, fpa, b, fb, fpb, lower, upper);
734 falpha = getF(alpha);
736 if ((a - alpha) * fpa <= std::numeric_limits<ValueType>::epsilon()) {
741 if (falpha > f0 + rho * alpha * fp0 || falpha >= fa) {
745 fpb = std::numeric_limits<ValueType>::quiet_NaN();
748 fpalpha = getDF(alpha);
778 const std::size_t order;
Provides traits to flexibly handle different types of variable arrays in function optimization algori...
Definition of type traits.
Fletcher's implementation of the BFGS method.
Definition: BFGSMinimizer.hpp:54
Status iterate(ValueType &f, VariableArrayType &x, VariableArrayType &g)
Performs a single BFGS iteration: line search along the current search direction, BFGS update of the ...
Definition: BFGSMinimizer.hpp:225
std::function< FVT(const VA &)> ObjectiveFunction
Type of the objective function.
Definition: BFGSMinimizer.hpp:67
ValueType getFunctionValue() const
Returns the function value at the end of the most recent iterate() call.
Definition: BFGSMinimizer.hpp:117
Status getStatus() const
Returns the current status of the minimizer.
Definition: BFGSMinimizer.hpp:135
Status minimize(VariableArrayType &x, VariableArrayType &g, std::size_t max_iter, const ValueType &g_norm, const ValueType &delta_f, bool do_setup=true)
Runs the BFGS minimization loop on x.
Definition: BFGSMinimizer.hpp:150
Status
Status bitmask reported by minimize() and getStatus(). Multiple flags may be combined.
Definition: BFGSMinimizer.hpp:73
@ NO_PROGRESS
No more progress towards the solution can be made.
Definition: BFGSMinimizer.hpp:78
@ SUCCESS
Iteration step completed successfully (no termination condition met yet).
Definition: BFGSMinimizer.hpp:76
@ GNORM_REACHED
The configured gradient-norm threshold has been reached.
Definition: BFGSMinimizer.hpp:82
@ ITER_LIMIT_REACHED
The maximum number of minimization iterations has been reached.
Definition: BFGSMinimizer.hpp:80
@ DELTAF_REACHED
The configured function-value delta between successive iterations has been reached.
Definition: BFGSMinimizer.hpp:84
BFGSMinimizer(const ObjectiveFunction &func, const GradientFunction &grad_func)
Constructs the BFGSMinimizer instance with the given objective and gradient functions.
Definition: BFGSMinimizer.hpp:92
ValueType getGradientNorm() const
Returns the L2 norm of the gradient at the end of the most recent iterate() call.
Definition: BFGSMinimizer.hpp:99
std::function< FVT(const VA &, VA &)> GradientFunction
Type of the gradient function (computes the objective value and writes the gradient into the second a...
Definition: BFGSMinimizer.hpp:65
ValueType setup(const VariableArrayType &x, VariableArrayType &g, const ValueType &step_size=0.001, const ValueType &tol=0.15)
Initializes the minimizer state for a subsequent iterate() / minimize() loop.
Definition: BFGSMinimizer.hpp:185
FVT FunctionValueType
The scalar return type of the objective and gradient functions.
Definition: BFGSMinimizer.hpp:62
ValueType getFunctionDelta() const
Returns the magnitude of the function-value decrease produced by the most recent iterate() call.
Definition: BFGSMinimizer.hpp:108
std::size_t getNumIterations() const
Returns the number of iterations performed by the most recent minimize() or iterate() loop.
Definition: BFGSMinimizer.hpp:126
VT ValueType
The scalar value type of VariableArrayType.
Definition: BFGSMinimizer.hpp:60
VA VariableArrayType
The type of the variable array passed to the minimizer.
Definition: BFGSMinimizer.hpp:58
constexpr unsigned int A
Generic type that covers any element except hydrogen.
Definition: AtomType.hpp:637
constexpr unsigned int B
Specifies Boron.
Definition: AtomType.hpp:87
constexpr unsigned int r
Specifies that the stereocenter has r configuration.
Definition: CIPDescriptor.hpp:76
The namespace of the Chemical Data Processing Library.
static void axpy(const T &alpha, const ArrayType &x, ArrayType &y)
Performs the in-place BLAS-style axpy operation .
Definition: MinimizerVariableArrayTraits.hpp:123
static void multiply(ArrayType &a, const T &v)
Multiplies every element of a by the scalar v.
Definition: MinimizerVariableArrayTraits.hpp:154
static void sub(ArrayType &a1, const ArrayType &a2)
Subtracts a2 from a1 element-wise ( ).
Definition: MinimizerVariableArrayTraits.hpp:164
static void assign(ArrayType &a1, const ArrayType &a2)
Copies the contents of a2 into a1.
Definition: MinimizerVariableArrayTraits.hpp:142
static void clear(ArrayType &a)
Sets all elements of a to the default-constructed ValueType.
Definition: MinimizerVariableArrayTraits.hpp:132
static RealType abs(ConstReference t)
Returns the absolute value of t (std::abs for signed types, the identity for unsigned types).
Definition: TypeTraits.hpp:131
static ValueType sqrt(ConstReference t)
Returns the square root of t.
Definition: TypeTraits.hpp:141
Primary traits template for scalar arithmetic value types.
Definition: TypeTraits.hpp:285