Basin

Search documentation

Search the guides, solvers, and migration docs.

  • Guide
  • Visualizer
  • Benchmarks

Documentation

  • Overview
  • Getting started
  • Migrating from Argmin
  • Migrating to Basin 2.0
  • Migrating to Basin 3.0

Solvers

  • Choosing a solver
  • First-order
    • Gradient descent
    • Nonlinear CG
    • Stochastic gradient descent
    • Projected gradient descent
  • Quasi-Newton
    • BFGS
    • L-BFGS
    • L-BFGS-B
  • Derivative-free
    • Nelder–Mead
    • MADS
    • NEWUOA
    • BOBYQA
    • LINCOA
    • COBYLA
    • Solis–Wets
  • Trust-region
    • Trust-region Newton
  • Nonlinear least squares
    • Gauss–Newton
    • Levenberg–Marquardt
    • Levenberg–Marquardt QR
    • Bounded Levenberg–Marquardt
    • Trust-region reflective
  • Global and stochastic
    • DIRECT
    • Globalized bounded Nelder–Mead
    • Simulated annealing
    • CMA-ES
    • Bounded CMA-ES
    • Differential evolution
    • Particle swarm
    • Random search
    • Steady-state genetic algorithm
    • Basin-hopping
  • Memetic
    • CMA-ES with local search
    • Bounded CMA-ES with local search
    • DE with local search
    • Local-search chains
    • CMA-ES chains
    • Solis–Wets chains
  • General constrained
    • SLSQP
    • Barrier method
    • Augmented Lagrangian
  • Scalar minimization
    • Brent
    • Brent with derivatives
    • Golden-section search
  • Root finding
    • Bisection
    • Brent
    • Secant
    • Newton
    • Halley
    • TOMS 748
Navigation

Documentation

  • Overview
  • Getting started
  • Migrating from Argmin
  • Migrating to Basin 2.0
  • Migrating to Basin 3.0

Solvers

  • Choosing a solver
  • First-order
    • Gradient descent
    • Nonlinear CG
    • Stochastic gradient descent
    • Projected gradient descent
  • Quasi-Newton
    • BFGS
    • L-BFGS
    • L-BFGS-B
  • Derivative-free
    • Nelder–Mead
    • MADS
    • NEWUOA
    • BOBYQA
    • LINCOA
    • COBYLA
    • Solis–Wets
  • Trust-region
    • Trust-region Newton
  • Nonlinear least squares
    • Gauss–Newton
    • Levenberg–Marquardt
    • Levenberg–Marquardt QR
    • Bounded Levenberg–Marquardt
    • Trust-region reflective
  • Global and stochastic
    • DIRECT
    • Globalized bounded Nelder–Mead
    • Simulated annealing
    • CMA-ES
    • Bounded CMA-ES
    • Differential evolution
    • Particle swarm
    • Random search
    • Steady-state genetic algorithm
    • Basin-hopping
  • Memetic
    • CMA-ES with local search
    • Bounded CMA-ES with local search
    • DE with local search
    • Local-search chains
    • CMA-ES chains
    • Solis–Wets chains
  • General constrained
    • SLSQP
    • Barrier method
    • Augmented Lagrangian
  • Scalar minimization
    • Brent
    • Brent with derivatives
    • Golden-section search
  • Root finding
    • Bisection
    • Brent
    • Secant
    • Newton
    • Halley
    • TOMS 748

COBYLA

COBYLA is a local derivative-free optimizer for constrained scalar functions. It estimates the objective and constraints by linear interpolation, then balances objective reduction against the largest constraint violation. You supply function values, and the starting point may be infeasible.

API reference

PropertyRequirement
ObjectiveA scalar function; smoothness helps the linear models
EvaluationsCostFunction and values for declared nonlinear blocks
SearchLocal, from one starting point
ConstraintsBounds, linear blocks, nonlinear equalities, and nonlinear inequalities
ParametersAll four dense backends, with f32 or f64

When to use it

Consider COBYLA when the objective or constraints lack reliable derivatives and you need a method that can recover from an infeasible start. Powell’s 1994 chapter introduces the linear interpolation method. Smoothness helps those models predict local behavior, although Basin does not require differentiability.

If all constraints are linear and the objective is smooth, compare LINCOA, which builds a quadratic objective model. For box bounds alone, compare BOBYQA. For a nonsmooth problem with nonlinear inequalities, compare the progressive-barrier mode of MADS.

COBYLA permits infeasible trial points, including points outside box bounds. Use it when your callbacks can evaluate those points. Its local search also means that different starts can find different constrained solutions.

How it works

At each stage, COBYLA maintains a simplex of n + 1 points for n parameters. The objective and each constraint have a linear interpolating model on those vertices. A trust-region subproblem proposes a step using the models; geometry steps repair the simplex when it becomes poorly shaped.

The method uses a merit function of the form objective + penalty * violation, where the violation is the largest positive constraint residual. The penalty changes as the method balances reducing the objective and improving feasibility. The resolution rho shrinks toward the configured final radius.

