First attempt at showing the use of a simple variable
This commit is contained in:
parent
bfd9ca5533
commit
102a147b97
|
@ -133,7 +133,7 @@ module DemoDist = {
|
|||
~unit,
|
||||
(),
|
||||
);
|
||||
let inputs =
|
||||
let inputs1 =
|
||||
RenderTypes.DistPlusRenderer.make(
|
||||
~samplingInputs={
|
||||
sampleCount: Some(options.sampleCount),
|
||||
|
@ -143,14 +143,37 @@ module DemoDist = {
|
|||
~distPlusIngredients,
|
||||
~shouldDownsample=options.downsampleTo |> E.O.isSome,
|
||||
~recommendedLength=options.downsampleTo |> E.O.default(1000),
|
||||
~inputVariables=
|
||||
[|("p", `SymbolicDist(`Float(1.0)))|]
|
||||
->Belt.Map.String.fromArray,
|
||||
(),
|
||||
);
|
||||
let response = DistPlusRenderer.run(inputs);
|
||||
switch (response) {
|
||||
| Ok(distPlus) =>
|
||||
let normalizedDistPlus = DistPlus.T.normalize(distPlus);
|
||||
<DistPlusPlot distPlus=normalizedDistPlus />;
|
||||
| Error(r) => r |> R.ste
|
||||
|
||||
let response1 = DistPlusRenderer.run(inputs1);
|
||||
let inputs2 =
|
||||
RenderTypes.DistPlusRenderer.make(
|
||||
~samplingInputs={
|
||||
sampleCount: Some(options.sampleCount),
|
||||
outputXYPoints: Some(options.outputXYPoints),
|
||||
kernelWidth: options.kernelWidth,
|
||||
},
|
||||
~distPlusIngredients,
|
||||
~shouldDownsample=options.downsampleTo |> E.O.isSome,
|
||||
~recommendedLength=options.downsampleTo |> E.O.default(1000),
|
||||
~inputVariables=
|
||||
[|("p", `SymbolicDist(`Float(2.0)))|]
|
||||
->Belt.Map.String.fromArray,
|
||||
(),
|
||||
);
|
||||
let response2 = DistPlusRenderer.run(inputs2);
|
||||
switch (response1, response2) {
|
||||
| (Ok(distPlus1), Ok(distPlus2)) =>
|
||||
<>
|
||||
<DistPlusPlot distPlus={DistPlus.T.normalize(distPlus1)} />
|
||||
<DistPlusPlot distPlus={DistPlus.T.normalize(distPlus2)} />
|
||||
</>
|
||||
| (Error(r), _) => r |> R.ste
|
||||
| (_, Error(r)) => r |> R.ste
|
||||
};
|
||||
| _ =>
|
||||
"Nothing to show. Try to change the distribution description."
|
||||
|
|
|
@ -106,7 +106,6 @@ let init = {
|
|||
showParams: false,
|
||||
showPercentiles: true,
|
||||
distributions: [
|
||||
{yLog: false, xLog: false, isCumulative: false, height: 4},
|
||||
{yLog: false, xLog: false, isCumulative: true, height: 1},
|
||||
{yLog: false, xLog: false, isCumulative: false, height: 1},
|
||||
],
|
||||
};
|
|
@ -37,6 +37,7 @@ let empty: DistTypes.continuousShape = {
|
|||
let stepwiseToLinear = (t: t): t =>
|
||||
make(~integralSumCache=t.integralSumCache, ~integralCache=t.integralCache, XYShape.Range.stepwiseToLinear(t.xyShape));
|
||||
|
||||
// Note: This results in a distribution with as many points as the sum of those in t1 and t2.
|
||||
let combinePointwise =
|
||||
(
|
||||
~integralSumCachesFn=(_, _) => None,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
type inputVars = Belt.Map.String.t(ExpressionTypes.ExpressionTree.node);
|
||||
|
||||
module MathJsonToMathJsAdt = {
|
||||
type arg =
|
||||
| Symbol(string)
|
||||
|
@ -50,24 +52,33 @@ module MathJsonToMathJsAdt = {
|
|||
module MathAdtToDistDst = {
|
||||
open MathJsonToMathJsAdt;
|
||||
|
||||
let handleSymbol = (inputVars: inputVars, sym) => {
|
||||
switch (Belt.Map.String.get(inputVars, sym)) {
|
||||
| Some(s) => Ok(s)
|
||||
| None => Error("Couldn't find.")
|
||||
};
|
||||
};
|
||||
|
||||
module MathAdtCleaner = {
|
||||
let transformWithSymbol = (f: float, s: string) =>
|
||||
switch (s) {
|
||||
| "K"
|
||||
| "k" => f *. 1000.
|
||||
| "k" => Some(f *. 1000.)
|
||||
| "M"
|
||||
| "m" => f *. 1000000.
|
||||
| "m" => Some(f *. 1000000.)
|
||||
| "B"
|
||||
| "b" => f *. 1000000000.
|
||||
| "b" => Some(f *. 1000000000.)
|
||||
| "T"
|
||||
| "t" => f *. 1000000000000.
|
||||
| _ => f
|
||||
| "t" => Some(f *. 1000000000000.)
|
||||
| _ => None
|
||||
};
|
||||
|
||||
let rec run =
|
||||
fun
|
||||
| Fn({name: "multiply", args: [|Value(f), Symbol(s)|]}) =>
|
||||
Value(transformWithSymbol(f, s))
|
||||
| Fn({name: "multiply", args: [|Value(f), Symbol(s)|]}) as doNothing =>
|
||||
transformWithSymbol(f, s)
|
||||
|> E.O.fmap(r => Value(r))
|
||||
|> E.O.default(doNothing)
|
||||
| Fn({name: "unaryMinus", args: [|Value(f)|]}) => Value((-1.0) *. f)
|
||||
| Fn({name, args}) => Fn({name, args: args |> E.A.fmap(run)})
|
||||
| Array(args) => Array(args |> E.A.fmap(run))
|
||||
|
@ -347,24 +358,26 @@ module MathAdtToDistDst = {
|
|||
};
|
||||
};
|
||||
|
||||
let rec nodeParser =
|
||||
let rec nodeParser = inputVars =>
|
||||
fun
|
||||
| Value(f) => Ok(`SymbolicDist(`Float(f)))
|
||||
| Fn({name, args}) => functionParser(nodeParser, name, args)
|
||||
| Symbol(s) => handleSymbol(inputVars, s)
|
||||
| Fn({name, args}) => functionParser(nodeParser(inputVars), name, args)
|
||||
| _ => {
|
||||
Error("This type not currently supported");
|
||||
};
|
||||
|
||||
let topLevel =
|
||||
let topLevel = inputVars =>
|
||||
fun
|
||||
| Value(_) as r => nodeParser(r)
|
||||
| Fn(_) as r => nodeParser(r)
|
||||
| Value(_) as r => nodeParser(inputVars, r)
|
||||
| Fn(_) as r => nodeParser(inputVars, r)
|
||||
| Array(_) => Error("Array not valid as top level")
|
||||
| Symbol(_) => Error("Symbol not valid as top level")
|
||||
| Symbol(s) => handleSymbol(inputVars, s)
|
||||
| Object(_) => Error("Object not valid as top level");
|
||||
|
||||
let run = (r): result(ExpressionTypes.ExpressionTree.node, string) =>
|
||||
r |> MathAdtCleaner.run |> topLevel;
|
||||
let run =
|
||||
(inputVars, r): result(ExpressionTypes.ExpressionTree.node, string) =>
|
||||
r |> MathAdtCleaner.run |> topLevel(inputVars);
|
||||
};
|
||||
|
||||
/* The MathJs parser doesn't support '.+' syntax, but we want it because it
|
||||
|
@ -374,7 +387,7 @@ module MathAdtToDistDst = {
|
|||
*/
|
||||
let pointwiseToRightLogShift = Js.String.replaceByRe([%re "/\.\+/g"], ">>>");
|
||||
|
||||
let fromString = str => {
|
||||
let fromString2 = (inputVars: inputVars, str) => {
|
||||
/* We feed the user-typed string into Mathjs.parseMath,
|
||||
which returns a JSON with (hopefully) a single-element array.
|
||||
This array element is the top-level node of a nested-object tree
|
||||
|
@ -384,7 +397,6 @@ let fromString = str => {
|
|||
Inside of this function, MathAdtToDistDst is called whenever a distribution function is encountered.
|
||||
*/
|
||||
let mathJsToJson = str |> pointwiseToRightLogShift |> Mathjs.parseMath;
|
||||
Js.log(mathJsToJson);
|
||||
let mathJsParse =
|
||||
E.R.bind(mathJsToJson, r => {
|
||||
switch (MathJsonToMathJsAdt.run(r)) {
|
||||
|
@ -394,6 +406,10 @@ let fromString = str => {
|
|||
});
|
||||
|
||||
Js.log(mathJsParse);
|
||||
let value = E.R.bind(mathJsParse, MathAdtToDistDst.run);
|
||||
let value = E.R.bind(mathJsParse, MathAdtToDistDst.run(inputVars));
|
||||
value;
|
||||
};
|
||||
|
||||
let fromString = (str, vars: inputVars) => {
|
||||
fromString2(vars, str);
|
||||
};
|
||||
|
|
|
@ -8,10 +8,13 @@ let run = (inputs: RenderTypes.DistPlusRenderer.inputs) => {
|
|||
(),
|
||||
)
|
||||
|> DistPlus.T.normalize;
|
||||
// let symbolicDist: ExpressionTypes.ExpressionTree.node = `SymbolicDist(`Float(30.0));
|
||||
// inputVariables: [|("p", symbolicDist)|] -> Belt.Map.String.fromArray,
|
||||
let output =
|
||||
ShapeRenderer.run({
|
||||
samplingInputs: inputs.samplingInputs,
|
||||
guesstimatorString: inputs.distPlusIngredients.guesstimatorString,
|
||||
inputVariables: inputs.inputVariables,
|
||||
symbolicInputs: {
|
||||
length: inputs.recommendedLength,
|
||||
},
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
module MS = Belt.Map.String;
|
||||
|
||||
module ShapeRenderer = {
|
||||
module Sampling = {
|
||||
type inputs = {
|
||||
|
@ -54,16 +56,18 @@ module ShapeRenderer = {
|
|||
samplingInputs: Sampling.inputs,
|
||||
symbolicInputs: Symbolic.inputs,
|
||||
guesstimatorString: string,
|
||||
inputVariables: MS.t(ExpressionTypes.ExpressionTree.node),
|
||||
};
|
||||
type outputs = {
|
||||
symbolic: option(Belt.Result.t(Symbolic.outputs, string)),
|
||||
sampling: option(Sampling.outputs),
|
||||
};
|
||||
let methodUsed = ({symbolic, sampling}:outputs) => switch(symbolic, sampling){
|
||||
let methodUsed = ({symbolic, sampling}: outputs) =>
|
||||
switch (symbolic, sampling) {
|
||||
| (Some(Ok(_)), _) => `Symbolic
|
||||
| (_, Some({shape: Some(_)})) => `Sampling
|
||||
| _ => `None
|
||||
}
|
||||
};
|
||||
let getShape = (r: outputs) =>
|
||||
switch (r.symbolic, r.sampling) {
|
||||
| (Some(Ok({shape})), _) => Some(shape)
|
||||
|
@ -86,6 +90,7 @@ module DistPlusRenderer = {
|
|||
samplingInputs: ShapeRenderer.Sampling.inputs,
|
||||
recommendedLength: int,
|
||||
shouldDownsample: bool,
|
||||
inputVariables: MS.t(ExpressionTypes.ExpressionTree.node),
|
||||
};
|
||||
module Ingredients = {
|
||||
let make =
|
||||
|
@ -107,6 +112,7 @@ module DistPlusRenderer = {
|
|||
~recommendedLength=defaultRecommendedLength,
|
||||
~shouldDownsample=defaultShouldDownsample,
|
||||
~distPlusIngredients,
|
||||
~inputVariables=[||]->Belt.Map.String.fromArray,
|
||||
(),
|
||||
)
|
||||
: inputs => {
|
||||
|
@ -114,14 +120,18 @@ module DistPlusRenderer = {
|
|||
samplingInputs,
|
||||
recommendedLength,
|
||||
shouldDownsample,
|
||||
inputVariables,
|
||||
};
|
||||
type outputs = {
|
||||
shapeRenderOutputs: ShapeRenderer.Combined.outputs,
|
||||
distPlus: option(DistTypes.distPlus)
|
||||
}
|
||||
module Outputs = {
|
||||
let distplus = (t:outputs) => t.distPlus
|
||||
let shapeRenderOutputs = (t:outputs) => t.shapeRenderOutputs
|
||||
let make = (shapeRenderOutputs, distPlus) => {shapeRenderOutputs, distPlus};
|
||||
}
|
||||
distPlus: option(DistTypes.distPlus),
|
||||
};
|
||||
module Outputs = {
|
||||
let distplus = (t: outputs) => t.distPlus;
|
||||
let shapeRenderOutputs = (t: outputs) => t.shapeRenderOutputs;
|
||||
let make = (shapeRenderOutputs, distPlus) => {
|
||||
shapeRenderOutputs,
|
||||
distPlus,
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -14,9 +14,9 @@ let formatString = str => {
|
|||
str |> formatMessyArray;
|
||||
};
|
||||
|
||||
let runSymbolic = (inputs: RenderTypes.ShapeRenderer.Combined.inputs) => {
|
||||
let run = (inputs: RenderTypes.ShapeRenderer.Combined.inputs) => {
|
||||
let str = formatString(inputs.guesstimatorString);
|
||||
let graph = MathJsParser.fromString(str);
|
||||
let graph = MathJsParser.fromString(str, inputs.inputVariables);
|
||||
graph
|
||||
|> E.R.bind(_, g =>
|
||||
ExpressionTree.toShape(
|
||||
|
@ -33,7 +33,3 @@ let runSymbolic = (inputs: RenderTypes.ShapeRenderer.Combined.inputs) => {
|
|||
|> E.R.fmap(RenderTypes.ShapeRenderer.Symbolic.make(g))
|
||||
);
|
||||
};
|
||||
|
||||
let run = (inputs: RenderTypes.ShapeRenderer.Combined.inputs) => {
|
||||
runSymbolic(inputs);
|
||||
};
|
||||
|
|
|
@ -32,6 +32,7 @@ module Triangular = {
|
|||
|
||||
module Normal = {
|
||||
type t = normal;
|
||||
let make = (mean, stdev):t => {mean, stdev};
|
||||
let pdf = (x, t: t) => Jstat.normal##pdf(x, t.mean, t.stdev);
|
||||
let cdf = (x, t: t) => Jstat.normal##cdf(x, t.mean, t.stdev);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user