diff --git a/packages/squiggle-lang/__tests__/GenericDist/GenericDistSparkline_Test.res b/packages/squiggle-lang/__tests__/GenericDist/GenericDistSparkline_Test.res index 8b3a8542..d2117936 100644 --- a/packages/squiggle-lang/__tests__/GenericDist/GenericDistSparkline_Test.res +++ b/packages/squiggle-lang/__tests__/GenericDist/GenericDistSparkline_Test.res @@ -1,17 +1,11 @@ open Jest open Expect -let normalDist: GenericDist_Types.genericDist = Symbolic(#Normal({mean: 5.0, stdev: 2.0})) -let uniformDist: GenericDist_Types.genericDist = Symbolic(#Uniform({low: 9.0, high: 10.0})) -let betaDist: GenericDist_Types.genericDist = Symbolic(#Beta({alpha: 2.0, beta: 5.0})) -let lognormalDist: GenericDist_Types.genericDist = Symbolic(#Lognormal({mu: 0.0, sigma: 1.0})) -let cauchyDist: GenericDist_Types.genericDist = Symbolic(#Cauchy({local: 1.0, scale: 1.0})) -let triangularDist: GenericDist_Types.genericDist = Symbolic(#Triangular({low: 1.0, medium: 2.0, high: 3.0})) -let exponentialDist: GenericDist_Types.genericDist = Symbolic(#Exponential({rate: 2.0})) +let {normalDist, uniformDist, betaDist, lognormalDist, cauchyDist, triangularDist, exponentialDist} = module(GenericDist_Fixtures) let runTest = (name: string, dist : GenericDist_Types.genericDist, expected: string) => { test(name, () => { - let result = GenericDist.toSparkline(~xyPointLength=100, ~sampleCount=100, ~buckets=20, dist) + let result = GenericDist.toSparkline(~sampleCount=100, ~buckets=20, dist) switch result { | Ok(sparkline) => expect(sparkline)->toEqual(expected) | Error(err) => expect("Error")->toEqual(expected) @@ -20,11 +14,11 @@ let runTest = (name: string, dist : GenericDist_Types.genericDist, expected: str } describe("sparkline of generic distribution", () => { - runTest("normal", normalDist, `▁▁▁▁▂▃▄▆▇██▇▆▄▃▂▁▁▁`) - runTest("uniform", uniformDist, `████████████████████`) - runTest("beta", uniformDist, `████████████████████`) - runTest("lognormal", lognormalDist, `█▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁`) - runTest("cauchy", cauchyDist, `▁▁▁▁▁▁▁▁▁██▁▁▁▁▁▁▁▁▁`) - runTest("triangular", triangularDist, `▁▂▃▄▄▅▆▇████▇▆▅▄▄▃▂▁`) - runTest("exponential", exponentialDist, `█▆▄▃▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁`) + runTest("normal", normalDist, `▁▃▄▅▆▇████████▇▆▅▄▃▁`) + runTest("uniform", uniformDist, `▁██▁`) + runTest("beta", betaDist, `▁▅▇█████████▇▇▆▅▄▃▂▁`) + runTest("lognormal", lognormalDist, `▁▇████▇▇▆▆▅▄▄▃▃▂▂▁▁▁`) + runTest("cauchy", cauchyDist, `▁▁▁▂▄▅▆▇████▇▆▅▄▂▁▁▁`) + runTest("triangular", triangularDist, `▁▃▄▅▆▆▇██████▇▆▆▅▄▃▁`) + runTest("exponential", exponentialDist, `███▇▇▆▆▆▅▅▄▄▃▃▃▂▂▁▁▁`) }) diff --git a/packages/squiggle-lang/__tests__/GenericDist/GenericDist_Fixtures.res b/packages/squiggle-lang/__tests__/GenericDist/GenericDist_Fixtures.res new file mode 100644 index 00000000..05f0981b --- /dev/null +++ b/packages/squiggle-lang/__tests__/GenericDist/GenericDist_Fixtures.res @@ -0,0 +1,11 @@ +let normalDist5: GenericDist_Types.genericDist = Symbolic(#Normal({mean: 5.0, stdev: 2.0})) +let normalDist10: GenericDist_Types.genericDist = Symbolic(#Normal({mean: 10.0, stdev: 2.0})) +let normalDist20: GenericDist_Types.genericDist = Symbolic(#Normal({mean: 20.0, stdev: 2.0})) +let normalDist: GenericDist_Types.genericDist = normalDist5 + +let betaDist: GenericDist_Types.genericDist = Symbolic(#Beta({alpha: 2.0, beta: 5.0})) +let lognormalDist: GenericDist_Types.genericDist = Symbolic(#Lognormal({mu: 0.0, sigma: 1.0})) +let cauchyDist: GenericDist_Types.genericDist = Symbolic(#Cauchy({local: 1.0, scale: 1.0})) +let triangularDist: GenericDist_Types.genericDist = Symbolic(#Triangular({low: 1.0, medium: 2.0, high: 3.0})) +let exponentialDist: GenericDist_Types.genericDist = Symbolic(#Exponential({rate: 2.0})) +let uniformDist: GenericDist_Types.genericDist = Symbolic(#Uniform({low: 9.0, high: 10.0})) diff --git a/packages/squiggle-lang/__tests__/GenericDist/GenericOperation__Test.res b/packages/squiggle-lang/__tests__/GenericDist/GenericOperation__Test.res index dc456865..c936e0bd 100644 --- a/packages/squiggle-lang/__tests__/GenericDist/GenericOperation__Test.res +++ b/packages/squiggle-lang/__tests__/GenericDist/GenericOperation__Test.res @@ -6,11 +6,8 @@ let env: DistributionOperation.env = { xyPointLength: 100, } -let normalDist5: GenericDist_Types.genericDist = Symbolic(#Normal({mean: 5.0, stdev: 2.0})) -let normalDist10: GenericDist_Types.genericDist = Symbolic(#Normal({mean: 10.0, stdev: 2.0})) -let normalDist20: GenericDist_Types.genericDist = Symbolic(#Normal({mean: 20.0, stdev: 2.0})) -let uniformDist: GenericDist_Types.genericDist = Symbolic(#Uniform({low: 9.0, high: 10.0})) +let {normalDist5, normalDist10, normalDist20, uniformDist} = module(GenericDist_Fixtures) let {toFloat, toDist, toString, toError} = module(DistributionOperation.Output) let {run} = module(DistributionOperation) let {fmap} = module(DistributionOperation.Output) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res index 7029e2ff..65f689cc 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res @@ -9,6 +9,3 @@ let expectParseToBe = (expr: string, answer: string) => let expectEvalToBe = (expr: string, answer: string) => Reducer.eval(expr)->ExpressionValue.toStringResult->expect->toBe(answer) - -// Current configuration does not ignore this file so we have to have a test -test("test helpers", () => expect(1)->toBe(1)) diff --git a/packages/squiggle-lang/__tests__/Symbolic_test.res b/packages/squiggle-lang/__tests__/Symbolic_test.res index eb953743..058a5528 100644 --- a/packages/squiggle-lang/__tests__/Symbolic_test.res +++ b/packages/squiggle-lang/__tests__/Symbolic_test.res @@ -22,12 +22,12 @@ describe("Normal distribution with sparklines", () => { let normalDistAtMean5: SymbolicDistTypes.normal = {mean: 5.0, stdev: 2.0} let normalDistAtMean10: SymbolicDistTypes.normal = {mean: 10.0, stdev: 2.0} - let range20Float = E.A.rangeFloat(0.0, 20.0) // [0.0,1.0,2.0,3.0,4.0,...19.0,] + let range20Float = E.A.Floats.range(0.0, 20.0, 20) // [0.0,1.0,2.0,3.0,4.0,...19.0,] let pdfNormalDistAtMean5 = x => Normal.pdf(x, normalDistAtMean5) let sparklineMean5 = pdfImage(pdfNormalDistAtMean5, range20Float) - makeTest("mean=5", Sparklines.create(sparklineMean5, ()), `▁▂▃▅███▅▃▂▁▁▁▁▁▁▁▁▁▁▁`) + makeTest("mean=5", Sparklines.create(sparklineMean5, ()), `▁▂▃▆██▇▅▂▁▁▁▁▁▁▁▁▁▁▁`) let sparklineMean15 = normalDistAtMean5 -> parameterWiseAdditionHelper(normalDistAtMean10) -> pdfImage(range20Float) - makeTest("parameter-wise addition of two normal distributions", Sparklines.create(sparklineMean15, ()), `▁▁▁▁▁▁▁▁▁▁▂▃▅▇███▇▅▃▂`) + makeTest("parameter-wise addition of two normal distributions", Sparklines.create(sparklineMean15, ()), `▁▁▁▁▁▁▁▁▁▂▃▄▆███▇▅▄▂`) }) diff --git a/packages/squiggle-lang/jest.config.js b/packages/squiggle-lang/jest.config.js index 09bf05a8..a44cd302 100644 --- a/packages/squiggle-lang/jest.config.js +++ b/packages/squiggle-lang/jest.config.js @@ -2,6 +2,7 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', + testPathIgnorePatterns: [".*Fixtures.bs.js", "/node_modules/", ".*Helpers.bs.js"], setupFilesAfterEnv: [ "/../../node_modules/bisect_ppx/src/runtime/js/jest.bs.js" ], diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res index ab2dd63f..f3f8402a 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res @@ -75,8 +75,10 @@ let toPointSet = (~xyPointLength, ~sampleCount, t): result => - toPointSet(~xyPointLength, ~sampleCount, t) -> E.R2.fmap(PointSetDist.toSparkline(buckets)) +let toSparkline = (~sampleCount: int, ~buckets: int = 20, t: t) : result => + toPointSet(~xyPointLength=buckets, ~sampleCount, t) + -> E.R.bind(x => x -> PointSetDist.T.toContinuous -> E.O2.toResult(GenericDist_Types.Other("Could not convert to continuous"))) + -> E.R2.fmap(c => Sparklines.create(Continuous.getShape(c).ys, ())) module Truncate = { let trySymbolicSimplification = (leftCutoff, rightCutoff, t: t): option => diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi index dcb929ca..c37385e4 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi @@ -25,7 +25,6 @@ let toPointSet: ( t, ) => result let toSparkline: ( - ~xyPointLength: int, ~sampleCount: int, ~buckets: int=?, t, diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res index e4e443fe..15186e0b 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res @@ -168,15 +168,6 @@ let pdf = (f: float, t: t) => { let inv = T.Integral.yToX let cdf = T.Integral.xToY - -@genType -let toSparkline = (buckets: int, t: t ): string => { - let size : float = T.maxX(t) -. T.minX(t) - let stepSize = size /. Belt.Int.toFloat(buckets) - let cdfImage = E.A.rangeFloat(~step=stepSize, T.minX(t), T.maxX(t)) -> Belt.Array.map(val => cdf(val,t)) - Sparklines.create(E.A.diff(cdfImage), ()) -} - let doN = (n, fn) => { let items = Belt.Array.make(n, 0.0) for x in 0 to n - 1 { @@ -200,7 +191,6 @@ let isFloat = (t: t) => let sampleNRendered = (n, dist) => { let integralCache = T.Integral.get(dist) let distWithUpdatedIntegralCache = T.updateIntegralCache(Some(integralCache), dist) - doN(n, () => sample(distWithUpdatedIntegralCache)) } diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index 30b48881..0411bf3c 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -101,6 +101,7 @@ module O2 = { let default = (a, b) => O.default(b, a) let toExn = (a, b) => O.toExn(b, a) let fmap = (a, b) => O.fmap(b, a) + let toResult = (a, b) => O.toResult(b, a) } /* Functions */ @@ -178,6 +179,7 @@ module R = { module R2 = { let fmap = (a,b) => R.fmap(b,a) + let bind = (a, b) => R.bind(b, a) } let safe_fn_of_string = (fn, s: string): option<'a> => @@ -290,13 +292,6 @@ module A = { |> Rationale.Result.return } - let diff = (arr: array): array => - Belt.Array.zipBy(arr, Belt.Array.sliceToEnd(arr, 1), (left, right) => right -. left) - - let rec rangeFloat = (~step: float=1.0, start : float, end: float) : array => - start > end ? - [] - : Belt.Array.concat([start], rangeFloat(~step, start +. step, end)) // This zips while taking the longest elements of each array. let zipMaxLength = (array1, array2) => { @@ -448,6 +443,10 @@ module A = { let mean = a => sum(a) /. (Array.length(a) |> float_of_int) let random = Js.Math.random_int + let diff = (arr: array): array => + Belt.Array.zipBy(arr, Belt.Array.sliceToEnd(arr, 1), (left, right) => right -. left) + + exception RangeError(string) let range = (min: float, max: float, n: int): array => switch n {