montecarlo
montecarlo, keyword
montecarlo opens a block repeated a fixed number of iterations and collects
sample aggregations over those iterations, either as scalars or vectors.
Examples
iterations = 10
montecarlo iterations with
x = random.uniform(0, 1)
sample avgX = avg(x)
show table "Monte Carlo" with
avgX as "Avg"
This produces the following table:
| Avg |
|---|
| 0.4521479 |
Full-table lookups are supported inside montecarlo blocks, and can be sampled per line.
table enum Key = "a", "b"
table U[Key] = with
[| as Key, as A |]
[| enum<<Key>>("a"), 10 |]
[| enum<<Key>>("b"), 20 |]
table T = with
[| as K |]
[| enum<<Key>>("a") |]
[| enum<<Key>>("b") |]
[| enum<<Key>>("a") |]
montecarlo 1000 with
r = random.uniform(0.8, 1.2)
T.A = U.A[T.K] * r
sample T.AvgA = avg(T.A)
show table "Average A" with
T.K
T.AvgA
This produces a table similar to:
| K | AvgA |
|---|---|
| a | 9.945009 |
| b | 19.89002 |
| a | 9.945009 |
The ranvar() accumulator also supports vector targets:
table T = extend.range(3)
montecarlo 100 with
sample T.R = ranvar(random.normal(T.N, 0.1))
show table "Empirical ranvars" with
T.N
mean(T.R) as "Mean"
dispersion(T.R) as "Dispersion"
Ordered processes inside a montecarlo block may use both by and scan.
The grouping and ordering are applied independently during every iteration:
table T = extend.range(4)
T.Group = T.N mod 2
montecarlo 100 with
T.Path = cumsum(random.uniform(0, T.N)) by T.Group scan T.N
sample T.AveragePath = avg(T.Path)
show table "Average paths" with
T.N
T.Group
T.AveragePath
Here, cumsum restarts for each value of T.Group on every simulated path,
and sample averages each row over the Monte Carlo iterations.
Remarks
The iteration count must be a positive integer. It can be any scalar number
value, not necessarily a const.
When ranvar() is used as an accumulator, the result is an empirical
distribution. With n sampled observations, its probabilities have a
resolution of 1 / n before any subsequent transformation. See
How to choose a Monte Carlo sample count
for guidance on selecting and validating the count.
Lookups inside montecarlo follow the usual rules: the lookup key must be an
ordinal dimension or an enum, not a raw text value.
When sampling a ranvar, out-of-bounds draws are discarded and the resulting
distribution is normalized over accepted samples only.
If a sampled value is invalid (for example, non-finite or out of bounds), the simulation fails at runtime with an error that names the sampler.