Basin folds bounds and linear and nonlinear blocks into residuals with the convention c(x) <= 0. An equality contributes residuals of opposite signs. The rows are neither normalized nor relaxed. The current implementation interpolates every constraint model, including linear constraints.

Example

Minimizing x[0] * x[1] inside the unit disk has minimum value -0.5. The example declares one nonlinear inequality, starts outside the disk, and checks both the selected objective and its reported violation.

use basin::{
    Cobyla, Constrained, ConstraintSet, ConstraintSolveError, CostFunction,
    Executor, NonlinearInequalityValues, Termination, ViolationMeasure,
};
use std::convert::Infallible;

struct Disk;

impl CostFunction for Disk {
    type Param = Vec<f64>;
    type Output = f64;
    type Error = Infallible;

    fn cost(&self, x: &Self::Param) -> Result<f64, Self::Error> {
        Ok(x[0] * x[1])
    }
}

impl NonlinearInequalityValues for Disk {
    type Param = Vec<f64>;
    type Values = Vec<f64>;
    type Error = Infallible;

    fn nonlinear_inequalities(
        &self,
        x: &Self::Param,
    ) -> Result<Self::Values, ConstraintSolveError<Self::Error>> {
        Ok(vec![x[0].powi(2) + x[1].powi(2) - 1.0])
    }
}

fn main() {
    let constraints = ConstraintSet::new().with_nonlinear_inequalities(1);
    let problem = Constrained::new(Disk, constraints);
    let solver = Cobyla::new()
        .with_initial_radius(0.5)
        .with_final_radius(1e-7);

    let result = Executor::from_start(problem, solver, vec![1.0, 1.0])
        .max_cost_evals(500)
        .run()
        .unwrap();

    assert!(matches!(
        result.report.termination,
        Termination::Converged(_)
    ));
    let (x, cost, violation) = result.state.best().unwrap();
    assert_eq!(violation.measure(), &ViolationMeasure::LInf);
    assert!(violation.value < 1e-5);
    assert!(x[0].powi(2) + x[1].powi(2) <= 1.0 + 1e-5);
    assert!((cost + 0.5).abs() < 1e-3);
}

The constraint callback returns the residual x[0]^2 + x[1]^2 - 1, so nonpositive values mean feasibility. Keep the declared count equal to the callback’s output length. Nonlinear equalities use a separate with_nonlinear_equalities declaration and NonlinearEqualityValues callback.

Practical considerations

Scale constraint residuals deliberately

The largest positive residual enters the merit function without row normalization. Multiplying a constraint by a positive constant preserves its feasible set but changes its influence on the search. Choose residual units that make the relative importance of violations sensible.

Equalities become paired inequalities. A small final radius does not guarantee that either residual is small enough for your application. Check each constraint at the returned point using your own feasibility tolerance.

Choose radii for the accuracy of your evaluations

The initial radius defaults to 1.0 and the final radius to 1e-6; require initial_radius > final_radius > 0. Rescale parameters so a single radius describes useful changes in each coordinate. Tiny radii cannot recover detail hidden by objective noise, constraint noise, or rounding.

Natural convergence means the final-radius stage finished, not that the constraints are satisfied. with_absolute_radius_tolerance adds an optional earlier check without changing the algorithm’s schedule. Inspect the termination report together with the violation report.

Budget objective and constraint calls

max_cost_evals limits objective calls. Nonlinear inequality and equality callbacks count separately as residual evaluations, so use max_evaluations(EvaluationKind::Residual, limit) when those callbacks have their own budget. Bound and linear arithmetic require no residual callbacks.

The selected point follows COBYLA’s feasibility and merit rules. Its objective can increase as feasibility improves, so objective-only executor targets and stall checks are unavailable for this state.

Implementation

COBYLA publishes the selected point, objective, and ViolationReport through SelectedState. The report uses the unscaled LInf measure with PrimaModeration: extreme and non-finite callback values undergo PRIMA’s moderation before model construction and reporting. Reported violation is the maximum positive folded residual, rather than a derivative-based optimality test.

The solver owns the simplex, penalty, filter, and radius schedule. Retain it with Executor::run_with_solver to inspect rho() or geometry_diagnostics(). Fresh initialization rebuilds those structures; an ExactCheckpoint preserves them for exact continuation.

Supported parameter types are Vec<F>, nalgebra::DVector<F>, ndarray::Array1<F>, and faer::Col<F>, with F = f32 or f64. Nonlinear values may use a different vector representation from the parameters. Present linear blocks additionally require the dense matrix capabilities documented in the API. The simplex calculations use pure-Rust internal buffers, need no BLAS/LAPACK provider, and work on WASM. Basin ports and cross-validates the algorithm against PRIMA.

References

  1. Powell, M. J. D. (1994). A direct search optimization method that models the objective and constraint functions by linear interpolation. In Advances in Optimization and Numerical Analysis (pp. 51–67). Springer. doi:10.1007/978-94-015-8330-5_4.

Basin v3.1.0 — numerical optimization for Rust.

GitHub docs.rs crates.io