diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res index b514232a..85d80919 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res @@ -11,25 +11,43 @@ let testEval = (~skip=false, str, result) => let testParse = (~skip=false, str, result) => testSkip(skip)(str, () => Reducer_TestHelpers.expectParseToBe(str, result)) -describe("eval", () => { - describe("expressions", () => { +describe("eval on distribution functions", () => { + describe("normal distribution", () => { testEval("normal(5,2)", "Ok(Normal(5,2))") + }) + describe("lognormal distribution", () => { + testEval("lognormal(5,2)", "Ok(Lognormal(5,2))") + }) + describe("unaryMinus", () => { + testEval("mean(-normal(5,2))", "Ok(-5.002887370380851)") + }) + describe("to", () => { testEval("5 to 2", "Error(TODO: Low value must be less than high value.)") testEval("to(2,5)", "Ok(Lognormal(1.1512925464970227,0.278507821238345))") testEval("to(-2,2)", "Ok(Normal(0,1.215913388057542))") - testEval("lognormal(5,2)", "Ok(Lognormal(5,2))") + }) + describe("mean", () => { testEval("mean(normal(5,2))", "Ok(5)") testEval("mean(lognormal(1,2))", "Ok(20.085536923187668)") + }) + describe("normalize", () => { testEval("normalize(normal(5,2))", "Ok(Normal(5,2))") + }) + describe("toPointSet", () => { testEval("toPointSet(normal(5,2))", "Ok(Point Set Distribution)") + }) + describe("toSampleSet", () => { testEval("toSampleSet(normal(5,2), 100)", "Ok(Sample Set Distribution)") + }) + describe("add", () => { testEval("add(normal(5,2), normal(10,2))", "Ok(Normal(15,2.8284271247461903))") testEval("add(normal(5,2), lognormal(10,2))", "Ok(Sample Set Distribution)") testEval("add(normal(5,2), 3)", "Ok(Point Set Distribution)") testEval("add(3, normal(5,2))", "Ok(Point Set Distribution)") testEval("3+normal(5,2)", "Ok(Point Set Distribution)") testEval("normal(5,2)+3", "Ok(Point Set Distribution)") - testEval("add(3, 3)", "Ok(6)") + }) + describe("truncate", () => { testEval("truncateLeft(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)") @@ -82,25 +100,26 @@ describe("eval", () => { }) }) -describe("MathJs parse", () => { - describe("literals operators paranthesis", () => { - testParse("mean(normal(5,2) + normal(5,1))", "Ok((:mean (:add (:normal 5 2) (:normal 5 1))))") - testParse("normal(5,2) .* normal(5,1)", "Ok((:dotMultiply (:normal 5 2) (:normal 5 1)))") - testParse("normal(5,2) ./ normal(5,1)", "Ok((:dotDivide (:normal 5 2) (:normal 5 1)))") - testParse("normal(5,2) .^ normal(5,1)", "Ok((:dotPow (:normal 5 2) (:normal 5 1)))") +describe("parse on distribution functions", () => { + describe("power", () => { testParse("normal(5,2) ^ normal(5,1)", "Ok((:pow (:normal 5 2) (:normal 5 1)))") testParse("3 ^ normal(5,1)", "Ok((:pow 3 (:normal 5 1)))") testParse("normal(5,2) ^ 3", "Ok((:pow (:normal 5 2) 3))") + }) + describe("pointwise arithmetic expressions", () => { + testParse(~skip=true, "normal(5,2) .+ normal(5,1)", "Ok((:dotAdd (:normal 5 2) (:normal 5 1)))") + testParse(~skip=true, "normal(5,2) .- normal(5,1)", "Ok((:dotSubtract (:normal 5 2) (:normal 5 1)))") + testParse("normal(5,2) .* normal(5,1)", "Ok((:dotMultiply (:normal 5 2) (:normal 5 1)))") + testParse("normal(5,2) ./ normal(5,1)", "Ok((:dotDivide (:normal 5 2) (:normal 5 1)))") + testParse("normal(5,2) .^ normal(5,1)", "Ok((:dotPow (:normal 5 2) (:normal 5 1)))") + }) + describe("equality", () => { testParse("5 == normal(5,2)", "Ok((:equal 5 (:normal 5 2)))") - describe("adding two normals", () => { - testParse( - ~skip=true, - "normal(5,2) .+ normal(5,1)", - "Ok((:dotAdd (:normal 5 2) (:normal 5 1)))", - ) - }) - describe("exponential of one distribution", () => { - testParse(~skip=true, "exp(normal(5,2)", "Ok((:pow (:normal 5 2) 3))") - }) + }) + describe("pointwise adding two normals", () => { + testParse(~skip=true, "normal(5,2) .+ normal(5,1)", "Ok((:dotAdd (:normal 5 2) (:normal 5 1)))") + }) + describe("exponential of one distribution", () => { + testParse(~skip=true, "exp(normal(5,2)", "Ok((:pow (:normal 5 2) 3))") }) }) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index 11376001..8fabdfa8 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -139,6 +139,8 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option< Helpers.twoDiststoDistFn(Algebraic, "log", a, GenericDist.fromFloat(Math.e))->Some | ("log10", [EvDistribution(a)]) => Helpers.twoDiststoDistFn(Algebraic, "log", a, GenericDist.fromFloat(10.0))->Some + | ("unaryMinus", [EvDistribution(a)]) => + Helpers.twoDiststoDistFn(Algebraic, "multiply", a, GenericDist.fromFloat(-1.0))->Some | (("add" | "multiply" | "subtract" | "divide" | "pow" | "log") as arithmetic, [a, b] as args) => Helpers.catchAndConvertTwoArgsToDists(args)->E.O2.fmap(((fst, snd)) => Helpers.twoDiststoDistFn(Algebraic, arithmetic, fst, snd)