# Probability distributions


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

``` bpl
]help •distribution
```

# `•distribution` — Distributions

`params •distribution name` returns the distribution called `name`, with
parameters `params`. `•distribution name` uses the distribution’s
standard parameters, listed in the table below. A distribution is a
keyed vector of four functions:

- `sample shape` draws random values. `g sample shape` draws them from a
  generator made by `•rand`.
- `density x` gives the probability density, or the probability mass for
  a discrete distribution.
- `cdf x` gives P(X ≤ x).
- `quantile p` inverts the CDF. `cdf⁻¹` is `quantile`. `quantile⁻¹` is
  `cdf`.

``` bpl
d←•distribution "normal"
d.cdf 0                         ⍝ 0.5
b←10 0.5 •distribution "binomial"
b.quantile 0.5                  ⍝ 5ₓ
```

Parameters are finite real units or vectors. Scale, shape, rate and
degrees of freedom are positive, except where stated.
[Distributions](distributions.ipynb) shows them in use.

<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 33%" />
<col style="width: 33%" />
</colgroup>
<thead>
<tr>
<th>Name</th>
<th>Parameters</th>
<th>Standard</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>"normal"</code></td>
<td>μ σ: mean, standard deviation</td>
<td>0 1</td>
</tr>
<tr>
<td><code>"uniform"</code></td>
<td>a b: lower and upper bounds, a &lt; b</td>
<td>0 1</td>
</tr>
<tr>
<td><code>"bernoulli"</code></td>
<td>p ∈ [0,1]</td>
<td></td>
</tr>
<tr>
<td><code>"binomial"</code></td>
<td>n p: integer trials n ≥ 0, p ∈ [0,1]</td>
<td></td>
</tr>
<tr>
<td><code>"poisson"</code></td>
<td>λ ≥ 0: mean</td>
<td></td>
</tr>
<tr>
<td><code>"beta"</code></td>
<td>α β: shapes</td>
<td></td>
</tr>
<tr>
<td><code>"gamma"</code></td>
<td>k θ: shape, scale, with mean kθ</td>
<td></td>
</tr>
<tr>
<td><code>"inversegamma"</code></td>
<td>α β: shape, scale, with density ∝ x⁻⁽ᵅ⁺¹⁾ exp(−β/x)</td>
<td></td>
</tr>
<tr>
<td><code>"exponential"</code></td>
<td>λ: rate, with mean 1/λ</td>
<td>1</td>
</tr>
<tr>
<td><code>"chisquared"</code></td>
<td>ν: degrees of freedom</td>
<td></td>
</tr>
<tr>
<td><code>"student"</code></td>
<td>ν: degrees of freedom, with location 0 and scale 1</td>
<td></td>
</tr>
<tr>
<td><code>"fisher"</code></td>
<td>ν₁ ν₂: degrees of freedom</td>
<td></td>
</tr>
<tr>
<td><code>"cauchy"</code>, <code>"laplace"</code>,
<code>"logistic"</code></td>
<td>location, scale</td>
<td>0 1</td>
</tr>
<tr>
<td><code>"lognormal"</code></td>
<td>μ σ: mean and standard deviation of log(X)</td>
<td>0 1</td>
</tr>
<tr>
<td><code>"weibull"</code></td>
<td>k λ: shape, scale</td>
<td></td>
</tr>
</tbody>
</table>

Errors: `DOMAIN` for an unknown name, a name that isn’t a string, a
monadic call for a distribution with no standard parameters, invalid
parameters, non-real inputs or p ∉ \[0,1\]; `LENGTH` for the wrong
number of parameters; `RANK` for matrix parameters or shapes; `SYNTAX`
for a dyadic call to `density`, `cdf` or `quantile`; `LIMIT` for
oversized shapes or sampler ranges.

Construct a distribution with `params •distribution name`, then sample
or evaluate it. Leave out the parameters to get the standard ones. For
the normal distribution they’re mean 0 and standard deviation 1:

``` bpl
n←•distribution "normal"
⍴n.sample 2 3
n.cdf 0
n.quantile 0.5
n.density 0
```

    [2 3]ₓ

    0.5

    0

    0.3989422804

`sample 100` returns a vector. `sample ⍬` returns a rank-0 array. Zero
dimensions give empty arrays. Continuous samples are floats. Discrete
samples are exact integers:

``` bpl
b←2 0.5 •distribution "binomial"
b.density 0 1 2
b.cdf 0.5 1.5
b.quantile 0.25 0.5 1
```

    0.25 0.5 0.25

    0.25 0.75

    [0 1 2]ₓ

Evaluation pervades arrays, preserving shape, nesting, keys and axis
names. Parameters belong to the constructed distribution.

``` bpl
u←•distribution "uniform"
u.cdf "low" "high":0.2 0.8
```

    ["low":0.2 "high":0.8]

## Reproducible draws

`•rand seed` makes a generator. Put it on the left of `sample` to draw
from a seeded stream. The same seed gives the same draws. Saved output
then stays the same when a notebook runs again. A generator also has
`roll` and `deal`, which work like `¿`. Copies of a generator share one
stream.

``` bpl
]help •rand
```

# `•rand` — Generator

`•rand seed` returns a generator: a keyed vector of two functions that
draw from one stream of random numbers. The seed is a nonnegative
integer. The same seed gives the same draws.

- `roll Y` works like `¿Y`.
- `X deal Y` works like `X¿Y`.

A distribution’s `sample` takes a generator on its left, as in
`g d.sample 3`. Copies of a generator share its stream. Drawing from one
copy moves every copy on.

Errors: `DOMAIN` for a seed that is not a nonnegative integer, or a left
argument to `sample` that is not a generator; `LENGTH` or `RANK` for
more than one seed; `SYNTAX` for a dyadic call to `•rand`.

``` bpl
g←•rand 42
g n.sample 3
g.roll 6 6 6
3 g.deal 10
```

    0.8343975468 ¯0.5149629281 1.407727573

    4 4 3

    1 5 2

## Parameters and support

Gamma takes scale, whereas exponential takes rate. These describe the
same distribution:

``` bpl
g←1 2 •distribution "gamma"
e←0.5 •distribution "exponential"
(g.cdf 2) = e.cdf 2
```

    $t

Quantile endpoints give the support bounds, including infinity. Discrete
quantiles return the smallest supported integer whose CDF reaches p. p=0
gives the lower support bound. Certain events stay constant at both
endpoints:

``` bpl
n←•distribution "normal"
n.quantile 0 1
p←0 •distribution "poisson"
p.sample 3
```

    ¯∞ ∞

    [0 0 0]ₓ

## Numerics

Numerical routines come from
[rustymath](https://github.com/AnswerDotAI/rustymath). An array of
numbers goes to it as one slice, so `density`, `cdf` and `quantile` on a
large array run without per-item overhead. Unseeded draws use the
thread-local RNG. Draws from a `•rand` generator use Xoshiro256++.
Binomial trials and Poisson rate are limited to 2⁵³ by the
floating-point samplers. Gamma scale must have a finite reciprocal.
Uniform intervals must have a finite width.
