| Home | Libraries | People | FAQ | More

### 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

- `Optimizer& opt` : Optimizer instance.
- `ConstraintPolicy project` : Projection policy applied after each `step()`. Default is `unconstrained_policy` (no projection).
- `ConvergencePolicy converged` : Stopping criterion. Default is `gradient_norm_convergence_policy(tol=1e-3)`.
- `TerminationPolicy terminate` : Hard stop criterion. Default is `max_iter_termination_policy(100000)`.
- `bool history` : If true, records `opt.objective_value()` after each iteration in `optimization_result::objective_history.`

##### 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)