Struct Qmc
pub struct Qmc { /* private fields */ }Expand description
A quasi-random Sobol or Halton sampler.
Stateless: construct with Qmc::new (unscrambled Sobol, the default) or
Qmc::new_with_halton, optionally randomize it with Qmc::with_scramble, and
hand it to a study through
StudyBuilder::sampler. See the
module-level documentation for the sequences and their guarantees.
use atune_core::sampler::{Qmc, Sampler};
use atune_core::id::{StudyId, TrialId, TrialNumber};
use atune_core::space::{Distribution, ParamSpec, SpaceSchema};
use atune_core::study::StudyView;
use atune_core::trial::TrialMeta;
let space = SpaceSchema::try_new([
ParamSpec::try_new("x", Distribution::try_new_with_float(0.0, 1.0).unwrap()).unwrap(),
ParamSpec::try_new("y", Distribution::try_new_with_float(0.0, 1.0).unwrap()).unwrap(),
])
.unwrap();
let qmc = Qmc::new();
let view = StudyView::new(StudyId::new(0), vec![], Some(space.clone()));
let meta = TrialMeta::new_with_study_seed(TrialId::new(1), TrialNumber::new(0), 42);
// The very first Sobol point is the origin of the cube.
let first = qmc.sample_relative(&view, &meta, &space).unwrap();
assert_eq!(first.get("x"), Some(&atune_core::space::ParamValue::F64(0.0)));
// A scrambled sequence moves it off the origin, reproducibly per seed.
let scrambled = Qmc::new().with_scramble(7);
let a = scrambled.sample_relative(&view, &meta, &space).unwrap();
let b = scrambled.sample_relative(&view, &meta, &space).unwrap();
assert_eq!(a, b);
assert_ne!(a, first);Implementations§
§impl Qmc
impl Qmc
pub const fn new() -> Self
pub const fn new() -> Self
Creates the default sampler: the unscrambled Sobol sequence with dimensions in schema declaration order.
Add with_schema_order(false) for the earlier
default, sorted parameter-name order.
pub const fn new_with_halton() -> Self
pub const fn new_with_halton() -> Self
Creates an unscrambled Halton sampler, dimensions in schema
declaration order like Qmc::new.
use atune_core::sampler::{Qmc, QmcSequence};
assert_eq!(Qmc::new_with_halton().sequence(), QmcSequence::Halton);
assert_eq!(Qmc::new_with_halton().scramble_seed(), None);
assert!(Qmc::new_with_halton().schema_order());pub const fn with_sequence(self, sequence: QmcSequence) -> Self
pub const fn with_sequence(self, sequence: QmcSequence) -> Self
Selects the sequence, keeping the scramble setting.
pub const fn with_scramble(self, seed: u64) -> Self
pub const fn with_scramble(self, seed: u64) -> Self
Opts into a seeded scramble of the sequence (off by default).
Sobol gets a linear matrix scramble plus a digital shift, Halton random
digit permutations — the randomizations SciPy’s scramble=True applies
and Optuna’s QMCSampler(scramble=True, seed=seed) exposes. The points
stay a pure function of (seed, trial number, space); every worker of a
study must use the same seed (the study seed is the natural choice).
use atune_core::sampler::Qmc;
let qmc = Qmc::new().with_scramble(42);
assert_eq!(qmc.scramble_seed(), Some(42));pub const fn with_schema_order(self, enabled: bool) -> Self
pub const fn with_schema_order(self, enabled: bool) -> Self
Assigns sequence dimensions in the schema’s declaration order (true,
the default) or in sorted parameter-name order (false).
Declaration order matches SciPy and Optuna, where the first declared
parameter receives dimension zero; unscrambled Halton then also follows
SciPy’s floating-point accumulation. Sorted name order was the
default before declaration order was promoted, and false reproduces
its points bit for bit.
use atune_core::sampler::Qmc;
assert!(Qmc::new().schema_order());
assert!(!Qmc::new().with_schema_order(false).schema_order());pub const fn sequence(&self) -> QmcSequence
pub const fn sequence(&self) -> QmcSequence
The sequence this sampler draws.
pub const fn scramble_seed(&self) -> Option<u64>
pub const fn scramble_seed(&self) -> Option<u64>
The scramble seed, or None for the unscrambled sequence.
pub const fn schema_order(&self) -> bool
pub const fn schema_order(&self) -> bool
Whether sequence dimensions follow the schema’s declaration order.
Trait Implementations§
impl Copy for Qmc
impl Eq for Qmc
§impl Sampler for Qmc
impl Sampler for Qmc
§fn infer_relative_space(&self, study: &StudyView) -> Result<SpaceSchema>
fn infer_relative_space(&self, study: &StudyView) -> Result<SpaceSchema>
The study’s declared space, or the intersection of the visible trials’ parameters for a define-by-run study — the same shape every built-in sampler infers.
§Errors
Error::InvalidSpace if a recorded
parameter name is empty, which no writer of this crate produces.
§fn sample_relative(
&self,
_study: &StudyView,
trial: &TrialMeta,
space: &SpaceSchema,
) -> Result<Assignment>
fn sample_relative( &self, _study: &StudyView, trial: &TrialMeta, space: &SpaceSchema, ) -> Result<Assignment>
The Sobol (or Halton) point of this trial’s number, dimension-assigned in declaration order, or by sorted name with schema order off.
§Errors
Error::InvalidSpace if a declared
distribution is malformed;
Error::Sampler once the trial number
leaves the sequence’s SOBOL_POINTS budget (Halton shares it, which
keeps every index’s digit expansion exact).
§fn sample_independent(
&self,
_study: &StudyView,
trial: &TrialMeta,
name: &str,
dist: &Distribution,
) -> Result<ParamValue>
fn sample_independent( &self, _study: &StudyView, trial: &TrialMeta, name: &str, dist: &Distribution, ) -> Result<ParamValue>
The uniform Random draw.
A parameter outside the relative space has no assigned Sobol dimension, so it cannot take part in the joint low-discrepancy fill; it gets the deterministic per-name uniform draw instead, exactly as Optuna’s QMC sampler does.
§Errors
Error::InvalidSpace if dist is
malformed.
§fn reseed(&self, _seed: u64)
fn reseed(&self, _seed: u64)
A no-op: the point is a pure function of the trial number (and the
construction-time scramble seed), so a reseed cannot move it without
breaking the low-discrepancy guarantee — Optuna’s QMCSampler likewise
leaves its scramble seed alone on reseed_rng.
See Random::reseed for the full argument.
§fn after_trial(&self, study: &StudyView, trial: &FrozenTrial) -> Result<()>
fn after_trial(&self, study: &StudyView, trial: &FrozenTrial) -> Result<()>
§fn state(&self) -> Result<Option<SamplerState>>
fn state(&self) -> Result<Option<SamplerState>>
§fn snapshots_space(&self) -> bool
fn snapshots_space(&self) -> bool
§fn reads_constraints(&self) -> bool
fn reads_constraints(&self) -> bool
FrozenTrial::constraints on the views it
is asked with. Read more