test count: 386
This commit is contained in:
parent
59fcd6a26c
commit
af0577f85e
|
@ -1,3 +1,7 @@
|
||||||
|
/*
|
||||||
|
This file was going to be too big and it will be factored into smaller files.
|
||||||
|
*/
|
||||||
|
|
||||||
open Jest
|
open Jest
|
||||||
open Expect
|
open Expect
|
||||||
open TestHelpers
|
open TestHelpers
|
||||||
|
@ -307,7 +311,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.915396627014363, ~digits=1)
|
| Some(x) => x -> expect -> toBeSoCloseTo(10.915396627014363, ~digits=0)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,8 +2,36 @@ open Jest
|
||||||
open Expect
|
open Expect
|
||||||
open TestHelpers
|
open TestHelpers
|
||||||
|
|
||||||
|
let {
|
||||||
|
algebraicAdd,
|
||||||
|
algebraicMultiply,
|
||||||
|
algebraicDivide,
|
||||||
|
algebraicSubtract,
|
||||||
|
algebraicLogarithm,
|
||||||
|
algebraicPower
|
||||||
|
} = module(DistributionOperation.Constructors)
|
||||||
|
|
||||||
|
let algebraicAdd = algebraicAdd(~env)
|
||||||
|
let algebraicMultiply = algebraicMultiply(~env)
|
||||||
|
let algebraicDivide = algebraicDivide(~env)
|
||||||
|
let algebraicSubtract = algebraicSubtract(~env)
|
||||||
|
let algebraicLogarithm = algebraicLogarithm(~env)
|
||||||
|
let algebraicPower = algebraicPower(~env)
|
||||||
|
|
||||||
|
|
||||||
describe("Mean", () => {
|
describe("Mean", () => {
|
||||||
|
|
||||||
|
let mean = GenericDist_Types.Constructors.UsingDists.mean
|
||||||
|
|
||||||
|
let runMean: result<DistributionTypes.genericDist, DistributionTypes.error> => float = distR => {
|
||||||
|
switch distR->E.R2.fmap(mean)->E.R2.fmap(run)->E.R2.fmap(toFloat) {
|
||||||
|
| Ok(Some(x)) => x
|
||||||
|
| _ => 9e99 // We trust input in test fixtures so this won't happen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let impossiblePath: string => assertion = algebraicOp => `${algebraicOp} has`->expect->toEqual("failed")
|
||||||
|
|
||||||
let distributions = list{
|
let distributions = list{
|
||||||
normalMake(0.0, 1e0),
|
normalMake(0.0, 1e0),
|
||||||
betaMake(2e0, 4e0),
|
betaMake(2e0, 4e0),
|
||||||
|
@ -12,11 +40,125 @@ describe("Mean", () => {
|
||||||
// cauchyMake(1e0, 1e0),
|
// cauchyMake(1e0, 1e0),
|
||||||
lognormalMake(1e0, 1e0),
|
lognormalMake(1e0, 1e0),
|
||||||
triangularMake(1e0, 1e1, 5e1),
|
triangularMake(1e0, 1e1, 5e1),
|
||||||
floatMake(1e1)
|
Ok(floatMake(1e1))
|
||||||
}
|
}
|
||||||
let digits = 7
|
let combinations = E.L.combinations2(distributions)
|
||||||
|
let zipDistsDists = E.L.zip(distributions, distributions)
|
||||||
|
let digits = -4
|
||||||
|
|
||||||
|
describe("addition", () => {
|
||||||
|
let testAdditionMean = (dist1'', dist2'') => {
|
||||||
|
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(algebraicAdd, 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("algebraicAdd")
|
||||||
|
| Ok(x) =>
|
||||||
|
switch x {
|
||||||
|
| None => impossiblePath("algebraicAdd")
|
||||||
|
| Some(x) => x->expect->toBeSoCloseTo(expected, ~digits=digits)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testAll("homogeneous addition", zipDistsDists, dists => {
|
||||||
|
let (dist1, dist2) = dists
|
||||||
|
testAdditionMean(dist1, dist2)
|
||||||
|
})
|
||||||
|
|
||||||
|
testAll("heterogeneoous addition (1)", combinations, dists => {
|
||||||
|
let (dist1, dist2) = dists
|
||||||
|
testAdditionMean(dist1, dist2)
|
||||||
|
})
|
||||||
|
|
||||||
|
testAll("heterogeneoous addition (commuted of 1 (or; 2))", combinations, dists => {
|
||||||
|
let (dist1, dist2) = dists
|
||||||
|
testAdditionMean(dist2, dist1)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("subtraction", () => {
|
||||||
|
let testSubtractionMean = (dist1'', dist2'') => {
|
||||||
|
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=digits)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testAll("homogeneous subtraction", zipDistsDists, dists => {
|
||||||
|
let (dist1, dist2) = dists
|
||||||
|
testSubtractionMean(dist1, dist2)
|
||||||
|
})
|
||||||
|
|
||||||
|
testAll("heterogeneoous subtraction (1)", combinations, dists => {
|
||||||
|
let (dist1, dist2) = dists
|
||||||
|
testSubtractionMean(dist1, dist2)
|
||||||
|
})
|
||||||
|
|
||||||
|
testAll("heterogeneoous subtraction (commuted of 1 (or; 2))", combinations, dists => {
|
||||||
|
let (dist1, dist2) = dists
|
||||||
|
testSubtractionMean(dist2, dist1)
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("multiplication", () => {
|
||||||
|
let testMultiplicationMean = (dist1'', dist2'') => {
|
||||||
|
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=digits)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testAll("homogeneous subtraction", zipDistsDists, dists => {
|
||||||
|
let (dist1, dist2) = dists
|
||||||
|
testMultiplicationMean(dist1, dist2)
|
||||||
|
})
|
||||||
|
|
||||||
|
testAll("heterogeneoous subtraction (1)", combinations, dists => {
|
||||||
|
let (dist1, dist2) = dists
|
||||||
|
testMultiplicationMean(dist1, dist2)
|
||||||
|
})
|
||||||
|
|
||||||
|
testAll("heterogeneoous subtraction (commuted of 1 (or; 2))", combinations, dists => {
|
||||||
|
let (dist1, dist2) = dists
|
||||||
|
testMultiplicationMean(dist2, dist1)
|
||||||
|
})
|
||||||
|
|
||||||
testAll("addition", () => {
|
|
||||||
true -> expect -> toBe(true)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
|
@ -28,16 +28,16 @@ describe("(Symbolic) mean", () => {
|
||||||
|
|
||||||
testAll("of exponential distributions", list{1e-7, 2.0, 10.0, 100.0}, rate => {
|
testAll("of exponential distributions", list{1e-7, 2.0, 10.0, 100.0}, rate => {
|
||||||
let meanValue = run(
|
let meanValue = run(
|
||||||
FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Exponential({rate: rate}))),
|
FromDist(ToFloat(#Mean), DistributionTypes.Symbolic(#Exponential({rate: rate}))),
|
||||||
)
|
)
|
||||||
meanValue->unpackFloat->expect->toBeCloseTo(1.0 /. rate) // https://en.wikipedia.org/wiki/Exponential_distribution#Mean,_variance,_moments,_and_median
|
meanValue->unpackFloat->expect->toBeCloseTo(1.0 /. rate) // https://en.wikipedia.org/wiki/Exponential_distribution#Mean,_variance,_moments,_and_median
|
||||||
})
|
})
|
||||||
|
|
||||||
test("of a cauchy distribution", () => {
|
test("of a cauchy distribution", () => {
|
||||||
let meanValue = run(
|
let meanValue = run(
|
||||||
FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Cauchy({local: 1.0, scale: 1.0}))),
|
FromDist(ToFloat(#Mean), DistributionTypes.Symbolic(#Cauchy({local: 1.0, scale: 1.0}))),
|
||||||
)
|
)
|
||||||
meanValue->unpackFloat->expect->toBeCloseTo(2.01868297874546)
|
meanValue->unpackFloat->expect->toBeSoCloseTo(1.0098094001641797, ~digits=5)
|
||||||
//-> toBe(GenDistError(Other("Cauchy distributions may have no mean value.")))
|
//-> toBe(GenDistError(Other("Cauchy distributions may have no mean value.")))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ describe("(Symbolic) mean", () => {
|
||||||
let meanValue = run(
|
let meanValue = run(
|
||||||
FromDist(
|
FromDist(
|
||||||
ToFloat(#Mean),
|
ToFloat(#Mean),
|
||||||
GenericDist_Types.Symbolic(#Triangular({low: low, medium: medium, high: high})),
|
DistributionTypes.Symbolic(#Triangular({low: low, medium: medium, high: high})),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
meanValue->unpackFloat->expect->toBeCloseTo((low +. medium +. high) /. 3.0) // https://www.statology.org/triangular-distribution/
|
meanValue->unpackFloat->expect->toBeCloseTo((low +. medium +. high) /. 3.0) // https://www.statology.org/triangular-distribution/
|
||||||
|
@ -63,7 +63,7 @@ describe("(Symbolic) mean", () => {
|
||||||
tup => {
|
tup => {
|
||||||
let (alpha, beta) = tup
|
let (alpha, beta) = tup
|
||||||
let meanValue = run(
|
let meanValue = run(
|
||||||
FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Beta({alpha: alpha, beta: beta}))),
|
FromDist(ToFloat(#Mean), DistributionTypes.Symbolic(#Beta({alpha: alpha, beta: beta}))),
|
||||||
)
|
)
|
||||||
meanValue->unpackFloat->expect->toBeCloseTo(1.0 /. (1.0 +. beta /. alpha)) // https://en.wikipedia.org/wiki/Beta_distribution#Mean
|
meanValue->unpackFloat->expect->toBeCloseTo(1.0 /. (1.0 +. beta /. alpha)) // https://en.wikipedia.org/wiki/Beta_distribution#Mean
|
||||||
},
|
},
|
||||||
|
@ -72,7 +72,7 @@ describe("(Symbolic) mean", () => {
|
||||||
// TODO: When we have our theory of validators we won't want this to be NaN but to be an error.
|
// TODO: When we have our theory of validators we won't want this to be NaN but to be an error.
|
||||||
test("of beta(0, 0)", () => {
|
test("of beta(0, 0)", () => {
|
||||||
let meanValue = run(
|
let meanValue = run(
|
||||||
FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Beta({alpha: 0.0, beta: 0.0}))),
|
FromDist(ToFloat(#Mean), DistributionTypes.Symbolic(#Beta({alpha: 0.0, beta: 0.0}))),
|
||||||
)
|
)
|
||||||
meanValue->unpackFloat->expect->ExpectJs.toBeFalsy
|
meanValue->unpackFloat->expect->ExpectJs.toBeFalsy
|
||||||
})
|
})
|
||||||
|
@ -83,7 +83,7 @@ describe("(Symbolic) mean", () => {
|
||||||
tup => {
|
tup => {
|
||||||
let (mu, sigma) = tup
|
let (mu, sigma) = tup
|
||||||
let meanValue = run(
|
let meanValue = run(
|
||||||
FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Lognormal({mu: mu, sigma: sigma}))),
|
FromDist(ToFloat(#Mean), DistributionTypes.Symbolic(#Lognormal({mu: mu, sigma: sigma}))),
|
||||||
)
|
)
|
||||||
meanValue->unpackFloat->expect->toBeCloseTo(Js.Math.exp(mu +. sigma ** 2.0 /. 2.0)) // https://brilliant.org/wiki/log-normal-distribution/
|
meanValue->unpackFloat->expect->toBeCloseTo(Js.Math.exp(mu +. sigma ** 2.0 /. 2.0)) // https://brilliant.org/wiki/log-normal-distribution/
|
||||||
},
|
},
|
||||||
|
@ -95,14 +95,14 @@ describe("(Symbolic) mean", () => {
|
||||||
tup => {
|
tup => {
|
||||||
let (low, high) = tup
|
let (low, high) = tup
|
||||||
let meanValue = run(
|
let meanValue = run(
|
||||||
FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Uniform({low: low, high: high}))),
|
FromDist(ToFloat(#Mean), DistributionTypes.Symbolic(#Uniform({low: low, high: high}))),
|
||||||
)
|
)
|
||||||
meanValue->unpackFloat->expect->toBeCloseTo((low +. high) /. 2.0) // https://en.wikipedia.org/wiki/Continuous_uniform_distribution#Moments
|
meanValue->unpackFloat->expect->toBeCloseTo((low +. high) /. 2.0) // https://en.wikipedia.org/wiki/Continuous_uniform_distribution#Moments
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
test("of a float", () => {
|
test("of a float", () => {
|
||||||
let meanValue = run(FromDist(ToFloat(#Mean), GenericDist_Types.Symbolic(#Float(7.7))))
|
let meanValue = run(FromDist(ToFloat(#Mean), DistributionTypes.Symbolic(#Float(7.7))))
|
||||||
meanValue->unpackFloat->expect->toBeCloseTo(7.7)
|
meanValue->unpackFloat->expect->toBeCloseTo(7.7)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
10
packages/squiggle-lang/__tests__/Utility_test.res
Normal file
10
packages/squiggle-lang/__tests__/Utility_test.res
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
open Jest
|
||||||
|
open Expect
|
||||||
|
|
||||||
|
describe("E.L.combinations2", () => {
|
||||||
|
test("size three", () => {
|
||||||
|
E.L.combinations2(list{"alice", "bob", "eve"}) -> expect -> toEqual(
|
||||||
|
list{("alice", "bob"), ("alice", "eve"), ("bob", "eve")}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
|
@ -178,6 +178,25 @@ module R = {
|
||||||
|
|
||||||
let errorIfCondition = (errorCondition, errorMessage, r) =>
|
let errorIfCondition = (errorCondition, errorMessage, r) =>
|
||||||
errorCondition(r) ? Error(errorMessage) : Ok(r)
|
errorCondition(r) ? Error(errorMessage) : Ok(r)
|
||||||
|
|
||||||
|
let ap = Rationale.Result.ap
|
||||||
|
let ap' = (r, a) => switch r {
|
||||||
|
| Ok(f) => fmap(f, a)
|
||||||
|
| Error(err) => Error(err)
|
||||||
|
}
|
||||||
|
// (a1 -> a2 -> r) -> m a1 -> m a2 -> m r // not in Rationale
|
||||||
|
let liftM2: (('a, 'b) => 'c, result<'a, 'd>, result<'b, 'd>) => result<'c, 'd> = (op, xR, yR) => {
|
||||||
|
ap'(fmap(op, xR), yR)
|
||||||
|
}
|
||||||
|
|
||||||
|
let liftJoin2: (('a, 'b) => result<'c, 'd>, result<'a, 'd>, result<'b, 'd>) => result<'c, 'd> = (op, xR, yR) => {
|
||||||
|
bind(liftM2(op, xR, yR), x => x)
|
||||||
|
}
|
||||||
|
|
||||||
|
let fmap2 = (f, r) => switch r {
|
||||||
|
| Ok(r) => r->Ok
|
||||||
|
| Error(x) => x->f->Error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module R2 = {
|
module R2 = {
|
||||||
|
@ -260,22 +279,28 @@ module L = {
|
||||||
let update = Rationale.RList.update
|
let update = Rationale.RList.update
|
||||||
let iter = List.iter
|
let iter = List.iter
|
||||||
let findIndex = Rationale.RList.findIndex
|
let findIndex = Rationale.RList.findIndex
|
||||||
/*
|
let headSafe = Belt.List.head
|
||||||
Output is size Choose(n + 2 - 1, 2) for binomial coefficient function Choose.
|
let tailSafe = Belt.List.tail
|
||||||
inspired by https://docs.python.org/3/library/itertools.html#itertools.combinations_with_replacement at r=2
|
let headExn = Belt.List.headExn
|
||||||
*/
|
let tailExn = Belt.List.tailExn
|
||||||
let completeGraph = xs => {
|
let zip = Belt.List.zip
|
||||||
// TODO
|
|
||||||
let rec loop = (x', xs') => {
|
let combinations2: list<'a> => list<('a, 'a)> = xs => {
|
||||||
let intermediate = fmap(y => append(y, list{x'}))
|
let rec loop: ('a, list<'a>) => list<('a, 'a)> = (x', xs') => {
|
||||||
// map (y => append(y, list{x'})) xs'
|
let n = length(xs')
|
||||||
|
if n == 0 {
|
||||||
|
list{}
|
||||||
|
} else {
|
||||||
|
let combs = fmap(y => (x', y), xs')
|
||||||
|
let hd = headExn(xs')
|
||||||
|
let tl = tailExn(xs')
|
||||||
|
concat(list{combs, loop(hd, tl)})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (headSafe(xs), tailSafe(xs)) {
|
||||||
|
| (Some(x'), Some(xs')) => loop(x', xs')
|
||||||
|
| (_, _) => list{}
|
||||||
}
|
}
|
||||||
|
|
||||||
let intermediate = fmap()
|
|
||||||
let n = length(xs)
|
|
||||||
|
|
||||||
let indices = list{0, 0}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user