Added truncate for SampleSet distribution

This commit is contained in:
Ozzie Gooen 2022-08-20 17:10:08 -07:00
parent c3bb0ba291
commit 516f4fa39d
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("truncateLeft(normal(5,2), 3)", "Ok(Point Set Distribution)")
testEval("truncateRight(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), 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)") testEval("isNormalized(truncate(normal(5,2), 3, 8))", "Ok(true)")
}) })

View File

@ -242,11 +242,19 @@ module Truncate = {
switch trySymbolicSimplification(leftCutoff, rightCutoff, t) { switch trySymbolicSimplification(leftCutoff, rightCutoff, t) {
| Some(r) => Ok(r) | Some(r) => Ok(r)
| None => | None =>
toPointSetFn(t)->E.R2.fmap(t => { switch t {
DistributionTypes.PointSet( | SampleSet(t) =>
PointSetDist.T.truncate(leftCutoff, rightCutoff, t)->PointSetDist.T.normalize, 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 stdev = t => T.get(t)->E.A.Floats.stdev
let variance = t => T.get(t)->E.A.Floats.variance let variance = t => T.get(t)->E.A.Floats.variance
let percentile = (t, f) => T.get(t)->E.A.Floats.percentile(f) 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); 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** **Examples**
@ -306,10 +323,10 @@ truncateLeft(normal(5, 2), 3);
### truncateRight ### 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** **Examples**
@ -388,7 +405,7 @@ The only functions that do not return normalized distributions are the pointwise
### normalize ### 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 normalize: (distribution) => distribution