Merge pull request #995 from quantified-uncertainty/sampleSet-truncate

Added truncate for SampleSet distribution
This commit is contained in:
Ozzie Gooen 2022-08-31 19:57:49 -07:00 committed by GitHub
commit 0fa34b09e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 11 deletions

View File

@ -74,6 +74,7 @@ describe("eval on distribution functions", () => {
testEval("truncateLeft(normal(5,2), 3)", "Ok(Point Set Distribution)")
testEval("truncateRight(normal(5,2), 3)", "Ok(Point Set Distribution)")
testEval("truncate(normal(5,2), 3, 8)", "Ok(Point Set Distribution)")
testEval("truncate(normal(5,2) |> SampleSet.fromDist, 3, 8)", "Ok(Sample Set Distribution)")
testEval("isNormalized(truncate(normal(5,2), 3, 8))", "Ok(true)")
})

View File

@ -242,11 +242,19 @@ module Truncate = {
switch trySymbolicSimplification(leftCutoff, rightCutoff, t) {
| Some(r) => Ok(r)
| None =>
toPointSetFn(t)->E.R2.fmap(t => {
DistributionTypes.PointSet(
PointSetDist.T.truncate(leftCutoff, rightCutoff, t)->PointSetDist.T.normalize,
)
})
switch t {
| SampleSet(t) =>
switch SampleSetDist.truncate(t, ~leftCutoff, ~rightCutoff) {
| Ok(r) => Ok(SampleSet(r))
| Error(err) => Error(DistributionTypes.SampleSetError(err))
}
| _ =>
toPointSetFn(t)->E.R2.fmap(t => {
DistributionTypes.PointSet(
PointSetDist.T.truncate(leftCutoff, rightCutoff, t)->PointSetDist.T.normalize,
)
})
}
}
}
}

View File

@ -131,3 +131,12 @@ let max = t => T.get(t)->E.A.Floats.max
let stdev = t => T.get(t)->E.A.Floats.stdev
let variance = t => T.get(t)->E.A.Floats.variance
let percentile = (t, f) => T.get(t)->E.A.Floats.percentile(f)
let truncateLeft = (t, f) => T.get(t)->E.A2.filter(x => x >= f)->T.make
let truncateRight = (t, f) => T.get(t)->E.A2.filter(x => x <= f)->T.make
let truncate = (t, ~leftCutoff: option<float>, ~rightCutoff: option<float>) => {
let withTruncatedLeft = t => leftCutoff |> E.O.dimap(left => truncateLeft(t, left), _ => Ok(t))
let withTruncatedRight = t => rightCutoff |> E.O.dimap(left => truncateRight(t, left), _ => Ok(t))
t->withTruncatedLeft |> E.R2.bind(withTruncatedRight)
}

View File

@ -290,12 +290,29 @@ quantile: (distribution, number) => number
quantile(normal(5, 2), 0.5);
```
### truncateLeft
### truncate
Truncates the left side of a distribution. Returns either a pointSet distribution or a symbolic distribution.
Truncates both the left side and the right side of a distribution.
```
truncateLeft: (distribution, l => number) => 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**
@ -306,10 +323,10 @@ truncateLeft(normal(5, 2), 3);
### truncateRight
Truncates the right side of a distribution. Returns either a pointSet distribution or a symbolic distribution.
Truncates the right side of a distribution.
```
truncateRight: (distribution, r => number) => distribution
truncateRight: (distribution, right: number) => distribution
```
**Examples**
@ -388,7 +405,7 @@ The only functions that do not return normalized distributions are the pointwise
### normalize
Normalize a distribution. This means scaling it appropriately so that it's cumulative sum is equal to 1. This only impacts Pointset distributions, because those are the only ones that can be non-normlized.
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