Skip to content

StochasBase: The Simulation Conductor

StochasBase is the central "brain" for a simulation trial. It orchestrates the lifecycle of a model by bridging the gap between mathematical uncertainty and deterministic execution.


Centralized Trial Orchestration

A single instance of StochasBase manages two distinct pillars of simulation inputs:

  • Aleatory Uncertainty (sample_dist): Represents "luck" or noise. These are random draws from probability distributions (Normal, Uniform, etc.) that you cannot control but must account for.
  • Epistemic Uncertainty (sample_design): Represents "choices." These are tunable parameters (Design Variables) used by optimizers like Optuna or pymoo to find peak performance.

The Pillars of Repeatability

To ensure that a simulation can be perfectly recreated by a colleague, the orchestrator utilizes a "Salted Seed" logic. Every random draw is a deterministic function of the trial's metadata:

\[Seed_{local} = \mathcal{H}(Seed_{global}, Trial_{num}, Variable_{name})\]
  • Global Seed: Controls the entire campaign.
  • Trial Number: Ensures trial 10 is different from trial 11.
  • Variable Name: Ensures "stiffness" doesn't get the same random value as "damping."

The "Baked" Registry (named)

While StochasBase is designed to automate randomness and optimization, you often need to bypass the math to test a specific "Golden Case" or debug a known failure point. Overrides allow you to inject fixed values into the Baked Registry before the simulation begins.

The orchestrator follows a strict priority sequence when a variable is requested:

  1. Registry Check: It looks in the named dictionary. If a value exists, it returns it immediately.
  2. Logic Execution: If the registry is empty, it proceeds to draw from a distribution or ask an optimizer for a suggestion.

By using with_overrides(), you populate the registry early, effectively "locking" those variables for the duration of the trial.


Quick Implementation

Python
import numpy as np

import stochas


class MyModel(stochas.StochasBase):
    """Put your logic for running your model here!"""


overrides = stochas.NamedValueDict()
overrides.update(
    stochas.NamedValue(
        name=stochas.ValueName("overridden_value"), stored_value=np.array([3.14])
    )
)

model = MyModel().with_seed(42).with_trial_num(1).with_overrides(overrides)

# 1. Random draw
noise = model.sample_dist(
    stochas.NormalDistribution(
        name=stochas.DistName("sensor_noise"), nominal=0, mu=0, sigma=0.1
    )
)

# 2. Tunable parameter
width = model.sample_design(
    stochas.DesignFloat(
        name=stochas.ValueName("base_width"), low=1.0, high=5.0, stored_value=2.5
    )
)

# Both are now registered in model.named for later analysis.

# fails to update named value dict! overridden_value is already in the named value dict
overridden_value = model.sample_dist(
    stochas.PoissonDistribution(name=stochas.DistName("overridden_value"), lam=4)
)
assert overridden_value == np.array([3.14])  # this check passes!