pub struct Cobyla<F = f64> { /* private fields */ }Expand description
COBYLA (Powell 1994): derivative-free optimization with general nonlinear inequality constraints.
COBYLA minimizes a smooth-or-not objective F(x) subject to c(x) ≤ 0 for
an arbitrary vector-valued constraint function c, using only objective and
constraint values — no derivatives. Each iteration interpolates linear
models of F and c at the vertices of a simplex, takes a trust-region step
under those linear models, and ranks points by the L-infinity merit
Φ = F + μ·[maxᵢ cᵢ]₊. The trust-region resolution ρ shrinks from ρ_beg
to ρ_end.
Drive it with an Executor over a CobylaState on a
problem implementing CostFunction and NonlinearInequalityConstraints:
use basin::{CostFunction, Cobyla, CobylaState, Executor, MaxCostEvals, NonlinearInequalityConstraints};
// min x0·x1 s.t. x0² + x1² ≤ 1 (optimum F* = −1/2 on the unit circle).
struct Disk;
impl CostFunction for Disk {
type Param = Vec<f64>;
type Output = f64;
type Error = std::convert::Infallible;
fn cost(&self, x: &Vec<f64>) -> Result<f64, std::convert::Infallible> {
Ok(x[0] * x[1])
}
}
impl NonlinearInequalityConstraints for Disk {
fn constraints(&self, x: &Vec<f64>) -> Result<Vec<f64>, std::convert::Infallible> {
Ok(vec![x[0] * x[0] + x[1] * x[1] - 1.0])
}
fn num_constraints(&self) -> usize { 1 }
}
let solver = Cobyla::new().with_rho_beg(0.5).with_rho_end(1e-6);
let state = CobylaState::new(vec![1.0, 1.0]);
let result = Executor::new(Disk, solver, state)
.terminate_on(MaxCostEvals(500))
.run()
.unwrap();
assert!((result.best_cost() - (-0.5)).abs() < 1e-3);§Configuration
with_rho_beg— initial trust-region radiusρ_beg(a reasonable coarse change to the variables; default1.0).with_rho_end— final radiusρ_end, ~ the required accuracy (default1e-6); must satisfyρ_beg > ρ_end > 0.
§Constraints
COBYLA binds NonlinearInequalityConstraints: the problem returns the
constraint vector c(x) (feasible iff every cᵢ(x) ≤ 0). Express box bounds
or linear constraints as nonlinear ones, and an equality g(x) = 0 as the
pair g ≤ 0, −g ≤ 0. The start point need not be feasible.
§Termination
Natural convergence is ρ reaching ρ_end, signalled as
TerminationReason::SolverConverged. Add
MaxCostEvals to cap the budget (each evaluated point
counts once) or RhoTolerance to stop at a coarser
ρ.
§Backends
Backend-generic: the parameter vector needs only Clone, VectorLen,
and indexing; COBYLA’s models are pure-Rust Vec<f64> scratch (no backend
matrix, no linear solve), so Vec<f64>, nalgebra, ndarray, and faer all
work, and it is wasm-clean.
§References
M. J. D. Powell, A direct search optimization method that models the objective and constraint functions by linear interpolation, in Advances in Optimization and Numerical Analysis (eds. Gomez & Hennart), Kluwer (1994), pp. 51–67. Ported from PRIMA.
Implementations§
Source§impl<F: Scalar> Cobyla<F>
impl<F: Scalar> Cobyla<F>
Sourcepub fn with_rho_beg(self, rho_beg: F) -> Self
pub fn with_rho_beg(self, rho_beg: F) -> Self
Set the initial trust-region radius ρ_beg (also the initial Δ).
Sourcepub fn with_rho_end(self, rho_end: F) -> Self
pub fn with_rho_end(self, rho_end: F) -> Self
Set the final trust-region radius ρ_end. Must satisfy ρ_beg > ρ_end > 0.
Trait Implementations§
Source§impl<V, F> InitialState<V> for Cobyla<F>
impl<V, F> InitialState<V> for Cobyla<F>
Source§impl<P, V, F> Solver<P, CobylaState<V, F>> for Cobyla<F>where
F: Scalar,
P: CostFunction<Param = V, Output = F> + NonlinearInequalityConstraints,
V: Clone + VectorLen + Index<usize, Output = F> + IndexMut<usize, Output = F>,
impl<P, V, F> Solver<P, CobylaState<V, F>> for Cobyla<F>where
F: Scalar,
P: CostFunction<Param = V, Output = F> + NonlinearInequalityConstraints,
V: Clone + VectorLen + Index<usize, Output = F> + IndexMut<usize, Output = F>,
Source§type Error = <P as CostFunction>::Error
type Error = <P as CostFunction>::Error
type Error. See the trait docs.Source§fn init(
&mut self,
problem: &mut Problem<P>,
state: CobylaState<V, F>,
) -> Result<CobylaState<V, F>, Self::Error>
fn init( &mut self, problem: &mut Problem<P>, state: CobylaState<V, F>, ) -> Result<CobylaState<V, F>, Self::Error>
Source§fn next_iter(
&mut self,
problem: &mut Problem<P>,
state: CobylaState<V, F>,
) -> Result<(CobylaState<V, F>, Option<TerminationReason>), Self::Error>
fn next_iter( &mut self, problem: &mut Problem<P>, state: CobylaState<V, F>, ) -> Result<(CobylaState<V, F>, Option<TerminationReason>), Self::Error>
Auto Trait Implementations§
impl<F> Freeze for Cobyla<F>where
F: Freeze,
impl<F> RefUnwindSafe for Cobyla<F>where
F: RefUnwindSafe,
impl<F> Send for Cobyla<F>where
F: Send,
impl<F> Sync for Cobyla<F>where
F: Sync,
impl<F> Unpin for Cobyla<F>where
F: Unpin,
impl<F> UnsafeUnpin for Cobyla<F>where
F: UnsafeUnpin,
impl<F> UnwindSafe for Cobyla<F>where
F: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.