pytyche.experiment.simulate¶
Sim-mode generator adapter — pytyche DGP templates as a Generator.
simulated_experiment_generator() wraps a registered
pytyche.generators scenario template as a callable conforming to the
Generator contract: the loop calls
generator(round_idx, plan) and receives (observed, truth) with
non-None truth. Visitors are allocated to the plan’s cells by weight and
each visitor’s treatment is drawn from the cell’s policy.assign —
TreePolicy routing happens at data-generation time, driving the
template’s assign_and_observe through its external
treatment_assignment hook (never the fixed treatment_probabilities
path).
Functions
|
Wrap a registered DGP template as a sim-mode |
- pytyche.experiment.simulate.simulated_experiment_generator(*, template, metric, effect_scale, K, seed=0, treatment_names=None, **template_kwargs)[source]¶
Wrap a registered DGP template as a sim-mode
Generatorcallable.The returned callable conforms to the single data-source contract (
Generator): invoked asgenerator(round_idx, plan), it synthesizes one round of observed data from the plan’s cell structure and returns(ObservedExperimentData, CalibrationTruth)— truth is always non-None (sim mode). Generation is deterministic per(seed, round_idx): replaying a round with the same plan reproduces it exactly, while distinct rounds draw fresh visitors.Variant naming defaults to the generator core’s: index 0 is
"control"and indices 1..K-1 are"treatment_1".."treatment_{K-1}".treatment_names=renames the variants for the experiment’s narrative (position 0 is the baseline; positions follow the template’s arm order) — presentation-only, the positional truth arrays are untouched. Apt.sequential_experiment(...)driven by this adapter must pass the effective names as itstreatments=universe, baseline first.Each returned visitors frame carries the reserved recording columns:
cell— the id of the plan cell that allocated the visitor (recorded at generation time; not derivable from the treatment received).propensity_1..propensity_{K-1}— the realized assignment propensities, i.e. the cell-weight blendP(Z = k | x, plan) = sum_c w_c * P_policy_c(k | x).
Real-data generators carry the same recording obligations: the loop requires the
cellcolumn, and the reserved propensity columns are the documented channel for adaptively-assigned designs (propensityat K = 2).The adapter is K >= 3 only: the generator core’s external
treatment_assignmenthook exists only for multi-arm truth, and the K = 2 paired sampling path is pinned out of bounds. For a K = 2 sequential experiment, write a custom generator instead.- Parameters:
template (
str) – Name of a registered scenario template — a key ofpytyche.generators.scenarios.TEMPLATES.metric (
str) – Canonical metric identifier passed to the template (e.g."revenue_per_visitor").effect_scale (
float) – Treatment-effect amplitude passed to the template.K (
int) – Number of treatment levels (control + K-1 treatments). Must be >= 3.seed (
int) – Master seed. Roundrdraws fromnp.random.default_rng(np.random.SeedSequence((seed, r))).treatment_names (
Sequence[str] |None) – Optional K unique variant names replacing the template’s, in template arm order (position 0 = baseline).**template_kwargs (
object) – Extra keyword arguments forwarded to the template (e.g.n_nuisance=,baseline_rate=).
- Return type:
Callable[[int,NextRoundPlan],tuple[ObservedExperimentData,CalibrationTruth|None]]- Returns:
A
Generator-conforming callable.- Raises:
ValueError – When
templateis not a registered template name, whenK < 3, or whentreatment_namesis not exactly K unique names.