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