Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

minimize

Synopsis
#include <boost/math/optimization/minimizer.hpp>

namespace boost {
namespace math {
namespace optimization {
template<typename RealType>
struct optimization_result
{
  size_t num_iter = 0;
  RealType objective_value;
  std::vector<RealType> objective_history;
  bool converged;
};

/* Minimize an objective using a given optimizer.
 *
 * The optimizer `opt` must expose a `step()` method and the associated
 * typedefs:
 *   - argument_container_t
 *   - real_type_t
 *
 * The behavior of the minimization loop is controlled by policy objects:
 *  - ConstraintPolicy: projects variables onto a feasible set
 *  - ConvergencePolicy: determines when convergence has been reached
 *  - TerminationPolicy: determines when optimization must stop regardless
 *    of convergence (e.g. max iterations)
 *
 * The function returns an `optimization_result` summarizing the run.
 */
template<class Optimizer,
         class ConstraintPolicy =
           unconstrained_policy<typename Optimizer::argument_container_t>,
         class ConvergencePolicy =
           gradient_norm_convergence_policy<typename Optimizer::real_type_t>,
         class TerminationPolicy = max_iter_termination_policy>
auto minimize(Optimizer& opt,
         ConstraintPolicy project = ConstraintPolicy{},
         ConvergencePolicy converged =
           ConvergencePolicy{
             static_cast<typename Optimizer::real_type_t>(1e-3) },
         TerminationPolicy terminate = TerminationPolicy(100000),
         bool history = true)

This header provides a generic driver function minimize that repeatedly advances an optimizer via step(), optionally projects parameters onto a constraint set, and stops when either a convergence criterion is met or a termination criterion triggers.

Parameters
Convergence Policies

Convergence policies decide when the optimization has converged. Each policy has the signature:

bool operator()(const GradientContainer& g, RealType objective_value) const;
gradient_norm_convergence_policy

Stops when the Euclidean norm of the gradient falls below a tolerance:

template<typename RealType>
struct gradient_norm_convergence_policy
{
explicit gradient_norm_convergence_policy(RealType tol);

template<class GradientContainer>
bool operator()(const GradientContainer& g, RealType objective_v) const;
};
objective_tol_convergence_policy

Stops when the absolute change in objective value between successive iterations drops below a tolerance:

template<typename RealType>
struct objective_tol_convergence_policy
{
explicit objective_tol_convergence_policy(RealType tol);

template<class GradientContainer>
bool operator()(const GradientContainer&, RealType objective_v) const;
};

The first call always returns false

relative_objective_tol_policy

Stops when the relative objective change drops below a tolerance:

template<typename RealType>
struct relative_objective_tol_policy
{
explicit relative_objective_tol_policy(RealType rel_tol);

template<class GradientContainer>
bool operator()(const GradientContainer&, RealType objective_v) const;
};

The relative change is computed as:

abs(obj - last_obj) / max(1, abs(last_obj))
combined_convergence_policy

Combines two convergence policies and stops when either triggers:

template<class Policy1, class Policy2>
struct combined_convergence_policy
{
combined_convergence_policy(Policy1 p1, Policy2 p2);

template<class GradientContainer, class RealType>
bool operator()(const GradientContainer& g, RealType obj) const;
};
Termination Policies

Termination policies provide a hard stop independent of convergence. Each policy has the signature:

bool operator()(size_t iter);
max_iter_termination_policy

Stops after a fixed number of iterations

struct max_iter_termination_policy { explicit max_iter_termination_policy(size_t max_iter); bool operator()(size_t iter); };
wallclock_termination_policy

Stops after a wall-clock time budget:

struct wallclock_termination_policy { explicit wallclock_termination_policy(std::chrono::milliseconds max_time); bool operator()(size_t iter) const; };
Constraint and Projection Policies

Projection policies modify the optimizer variables after each step. Each policy has the signature:

void operator()(ArgumentContainer& x) const;
unconstrained_policy

No projection; leaves parameters unchanged

template<typename ArgumentContainer> struct unconstrained_policy { void operator()(ArgumentContainer&); };
box_constraints

Clamps each variable into [min, max]

template<typename ArgumentContainer, typename RealType> struct box_constraints { box_constraints(RealType min, RealType max); void operator()(ArgumentContainer& x); };
nonnegativity_constraint

Sets anything less than 0 to 0

template<typename ArgumentContainer, typename RealType> struct nonnegativity_constraint { void operator()(ArgumentContainer& x) const; };
l2_ball_constraint

Projects onto the L2 ball of radius radius by uniform scaling when needed

template<typename ArgumentContainer, typename RealType> struct l2_ball_constraint { explicit l2_ball_constraint(RealType radius); void operator()(ArgumentContainer& x) const; };
l1_ball_constraint

Projects onto the L1 ball of radius radius by uniform scaling

template<typename ArgumentContainer, typename RealType> struct l1_ball_constraint { explicit l1_ball_constraint(RealType radius); void operator()(ArgumentContainer& x) const; };

This is not the exact Euclidean projection onto the L1 ball; it is a simple scaling-based constraint

simplex_constraint

Projects onto the scaled probability simplex by clipping negatives to 0 and renormalizing to sum to 1

template<typename ArgumentContainer, typename RealType> struct simplex_constraint { void operator()(ArgumentContainer& x) const; };
function_constraint

Wraps a user-provided projection function

template<typename ArgumentContainer> struct function_constraint { using func_t = void (*)(ArgumentContainer&); explicit function_constraint(func_t f); void operator()(ArgumentContainer& x) const; };
unit_sphere_constraint

Normalizes the vector to unit L2 norm

template<typename ArgumentContainer, typename RealType> struct unit_sphere_constraint { void operator()(ArgumentContainer& x) const; };

This projects onto the unit sphere (if ||x||_2 > 0)


PrevUpHomeNext