Renaming, removed some Js.logs

This commit is contained in:
Sebastian Kosch 2020-06-13 18:54:54 -07:00
parent 8827650da3
commit 214f3b9e58
2 changed files with 63 additions and 65 deletions

View File

@ -91,19 +91,19 @@ module MathAdtToDistDst = {
let normal: array(arg) => result(SymbolicDist.distTree, string) =
fun
| [|Value(mean), Value(stdev)|] =>
Ok(`Distribution(`Normal({mean, stdev})))
Ok(`Simple(`Normal({mean, stdev})))
| _ => Error("Wrong number of variables in normal distribution");
let lognormal: array(arg) => result(SymbolicDist.distTree, string) =
fun
| [|Value(mu), Value(sigma)|] => Ok(`Distribution(`Lognormal({mu, sigma})))
| [|Value(mu), Value(sigma)|] => Ok(`Simple(`Lognormal({mu, sigma})))
| [|Object(o)|] => {
let g = Js.Dict.get(o);
switch (g("mean"), g("stdev"), g("mu"), g("sigma")) {
| (Some(Value(mean)), Some(Value(stdev)), _, _) =>
Ok(`Distribution(SymbolicDist.Lognormal.fromMeanAndStdev(mean, stdev)))
Ok(`Simple(SymbolicDist.Lognormal.fromMeanAndStdev(mean, stdev)))
| (_, _, Some(Value(mu)), Some(Value(sigma))) =>
Ok(`Distribution(`Lognormal({mu, sigma})))
Ok(`Simple(`Lognormal({mu, sigma})))
| _ => Error("Lognormal distribution would need mean and stdev")
};
}
@ -112,10 +112,10 @@ module MathAdtToDistDst = {
let to_: array(arg) => result(SymbolicDist.distTree, string) =
fun
| [|Value(low), Value(high)|] when low <= 0.0 && low < high=> {
Ok(`Distribution(SymbolicDist.Normal.from90PercentCI(low, high)));
Ok(`Simple(SymbolicDist.Normal.from90PercentCI(low, high)));
}
| [|Value(low), Value(high)|] when low < high => {
Ok(`Distribution(SymbolicDist.Lognormal.from90PercentCI(low, high)));
Ok(`Simple(SymbolicDist.Lognormal.from90PercentCI(low, high)));
}
| [|Value(_), Value(_)|] =>
Error("Low value must be less than high value.")
@ -123,29 +123,29 @@ module MathAdtToDistDst = {
let uniform: array(arg) => result(SymbolicDist.distTree, string) =
fun
| [|Value(low), Value(high)|] => Ok(`Distribution(`Uniform({low, high})))
| [|Value(low), Value(high)|] => Ok(`Simple(`Uniform({low, high})))
| _ => Error("Wrong number of variables in lognormal distribution");
let beta: array(arg) => result(SymbolicDist.distTree, string) =
fun
| [|Value(alpha), Value(beta)|] => Ok(`Distribution(`Beta({alpha, beta})))
| [|Value(alpha), Value(beta)|] => Ok(`Simple(`Beta({alpha, beta})))
| _ => Error("Wrong number of variables in lognormal distribution");
let exponential: array(arg) => result(SymbolicDist.distTree, string) =
fun
| [|Value(rate)|] => Ok(`Distribution(`Exponential({rate: rate})))
| [|Value(rate)|] => Ok(`Simple(`Exponential({rate: rate})))
| _ => Error("Wrong number of variables in Exponential distribution");
let cauchy: array(arg) => result(SymbolicDist.distTree, string) =
fun
| [|Value(local), Value(scale)|] =>
Ok(`Distribution(`Cauchy({local, scale})))
Ok(`Simple(`Cauchy({local, scale})))
| _ => Error("Wrong number of variables in cauchy distribution");
let triangular: array(arg) => result(SymbolicDist.distTree, string) =
fun
| [|Value(low), Value(medium), Value(high)|] =>
Ok(`Distribution(`Triangular({low, medium, high})))
Ok(`Simple(`Triangular({low, medium, high})))
| _ => Error("Wrong number of variables in triangle distribution");
let multiModal =
@ -158,7 +158,7 @@ module MathAdtToDistDst = {
args
|> E.A.fmap(
fun
| Ok(`Distribution(d)) => Ok(`Distribution(d))
| Ok(`Simple(d)) => Ok(`Simple(d))
| Ok(`Combination(t1, t2, op)) => Ok(`Combination(t1, t2, op))
| Ok(`PointwiseSum(t1, t2)) => Ok(`PointwiseSum(t1, t2))
| Ok(`PointwiseProduct(t1, t2)) => Ok(`PointwiseProduct(t1, t2))
@ -182,7 +182,7 @@ module MathAdtToDistDst = {
|> E.A.fmapi((index, t) => {
let w = weights |> E.A.get(_, index) |> E.O.default(1.0);
`VerticalScaling(t, `Distribution(`Float(w)))
`VerticalScaling(t, `Simple(`Float(w)))
});
let pointwiseSum = components
@ -197,7 +197,6 @@ module MathAdtToDistDst = {
};
let arrayParser = (args:array(arg)):result(SymbolicDist.distTree, string) => {
Js.log2("SAMPLING NOW!", args);
let samples = args
|> E.A.fmap(
fun
@ -213,7 +212,7 @@ module MathAdtToDistDst = {
SymbolicDist.ContinuousShape.make(_pdf, cdf)
});
switch(shape){
| Some(s) => Ok(`Distribution(`ContinuousShape(s)))
| Some(s) => Ok(`Simple(`ContinuousShape(s)))
| None => Error("Rendering did not work")
}
}
@ -231,7 +230,7 @@ module MathAdtToDistDst = {
| Fn({name: "exponential", args}) => exponential(args)
| Fn({name: "cauchy", args}) => cauchy(args)
| Fn({name: "triangular", args}) => triangular(args)
| Value(f) => Ok(`Distribution(`Float(f)))
| Value(f) => Ok(`Simple(`Float(f)))
| Fn({name: "mm", args}) => {
let weights =
args
@ -284,7 +283,7 @@ module MathAdtToDistDst = {
args
|> E.A.fmap(functionParser)
|> (fun
| [|Ok(l), Ok(`Distribution(`Float(0.0)))|] => Error("Division by zero")
| [|Ok(l), Ok(`Simple(`Float(0.0)))|] => Error("Division by zero")
| [|Ok(l), Ok(r)|] => Ok(`Combination(l, r, `DivideOperation))
| _ => Error("Division needs two operands"))
}
@ -299,14 +298,14 @@ module MathAdtToDistDst = {
args
|> E.A.fmap(functionParser)
|> (fun
| [|Ok(l), Ok(`Distribution(`Float(r)))|] => Ok(`LeftTruncate(l, r))
| [|Ok(l), Ok(`Simple(`Float(r)))|] => Ok(`LeftTruncate(l, r))
| _ => Error("leftTruncate needs two arguments: the expression and the cutoff"))
}
| Fn({name: "rightTruncate", args}) => {
args
|> E.A.fmap(functionParser)
|> (fun
| [|Ok(l), Ok(`Distribution(`Float(r)))|] => Ok(`RightTruncate(l, r))
| [|Ok(l), Ok(`Simple(`Float(r)))|] => Ok(`RightTruncate(l, r))
| _ => Error("rightTruncate needs two arguments: the expression and the cutoff"))
}
| Fn({name}) => Error(name ++ ": function not supported")
@ -320,7 +319,7 @@ module MathAdtToDistDst = {
|> (
fun
| Fn(_) => functionParser(r)
| Value(r) => Ok(`Distribution(`Float(r)))
| Value(r) => Ok(`Simple(`Float(r)))
| Array(r) => arrayParser(r)
| Symbol(_) => Error("Symbol not valid as top level")
| Object(_) => Error("Object not valid as top level")

