Skip to main content

Crate bobyqa

Crate bobyqa 

Source
Expand description

A pure-Rust, dependency-free port of M. J. D. Powell’s BOBYQA (Bound Optimization BY Quadratic Approximation) — a derivative-free, box-constrained local optimizer, ported from PRIMA’s modern Fortran.

Trajectory-parity-tested bit-exact against PRIMA (natively and on wasm32-wasip1).

One public solver surface: Bobyqa, the faithful PRIMA port. By default it stops as soon as rho reaches rho_end; setting Config::restart lets the solve continue instead — rho/delta go back to rho_begin and the interpolation set is rebuilt from scratch around the best point found — for objectives where a single rho_end convergence stalls short (noisy or quantized landscapes, long rho tails on hard fits). With restart: None the solver is bit-exact-unchanged by the restart machinery’s existence.

Three invariants hold across every call:

  • Feasibility — every point at which the objective is evaluated lies within [lower, upper].
  • Determinism — no global mutable state, no RNG, no I/O, no threads; identical inputs give identical outputs on a given target.
  • Zero-alloc warm path — heap allocation happens only at construction time (Bobyqa::new is the sole allocation site, sized once for the problem’s (n, npt) and restart schedule); a built solver then runs Bobyqa::minimize with no further allocation.

§Cargo features and no_std

The crate is #![no_std] + alloc. Two orthogonal features (both hold the bit-exact parity guarantee):

  • std (default) — gates the std::error::Error impl on Status; without it Status keeps Display only. Nothing else.
  • libm — backs the float math with the libm crate instead of std intrinsics; the only dependency, pulled in only by this feature.

no_std consumers build with default-features = false, features = ["libm"]. At least one of the two features must be enabled.

Structs§

Bobyqa
A reusable BOBYQA solver: holds every buffer the algorithm needs, built once per problem size and driven across many Bobyqa::minimize calls.
Config
Tuning knobs for Bobyqa. No Default: npt’s default (2n + 1) needs n — start from Config::new and assign the fields to override (#[non_exhaustive] rules out struct literals, update syntax included, outside this crate).
Outcome
The result of one Bobyqa::minimize call.
RestartConfig
The restart schedule, plugged in via Config::restart. A restart puts rho/delta back to rho_begin and rebuilds the interpolation set from scratch around the best point found so far, then carries on; the returned point is the best over every cycle, so a restart can never return something worse than stopping would have.

Enums§

Status
Why the solver stopped (or why construction failed).

Constants§

FUNCMAX
PRIMA’s moderated-extreme-barrier ceiling (consts.F90 L169, 10^min(30, range/2) = 1e30 for f64). Every objective value is passed through PRIMA’s moderatef before the solver uses it: NaN and +inf become FUNCMAX, and any finite value above it is clamped to it. This is what lets BOBYQA keep making progress past an occasional non-finite evaluation.
MAX_RESTARTS_CAP
Upper bound on RestartConfig::max_restarts (safe-checks spec S2): far above any real schedule (the recommended one is 1), it exists so the max_restarts + 1 instrumentation store can neither overflow nor become a caller-sized giant allocation.

Functions§

bobyqa
One-shot convenience over Bobyqa: infers n from x.len(), builds a throwaway solver, and runs a single minimisation. Allocates per call — hot loops re-solving many problems of one size should build a Bobyqa once and reuse it.