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, ~distPlusIngredients,
~shouldDownsample=options.downsampleTo |> E.O.isSome, ~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); 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 = module T =
Dist({ Dist({
type t = DistTypes.shape; 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) { switch (distToFloatOp) {
| `Pdf(f) => pdf(f, s) | `Pdf(f) => pdf(f, s)
| `Cdf(f) => pdf(f, s)
| `Inv(f) => inv(f, s) | `Inv(f) => inv(f, s)
| `Sample => sample(s) | `Sample => sample(s)
| `Mean => T.mean(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 combineStepwise = combine(~xToYSelection=XtoY.stepwiseIncremental);
let combineIfAtX = combine(~xToYSelection=XtoY.stepwiseIfAtX); let combineIfAtX = combine(~xToYSelection=XtoY.stepwiseIfAtX);

View File

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

View File

@ -1,7 +1,7 @@
type algebraicOperation = [ | `Add | `Multiply | `Subtract | `Divide]; type algebraicOperation = [ | `Add | `Multiply | `Subtract | `Divide];
type pointwiseOperation = [ | `Add | `Multiply]; type pointwiseOperation = [ | `Add | `Multiply];
type scaleOperation = [ | `Multiply | `Exponentiate | `Log]; 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 = { module ExpressionTree = {
type node = [ type node = [

View File

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

View File

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

View File

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