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::newis the sole allocation site, sized once for the problem’s(n, npt)and restart schedule); a built solver then runsBobyqa::minimizewith 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 thestd::error::Errorimpl onStatus; without itStatuskeepsDisplayonly. Nothing else.libm— backs the float math with thelibmcrate 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::minimizecalls. - Config
- Tuning knobs for
Bobyqa. NoDefault:npt’s default (2n + 1) needsn— start fromConfig::newand assign the fields to override (#[non_exhaustive]rules out struct literals, update syntax included, outside this crate). - Outcome
- The result of one
Bobyqa::minimizecall. - Restart
Config - The restart schedule, plugged in via
Config::restart. A restart putsrho/deltaback torho_beginand 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.F90L169,10^min(30, range/2)=1e30forf64). Every objective value is passed through PRIMA’smoderatefbefore the solver uses it:NaNand+infbecomeFUNCMAX, 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 is1), it exists so themax_restarts + 1instrumentation store can neither overflow nor become a caller-sized giant allocation.