600 lines
12 KiB
Plaintext
600 lines
12 KiB
Plaintext
---
|
||
sidebar_position: 3
|
||
title: Distribution
|
||
---
|
||
|
||
import Admonition from "@theme/Admonition";
|
||
import TOCInline from "@theme/TOCInline";
|
||
|
||
Distributions are the flagship data type in Squiggle. The distribution type is a generic data type that contains one of three different formats of distributions.
|
||
These subtypes are [point set](/docs/Api/DistPointSet), [sample set](/docs/Api/DistSampleSet), and symbolic. The first two of these have a few custom functions that only work on them. You can read more about the differences between these formats [here](/docs/Discussions/Three-Formats-Of-Distributions).
|
||
|
||
Several functions below only can work on particular distribution formats.
|
||
For example, scoring and pointwise math requires the point set format. When this happens, the types are automatically converted to the correct format. These conversions are lossy.
|
||
|
||
<TOCInline toc={toc} />
|
||
|
||
## Distribution Creation
|
||
|
||
These are functions for creating primative distributions. Many of these could optionally take in distributions as inputs. In these cases, Monte Carlo Sampling will be used to generate the greater distribution. This can be used for simple hierarchical models.
|
||
|
||
See a longer tutorial on creating distributions [here](/docs/Guides/DistributionCreation).
|
||
|
||
### normal
|
||
|
||
```
|
||
normal: (distribution|number, distribution|number) => distribution
|
||
normal: (dict<{p5: distribution|number, p95: distribution|number}>) => distribution
|
||
normal: (dict<{mean: distribution|number, stdev: distribution|number}>) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```js
|
||
normal(5, 1)
|
||
normal({ p5: 4, p95: 10 })
|
||
normal({ mean: 5, stdev: 2 })
|
||
normal(5 to 10, normal(3, 2))
|
||
normal({ mean: uniform(5, 9), stdev: 3 })
|
||
```
|
||
|
||
### lognormal
|
||
|
||
```
|
||
lognormal: (distribution|number, distribution|number) => distribution
|
||
lognormal: (dict<{p5: distribution|number, p95: distribution|number}>) => distribution
|
||
lognormal: (dict<{mean: distribution|number, stdev: distribution|number}>) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
lognormal(0.5, 0.8);
|
||
lognormal({ p5: 4, p95: 10 });
|
||
lognormal({ mean: 5, stdev: 2 });
|
||
```
|
||
|
||
### uniform
|
||
|
||
```
|
||
uniform: (distribution|number, distribution|number) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
uniform(10, 12);
|
||
```
|
||
|
||
### beta
|
||
|
||
```
|
||
beta: (distribution|number, distribution|number) => distribution
|
||
beta: (dict<{mean: distribution|number, stdev: distribution|number}>) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
beta(20, 25);
|
||
beta({ mean: 0.39, stdev: 0.1 });
|
||
```
|
||
|
||
### cauchy
|
||
|
||
```
|
||
cauchy: (distribution|number, distribution|number) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
cauchy(5, 1);
|
||
```
|
||
|
||
### gamma
|
||
|
||
```javascript
|
||
gamma: (distribution|number, distribution|number) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```js
|
||
gamma(5, 1);
|
||
```
|
||
|
||
### logistic
|
||
|
||
```
|
||
logistic: (distribution|number, distribution|number) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
gamma(5, 1);
|
||
```
|
||
|
||
### exponential
|
||
|
||
```
|
||
exponential: (distribution|number) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
exponential(2);
|
||
```
|
||
|
||
### bernoulli
|
||
|
||
```
|
||
bernoulli: (distribution|number) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
bernoulli(0.5);
|
||
```
|
||
|
||
### triangular
|
||
|
||
```javascript
|
||
triangular: (number, number, number) => distribution;
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
triangular(5, 10, 20);
|
||
```
|
||
|
||
### to / credibleIntervalToDistribution
|
||
|
||
The `to` function is an easy way to generate simple distributions using predicted _5th_ and _95th_ percentiles.
|
||
|
||
If both values are above zero, a `lognormal` distribution is used. If not, a `normal` distribution is used.
|
||
|
||
`To` is an alias for `credibleIntervalToDistribution`. However, because of its frequent use, it is recommended to use the shorter name.
|
||
|
||
```
|
||
to: (distribution|number, distribution|number) => distribution
|
||
credibleIntervalToDistribution(distribution|number, distribution|number) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
5 to 10
|
||
to(5,10)
|
||
-5 to 5
|
||
```
|
||
|
||
### mixture
|
||
|
||
```
|
||
mixture: (...distributionLike, weights?:list<float>) => distribution
|
||
mixture: (list<distributionLike>, weights?:list<float>) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
mixture(normal(5, 1), normal(10, 1), 8);
|
||
mx(normal(5, 1), normal(10, 1), [0.3, 0.7]);
|
||
mx([normal(5, 1), normal(10, 1)], [0.3, 0.7]);
|
||
```
|
||
|
||
## Functions
|
||
|
||
### sample
|
||
|
||
One random sample from the distribution
|
||
|
||
```
|
||
sample: (distribution) => number
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
sample(normal(5, 2));
|
||
```
|
||
|
||
### sampleN
|
||
|
||
N random samples from the distribution
|
||
|
||
```
|
||
sampleN: (distribution, number) => list<number>
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
sampleN(normal(5, 2), 100);
|
||
```
|
||
|
||
### mean
|
||
|
||
The distribution mean
|
||
|
||
```
|
||
mean: (distribution) => number
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
mean(normal(5, 2));
|
||
```
|
||
|
||
### stdev
|
||
|
||
Standard deviation. Only works now on sample set distributions (so converts other distributions into sample set in order to calculate.)
|
||
|
||
```
|
||
stdev: (distribution) => number
|
||
```
|
||
|
||
### variance
|
||
|
||
Variance. Similar to stdev, only works now on sample set distributions.
|
||
|
||
```
|
||
variance: (distribution) => number
|
||
```
|
||
|
||
### mode
|
||
|
||
```
|
||
mode: (distribution) => number
|
||
```
|
||
|
||
### cdf
|
||
|
||
```
|
||
cdf: (distribution, number) => number
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
cdf(normal(5, 2), 3);
|
||
```
|
||
|
||
### pdf
|
||
|
||
```
|
||
pdf: (distribution, number) => number
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
pdf(normal(5, 2), 3);
|
||
```
|
||
|
||
### quantile
|
||
|
||
```
|
||
quantile: (distribution, number) => number
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
quantile(normal(5, 2), 0.5);
|
||
```
|
||
|
||
### truncate
|
||
|
||
Truncates both the left side and the right side of a distribution.
|
||
|
||
```
|
||
truncate: (distribution, left: number, right: number) => distribution
|
||
```
|
||
|
||
<Admonition type="note" title="Implementation Details">
|
||
<p>
|
||
Sample set distributions are truncated by filtering samples, but point set
|
||
distributions are truncated using direct geometric manipulation. Uniform
|
||
distributions are truncated symbolically. Symbolic but non-uniform
|
||
distributions get converted to Point Set distributions.
|
||
</p>
|
||
</Admonition>
|
||
|
||
### truncateLeft
|
||
|
||
Truncates the left side of a distribution.
|
||
|
||
```
|
||
truncateLeft: (distribution, left: number) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
truncateLeft(normal(5, 2), 3);
|
||
```
|
||
|
||
### truncateRight
|
||
|
||
Truncates the right side of a distribution.
|
||
|
||
```
|
||
truncateRight: (distribution, right: number) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
truncateRight(normal(5, 2), 6);
|
||
```
|
||
|
||
### klDivergence
|
||
|
||
[Kullback–Leibler divergence](https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence) between two distributions.
|
||
|
||
```
|
||
klDivergence: (distribution, distribution) => number
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
klDivergence(normal(5, 2), normal(5, 4)); // returns 0.57
|
||
```
|
||
|
||
### logScore
|
||
|
||
A log loss score. Often that often acts as a [scoring rule](https://en.wikipedia.org/wiki/Scoring_rule). Useful when evaluating the accuracy of a forecast.
|
||
|
||
Note that it is fairly slow.
|
||
|
||
```
|
||
Dist.logScore: ({estimate: distribution, ?prior: distribution, answer: distribution|number}) => number
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
Dist.logScore({
|
||
estimate: normal(5, 2),
|
||
answer: normal(4.5, 1.2),
|
||
prior: normal(6, 4),
|
||
}); // returns -0.597.57
|
||
```
|
||
|
||
## Display
|
||
|
||
### toString
|
||
|
||
```
|
||
toString: (distribution) => string
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
toString(normal(5, 2));
|
||
```
|
||
|
||
### sparkline
|
||
|
||
Produce a sparkline of length n. For example, `▁▁▁▁▁▂▄▆▇██▇▆▄▂▁▁▁▁▁`. These can be useful for testing or quick text visualizations.
|
||
|
||
```
|
||
sparkline: (distribution, n = 20) => string
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
toSparkline(truncateLeft(normal(5, 2), 3), 20); // produces ▁▇█████▇▅▄▃▂▂▁▁▁▁▁▁▁
|
||
```
|
||
|
||
## Normalization
|
||
|
||
There are some situations where computation will return unnormalized distributions. This means that their cumulative sums are not equal to 1.0. Unnormalized distributions are not valid for many relevant functions; for example, klDivergence and scoring.
|
||
|
||
The only functions that do not return normalized distributions are the pointwise arithmetic operations and the scalewise arithmetic operations. If you use these functions, it is recommended that you consider normalizing the resulting distributions.
|
||
|
||
### normalize
|
||
|
||
Normalize a distribution. This means scaling it appropriately so that it's cumulative sum is equal to 1. This only impacts Point Set distributions, because those are the only ones that can be non-normlized.
|
||
|
||
```
|
||
normalize: (distribution) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
normalize(normal(5, 2));
|
||
```
|
||
|
||
### isNormalized
|
||
|
||
Check of a distribution is normalized. Most distributions are typically normalized, but there are some commands that could produce non-normalized distributions.
|
||
|
||
```
|
||
isNormalized: (distribution) => bool
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
isNormalized(normal(5, 2)); // returns true
|
||
```
|
||
|
||
### integralSum
|
||
|
||
**Note: If you have suggestions for better names for this, please let us know.**
|
||
|
||
Get the sum of the integral of a distribution. If the distribution is normalized, this will be 1.0. This is useful for understanding unnormalized distributions.
|
||
|
||
```
|
||
integralSum: (distribution) => number
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
integralSum(normal(5, 2));
|
||
```
|
||
|
||
## Regular Arithmetic Operations
|
||
|
||
Regular arithmetic operations cover the basic mathematical operations on distributions. They work much like their equivalent operations on numbers.
|
||
|
||
The infixes `+`,`-`, `*`, `/`, `^` are supported for addition, subtraction, multiplication, division, power, and unaryMinus.
|
||
|
||
```javascript
|
||
pointMass(5 + 10) == pointMass(5) + pointMass(10);
|
||
```
|
||
|
||
### add
|
||
|
||
```
|
||
add: (distributionLike, distributionLike) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
normal(0, 1) + normal(1, 3); // returns normal(1, 3.16...)
|
||
add(normal(0, 1), normal(1, 3)); // returns normal(1, 3.16...)
|
||
```
|
||
|
||
### sum
|
||
|
||
**Todo: Not yet implemented**
|
||
|
||
```
|
||
sum: (list<distributionLike>) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
sum([normal(0, 1), normal(1, 3), uniform(10, 1)]);
|
||
```
|
||
|
||
### multiply
|
||
|
||
```
|
||
multiply: (distributionLike, distributionLike) => distribution
|
||
```
|
||
|
||
### product
|
||
|
||
```
|
||
product: (list<distributionLike>) => distribution
|
||
```
|
||
|
||
### subtract
|
||
|
||
```
|
||
subtract: (distributionLike, distributionLike) => distribution
|
||
```
|
||
|
||
### divide
|
||
|
||
```
|
||
divide: (distributionLike, distributionLike) => distribution
|
||
```
|
||
|
||
### pow
|
||
|
||
```
|
||
pow: (distributionLike, distributionLike) => distribution
|
||
```
|
||
|
||
### exp
|
||
|
||
```
|
||
exp: (distributionLike, distributionLike) => distribution
|
||
```
|
||
|
||
### log
|
||
|
||
```
|
||
log: (distributionLike, distributionLike) => distribution
|
||
```
|
||
|
||
### log10
|
||
|
||
```
|
||
log10: (distributionLike, distributionLike) => distribution
|
||
```
|
||
|
||
### unaryMinus
|
||
|
||
```
|
||
unaryMinus: (distribution) => distribution
|
||
```
|
||
|
||
**Examples**
|
||
|
||
```javascript
|
||
-normal(5, 2); // same as normal(-5, 2)
|
||
unaryMinus(normal(5, 2)); // same as normal(-5, 2)
|
||
```
|
||
|
||
## Pointwise Arithmetic Operations
|
||
|
||
<Admonition type="caution" title="Unnormalized Results">
|
||
<p>
|
||
Pointwise arithmetic operations typically return unnormalized or completely
|
||
invalid distributions. For example, the operation{" "}
|
||
<code>normal(5,2) .- uniform(10,12)</code> results in a distribution-like
|
||
object with negative probability mass.
|
||
</p>
|
||
</Admonition>
|
||
|
||
Pointwise arithmetic operations cover the standard arithmetic operations, but work in a different way than the regular operations. These operate on the y-values of the distributions instead of the x-values. A pointwise addition would add the y-values of two distributions.
|
||
|
||
The infixes `.+`,`.-`, `.*`, `./`, `.^` are supported for their respective operations.
|
||
|
||
The `mixture` methods works with pointwise addition.
|
||
|
||
### dotAdd
|
||
|
||
```
|
||
dotAdd: (distributionLike, distributionLike) => distribution
|
||
```
|
||
|
||
### dotMultiply
|
||
|
||
```
|
||
dotMultiply: (distributionLike, distributionLike) => distribution
|
||
```
|
||
|
||
### dotSubtract
|
||
|
||
```
|
||
dotSubtract: (distributionLike, distributionLike) => distribution
|
||
```
|
||
|
||
### dotDivide
|
||
|
||
```
|
||
dotDivide: (distributionLike, distributionLike) => distribution
|
||
```
|
||
|
||
### dotPow
|
||
|
||
```
|
||
dotPow: (distributionLike, distributionLike) => distribution
|
||
```
|
||
|
||
### dotExp
|
||
|
||
```
|
||
dotExp: (distributionLike, distributionLike) => distribution
|
||
```
|