refactored to a higher level of abstraction

This commit is contained in:
Quinn Dougherty 2022-04-13 10:30:23 -04:00
parent e9e6cab099
commit 165427f137
3 changed files with 29 additions and 64 deletions

View File

@ -251,7 +251,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(0.0013961779932477507, ~digits=4) | Some(x) => x->expect->toBeSoCloseTo(0.0013961779932477507, ~digits=3)
} }
}) })
test("(beta(alpha=2, beta=5) + uniform(low=9, high=10)).cdf(10)", () => { test("(beta(alpha=2, beta=5) + uniform(low=9, high=10)).cdf(10)", () => {
@ -343,7 +343,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(10.927078217530806, ~digits=1) | Some(x) => x->expect->toBeSoCloseTo(10.927078217530806, ~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)", () => {

View File

@ -45,28 +45,27 @@ describe("Mean", () => {
let zipDistsDists = E.L.zip(distributions, distributions) let zipDistsDists = E.L.zip(distributions, distributions)
let digits = -4 let digits = -4
describe("addition", () => { let testOperationMean = (distOp, description, floatOp, dist1', dist2') => {
let testAdditionMean = (dist1'', dist2'') => { let dist1 = dist1'->E.R2.fmap(x=>DistributionTypes.Symbolic(x))->E.R2.fmap2(s=>DistributionTypes.Other(s))
let dist1' = E.R.fmap(x => DistributionTypes.Symbolic(x), dist1'') let dist2 = dist2'->E.R2.fmap(x=>DistributionTypes.Symbolic(x))->E.R2.fmap2(s=>DistributionTypes.Other(s))
let dist2' = E.R.fmap(x => DistributionTypes.Symbolic(x), dist2'') let received =
let dist1 = E.R.fmap2(s => DistributionTypes.Other(s), dist1') E.R.liftJoin2(distOp, dist1, dist2)
let dist2 = E.R.fmap2(s => DistributionTypes.Other(s), dist2') ->E.R2.fmap(mean)
->E.R2.fmap(run)
let received = ->E.R2.fmap(toFloat)
E.R.liftJoin2(algebraicAdd, dist1, dist2) let expected = floatOp(runMean(dist1), runMean(dist2))
->E.R2.fmap(mean) switch received {
->E.R2.fmap(run) | Error(err) => impossiblePath(description)
->E.R2.fmap(toFloat) | Ok(x) =>
let expected = runMean(dist1) +. runMean(dist2) switch x {
switch received { | None => impossiblePath(description)
| Error(err) => impossiblePath("algebraicAdd") | Some(x) => x->expect->toBeSoCloseTo(expected, ~digits)
| Ok(x) =>
switch x {
| None => impossiblePath("algebraicAdd")
| Some(x) => x->expect->toBeSoCloseTo(expected, ~digits)
}
} }
} }
}
describe("addition", () => {
let testAdditionMean = testOperationMean(algebraicAdd, "algebraicAdd", (x,y)=>x+.y)
testAll("homogeneous addition", zipDistsDists, dists => { testAll("homogeneous addition", zipDistsDists, dists => {
let (dist1, dist2) = dists let (dist1, dist2) = dists
@ -85,27 +84,7 @@ describe("Mean", () => {
}) })
describe("subtraction", () => { describe("subtraction", () => {
let testSubtractionMean = (dist1'', dist2'') => { let testSubtractionMean = testOperationMean(algebraicSubtract, "algebraicSubtract", (x,y)=>x-.y)
let dist1' = E.R.fmap(x => DistributionTypes.Symbolic(x), dist1'')
let dist2' = E.R.fmap(x => DistributionTypes.Symbolic(x), dist2'')
let dist1 = E.R.fmap2(s => DistributionTypes.Other(s), dist1')
let dist2 = E.R.fmap2(s => DistributionTypes.Other(s), dist2')
let received =
E.R.liftJoin2(algebraicSubtract, dist1, dist2)
->E.R2.fmap(mean)
->E.R2.fmap(run)
->E.R2.fmap(toFloat)
let expected = runMean(dist1) -. runMean(dist2)
switch received {
| Error(err) => impossiblePath("algebraicSubtract")
| Ok(x) =>
switch x {
| None => impossiblePath("algebraicSubtract")
| Some(x) => x->expect->toBeSoCloseTo(expected, ~digits)
}
}
}
testAll("homogeneous subtraction", zipDistsDists, dists => { testAll("homogeneous subtraction", zipDistsDists, dists => {
let (dist1, dist2) = dists let (dist1, dist2) = dists
@ -124,27 +103,7 @@ describe("Mean", () => {
}) })
describe("multiplication", () => { describe("multiplication", () => {
let testMultiplicationMean = (dist1'', dist2'') => { let testMultiplicationMean = testOperationMean(algebraicMultiply, "algebraicMultiply", (x,y)=>x*.y)
let dist1' = E.R.fmap(x => DistributionTypes.Symbolic(x), dist1'')
let dist2' = E.R.fmap(x => DistributionTypes.Symbolic(x), dist2'')
let dist1 = E.R.fmap2(s => DistributionTypes.Other(s), dist1')
let dist2 = E.R.fmap2(s => DistributionTypes.Other(s), dist2')
let received =
E.R.liftJoin2(algebraicMultiply, dist1, dist2)
->E.R2.fmap(mean)
->E.R2.fmap(run)
->E.R2.fmap(toFloat)
let expected = runMean(dist1) *. runMean(dist2)
switch received {
| Error(err) => impossiblePath("algebraicMultiply")
| Ok(x) =>
switch x {
| None => impossiblePath("algebraicMultiply")
| Some(x) => x->expect->toBeSoCloseTo(expected, ~digits)
}
}
}
testAll("homogeneous subtraction", zipDistsDists, dists => { testAll("homogeneous subtraction", zipDistsDists, dists => {
let (dist1, dist2) = dists let (dist1, dist2) = dists

View File

@ -215,6 +215,12 @@ module R2 = {
| Ok(r) => Ok(r) | Ok(r) => Ok(r)
| Error(e) => map(e) | Error(e) => map(e)
} }
let fmap2 = (xR, f) =>
switch xR {
| Ok(x) => x->Ok
| Error(x) => x->f->Error
}
} }
let safe_fn_of_string = (fn, s: string): option<'a> => let safe_fn_of_string = (fn, s: string): option<'a> =>