tauopt.engine.strategies.sobol#
Scrambled-Sobol space-filling strategy (the bootstrap workhorse).
The scramble seed stays FIXED for an experiment (resolve_seed derives it from the space, not the full state) and the engine fast-forwards past the points already drawn – so successive asks genuinely continue one low-discrepancy sequence.
Linear constraints are honored by rejection with FEASIBLE-index accounting: the
history count skips the first skip feasible sequence points (raw fast-forward
would let previously-issued points re-emerge as duplicates, since rejected draws
consume sequence indexes that history never records). Unconstrained spaces keep the
v0 fast-forward path verbatim.
Center-in-bootstrap (cfg.center_in_bootstrap): the
domain center (0.5 per canonical normalized coordinate, decoded normally) rides
the stream per the following three-branch decision table:
Center ill-defined (mixed space – categorical/grid/conditional axes; plain double/integer boxes have centers) OR design-infeasible -> deterministic recorded SKIP; the stream and cursor are byte-identical to the unflagged path.
Unconstrained space -> ONE fixed toroidal shift s = (0.5 - x_0) mod 1 computed from sequence index zero (a throwaway same-seed generator reads x_0, so the real cursor advances exactly as today), applied to the entire indexed stream – values only, index-independent. Shifted index 0 IS the center by construction.
Linearly-constrained space (the rejection loop – shifting interacts with acceptance, so the generator cannot carry the shift) -> the center is emitted directly as slot 0 on the experiment’s first ask (skip == 0); raw index 0 is consumed-and-discarded in the center’s favor on EVERY flagged ask, and the feasible walk runs from raw index 1 with (skip - 1) feasible slots behind it – cursor mechanics identical to today from index 1 on.
“Already observed/pending” centers are emission-skips handled by the cursor law itself (any history entry => skip >= 1 => index/slot 0 already consumed) – the stream law never flips mid-experiment (the only P4-coherent reading). The branch decision is recorded in provenance via record_center (never hashed, never seeded – the flag is a top-level config field excluded from resolve_seed’s derivation, so branch-1 and flag-off streams are bit-identical).
Module Contents#
Classes#
Scrambled-Sobol space-filling strategy (the module docstring carries the stream and cursor laws). The default policy’s bootstrap rung until max(4, 2*dim) successful observations, and the rung below the GP strategies on both never-fail ladders (pin P6). Requires tauopt[local] (numpy/scipy). |
API#
- class tauopt.engine.strategies.sobol.SobolStrategy#
Scrambled-Sobol space-filling strategy (the module docstring carries the stream and cursor laws). The default policy’s bootstrap rung until max(4, 2*dim) successful observations, and the rung below the GP strategies on both never-fail ladders (pin P6). Requires tauopt[local] (numpy/scipy).
- name#
‘sobol’
- suggest(state: tauopt.engine.state.ExperimentState, cfg: tauopt.engine.config.OptimizerConfig, n: int = 1) list[tauopt.engine.strategies.base.SuggestionDraft]#
Return the next n decoded, linearly-feasible points of the experiment’s one indexed stream (fixed space-derived scramble seed, history skip applied), so successive asks continue a single low-discrepancy sequence (pins P4/P7). Raises ValueError when linear constraints reject 100,000 consecutive points (feasible region too small to sample).
- suggest_unique(state: tauopt.engine.state.ExperimentState, cfg: tauopt.engine.config.OptimizerConfig, n: int = 1, exclude: frozenset[str] = frozenset()) list[tauopt.engine.strategies.base.SuggestionDraft]#
Dedup repair path: advance the stream past collisions (exclusion-aware), at most SEQUENCE_REPAIR_FACTOR * n examined candidates.