Skip to main content

Problem

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

pub fn name(&self) -> &str

The problem’s label.

pub fn dimension(&self) -> usize

The number of decision variables.

pub const fn optimum(&self) -> f64

The known global minimum value.

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

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

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

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

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

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

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

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

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

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

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§

§

impl Clone for Problem

§

fn clone(&self) -> Problem

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Problem

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> ByRef<T> for T

§

fn by_ref(&self) -> &T

§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more