distributions.DistributionRegistry
Registry for probability distribution classes with batch creation
Usage
distributions.DistributionRegistry()capabilities.
The DistributionRegistry provides a central repository for registering distribution classes and instantiating them from configuration data. This facilitates dynamic creation of distribution objects based on runtime configuration, supporting scenarios like simulation models, statistical analysis, or any application requiring configurable random distributions.
Key features: - Register distribution classes with a simple decorator - Create distribution instances from class names and parameters - Batch create multiple distributions from a dictionary or list - Automatic generation of statistically independent random seeds
Examples
Register distribution classes:
>>> @DistributionRegistry.register()
... class Exponential:
... def __init__(self, mean, random_seed=None):
... self.rng = np.random.default_rng(random_seed)
... self.mean = mean
...
... def sample(self, size=None):
... return self.rng.exponential(self.mean, size=size)
...
>>> @DistributionRegistry.register("uniform_dist") # Custom name
... class Uniform:
... def __init__(self, low, high, random_seed=None):
... self.rng = np.random.default_rng(random_seed)
... self.low = low
... self.high = high
...
... def sample(self, size=None):
... return self.rng.uniform(self.low, self.high, size=size)Create a distribution with parameters:
>>> exp_dist = DistributionRegistry.create("Exponential", mean=2.0)
>>> exp_dist.sample(5) # Generate 5 samplesCreate multiple distributions from a flat configuration:
>>> config = {
... "arrivals": {
... "class_name": "Exponential",
... "params": {"mean": 5.0}
... },
... "service_times": {
... "class_name": "uniform_dist",
... "params": {"low": 1.0, "high": 3.0}
... }
... }
>>> distributions = DistributionRegistry.create_batch(config,
... main_seed=12345)
>>> arrivals = distributions["arrivals"]
>>> service_times = distributions["service_times"]Create distributions from a nested configuration:
>>> config = {
... "call": {
... "C1": {"class_name": "Exponential", "params": {"mean": 10.0}},
... "C2": {"class_name": "Exponential", "params": {"mean": 8.0}},
... },
... "response_time": {
... "C1": {
... "class_name": "Lognormal",
... "params": {"mean": 30.0, "stdev": 5.0},
... },
... },
... }
>>> dists = DistributionRegistry.create_batch(
... config, main_seed=42, preserve_structure=True
... )
>>> dists["call"]["C1"].sample(5)
>>> dists["response_time"]["C1"].sample(5)Notes
When creating distributions in batch with a main_seed, each distribution receives its own statistically independent seed derived from the main seed. This ensures proper statistical independence between random number streams while maintaining overall reproducibility through the main seed.
When preserve_structure=True, the output mirrors the shape of the input configuration, so nested configs produce nested dicts of instances. When preserve_structure=False (default), all leaf distributions are flattened into a single dict whose keys are the path components joined by underscores (e.g. "call_C1").
With sort=True (default), keys at every nesting level are sorted alphabetically before seeds are assigned. This ensures that seed assignment is stable even if the insertion order of keys in the config dict changes between runs.
Methods
| Name | Description |
|---|---|
| create() | Create a distribution instance by name. |
| create_batch() | Create multiple distributions from a configuration dictionary or list. |
| get() | Get a distribution class by name. |
| get_template() | Generate a template configuration containing all registered |
| register() | Decorator to register a distribution class in the registry. |
create()
Create a distribution instance by name.
Usage
create(name, **params)Parameters
name: str-
Name of the registered distribution class
**params- Parameters to pass to the distribution constructor
Returns
Any- Instance of the requested distribution class
create_batch()
Create multiple distributions from a configuration dictionary or list.
Usage
create_batch(config, main_seed=None, sort=True, preserve_structure=False)Accepts both flat and arbitrarily nested dict configurations. Every leaf must be a dict with exactly the keys 'class_name' and 'params'.
Parameters
config: Union[List[Dict], Dict[str, Dict]]-
One of:
A list of distribution configs, each with
'class_name'and'params'. Returns a list of instances.A flat dict mapping names to distribution configs:
{ "arrivals": { "class_name": "Exponential", "params": {"mean": 5.0}, } }A nested dict where intermediate keys group distributions and leaves are distribution configs:
{ "call": { "C1": { "class_name": "Exponential", "params": {"mean": 10.0}, } } }
main_seed: Optional[int] = None-
Master seed to generate individual seeds for each distribution. If None, random seeds will still be generated for independence.
sort: Optional[bool] = True-
If True, keys at every nesting level are sorted alphabetically before seeds are assigned. This ensures deterministic seed assignment even if config key insertion order changes between runs. Not relevant for top-level lists.
preserve_structure: Optional[bool] = False-
Controls the shape of the returned dict when
configis a dict.False(default): all distributions are returned in a single flat dict whose keys are the path components of each leaf joined by underscores, e.g."call_C1".True: the returned dict mirrors the nesting of the input config, soresult["call"]["C1"]gives the distribution directly.
configis a list.
Returns
Union[List, Dict]-
- A list of distribution instances if
configwas a list. - A flat dict of distribution instances if
configwas a dict andpreserve_structure=False. - A nested dict of distribution instances if
configwas a dict andpreserve_structure=True.
- A list of distribution instances if
Raises
TypeError-
If
configis neither a list nor a dictionary. ValueError- If any distribution config is malformed, if a required key is missing or an unexpected key is present, or if the config contains values that are neither dicts, lists, nor valid distribution configs.
get()
Get a distribution class by name.
Usage
get(name)Parameters
name: str- Name of the registered distribution class
Returns
type- The registered distribution class
Raises
ValueError- If the distribution name is not found in the registry
get_template()
Generate a template configuration containing all registered
Usage
get_template(format="json", indent=2)distributions.
This helper method creates a template that includes all registered distribution types with appropriate dummy parameters. Users can modify this template and pass it directly to create_batch() to instantiate their distributions.
Parameters
format: str = "json"-
Output format:
'dict'for a Python dictionary or'json'for a JSON string. indent: int = 2-
Indentation for JSON formatting (only used when
format='json').
Returns
Union[Dict, str]-
Either a dictionary (if
format='dict') or a JSON string (ifformat='json') containing template configurations for all registered distributions.
Examples
>>> template = DistributionRegistry.get_template(format='dict')
>>> print(list(template.keys()))
['Exponential_example', 'Normal_example', 'Uniform_example', ...]>>> template = DistributionRegistry.get_template(format='json')
>>> print(template[:70])
{
"Exponential_example": {
"class_name": "Exponential",
"params": {register()
Decorator to register a distribution class in the registry.
Usage
register(name=None)Parameters
name: Optional[str] = None- Name to register the class under. If None, uses the class name.
Returns
Callable- Decorator function that registers the class