Add distToFloat functions

This commit is contained in:
Sebastian Kosch 2020-07-13 12:05:00 -07:00
parent d119db88a1
commit fed98763d5
8 changed files with 61 additions and 26 deletions

View File

@ -142,7 +142,7 @@ module DemoDist = {
},
~distPlusIngredients,
~shouldDownsample=options.downsampleTo |> E.O.isSome,
~recommendedLength=options.downsampleTo |> E.O.default(10000),
~recommendedLength=options.downsampleTo |> E.O.default(100),
(),
);
let response = DistPlusRenderer.run(inputs);

View File

@ -70,19 +70,6 @@ let combinePointwise =
)
};
// TODO: implement these functions
let pdf = (f: float, t: t): float => {
0.0;
};
let inv = (f: float, t: t): float => {
0.0;
};
let sample = (t: t): float => {
0.0;
};
module T =
Dist({
type t = DistTypes.shape;
@ -205,9 +192,23 @@ module T =
};
});
let operate = (distToFloatOp: ExpressionTypes.distToFloatOperation, s) =>
let pdf = (f: float, t: t) => {
let mixedPoint: DistTypes.mixedPoint = T.xToY(f, t);
mixedPoint.continuous +. mixedPoint.discrete;
};
let inv = T.Integral.yToX(~cache=None);
let cdf = T.Integral.xToY(~cache=None);
let sample = (t: t): float => {
// this can go, already taken care of in Ozzie's sampling branch
0.0
};
let operate = (distToFloatOp: ExpressionTypes.distToFloatOperation, s): float =>
switch (distToFloatOp) {
| `Pdf(f) => pdf(f, s)
| `Cdf(f) => pdf(f, s)
| `Inv(f) => inv(f, s)
| `Sample => sample(s)
| `Mean => T.mean(s)

View File

@ -260,7 +260,6 @@ module PointwiseCombination = {
}
};
//let combineLinear = combine(~xToYSelection=XtoY.linear);
let combineStepwise = combine(~xToYSelection=XtoY.stepwiseIncremental);
let combineIfAtX = combine(~xToYSelection=XtoY.stepwiseIfAtX);

View File

@ -227,6 +227,7 @@ let toLeaf =
node: t,
)
: result(t, string) => {
Js.log2("EVALUATION PARAMS", evaluationParams);
switch (node) {
// Leaf nodes just stay leaf nodes
| `SymbolicDist(_)

View File

@ -1,7 +1,7 @@
type algebraicOperation = [ | `Add | `Multiply | `Subtract | `Divide];
type pointwiseOperation = [ | `Add | `Multiply];
type scaleOperation = [ | `Multiply | `Exponentiate | `Log];
type distToFloatOperation = [ | `Pdf(float) | `Inv(float) | `Mean | `Sample];
type distToFloatOperation = [ | `Pdf(float) | `Cdf(float) | `Inv(float) | `Mean | `Sample];
module ExpressionTree = {
type node = [

View File

@ -237,7 +237,8 @@ module MathAdtToDistDst = {
args: array(result(ExpressionTypes.ExpressionTree.node, string)),
) => {
let toOkAlgebraic = r => Ok(`AlgebraicCombination(r));
let toOkTrunctate = r => Ok(`Truncate(r));
let toOkTruncate = r => Ok(`Truncate(r));
let toOkFloatFromDist = r => Ok(`FloatFromDist(r))
switch (name, args) {
| ("add", [|Ok(l), Ok(r)|]) => toOkAlgebraic((`Add, l, r))
| ("add", _) => Error("Addition needs two operands")
@ -249,11 +250,11 @@ module MathAdtToDistDst = {
| ("divide", _) => Error("Division needs two operands")
| ("pow", _) => Error("Exponentiation is not yet supported.")
| ("leftTruncate", [|Ok(d), Ok(`SymbolicDist(`Float(lc)))|]) =>
toOkTrunctate((Some(lc), None, d))
toOkTruncate((Some(lc), None, d))
| ("leftTruncate", _) =>
Error("leftTruncate needs two arguments: the expression and the cutoff")
| ("rightTruncate", [|Ok(d), Ok(`SymbolicDist(`Float(rc)))|]) =>
toOkTrunctate((None, Some(rc), d))
toOkTruncate((None, Some(rc), d))
| ("rightTruncate", _) =>
Error(
"rightTruncate needs two arguments: the expression and the cutoff",
@ -266,9 +267,19 @@ module MathAdtToDistDst = {
Ok(`SymbolicDist(`Float(rc))),
|],
) =>
toOkTrunctate((Some(lc), Some(rc), d))
toOkTruncate((Some(lc), Some(rc), d))
| ("truncate", _) =>
Error("truncate needs three arguments: the expression and both cutoffs")
| ("pdf", [|Ok(d), Ok(`SymbolicDist(`Float(v)))|]) =>
toOkFloatFromDist((`Pdf(v), d))
| ("cdf", [|Ok(d), Ok(`SymbolicDist(`Float(v)))|]) =>
toOkFloatFromDist((`Cdf(v), d))
| ("inv", [|Ok(d), Ok(`SymbolicDist(`Float(v)))|]) =>
toOkFloatFromDist((`Inv(v), d))
| ("mean", [|Ok(d)|]) =>
toOkFloatFromDist((`Mean, d))
| ("sample", [|Ok(d)|]) =>
toOkFloatFromDist((`Sample, d))
| _ => Error("This type not currently supported")
};
};
@ -316,11 +327,12 @@ module MathAdtToDistDst = {
| "pow"
| "leftTruncate"
| "rightTruncate"
| "truncate" => operationParser(name, parseArgs())
| "mean" as n
| "inv" as n
| "sample" as n
| "pdf" as n
| "truncate"
| "mean"
| "inv"
| "sample"
| "cdf"
| "pdf" => operationParser(name, parseArgs())
| n => Error(n ++ "(...) is not currently supported")
};
};

View File

@ -41,6 +41,7 @@ module DistToFloat = {
let format = (operation, value) =>
switch (operation) {
| `Cdf(f) => {j|cdf(x=$f,$value)|j}
| `Pdf(f) => {j|pdf(x=$f,$value)|j}
| `Inv(f) => {j|inv(x=$f,$value)|j}
| `Sample => "sample($value)"

View File

@ -3,6 +3,7 @@ open SymbolicTypes;
module Exponential = {
type t = exponential;
let pdf = (x, t: t) => Jstat.exponential##pdf(x, t.rate);
let cdf = (x, t: t) => Jstat.exponential##cdf(x, t.rate);
let inv = (p, t: t) => Jstat.exponential##inv(p, t.rate);
let sample = (t: t) => Jstat.exponential##sample(t.rate);
let mean = (t: t) => Ok(Jstat.exponential##mean(t.rate));
@ -12,6 +13,7 @@ module Exponential = {
module Cauchy = {
type t = cauchy;
let pdf = (x, t: t) => Jstat.cauchy##pdf(x, t.local, t.scale);
let cdf = (x, t: t) => Jstat.cauchy##cdf(x, t.local, t.scale);
let inv = (p, t: t) => Jstat.cauchy##inv(p, t.local, t.scale);
let sample = (t: t) => Jstat.cauchy##sample(t.local, t.scale);
let mean = (_: t) => Error("Cauchy distributions have no mean value.");
@ -21,6 +23,7 @@ module Cauchy = {
module Triangular = {
type t = triangular;
let pdf = (x, t: t) => Jstat.triangular##pdf(x, t.low, t.high, t.medium);
let cdf = (x, t: t) => Jstat.triangular##cdf(x, t.low, t.high, t.medium);
let inv = (p, t: t) => Jstat.triangular##inv(p, t.low, t.high, t.medium);
let sample = (t: t) => Jstat.triangular##sample(t.low, t.high, t.medium);
let mean = (t: t) => Ok(Jstat.triangular##mean(t.low, t.high, t.medium));
@ -30,6 +33,7 @@ module Triangular = {
module Normal = {
type t = normal;
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 from90PercentCI = (low, high) => {
let mean = E.A.Floats.mean([|low, high|]);
@ -72,6 +76,7 @@ module Normal = {
module Beta = {
type t = beta;
let pdf = (x, t: t) => Jstat.beta##pdf(x, t.alpha, t.beta);
let cdf = (x, t: t) => Jstat.beta##cdf(x, t.alpha, t.beta);
let inv = (p, t: t) => Jstat.beta##inv(p, t.alpha, t.beta);
let sample = (t: t) => Jstat.beta##sample(t.alpha, t.beta);
let mean = (t: t) => Ok(Jstat.beta##mean(t.alpha, t.beta));
@ -81,6 +86,7 @@ module Beta = {
module Lognormal = {
type t = lognormal;
let pdf = (x, t: t) => Jstat.lognormal##pdf(x, t.mu, t.sigma);
let cdf = (x, t: t) => Jstat.lognormal##cdf(x, t.mu, t.sigma);
let inv = (p, t: t) => Jstat.lognormal##inv(p, t.mu, t.sigma);
let mean = (t: t) => Ok(Jstat.lognormal##mean(t.mu, t.sigma));
let sample = (t: t) => Jstat.lognormal##sample(t.mu, t.sigma);
@ -126,6 +132,7 @@ module Lognormal = {
module Uniform = {
type t = uniform;
let pdf = (x, t: t) => Jstat.uniform##pdf(x, t.low, t.high);
let cdf = (x, t: t) => Jstat.uniform##cdf(x, t.low, t.high);
let inv = (p, t: t) => Jstat.uniform##inv(p, t.low, t.high);
let sample = (t: t) => Jstat.uniform##sample(t.low, t.high);
let mean = (t: t) => Ok(Jstat.uniform##mean(t.low, t.high));
@ -135,6 +142,7 @@ module Uniform = {
module Float = {
type t = float;
let pdf = (x, t: t) => x == t ? 1.0 : 0.0;
let cdf = (x, t: t) => x >= t ? 1.0 : 0.0;
let inv = (p, t: t) => p < t ? 0.0 : 1.0;
let mean = (t: t) => Ok(t);
let sample = (t: t) => t;
@ -157,6 +165,18 @@ module T = {
| `Float(n) => Float.pdf(x, n)
};
let cdf = (x, dist) =>
switch (dist) {
| `Normal(n) => Normal.cdf(x, n)
| `Triangular(n) => Triangular.cdf(x, n)
| `Exponential(n) => Exponential.cdf(x, n)
| `Cauchy(n) => Cauchy.cdf(x, n)
| `Lognormal(n) => Lognormal.cdf(x, n)
| `Uniform(n) => Uniform.cdf(x, n)
| `Beta(n) => Beta.cdf(x, n)
| `Float(n) => Float.cdf(x, n)
};
let inv = (x, dist) =>
switch (dist) {
| `Normal(n) => Normal.inv(x, n)
@ -226,6 +246,7 @@ module T = {
let operate = (distToFloatOp: ExpressionTypes.distToFloatOperation, s) =>
switch (distToFloatOp) {
| `Cdf(f) => Ok(cdf(f, s))
| `Pdf(f) => Ok(pdf(f, s))
| `Inv(f) => Ok(inv(f, s))
| `Sample => Ok(sample(s))