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

View File

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