Further basic cleanup
This commit is contained in:
parent
905ecf0ad3
commit
9520175795
|
@ -329,7 +329,7 @@ let shape: DistTypes.xyShape = {xs: [|1., 4., 8.|], ys: [|8., 9., 2.|]};
|
|||
// let distPlus =
|
||||
// DistPlus.make(
|
||||
// ~shape=Mixed(mixed),
|
||||
// ~guesstimatorString=None,
|
||||
// ~squiggleString=None,
|
||||
// (),
|
||||
// );
|
||||
// makeTest("minX", T.minX(distPlus), 1.0);
|
||||
|
|
|
@ -3,8 +3,7 @@ open Antd.Grid;
|
|||
|
||||
module FormConfig = [%lenses
|
||||
type state = {
|
||||
guesstimatorString: string,
|
||||
//
|
||||
squiggleString: string,
|
||||
sampleCount: string,
|
||||
outputXYPoints: string,
|
||||
downsampleTo: string,
|
||||
|
@ -122,18 +121,13 @@ module Styles = {
|
|||
|
||||
module DemoDist = {
|
||||
[@react.component]
|
||||
let make = (~guesstimatorString:string, ~options) => {
|
||||
let make = (~squiggleString:string, ~options) => {
|
||||
<Antd.Card title={"Distribution" |> R.ste}>
|
||||
<div>
|
||||
{switch (options) {
|
||||
| Some(options) =>
|
||||
let distPlusIngredients =
|
||||
DistPlusRenderer.Inputs.Ingredients.make(
|
||||
~guesstimatorString,
|
||||
(),
|
||||
);
|
||||
let inputs1 =
|
||||
DistPlusRenderer.Inputs.make(
|
||||
ProgramEvaluator.Inputs.make(
|
||||
~samplingInputs={
|
||||
sampleCount: Some(options.sampleCount),
|
||||
outputXYPoints: Some(options.outputXYPoints),
|
||||
|
@ -141,7 +135,7 @@ module DemoDist = {
|
|||
shapeLength:
|
||||
Some(options.downsampleTo |> E.O.default(1000)),
|
||||
},
|
||||
~distPlusIngredients,
|
||||
~squiggleString,
|
||||
~environment=
|
||||
[|
|
||||
("K", `SymbolicDist(`Float(1000.0))),
|
||||
|
@ -153,7 +147,7 @@ module DemoDist = {
|
|||
(),
|
||||
);
|
||||
|
||||
let response1 = DistPlusRenderer.run2(inputs1);
|
||||
let response1 = ProgramEvaluator.evaluateProgram(inputs1);
|
||||
switch (response1) {
|
||||
| Ok(`DistPlus(distPlus1)) =>
|
||||
<DistPlusPlot distPlus={DistPlus.T.normalize(distPlus1)} />
|
||||
|
@ -161,15 +155,15 @@ module DemoDist = {
|
|||
<ForetoldComponents.NumberShower number=f precision=3 />
|
||||
| Ok(`Function((f, a), env)) =>
|
||||
// Problem: When it gets the function, it doesn't save state about previous commands
|
||||
let foo: DistPlusRenderer.Inputs.inputs = {
|
||||
distPlusIngredients: inputs1.distPlusIngredients,
|
||||
let foo: ProgramEvaluator.Inputs.inputs = {
|
||||
squiggleString,
|
||||
samplingInputs: inputs1.samplingInputs,
|
||||
environment: env,
|
||||
};
|
||||
let results =
|
||||
E.A.Floats.range(options.diagramStart, options.diagramStop, options.diagramCount)
|
||||
|> E.A.fmap(r =>
|
||||
DistPlusRenderer.runFunction(
|
||||
ProgramEvaluator.evaluateFunction(
|
||||
foo,
|
||||
(f, a),
|
||||
[|`SymbolicDist(`Float(r))|],
|
||||
|
@ -199,18 +193,6 @@ module DemoDist = {
|
|||
};
|
||||
};
|
||||
|
||||
// guesstimatorString: "
|
||||
// us_economy_2018 = (10.5 to 10.6)T
|
||||
// growth_rate = 1.08 to 1.2
|
||||
// us_economy(t) = us_economy_2018 * (growth_rate^t)
|
||||
|
||||
// us_population_2019 = 320M to 330M
|
||||
// us_population_growth_rate = 1.01 to 1.02
|
||||
// us_population(t) = us_population_2019 * (us_population_growth_rate^t)
|
||||
|
||||
// gdp_per_person(t) = us_economy(t)/us_population(t)
|
||||
// gdp_per_person
|
||||
// ",
|
||||
[@react.component]
|
||||
let make = () => {
|
||||
let (reloader, setReloader) = React.useState(() => 1);
|
||||
|
@ -220,8 +202,8 @@ let make = () => {
|
|||
~schema,
|
||||
~onSubmit=({state}) => {None},
|
||||
~initialState={
|
||||
//guesstimatorString: "mm(normal(-10, 2), uniform(18, 25), lognormal({mean: 10, stdev: 8}), triangular(31,40,50))",
|
||||
guesstimatorString: "mm(normal(5,2), normal(10,2))",
|
||||
//squiggleString: "mm(normal(-10, 2), uniform(18, 25), lognormal({mean: 10, stdev: 8}), triangular(31,40,50))",
|
||||
squiggleString: "mm(normal(5,2), normal(10,2))",
|
||||
sampleCount: "1000",
|
||||
outputXYPoints: "1000",
|
||||
downsampleTo: "",
|
||||
|
@ -238,7 +220,7 @@ let make = () => {
|
|||
reform.submit();
|
||||
};
|
||||
|
||||
let guesstimatorString = reform.state.values.guesstimatorString;
|
||||
let squiggleString = reform.state.values.squiggleString;
|
||||
let sampleCount = reform.state.values.sampleCount |> Js.Float.fromString;
|
||||
let outputXYPoints =
|
||||
reform.state.values.outputXYPoints |> Js.Float.fromString;
|
||||
|
@ -273,9 +255,9 @@ let make = () => {
|
|||
|
||||
let demoDist =
|
||||
React.useMemo1(
|
||||
() => <DemoDist guesstimatorString options />,
|
||||
() => <DemoDist squiggleString options />,
|
||||
[|
|
||||
reform.state.values.guesstimatorString,
|
||||
reform.state.values.squiggleString,
|
||||
reform.state.values.sampleCount,
|
||||
reform.state.values.outputXYPoints,
|
||||
reform.state.values.downsampleTo,
|
||||
|
@ -307,7 +289,7 @@ let make = () => {
|
|||
<Row _type=`flex className=Styles.rows>
|
||||
<Col span=24>
|
||||
<FieldText
|
||||
field=FormConfig.GuesstimatorString
|
||||
field=FormConfig.SquiggleString
|
||||
label="Program"
|
||||
/>
|
||||
</Col>
|
||||
|
|
|
@ -3,7 +3,7 @@ let plotBlue = `hex("1860ad");
|
|||
|
||||
let showAsForm = (distPlus: DistTypes.distPlus) => {
|
||||
<div>
|
||||
<Antd.Input value={distPlus.guesstimatorString |> E.O.default("")} />
|
||||
<Antd.Input value={distPlus.squiggleString |> E.O.default("")} />
|
||||
</div>;
|
||||
};
|
||||
|
||||
|
|
|
@ -11,17 +11,8 @@ module Inputs = {
|
|||
let defaultRecommendedLength = 100;
|
||||
let defaultShouldDownsample = true;
|
||||
|
||||
type ingredients = {guesstimatorString: string};
|
||||
|
||||
module Ingredients = {
|
||||
type t = ingredients;
|
||||
let make = (~guesstimatorString: string, ()): t => {
|
||||
guesstimatorString: guesstimatorString,
|
||||
};
|
||||
};
|
||||
|
||||
type inputs = {
|
||||
distPlusIngredients: ingredients,
|
||||
squiggleString: string,
|
||||
samplingInputs: SamplingInputs.t,
|
||||
environment: ExpressionTypes.ExpressionTree.environment,
|
||||
};
|
||||
|
@ -36,50 +27,41 @@ module Inputs = {
|
|||
let make =
|
||||
(
|
||||
~samplingInputs=empty,
|
||||
~distPlusIngredients,
|
||||
~squiggleString,
|
||||
~environment=ExpressionTypes.ExpressionTree.Environment.empty,
|
||||
(),
|
||||
)
|
||||
: inputs => {
|
||||
distPlusIngredients,
|
||||
samplingInputs,
|
||||
squiggleString,
|
||||
environment,
|
||||
};
|
||||
};
|
||||
|
||||
module Internals = {
|
||||
type inputs = {
|
||||
samplingInputs: Inputs.SamplingInputs.t,
|
||||
guesstimatorString: string,
|
||||
environment: ExpressionTypes.ExpressionTree.environment,
|
||||
};
|
||||
|
||||
let addVariable =
|
||||
({samplingInputs, guesstimatorString, environment}: inputs, str, node)
|
||||
: inputs => {
|
||||
(
|
||||
{samplingInputs, squiggleString, environment}: Inputs.inputs,
|
||||
str,
|
||||
node,
|
||||
)
|
||||
: Inputs.inputs => {
|
||||
samplingInputs,
|
||||
guesstimatorString,
|
||||
squiggleString,
|
||||
environment:
|
||||
ExpressionTypes.ExpressionTree.Environment.update(environment, str, _ =>
|
||||
Some(node)
|
||||
),
|
||||
};
|
||||
|
||||
let distPlusRenderInputsToInputs = (inputs: Inputs.inputs): inputs => {
|
||||
{
|
||||
samplingInputs: inputs.samplingInputs,
|
||||
guesstimatorString: inputs.distPlusIngredients.guesstimatorString,
|
||||
environment: inputs.environment,
|
||||
};
|
||||
};
|
||||
|
||||
type outputs = {
|
||||
graph: ExpressionTypes.ExpressionTree.node,
|
||||
shape: DistTypes.shape,
|
||||
};
|
||||
let makeOutputs = (graph, shape): outputs => {graph, shape};
|
||||
|
||||
let makeInputs = (inputs): ExpressionTypes.ExpressionTree.samplingInputs => {
|
||||
let makeInputs =
|
||||
(inputs: Inputs.inputs): ExpressionTypes.ExpressionTree.samplingInputs => {
|
||||
sampleCount: inputs.samplingInputs.sampleCount |> E.O.default(10000),
|
||||
outputXYPoints:
|
||||
inputs.samplingInputs.outputXYPoints |> E.O.default(10000),
|
||||
|
@ -91,7 +73,7 @@ module Internals = {
|
|||
ExpressionTree.toLeaf(makeInputs(inputs), inputs.environment, node);
|
||||
};
|
||||
|
||||
let runProgram = (inputs: inputs, p: ExpressionTypes.Program.program) => {
|
||||
let runProgram = (inputs: Inputs.inputs, p: ExpressionTypes.Program.program) => {
|
||||
let ins = ref(inputs);
|
||||
p
|
||||
|> E.A.fmap(
|
||||
|
@ -109,23 +91,19 @@ module Internals = {
|
|||
|> E.A.R.firstErrorOrOpen;
|
||||
};
|
||||
|
||||
let inputsToLeaf = (inputs: inputs) => {
|
||||
MathJsParser.fromString(inputs.guesstimatorString)
|
||||
let inputsToLeaf = (inputs: Inputs.inputs) => {
|
||||
MathJsParser.fromString(inputs.squiggleString)
|
||||
|> E.R.bind(_, g => runProgram(inputs, g))
|
||||
|> E.R.bind(_, r => E.A.last(r) |> E.O.toResult("No rendered lines"));
|
||||
};
|
||||
|
||||
let outputToDistPlus = (inputs: Inputs.inputs, shape: DistTypes.shape) => {
|
||||
DistPlus.make(
|
||||
~shape,
|
||||
~guesstimatorString=Some(inputs.distPlusIngredients.guesstimatorString),
|
||||
(),
|
||||
);
|
||||
DistPlus.make(~shape, ~squiggleString=Some(inputs.squiggleString), ());
|
||||
};
|
||||
};
|
||||
|
||||
let renderIfNeeded =
|
||||
(inputs, node: ExpressionTypes.ExpressionTree.node)
|
||||
(inputs: Inputs.inputs, node: ExpressionTypes.ExpressionTree.node)
|
||||
: result(ExpressionTypes.ExpressionTree.node, string) =>
|
||||
node
|
||||
|> (
|
||||
|
@ -133,7 +111,7 @@ let renderIfNeeded =
|
|||
| `Normalize(_) as n
|
||||
| `SymbolicDist(_) as n => {
|
||||
`Render(n)
|
||||
|> Internals.runNode(Internals.distPlusRenderInputsToInputs(inputs))
|
||||
|> Internals.runNode(inputs)
|
||||
|> (
|
||||
fun
|
||||
| Ok(`RenderedDist(_)) as r => r
|
||||
|
@ -144,28 +122,7 @@ let renderIfNeeded =
|
|||
| n => Ok(n)
|
||||
);
|
||||
|
||||
let run = (inputs: Inputs.inputs) => {
|
||||
inputs
|
||||
|> Internals.distPlusRenderInputsToInputs
|
||||
|> Internals.inputsToLeaf
|
||||
|> E.R.bind(_, ((lastIns, r)) =>
|
||||
r
|
||||
|> renderIfNeeded(inputs)
|
||||
|> (
|
||||
fun
|
||||
| Ok(`RenderedDist(n)) => Ok(n)
|
||||
| Ok(n) =>
|
||||
Error(
|
||||
"Didn't output a rendered distribution. Format:"
|
||||
++ ExpressionTree.toString(n),
|
||||
)
|
||||
| Error(r) => Error(r)
|
||||
)
|
||||
)
|
||||
|> E.R.fmap(Internals.outputToDistPlus(inputs));
|
||||
};
|
||||
|
||||
let exportDistPlus =
|
||||
let coersionToExportedTypes =
|
||||
(
|
||||
inputs,
|
||||
env: ProbExample.ExpressionTypes.ExpressionTree.environment,
|
||||
|
@ -189,42 +146,18 @@ let exportDistPlus =
|
|||
),
|
||||
);
|
||||
|
||||
// This isn't ok with floats, which can't be done in a function easily
|
||||
let exportDistPlus2 =
|
||||
(
|
||||
inputs,
|
||||
env: ProbExample.ExpressionTypes.ExpressionTree.environment,
|
||||
node: ExpressionTypes.ExpressionTree.node,
|
||||
) =>
|
||||
node
|
||||
|> renderIfNeeded(inputs)
|
||||
|> E.R.bind(
|
||||
_,
|
||||
fun
|
||||
| `RenderedDist(n) =>
|
||||
Ok(`DistPlus(Internals.outputToDistPlus(inputs, n)))
|
||||
| `Function(n) => Ok(`Function((n, env)))
|
||||
| n =>
|
||||
Error(
|
||||
"Didn't output a rendered distribution. Format:"
|
||||
++ ExpressionTree.toString(n),
|
||||
),
|
||||
);
|
||||
|
||||
let run2 = (inputs: Inputs.inputs) => {
|
||||
let evaluateProgram = (inputs: Inputs.inputs) => {
|
||||
inputs
|
||||
|> Internals.distPlusRenderInputsToInputs
|
||||
|> Internals.inputsToLeaf
|
||||
|> E.R.bind(_, ((a, b)) => exportDistPlus(inputs, a, b));
|
||||
|> E.R.bind(_, ((a, b)) => coersionToExportedTypes(inputs, a, b));
|
||||
};
|
||||
|
||||
let runFunction =
|
||||
let evaluateFunction =
|
||||
(
|
||||
ins: Inputs.inputs,
|
||||
inputs: Inputs.inputs,
|
||||
fn: (array(string), ExpressionTypes.ExpressionTree.node),
|
||||
fnInputs,
|
||||
) => {
|
||||
let inputs = ins |> Internals.distPlusRenderInputsToInputs;
|
||||
let output =
|
||||
ExpressionTree.runFunction(
|
||||
Internals.makeInputs(inputs),
|
||||
|
@ -232,5 +165,5 @@ let runFunction =
|
|||
fnInputs,
|
||||
fn,
|
||||
);
|
||||
output |> E.R.bind(_, exportDistPlus2(ins, inputs.environment));
|
||||
output |> E.R.bind(_, coersionToExportedTypes(inputs, inputs.environment));
|
||||
};
|
|
@ -6,14 +6,14 @@ let shapeIntegral = shape => Shape.T.Integral.get(shape);
|
|||
let make =
|
||||
(
|
||||
~shape,
|
||||
~guesstimatorString,
|
||||
~squiggleString,
|
||||
~domain=Complete,
|
||||
~unit=UnspecifiedDistribution,
|
||||
(),
|
||||
)
|
||||
: t => {
|
||||
let integral = shapeIntegral(shape);
|
||||
{shape, domain, integralCache: integral, unit, guesstimatorString};
|
||||
{shape, domain, integralCache: integral, unit, squiggleString};
|
||||
};
|
||||
|
||||
let update =
|
||||
|
@ -22,14 +22,14 @@ let update =
|
|||
~integralCache=?,
|
||||
~domain=?,
|
||||
~unit=?,
|
||||
~guesstimatorString=?,
|
||||
~squiggleString=?,
|
||||
t: t,
|
||||
) => {
|
||||
shape: E.O.default(t.shape, shape),
|
||||
integralCache: E.O.default(t.integralCache, integralCache),
|
||||
domain: E.O.default(t.domain, domain),
|
||||
unit: E.O.default(t.unit, unit),
|
||||
guesstimatorString: E.O.default(t.guesstimatorString, guesstimatorString),
|
||||
squiggleString: E.O.default(t.squiggleString, squiggleString),
|
||||
};
|
||||
|
||||
let updateShape = (shape, t) => {
|
||||
|
|
|
@ -68,7 +68,7 @@ module ShapeMonad = {
|
|||
};
|
||||
|
||||
type generationSource =
|
||||
| GuesstimatorString(string)
|
||||
| SquiggleString(string)
|
||||
| Shape(shape);
|
||||
|
||||
type distributionUnit =
|
||||
|
@ -80,7 +80,7 @@ type distPlus = {
|
|||
domain,
|
||||
integralCache: continuousShape,
|
||||
unit: distributionUnit,
|
||||
guesstimatorString: option(string),
|
||||
squiggleString: option(string),
|
||||
};
|
||||
|
||||
module DistributionUnit = {
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
// Not yet used
|
||||
type inputs = {
|
||||
samplingInputs: ExpressionTypes.ExpressionTree.SamplingInputs.t,
|
||||
program: string,
|
||||
environment: ExpressionTypes.ExpressionTree.environment,
|
||||
};
|
||||
|
||||
let addVariable =
|
||||
({program, samplingInputs, environment}: inputs, str, node): inputs => {
|
||||
samplingInputs,
|
||||
program,
|
||||
environment:
|
||||
ExpressionTypes.ExpressionTree.Environment.update(environment, str, _ =>
|
||||
Some(node)
|
||||
),
|
||||
};
|
||||
|
||||
let runNode = (inputs: inputs, node) => {
|
||||
ExpressionTree.toLeaf(
|
||||
ExpressionTypes.ExpressionTree.SamplingInputs.withDefaults(
|
||||
inputs.samplingInputs,
|
||||
),
|
||||
inputs.environment,
|
||||
node,
|
||||
);
|
||||
};
|
||||
|
||||
let runProgram = (inputs: inputs, p: ExpressionTypes.Program.program) => {
|
||||
let ins = ref(inputs);
|
||||
p
|
||||
|> E.A.fmap(
|
||||
fun
|
||||
| `Assignment(name, node) => {
|
||||
ins := addVariable(ins^, name, node);
|
||||
None;
|
||||
}
|
||||
| `Expression(node) =>
|
||||
Some(runNode(ins^, node) |> E.R.fmap(r => (ins, r))),
|
||||
)
|
||||
|> E.A.O.concatSomes
|
||||
|> E.A.R.firstErrorOrOpen;
|
||||
};
|
||||
|
||||
let inputsToLeaf = (inputs: inputs) => {
|
||||
MathJsParser.fromString(inputs.program)
|
||||
|> E.R.bind(_, g => runProgram(inputs, g))
|
||||
|> E.R.bind(_, r => E.A.last(r) |> E.O.toResult("No rendered lines"));
|
||||
};
|
Loading…
Reference in New Issue
Block a user