View File

@ -61,7 +61,7 @@ type operation = [
];
type distTree = [
| `Distribution(dist)
| `Simple(dist)
| `Combination(distTree, distTree, operation)
| `PointwiseSum(distTree, distTree)
| `PointwiseProduct(distTree, distTree)
@ -315,13 +315,13 @@ module GenericSimple = {
module DistTree = {
type nodeResult = [
| `Distribution(dist)
| `Simple(dist)
// RenderedShape: continuous xyShape, discrete xyShape, total value.
| `RenderedShape(DistTypes.continuousShape, DistTypes.discreteShape, integral)
];
let evaluateDistribution = (d: dist): nodeResult => {
`Distribution(d)
`Simple(d)
};
// This is a performance bottleneck!
@ -406,7 +406,7 @@ module DistTree = {
// First, deal with the discrete-discrete convolution:
let (ddxs, ddys) = jsDiscreteCombinationConvolve(sd1.xs, sd1.ys, sd2.xs, sd2.ys, func);
let ddxy: DistTypes.discreteShape = {xs: cdxs, ys: cdys};
let ddxy: DistTypes.discreteShape = {xs: ddxs, ys: ddys};
// Then, do the other three:
let downsample = (sc: DistTypes.continuousShape) => {
@ -415,8 +415,7 @@ module DistTree = {
scSqLength > 10. ? Distributions.Continuous.T.truncate(int_of_float(scSqLength), sc) : sc;
};
let combinePointConvolutionResults = ccs
|> E.A.fmap(s => {
let combinePointConvolutionResults = ca => ca |> E.A.fmap(s => {
// s is an array of (x, y) objects
let (xs, ys) = Belt.Array.unzip(s);
Distributions.Continuous.make(`Linear, {xs, ys});
@ -440,46 +439,46 @@ module DistTree = {
let func = funcFromOp(op);
switch ((et1, et2, op)) {
/* Known cases: replace symbolic with symbolic distribution */
| (`Distribution(`Float(v1)), `Distribution(`Float(v2)), _) => {
`Distribution(`Float(func(v1, v2)))
| (`Simple(`Float(v1)), `Simple(`Float(v2)), _) => {
`Simple(`Float(func(v1, v2)))
}
| (`Distribution(`Normal(n2)), `Distribution(`Float(v1)), `AddOperation)
| (`Distribution(`Float(v1)), `Distribution(`Normal(n2)), `AddOperation) => {
| (`Simple(`Normal(n2)), `Simple(`Float(v1)), `AddOperation)
| (`Simple(`Float(v1)), `Simple(`Normal(n2)), `AddOperation) => {
let n: normal = {mean: v1 +. n2.mean, stdev: n2.stdev};
`Distribution(`Normal(n))
`Simple(`Normal(n))
}
| (`Distribution(`Normal(n1)), `Distribution(`Normal(n2)), `AddOperation) => {
| (`Simple(`Normal(n1)), `Simple(`Normal(n2)), `AddOperation) => {
let n: normal = {mean: n1.mean +. n2.mean, stdev: sqrt(n1.stdev ** 2. +. n2.stdev ** 2.)};
`Distribution(`Normal(n));
`Simple(`Normal(n));
}
| (`Distribution(`Normal(n1)), `Distribution(`Normal(n2)), `SubtractOperation) => {
| (`Simple(`Normal(n1)), `Simple(`Normal(n2)), `SubtractOperation) => {
let n: normal = {mean: n1.mean -. n2.mean, stdev: sqrt(n1.stdev ** 2. +. n2.stdev ** 2.)};
`Distribution(`Normal(n));
`Simple(`Normal(n));
}
| (`Distribution(`Lognormal(l1)), `Distribution(`Lognormal(l2)), `MultiplyOperation) => {
| (`Simple(`Lognormal(l1)), `Simple(`Lognormal(l2)), `MultiplyOperation) => {
let l: lognormal = {mu: l1.mu +. l2.mu, sigma: l1.sigma +. l2.sigma};
`Distribution(`Lognormal(l));
`Simple(`Lognormal(l));
}
| (`Distribution(`Lognormal(l1)), `Distribution(`Lognormal(l2)), `DivideOperation) => {
| (`Simple(`Lognormal(l1)), `Simple(`Lognormal(l2)), `DivideOperation) => {
let l: lognormal = {mu: l1.mu -. l2.mu, sigma: l1.sigma +. l2.sigma};
`Distribution(`Lognormal(l));
`Simple(`Lognormal(l));
}
/* General cases: convolve the XYShapes */
| (`Distribution(d1), `Distribution(d2), _) => {
| (`Simple(d1), `Simple(d2), _) => {
let (sc1, sd1) = renderDistributionToXYShape(d1, n);
let (sc2, sd2) = renderDistributionToXYShape(d2, n);
let (sc, sd) = combinationDistributionOfXYShapes(sc1, sd1, sc2, sd2, func);
`RenderedShape(sc, sd, 1.0)
}
| (`Distribution(d2), `RenderedShape(sc1, sd1, i1), _)
| (`RenderedShape(sc1, sd1, i1), `Distribution(d2), _) => {
| (`Simple(d1), `RenderedShape(sc2, sd2, i2), _)
| (`RenderedShape(sc2, sd2, i2), `Simple(d1), _) => {
let (sc1, sd1) = renderDistributionToXYShape(d1, n);
let (sc, sd) = combinationDistributionOfXYShapes(sc1, sd1, sc2, sd2, func);
`RenderedShape(sc, sd, i2)
@ -495,24 +494,24 @@ module DistTree = {
let evaluatePointwiseSum = (et1: nodeResult, et2: nodeResult, n: int) => {
switch ((et1, et2)) {
/* Known cases: */
| (`Distribution(`Float(v1)), `Distribution(`Float(v2))) => {
| (`Simple(`Float(v1)), `Simple(`Float(v2))) => {
v1 == v2
? `RenderedShape(Distributions.Continuous.empty, Distributions.Discrete.make({xs: [|v1|], ys: [|2.|]}), 2.)
: `RenderedShape(Distributions.Continuous.empty, Distributions.Discrete.empty, 0.) // TODO: add warning: shouldn't pointwise add scalars.
}
| (`Distribution(`Float(v1)), `Distribution(d2))
| (`Distribution(d2), `Distribution(`Float(v1))) => {
| (`Simple(`Float(v1)), `Simple(d2))
| (`Simple(d2), `Simple(`Float(v1))) => {
let sd1: DistTypes.xyShape = {xs: [|v1|], ys: [|1.|]};
let (sc2, sd2) = renderDistributionToXYShape(d2, n);
`RenderedShape(sc2, Distributions.Discrete.reduce((+.), [|sd1, sd2|]), 2.)
}
| (`Distribution(d1), `Distribution(d2)) => {
| (`Simple(d1), `Simple(d2)) => {
let (sc1, sd1) = renderDistributionToXYShape(d1, n);
let (sc2, sd2) = renderDistributionToXYShape(d2, n);
`RenderedShape(Distributions.Continuous.reduce((+.), [|sc1, sc2|]), Distributions.Discrete.reduce((+.), [|sd1, sd2|]), 2.)
}
| (`Distribution(d1), `RenderedShape(sc2, sd2, i2))
| (`RenderedShape(sc2, sd2, i2), `Distribution(d1)) => {
| (`Simple(d1), `RenderedShape(sc2, sd2, i2))
| (`RenderedShape(sc2, sd2, i2), `Simple(d1)) => {
let (sc1, sd1) = renderDistributionToXYShape(d1, n);
`RenderedShape(Distributions.Continuous.reduce((+.), [|sc1, sc2|]), Distributions.Discrete.reduce((+.), [|sd1, sd2|]), 1. +. i2)
}
@ -525,42 +524,42 @@ module DistTree = {
let evaluatePointwiseProduct = (et1: nodeResult, et2: nodeResult, n: int) => {
switch ((et1, et2)) {
/* Known cases: */
| (`Distribution(`Float(v1)), `Distribution(`Float(v2))) => {
| (`Simple(`Float(v1)), `Simple(`Float(v2))) => {
v1 == v2
? `RenderedShape(Distributions.Continuous.empty, Distributions.Discrete.make({xs: [|v1|], ys: [|1.|]}), 1.)
: `RenderedShape(Distributions.Continuous.empty, Distributions.Discrete.empty, 0.) // TODO: add warning: shouldn't pointwise multiply scalars.
}
| (`Distribution(`Float(v1)), `Distribution(d2)) => {
| (`Simple(`Float(v1)), `Simple(d2)) => {
// evaluate d2 at v1
let y = GenericSimple.pdf(v1, d2);
`RenderedShape(Distributions.Continuous.empty, Distributions.Discrete.make({xs: [|v1|], ys: [|y|]}), y)
}
| (`Distribution(d1), `Distribution(`Float(v2))) => {
| (`Simple(d1), `Simple(`Float(v2))) => {
// evaluate d1 at v2
let y = GenericSimple.pdf(v2, d1);
`RenderedShape(Distributions.Continuous.empty, Distributions.Discrete.make({xs: [|v2|], ys: [|y|]}), y)
}
| (`Distribution(`Normal(n1)), `Distribution(`Normal(n2))) => {
| (`Simple(`Normal(n1)), `Simple(`Normal(n2))) => {
let mean = (n1.mean *. n2.stdev**2. +. n2.mean *. n1.stdev**2.) /. (n1.stdev**2. +. n2.stdev**2.);
let stdev = 1. /. ((1. /. n1.stdev**2.) +. (1. /. n2.stdev**2.));
let integral = 0; // TODO
`RenderedShape(Distributions.Continuous.empty, Distributions.Discrete.empty, 0.)
}
/* General cases */
| (`Distribution(d1), `Distribution(d2)) => {
| (`Simple(d1), `Simple(d2)) => {
// NOT IMPLEMENTED YET
// TODO: evaluate integral properly
let (sc1, sd1) = renderDistributionToXYShape(d1, n);
let (sc2, sd2) = renderDistributionToXYShape(d2, n);
`RenderedShape(Distributions.Continuous.empty, Distributions.Discrete.empty, 0.)
}
| (`Distribution(d1), `RenderedShape(sc2, sd2, i2)) => {
| (`Simple(d1), `RenderedShape(sc2, sd2, i2)) => {
// NOT IMPLEMENTED YET
// TODO: evaluate integral properly
let (sc1, sd1) = renderDistributionToXYShape(d1, n);
`RenderedShape(Distributions.Continuous.empty, Distributions.Discrete.empty, 0.)
}
| (`RenderedShape(sc1, sd1, i1), `Distribution(d1)) => {
| (`RenderedShape(sc1, sd1, i1), `Simple(d1)) => {
// NOT IMPLEMENTED YET
// TODO: evaluate integral properly
let (sc2, sd2) = renderDistributionToXYShape(d1, n);
@ -588,7 +587,7 @@ module DistTree = {
`RenderedShape(scn, sdn, 1.)
}
| `Distribution(d) => `Distribution(d) // any kind of atomic dist should already be normalized -- TODO: THIS IS ACTUALLY FALSE! E.g. pointwise product of normal * normal
| `Simple(d) => `Simple(d) // any kind of atomic dist should already be normalized -- TODO: THIS IS ACTUALLY FALSE! E.g. pointwise product of normal * normal
}
};
@ -604,7 +603,7 @@ module DistTree = {
};
switch (et) {
| `Distribution(d) => {
| `Simple(d) => {
let (sc, sd) = renderDistributionToXYShape(d, n);
let scc = sc |> Distributions.Continuous.shapeMap(cut);
@ -629,8 +628,8 @@ module DistTree = {
let scale = (i: float, s: DistTypes.xyShape): DistTypes.xyShape => {xs: s.xs, ys: s.ys |> E.A.fmap(y => y *. i)};
switch ((et1, et2)) {
| (`Distribution(`Float(v)), `Distribution(d))
| (`Distribution(d), `Distribution(`Float(v))) => {
| (`Simple(`Float(v)), `Simple(d))
| (`Simple(d), `Simple(`Float(v))) => {
let (sc, sd) = renderDistributionToXYShape(d, n);
let scc = sc |> Distributions.Continuous.shapeMap(scale(v));
@ -640,8 +639,8 @@ module DistTree = {
`RenderedShape(scc, sdc, newIntegral);
}
| (`Distribution(`Float(v)), `RenderedShape(sc, sd, i))
| (`RenderedShape(sc, sd, i), `Distribution(`Float(v))) => {
| (`Simple(`Float(v)), `RenderedShape(sc, sd, i))
| (`RenderedShape(sc, sd, i), `Simple(`Float(v))) => {
let scc = sc |> Distributions.Continuous.shapeMap(scale(v));
let sdc = sd |> scale(v);
@ -655,7 +654,7 @@ module DistTree = {
let renderNode = (et: nodeResult, n: int) => {
switch (et) {
| `Distribution(d) => {
| `Simple(d) => {
let (sc, sd) = renderDistributionToXYShape(d, n);
`RenderedShape(sc, sd, 1.0);
}
@ -666,7 +665,7 @@ module DistTree = {
let rec evaluateNode = (treeNode: distTree, n: int): nodeResult => {
// returns either a new symbolic distribution
switch (treeNode) {
| `Distribution(d) => evaluateDistribution(d)
| `Simple(d) => evaluateDistribution(d)
| `Combination(t1, t2, op) => evaluateCombinationDistribution(evaluateNode(t1, n), evaluateNode(t2, n), op, n)
| `PointwiseSum(t1, t2) => evaluatePointwiseSum(evaluateNode(t1, n), evaluateNode(t2, n), n)
| `PointwiseProduct(t1, t2) => evaluatePointwiseProduct(evaluateNode(t1, n), evaluateNode(t2, n), n)
@ -682,7 +681,7 @@ module DistTree = {
let treeShape = evaluateNode(`Render(`Normalize(treeNode)), n);
switch (treeShape) {
| `Distribution(_) => E.O.toExn("No shape found!", None)
| `Simple(_) => E.O.toExn("No shape found!", None)
| `RenderedShape(sc, sd, _) => {
let shape = MixedShapeBuilder.buildSimple(~continuous=Some(sc), ~discrete=sd);
@ -701,7 +700,7 @@ module DistTree = {
};
switch (treeNode) {
| `Distribution(d) => GenericSimple.toString(d)
| `Simple(d) => GenericSimple.toString(d)
| `Combination(t1, t2, op) => toString(t1) ++ stringFromOp(op) ++ toString(t2)
| `PointwiseSum(t1, t2) => toString(t1) ++ " .+ " ++ toString(t2)
| `PointwiseProduct(t1, t2) => toString(t1) ++ " .* " ++ toString(t2)