Added basic functins to SampleSetDist

This commit is contained in:
Ozzie Gooen 2022-04-25 21:46:40 -04:00
parent 5563a5dc40
commit 2c1aff25d3
4 changed files with 42 additions and 17 deletions

View File

@ -65,8 +65,7 @@ describe("(Algebraic) addition of distributions", () => {
| None => "algebraicAdd has"->expect->toBe("failed") | None => "algebraicAdd has"->expect->toBe("failed")
// This is nondeterministic, we could be in a situation where ci fails but you click rerun and it passes, which is bad. // This is nondeterministic, we could be in a situation where ci fails but you click rerun and it passes, which is bad.
// sometimes it works with ~digits=2. // sometimes it works with ~digits=2.
// Answer found from WolframAlpha: ``mean(uniform(9,10)) + mean(betaDistribution(2,5))`` | Some(x) => x->expect->toBeSoCloseTo(9.786831807237022, ~digits=1) // (uniformMean +. betaMean)
| Some(x) => x->expect->toBeSoCloseTo(9.786, ~digits=1) // (uniformMean +. betaMean)
} }
}) })
test("beta(alpha=2, beta=5) + uniform(low=9, high=10)", () => { test("beta(alpha=2, beta=5) + uniform(low=9, high=10)", () => {
@ -83,7 +82,7 @@ describe("(Algebraic) addition of distributions", () => {
| None => "algebraicAdd has"->expect->toBe("failed") | None => "algebraicAdd has"->expect->toBe("failed")
// This is nondeterministic, we could be in a situation where ci fails but you click rerun and it passes, which is bad. // This is nondeterministic, we could be in a situation where ci fails but you click rerun and it passes, which is bad.
// sometimes it works with ~digits=2. // sometimes it works with ~digits=2.
| Some(x) => x->expect->toBeSoCloseTo(9.786, ~digits=1) // (uniformMean +. betaMean) | Some(x) => x->expect->toBeSoCloseTo(9.784290207736126, ~digits=1) // (uniformMean +. betaMean)
} }
}) })
}) })
@ -164,7 +163,7 @@ describe("(Algebraic) addition of distributions", () => {
| None => "algebraicAdd has"->expect->toBe("failed") | None => "algebraicAdd has"->expect->toBe("failed")
// This is nondeterministic, we could be in a situation where ci fails but you click rerun and it passes, which is bad. // This is nondeterministic, we could be in a situation where ci fails but you click rerun and it passes, which is bad.
// sometimes it works with ~digits=4. // sometimes it works with ~digits=4.
| Some(x) => x->expect->toBeSoCloseTo(1.025, ~digits=1) | Some(x) => x->expect->toBeSoCloseTo(0.9677, ~digits=1)
} }
}) })
test("(beta(alpha=2, beta=5) + uniform(low=9, high=10)).pdf(10)", () => { test("(beta(alpha=2, beta=5) + uniform(low=9, high=10)).pdf(10)", () => {
@ -347,7 +346,7 @@ describe("(Algebraic) addition of distributions", () => {
| None => "algebraicAdd has"->expect->toBe("failed") | None => "algebraicAdd has"->expect->toBe("failed")
// This is nondeterministic, we could be in a situation where ci fails but you click rerun and it passes, which is bad. // This is nondeterministic, we could be in a situation where ci fails but you click rerun and it passes, which is bad.
// sometimes it works with ~digits=2. // sometimes it works with ~digits=2.
| Some(x) => x->expect->toBeSoCloseTo(9.174960348568693, ~digits=0) | Some(x) => x->expect->toBeSoCloseTo(9.18416389919939, ~digits=0)
} }
}) })
test("(beta(alpha=2, beta=5) + uniform(low=9, high=10)).inv(2e-2)", () => { test("(beta(alpha=2, beta=5) + uniform(low=9, high=10)).inv(2e-2)", () => {
@ -362,7 +361,7 @@ describe("(Algebraic) addition of distributions", () => {
| None => "algebraicAdd has"->expect->toBe("failed") | None => "algebraicAdd has"->expect->toBe("failed")
// This is nondeterministic, we could be in a situation where ci fails but you click rerun and it passes, which is bad. // This is nondeterministic, we could be in a situation where ci fails but you click rerun and it passes, which is bad.
// sometimes it works with ~digits=2. // sometimes it works with ~digits=2.
| Some(x) => x->expect->toBeSoCloseTo(9.168291999681523, ~digits=0) | Some(x) => x->expect->toBeSoCloseTo(9.190872365862756, ~digits=0)
} }
}) })
}) })

