EB#
A domain-specific language for Monte Carlo simulation and stochastic modeling.
EB is being developed as part of a PhD research project.
Why EB?#
- Clarity
Write models that read like their mathematical specification. Guard expressions and lineitems make conditional logic and time-series relationships explicit.
- Correctness
The type system and domain-specific constructs catch errors early. Observations are collected automatically at the right granularity.
- Performance
Compile to native binary for production. Use the REPL for exploration. Run millions of iterations efficiently.
Features#
Lineitems: Time-varying expressions re-evaluated each period with automatic history
Observations: Data collection at period, iteration, run, or simulation level
Guard expressions: Pattern matching for clean conditional logic
Scenarios: Named parameter sets for comparative analysis
Native compilation: Generate C code for high-performance execution
Example#
The run() {I, R} statement executes I iterations across R runs.
A lineitem (li) is an expression evaluated once per iteration.
# Estimate Pi using Monte Carlo
niter := 100_000
nrun := 100
li x := :randu(-1.0, 1.0)
li y := :randu(-1.0, 1.0)
li inside := | x^2 + y^2 <= 1.0 -> inside + 1
| _ -> inside
obs_r estimate := 4.0 * inside / niter
run() {niter, nrun}
:print(:boxplot(estimate))
:print("estimate of Pi, mean of observations:", :mean(estimate))
Output:
[min=3.1265, Q1=3.1370, med=3.1411, Q3=3.1447, max=3.1535, n=100]
estimate of Pi, mean of observations: 3.14092
Comparison with Python#
The same Monte Carlo Pi estimation in Python:
import random
import statistics
niter = 100_000
nrun = 100
estimates = []
for run in range(nrun):
inside = 0
for i in range(niter):
x = random.uniform(-1.0, 1.0)
y = random.uniform(-1.0, 1.0)
if x**2 + y**2 <= 1.0:
inside += 1
estimate = 4.0 * inside / niter
estimates.append(estimate)
sorted_est = sorted(estimates)
n = len(sorted_est)
min_v = sorted_est[0]
q1 = sorted_est[int(n * 0.25)]
med = sorted_est[int(n * 0.50)]
q3 = sorted_est[int(n * 0.75)]
max_v = sorted_est[-1]
print(f"[min={min_v:.4f}, Q1={q1:.4f}, med={med:.4f}, Q3={q3:.4f}, max={max_v:.4f}, n={n}]")
print("estimate of Pi:", statistics.mean(estimates))
Timing: 5.8s (Python) vs 1.5s (EB)
% time python3 pi.py
python3 pi.py 5.74s user 0.02s system 99% cpu 5.775 total
% time ./pi
./pi 1.52s user 0.00s system 99% cpu 1.530 total