User Guide¶
Basic Usage¶
Import parse_dist and pass a distribution string:
from distparser import parse_dist
# All keyword arguments
dist = parse_dist("norm(loc=0, scale=1)")
# All positional (matched to param_order)
dist = parse_dist("uniform(0, 1)")
# Mixed — keyword overrides positional
dist = parse_dist("uniform(0, loc=5)") # loc=5 wins
# No arguments — uses scipy defaults
dist = parse_dist("expon()")
The returned object is a frozen scipy.stats distribution. You can call .rvs(), .pdf(), .cdf(), .mean(), .std(), and all other standard methods.
Supported Distributions¶
| Name | param_order |
|---|---|
uniform |
loc, scale |
norm |
loc, scale |
expon |
loc, scale |
gamma |
a, loc, scale |
beta |
a, b, loc, scale |
lognorm |
s, loc, scale |
weibull_min |
c, loc, scale |
t |
df, loc, scale |
chi2 |
df, loc, scale |
f |
dfn, dfd, loc, scale |
pareto |
b, loc, scale |
cauchy |
loc, scale |
laplace |
loc, scale |
logistic |
loc, scale |
rayleigh |
loc, scale |
Use parse_dist("name(args)") — positional args fill param_order left-to-right; keyword args match by name.
Extending the Registry¶
Register custom distributions at runtime:
from distparser import register_distribution, parse_dist
from scipy.stats import gumbel_r
register_distribution("gumbel", gumbel_r, ["loc", "scale"])
dist = parse_dist("gumbel(loc=10, scale=3)")
Error Handling¶
All exceptions inherit from DistParserError:
from distparser import parse_dist, ParseError, UnknownDistributionError
try:
dist = parse_dist("typo(0, 1)")
except UnknownDistributionError as e:
print(f"Unknown: {e}") # Unknown: 'typo'. Registered: beta, cauchy, ...
try:
dist = parse_dist("not valid")
except ParseError as e:
print(f"Parse: {e}") # Parse: Cannot parse 'not valid'. Expected format: 'name(args)'.
DistGraph — dependency-aware evaluation¶
DistGraph accepts a flat dictionary of keys and expressions. It automatically
detects cross‑references, resolves evaluation order via topological sort, and
injects resolved values into subsequent expressions.
from distparser import DistGraph
config = {
"offset": 10,
"scale": "uniform(1, 3)",
"point": "offset + scale * norm(0, 1)",
}
graph = DistGraph(config, seed=42)
result = graph.resolve_all()
print(result["point"])
Non‑string values (numbers, lists) pass through unchanged. Circular
dependencies raise a ParseError.
Distribution Aliases¶
Common shorthands are built in:
| Alias | Canonical |
|---|---|
normal |
norm |
gaussian |
norm |
unif |
uniform |
from distparser import parse_dist
d = parse_dist("normal(loc=0, scale=1)") # resolves to norm
Seed Management¶
Three levels of RNG control:
from distparser import seed, seed_context, DistGraph
# Global seed
seed(42)
# Context manager (temporary override)
with seed_context(99):
g = DistGraph({"x": "uniform(0, 1)"})
# Per-instance seed (highest priority)
g = DistGraph({"x": "uniform(0, 1)"}, seed=123)
Priority: per‑instance > context manager > global.
Bounds Constraints¶
Specify output bounds directly in the expression string using min/max or
lbound/rbound keyword arguments. The sampled value is automatically
clipped to the given range.
from distparser import DistGraph
config = {
"wall_thickness": "norm(loc=0.25, scale=0.025, min=0.0, max=1.0)",
}
graph = DistGraph(config, seed=42)
result = graph.resolve_all()
print(result["wall_thickness"]) # clipped to [0.0, 1.0]
bounds = graph.get_bounds("wall_thickness")
print(bounds) # {"min": 0.0, "max": 1.0}
Bounds are applied as a final clip after sampling.