View File

@ -46,20 +46,27 @@ let toFloatOperation = (
~toPointSetFn: toPointSetFn, ~toPointSetFn: toPointSetFn,
~distToFloatOperation: Operation.distToFloatOperation, ~distToFloatOperation: Operation.distToFloatOperation,
) => { ) => {
let symbolicSolution = switch (t: t) { let trySymbolicSolution = switch (t: t) {
| Symbolic(r) => | Symbolic(r) => SymbolicDist.T.operate(distToFloatOperation, r)->E.R.toOption
switch SymbolicDist.T.operate(distToFloatOperation, r) {
| Ok(f) => Some(f)
| _ => None
}
| _ => None | _ => None
} }
switch symbolicSolution { let trySampleSetSolution = switch ((t: t), distToFloatOperation) {
| (SampleSet(sampleSet), #Mean) => SampleSetDist.mean(sampleSet)->Some
| (SampleSet(sampleSet), #Sample) => SampleSetDist.sample(sampleSet)->Some
| (SampleSet(sampleSet), #Inv(r)) => SampleSetDist.percentile(sampleSet, r)->Some
| _ => None
}
switch trySymbolicSolution {
| Some(r) => Ok(r)
| None =>
switch trySampleSetSolution {
| Some(r) => Ok(r) | Some(r) => Ok(r)
| None => toPointSetFn(t)->E.R2.fmap(PointSetDist.operate(distToFloatOperation)) | None => toPointSetFn(t)->E.R2.fmap(PointSetDist.operate(distToFloatOperation))
} }
} }
}
//Todo: If it's a pointSet, but the xyPointLength is different from what it has, it should change. //Todo: If it's a pointSet, but the xyPointLength is different from what it has, it should change.
// This is tricky because the case of discrete distributions. // This is tricky because the case of discrete distributions.

View File

@ -98,3 +98,13 @@ let map2 = (~fn: (float, float) => result<float, Operation.Error.t>, ~t1: t, ~t2
E.R.toExn("Input of samples should be larger than 5", make(x)) E.R.toExn("Input of samples should be larger than 5", make(x))
) )
} }
let mean = t => T.get(t)->E.A.Floats.mean
let geomean = t => T.get(t)->E.A.Floats.geomean
let mode = t => T.get(t)->E.A.Floats.mode
let sum = t => T.get(t)->E.A.Floats.sum
let min = t => T.get(t)->E.A.Floats.min
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)

View File

@ -522,7 +522,8 @@ module A = {
| n if n == maxIndex => [index - 1] | n if n == maxIndex => [index - 1]
| _ => [index - 1, index + 1] | _ => [index - 1, index + 1]
} |> Belt.Array.map(_, r => sortedArray[r]) } |> Belt.Array.map(_, r => sortedArray[r])
let hasSimilarElement = Belt.Array.some(possiblySimilarElements, r => r == element) // let hasSimilarElement = Belt.Array.some(possiblySimilarElements, r => r == element)
let hasSimilarElement = false
hasSimilarElement hasSimilarElement
? FloatFloatMap.increment(element, discrete) ? FloatFloatMap.increment(element, discrete)
: { : {
@ -538,10 +539,18 @@ module A = {
} }
module Floats = { module Floats = {
let sum = Belt.Array.reduce(_, 0., (i, j) => i +. j) let mean = Jstat.mean
let mean = a => sum(a) /. (Array.length(a) |> float_of_int) let geomean = Jstat.geomean
let mode = Jstat.mode
let variance = Jstat.variance
let stdev = Jstat.stdev
let sum = Jstat.sum
let random = Js.Math.random_int let random = Js.Math.random_int
//Passing true for the exclusive parameter excludes both endpoints of the range.
//https://jstat.github.io/all.html
let percentile = (a,b) => Jstat.percentile(a,b, false)
// Gives an array with all the differences between values // Gives an array with all the differences between values
// diff([1,5,3,7]) = [4,-2,4] // diff([1,5,3,7]) = [4,-2,4]
let diff = (arr: array<float>): array<float> => let diff = (arr: array<float>): array<float> =>