diff --git a/showcase/entries/Continuous2.re b/showcase/entries/Continuous2.re index f6cb9a53..e46218ef 100644 --- a/showcase/entries/Continuous2.re +++ b/showcase/entries/Continuous2.re @@ -6,18 +6,18 @@ // uniform(0,1) > 0.3 ? lognormal(6.652, -0.41): 0 let timeDist ={ - let ingredients = RenderTypes.DistPlusRenderer.Ingredients.make( + let ingredients = DistPlusRenderer.Inputs.Ingredients.make( ~guesstimatorString="(floor(10 to 15))", ~domain=RightLimited({xPoint: 50.0, excludingProbabilityMass: 0.3}), ~unit= DistTypes.TimeDistribution({zero: MomentRe.momentNow(), unit: `years}), ()); - let inputs = RenderTypes.DistPlusRenderer.make(~distPlusIngredients=ingredients,()) + let inputs = DistPlusRenderer.Inputs.make(~distPlusIngredients=ingredients,()) inputs |> DistPlusRenderer.run } let setup = dist => - RenderTypes.DistPlusRenderer.make(~distPlusIngredients=dist,()) + DistPlusRenderer.Inputs.make(~distPlusIngredients=dist,()) |> DistPlusRenderer.run |> E.R.fmap(distPlus => ) |> E.R.toOption @@ -28,7 +28,7 @@ let simpleExample = (name, guesstimatorString) =>

{name |> ReasonReact.string}

