Struct Problem
pub struct Problem { /* private fields */ }Expand description
A synthetic benchmark problem: a boxed continuous domain and a pure objective to minimize.
Build one with a named constructor (Problem::sphere,
Problem::rastrigin, Problem::ackley, Problem::branin) and hand it
to harness::optimize.
Implementations§
§impl Problem
impl Problem
pub fn schema(&self) -> Result<SpaceSchema>
pub fn schema(&self) -> Result<SpaceSchema>
The search space, one linear float parameter per variable, in order.
§Errors
Error::InvalidSpace if a bound is
not finite or a name repeats — which the built-in constructors never
produce, so this is infallible in practice and exists only because the
underlying builders are fallible.
pub fn eval(&self, assignment: &Assignment) -> f64
pub fn eval(&self, assignment: &Assignment) -> f64
Evaluates the objective at assignment.
Reads each variable by name in declaration order. A parameter that is
missing or not a float yields NaN for that coordinate rather than
panicking; a NaN objective simply never improves the best-so-far curve,
so a malformed assignment degrades gracefully instead of aborting a run.
pub fn with_offsets(self, offsets: Vec<f64>) -> Self
pub fn with_offsets(self, offsets: Vec<f64>) -> Self
Replaces the per-variable offsets, moving the optimum off the domain centre — or, with an offset larger than the half-width, outside the box entirely, which is the misplaced-optimum arm of the open-range benchmark (§17.2 of the open-search-spaces plan): nothing clamps an offset to the domain, and the objective is a pure function that is perfectly happy to be evaluated wherever a widened range sends it.
offsets must have one entry per variable; a debug build stops on a
mismatch, a release build zips and ignores the excess exactly as
Problem::eval would.
pub fn log_sphere_centered(dim: usize, low: f64, high: f64) -> Self
pub fn log_sphere_centered(dim: usize, low: f64, high: f64) -> Self
A dim-dimensional log-scaled sphere: f(x) = Σ (ln xᵢ − ln c)²
over [low, high]^dim searched in log space, minimum 0 at xᵢ = c.
The log arm of the open-range benchmark. Displacement is expressed
through the fixed centre c rather than through
Problem::with_offsets, because eval’s raw-coordinate subtraction
can push a log-scaled variable to zero or below, where its logarithm —
and the whole objective — stops existing; moving the optimum
multiplicatively keeps every evaluation inside the function’s own
domain, which is also how a log parameter is misplaced in practice:
the right learning rate is 10× above the guessed range, not shifted by
an additive constant. The objective is a plain fn pointer, so c
cannot be a runtime argument; each arm is its own named constructor
with its centre baked in.
Problem::log_sphere_centered puts c = 1; pick low < 1 < high
and the optimum is inside the box (the control arm).
pub fn log_sphere_displaced(dim: usize, low: f64, high: f64) -> Self
pub fn log_sphere_displaced(dim: usize, low: f64, high: f64) -> Self
The misplaced arm of Problem::log_sphere_centered: the same
objective with its centre at c = 10. Pick a box whose high sits
below 10 — say [1e-4, 1e-1], three decades short, the classic
too-timid learning-rate guess — and the optimum is outside it by a
factor of high / 10.
pub fn sphere(dim: usize) -> Self
pub fn sphere(dim: usize) -> Self
The sphere function, f(x) = Σ xᵢ², over [-5.12, 5.12]^dim.
The canonical smooth, convex, unimodal test problem. Minimum 0 at the
origin. This is the problem on which a learning sampler must beat uniform
random cleanly — if it cannot separate here, nothing else matters.
pub fn shifted_sphere(dim: usize) -> Self
pub fn shifted_sphere(dim: usize) -> Self
The shifted sphere, f(x) = Σ (xᵢ − cᵢ)², over [-5.12, 5.12]^dim.
The offset cᵢ alternates +1.234 / −2.345 so the minimizer is at a
point that is not a Sobol grid node — unlike the centered
sphere, whose optimum a Sobol point lands on exactly
at index 1. This is the problem on which the Sobol-beats-random claim is a
genuine low-discrepancy-coverage result rather than a lucky exact hit.
Minimum 0 at c.
pub fn ill_scaled_ellipsoid(dim: usize) -> Self
pub fn ill_scaled_ellipsoid(dim: usize) -> Self
The ill-scaled ellipsoid, f(x) = Σ 10^(2i/(d−1))·(xᵢ − cᵢ)², over
[-5.12, 5.12]^dim with the minimizer shifted off the Sobol grid.
A smooth convex bowl like the sphere, but badly
anisotropic: the per-axis curvature spans a factor of 100 (condition
number 10^2 for dim ≥ 2), so the correlation length of the objective
is genuinely different along each axis. A single median-heuristic
lengthscale — the M6.2 default — is a poor compromise for such a surface,
whereas an MLE-fitted lengthscale (and noise) adapts to it. This is the
problem M6.2b’s marginal-likelihood fit is meant to help on, and the
HyperFit::Mle-vs-HyperFit::MedianHeuristic ablation runs here
(docs/design/09-implementation.md §8.3).
The offset cᵢ alternates +1.234 / −2.345 exactly as
shifted_sphere, so the optimum is not a Sobol
warmup node (no “lucky exact hit” — the §8.3 vacuous-oracle trap).
Minimum 0 at c.
pub fn rastrigin(dim: usize) -> Self
pub fn rastrigin(dim: usize) -> Self
The Rastrigin function over [-5.12, 5.12]^dim.
f(x) = 10·dim + Σ (xᵢ² − 10·cos(2π·xᵢ)). Highly multimodal (a
grid of local minima) but with a smooth global bowl, minimum 0 at the
origin. A learning sampler should still beat random here, by a smaller
margin than on the sphere.
pub fn ackley(dim: usize) -> Self
pub fn ackley(dim: usize) -> Self
The Ackley function over [-32.768, 32.768]^dim.
A nearly-flat outer region around a sharp central funnel; minimum 0 at
the origin. Punishing for uniform random (the funnel is a small target),
which is exactly why a sampler that concentrates its draws does better.
pub fn branin() -> Self
pub fn branin() -> Self
The Branin (Branin-Hoo) function, a smooth 2-D problem.
x0 ∈ [-5, 10], x1 ∈ [0, 15]. Three equal global minima of value
≈ 0.397887. Smooth and low-dimensional, so — like the sphere — a
clear separator between a learning sampler and random.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Problem
impl RefUnwindSafe for Problem
impl Send for Problem
impl Sync for Problem
impl Unpin for Problem
impl UnsafeUnpin for Problem
impl UnwindSafe for Problem
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T, U> Imply<T> for U
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
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 more