- {setup(RenderTypes.DistPlusRenderer.Ingredients.make(~guesstimatorString, ()))} + {setup(DistPlusRenderer.Inputs.Ingredients.make(~guesstimatorString, ()))} ; let timeExample = (name, guesstimatorString) => @@ -37,7 +37,7 @@ let timeExample = (name, guesstimatorString) => {name |> ReasonReact.string} {setup( - RenderTypes.DistPlusRenderer.Ingredients.make( + DistPlusRenderer.Inputs.Ingredients.make( ~guesstimatorString, ~unit=TimeDistribution({zero: MomentRe.momentNow(), unit: `years}), (), diff --git a/showcase/entries/ExpressionTreeExamples.re b/showcase/entries/ExpressionTreeExamples.re index 2ca91990..a93f61d1 100644 --- a/showcase/entries/ExpressionTreeExamples.re +++ b/showcase/entries/ExpressionTreeExamples.re @@ -1,5 +1,5 @@ let setup = dist => - RenderTypes.DistPlusRenderer.make(~distPlusIngredients=dist, ()) + DistPlusRenderer.Inputs.make(~distPlusIngredients=dist, ()) |> DistPlusRenderer.run |> E.R.fmap(distPlus => ) |> E.R.toOption @@ -10,7 +10,7 @@ let simpleExample = (guesstimatorString, ~problem="", ()) =>

{guesstimatorString |> ReasonReact.string}

{problem |> (e => "problem: " ++ e) |> ReasonReact.string}

{setup( - RenderTypes.DistPlusRenderer.Ingredients.make(~guesstimatorString, ()), + DistPlusRenderer.Inputs.Ingredients.make(~guesstimatorString, ()), )} ; diff --git a/src/components/DistBuilder.re b/src/components/DistBuilder.re index fac4e483..c58fcd11 100644 --- a/src/components/DistBuilder.re +++ b/src/components/DistBuilder.re @@ -128,13 +128,6 @@ module Styles = { ]); }; -type inputs = { - samplingInputs: RenderTypes.ShapeRenderer.Sampling.inputs, - guesstimatorString: string, - length: int, - shouldDownsampleSampledDistribution: int, -}; - module DemoDist = { [@react.component] let make = (~guesstimatorString, ~domain, ~unit, ~options) => { @@ -144,14 +137,14 @@ module DemoDist = { {switch (domain, unit, options) { | (Some(domain), Some(unit), Some(options)) => let distPlusIngredients = - RenderTypes.DistPlusRenderer.Ingredients.make( + DistPlusRenderer.Inputs.Ingredients.make( ~guesstimatorString, ~domain, ~unit, (), ); let inputs1 = - RenderTypes.DistPlusRenderer.make( + DistPlusRenderer.Inputs.make( ~samplingInputs={ sampleCount: Some(options.sampleCount), outputXYPoints: Some(options.outputXYPoints), diff --git a/src/distPlus/renderers/DistPlusRenderer.re b/src/distPlus/renderers/DistPlusRenderer.re index c38758f3..5028590e 100644 --- a/src/distPlus/renderers/DistPlusRenderer.re +++ b/src/distPlus/renderers/DistPlusRenderer.re @@ -1,52 +1,110 @@ -type inputs = { - samplingInputs: RenderTypes.ShapeRenderer.Sampling.inputs, - symbolicInputs: RenderTypes.ShapeRenderer.Symbolic.inputs, - guesstimatorString: string, - inputVariables: Belt.Map.String.t(ExpressionTypes.ExpressionTree.node), -}; -type outputs = { - graph: ExpressionTypes.ExpressionTree.node, - shape: DistTypes.shape, -}; -let makeOutputs = (graph, shape): outputs => {graph, shape}; +// TODO: This setup is more confusing than it should be, there's more work to do in cleanup here. -let inputsToShape = (inputs: inputs) => { - MathJsParser.fromString(inputs.guesstimatorString, inputs.inputVariables) - |> E.R.bind(_, g => - ExpressionTree.toShape( - inputs.symbolicInputs.length, - { - sampleCount: - inputs.samplingInputs.sampleCount |> E.O.default(10000), - outputXYPoints: - inputs.samplingInputs.outputXYPoints |> E.O.default(10000), - kernelWidth: inputs.samplingInputs.kernelWidth, - }, - g, - ) - |> E.R.fmap(makeOutputs(g)) - ); +module Inputs = { + let defaultRecommendedLength = 10000; + let defaultShouldDownsample = true; + type ingredients = { + guesstimatorString: string, + domain: DistTypes.domain, + unit: DistTypes.distributionUnit, + }; + module Ingredients = { + type t = ingredients; + let make = + ( + ~guesstimatorString, + ~domain=DistTypes.Complete, + ~unit=DistTypes.UnspecifiedDistribution, + (), + ) + : t => { + guesstimatorString, + domain, + unit, + }; + }; + type inputs = { + distPlusIngredients: ingredients, + samplingInputs: RenderTypes.ShapeRenderer.Sampling.inputs, + recommendedLength: int, + shouldDownsample: bool, + inputVariables: Belt.Map.String.t(ExpressionTypes.ExpressionTree.node), + }; + let make = + ( + ~samplingInputs=RenderTypes.ShapeRenderer.Sampling.Inputs.empty, + ~recommendedLength=defaultRecommendedLength, + ~shouldDownsample=defaultShouldDownsample, + ~distPlusIngredients, + ~inputVariables=[||]->Belt.Map.String.fromArray, + (), + ) + : inputs => { + distPlusIngredients, + samplingInputs, + recommendedLength, + shouldDownsample, + inputVariables, + }; }; -let run = (inputs: RenderTypes.DistPlusRenderer.inputs) => { - let output = - inputsToShape({ +module Internals = { + type inputs = { + samplingInputs: RenderTypes.ShapeRenderer.Sampling.inputs, + symbolicInputs: RenderTypes.ShapeRenderer.Symbolic.inputs, + guesstimatorString: string, + inputVariables: Belt.Map.String.t(ExpressionTypes.ExpressionTree.node), + }; + + let distPlusRenderInputsToInputs = (inputs: Inputs.inputs): inputs => { + { samplingInputs: inputs.samplingInputs, guesstimatorString: inputs.distPlusIngredients.guesstimatorString, inputVariables: inputs.inputVariables, symbolicInputs: { length: inputs.recommendedLength, }, - }); - output - |> E.R.fmap((o: outputs) => - DistPlus.make( - ~shape=o.shape, - ~domain=inputs.distPlusIngredients.domain, - ~unit=inputs.distPlusIngredients.unit, - ~guesstimatorString= - Some(inputs.distPlusIngredients.guesstimatorString), - (), - ) - ); + }; + }; + + type outputs = { + graph: ExpressionTypes.ExpressionTree.node, + shape: DistTypes.shape, + }; + let makeOutputs = (graph, shape): outputs => {graph, shape}; + + let inputsToShape = (inputs: inputs) => { + MathJsParser.fromString(inputs.guesstimatorString, inputs.inputVariables) + |> E.R.bind(_, g => + ExpressionTree.toShape( + inputs.symbolicInputs.length, + { + sampleCount: + inputs.samplingInputs.sampleCount |> E.O.default(10000), + outputXYPoints: + inputs.samplingInputs.outputXYPoints |> E.O.default(10000), + kernelWidth: inputs.samplingInputs.kernelWidth, + }, + g, + ) + |> E.R.fmap(makeOutputs(g)) + ); + }; + + let outputToDistPlus = (inputs: Inputs.inputs, outputs: outputs) => { + DistPlus.make( + ~shape=outputs.shape, + ~domain=inputs.distPlusIngredients.domain, + ~unit=inputs.distPlusIngredients.unit, + ~guesstimatorString=Some(inputs.distPlusIngredients.guesstimatorString), + (), + ); + }; +}; + +let run = (inputs: Inputs.inputs) => { + inputs + |> Internals.distPlusRenderInputsToInputs + |> Internals.inputsToShape + |> E.R.fmap(Internals.outputToDistPlus(inputs)); }; diff --git a/src/distPlus/renderers/RenderTypes.re b/src/distPlus/renderers/RenderTypes.re index fafcdb4d..b222dcf8 100644 --- a/src/distPlus/renderers/RenderTypes.re +++ b/src/distPlus/renderers/RenderTypes.re @@ -34,51 +34,3 @@ module ShapeRenderer = { type inputs = {length: int}; }; }; - -module DistPlusRenderer = { - let defaultRecommendedLength = 10000; - let defaultShouldDownsample = true; - type ingredients = { - guesstimatorString: string, - domain: DistTypes.domain, - unit: DistTypes.distributionUnit, - }; - module Ingredients = { - type t = ingredients; - let make = - ( - ~guesstimatorString, - ~domain=DistTypes.Complete, - ~unit=DistTypes.UnspecifiedDistribution, - (), - ) - : t => { - guesstimatorString, - domain, - unit, - }; - }; - type inputs = { - distPlusIngredients: ingredients, - samplingInputs: ShapeRenderer.Sampling.inputs, - recommendedLength: int, - shouldDownsample: bool, - inputVariables: MS.t(ExpressionTypes.ExpressionTree.node), - }; - let make = - ( - ~samplingInputs=ShapeRenderer.Sampling.Inputs.empty, - ~recommendedLength=defaultRecommendedLength, - ~shouldDownsample=defaultShouldDownsample, - ~distPlusIngredients, - ~inputVariables=[||]->Belt.Map.String.fromArray, - (), - ) - : inputs => { - distPlusIngredients, - samplingInputs, - recommendedLength, - shouldDownsample, - inputVariables, - }; -}; diff --git a/src/interface/FormBuilder.re b/src/interface/FormBuilder.re index ea06e318..9fa67fed 100644 --- a/src/interface/FormBuilder.re +++ b/src/interface/FormBuilder.re @@ -17,9 +17,9 @@ let propValue = (t: Prop.Value.t) => { switch (t) { | SelectSingle(r) => r |> ReasonReact.string | ConditionalArray(r) => "Array" |> ReasonReact.string - | DistPlusIngredients((r: RenderTypes.DistPlusRenderer.ingredients)) => + | DistPlusIngredients((r: DistPlusRenderer.Inputs.ingredients)) => let newDistribution = - RenderTypes.DistPlusRenderer.make( + DistPlusRenderer.Inputs.make( ~distPlusIngredients=r, ~recommendedLength=10000, ~shouldDownsample=true, diff --git a/src/interface/Prop.re b/src/interface/Prop.re index c956da04..e20a1f8c 100644 --- a/src/interface/Prop.re +++ b/src/interface/Prop.re @@ -9,7 +9,7 @@ module Value = { | DateTime(MomentRe.Moment.t) | FloatPoint(float) | Probability(float) - | DistPlusIngredients(RenderTypes.DistPlusRenderer.ingredients) + | DistPlusIngredients(DistPlusRenderer.Inputs.ingredients) | ConditionalArray(array(conditional)) | FloatCdf(string); @@ -85,7 +85,7 @@ module ValueCluster = { [ | `combination(range(MomentRe.Moment.t)) | `item(string)], ) | Probability([ | `item(string)]) - | DistPlusIngredients([ | `item(RenderTypes.DistPlusRenderer.ingredients)]) + | DistPlusIngredients([ | `item(DistPlusRenderer.Inputs.ingredients)]) | ConditionalArray([ | `item(array(conditional))]) | FloatCdf([ | `item(string)]); }; diff --git a/src/models/EAFunds.re b/src/models/EAFunds.re index 215bfe2a..c4dd6dd1 100644 --- a/src/models/EAFunds.re +++ b/src/models/EAFunds.re @@ -110,7 +110,7 @@ module Model = { // TODO: Fixe number that integral is calculated for let getGlobalCatastropheChance = dateTime => { GlobalCatastrophe.makeI(MomentRe.momentNow()) - |> RenderTypes.DistPlusRenderer.make(~distPlusIngredients=_, ()) + |> DistPlusRenderer.Inputs.make(~distPlusIngredients=_, ()) |> DistPlusRenderer.run |> E.R.bind(_, r => r @@ -157,7 +157,7 @@ module Model = { }; let distPlusIngredients = - RenderTypes.DistPlusRenderer.Ingredients.make( + DistPlusRenderer.Inputs.Ingredients.make( ~guesstimatorString=str, ~domain=Complete, ~unit=UnspecifiedDistribution, @@ -167,7 +167,7 @@ module Model = { | CHANCE_OF_EXISTENCE => Prop.Value.DistPlusIngredients( - RenderTypes.DistPlusRenderer.Ingredients.make( + DistPlusRenderer.Inputs.Ingredients.make( ~guesstimatorString= GuesstimatorDist.min( GlobalCatastrophe.guesstimatorString, diff --git a/src/models/GlobalCatastrophe.re b/src/models/GlobalCatastrophe.re index e01422b3..9f675267 100644 --- a/src/models/GlobalCatastrophe.re +++ b/src/models/GlobalCatastrophe.re @@ -1,7 +1,7 @@ let guesstimatorString = "uniform(1, 100)"; let makeI = (currentDateTime: MomentRe.Moment.t) => { - RenderTypes.DistPlusRenderer.Ingredients.make( + DistPlusRenderer.Inputs.Ingredients.make( ~guesstimatorString, ~unit=TimeDistribution({zero: currentDateTime, unit: `years}), ~domain=RightLimited({xPoint: 300.0, excludingProbabilityMass: 0.3}), diff --git a/src/models/Human.re b/src/models/Human.re index 9ff30a77..2439adcc 100644 --- a/src/models/Human.re +++ b/src/models/Human.re @@ -2,7 +2,7 @@ let guesstimatorString = age => GuesstimatorDist.normal(72.0 -. age, 5.0 -. age *. 0.01); let makeI = (age: float) => { - RenderTypes.DistPlusRenderer.Ingredients.make( + DistPlusRenderer.Inputs.Ingredients.make( ~guesstimatorString=guesstimatorString(age), ~unit=TimeDistribution({zero: MomentRe.momentNow(), unit: `years}), ~domain=RightLimited({xPoint: 300.0, excludingProbabilityMass: 0.3}),