Added additional distributions

This commit is contained in:
Ozzie Gooen 2020-03-26 16:01:52 +00:00
parent f7e3643a1e
commit e17e2aca2e
4 changed files with 116 additions and 18 deletions

View File

@ -77,7 +77,7 @@ let make = () => {
~validationStrategy=OnDemand,
~schema,
~onSubmit=({state}) => {None},
~initialState={guesstimatorString: "mm(1 to 10000)"},
~initialState={guesstimatorString: "mm(1 to 1000)"},
(),
);

View File

@ -27,7 +27,31 @@ type beta = {
[@bs.meth] "inv": (float, float, float) => float,
[@bs.meth] "sample": (float, float) => float,
};
type exponential = {
.
[@bs.meth] "pdf": (float, float) => float,
[@bs.meth] "cdf": (float, float) => float,
[@bs.meth] "inv": (float, float) => float,
[@bs.meth] "sample": float => float,
};
type cauchy = {
.
[@bs.meth] "pdf": (float, float, float) => float,
[@bs.meth] "cdf": (float, float, float) => float,
[@bs.meth] "inv": (float, float, float) => float,
[@bs.meth] "sample": (float, float) => float,
};
type triangular = {
.
[@bs.meth] "pdf": (float, float, float, float) => float,
[@bs.meth] "cdf": (float, float, float, float) => float,
[@bs.meth] "inv": (float, float, float, float) => float,
[@bs.meth] "sample": (float, float, float) => float,
};
[@bs.module "jStat"] external normal: normal = "normal";
[@bs.module "jStat"] external lognormal: lognormal = "lognormal";
[@bs.module "jStat"] external uniform: uniform = "uniform";
[@bs.module "jStat"] external beta: beta = "beta";
[@bs.module "jStat"] external beta: beta = "beta";
[@bs.module "jStat"] external exponential: exponential = "exponential";
[@bs.module "jStat"] external cauchy: cauchy = "cauchy";
[@bs.module "jStat"] external triangular: triangular = "triangular";

View File

@ -124,6 +124,23 @@ module MathAdtToDistDst = {
| [|Value(alpha), Value(beta)|] => Ok(`Simple(`Beta({alpha, beta})))
| _ => Error("Wrong number of variables in lognormal distribution");
let exponential: array(arg) => result(SymbolicDist.bigDist, string) =
fun
| [|Value(rate)|] => Ok(`Simple(`Exponential({rate: rate})))
| _ => Error("Wrong number of variables in Exponential distribution");
let cauchy: array(arg) => result(SymbolicDist.bigDist, string) =
fun
| [|Value(local), Value(scale)|] =>
Ok(`Simple(`Cauchy({local, scale})))
| _ => Error("Wrong number of variables in cauchy distribution");
let triangular: array(arg) => result(SymbolicDist.bigDist, string) =
fun
| [|Value(low), Value(medium), Value(high)|] =>
Ok(`Simple(`Triangular({low, medium, high})))
| _ => Error("Wrong number of variables in triangle distribution");
let multiModal =
(
args: array(result(SymbolicDist.bigDist, string)),
@ -157,6 +174,9 @@ module MathAdtToDistDst = {
| Fn({name: "uniform", args}) => uniform(args)
| Fn({name: "beta", args}) => beta(args)
| Fn({name: "to", args}) => to_(args)
| Fn({name: "exponential", args}) => exponential(args)
| Fn({name: "cauchy", args}) => cauchy(args)
| Fn({name: "triangular", args}) => triangular(args)
| Fn({name: "mm", args}) => {
let dists = args |> E.A.fmap(functionParser);
let weights =

View File

@ -18,17 +18,57 @@ type beta = {
beta: float,
};
type exponential = {rate: float};
type cauchy = {
local: float,
scale: float,
};
type triangular = {
low: float,
medium: float,
high: float,
};
type dist = [
| `Normal(normal)
| `Beta(beta)
| `Lognormal(lognormal)
| `Uniform(uniform)
| `Exponential(exponential)
| `Cauchy(cauchy)
| `Triangular(triangular)
];
type pointwiseAdd = array((dist, float));
type bigDist = [ | `Simple(dist) | `PointwiseCombination(pointwiseAdd)];
module Exponential = {
type t = exponential;
let pdf = (x, t: t) => Jstat.exponential##pdf(x, t.rate);
let inv = (p, t: t) => Jstat.exponential##inv(p, t.rate);
let sample = (t: t) => Jstat.exponential##sample(t.rate);
let toString = ({rate}: t) => {j|Exponential($rate)|j};
};
module Cauchy = {
type t = cauchy;
let pdf = (x, t: t) => Jstat.cauchy##pdf(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 toString = ({local, scale}: t) => {j|Cauchy($local, $scale)|j};
};
module Triangular = {
type t = triangular;
let pdf = (x, t: t) => Jstat.triangular##pdf(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 toString = ({low, medium, high}: t) => {j|Triangular($low, $medium, $high)|j};
};
module Normal = {
type t = normal;
let pdf = (x, t: t) => Jstat.normal##pdf(x, t.mean, t.stdev);
@ -87,6 +127,9 @@ module GenericSimple = {
let pdf = (x, dist) =>
switch (dist) {
| `Normal(n) => Normal.pdf(x, n)
| `Triangular(n) => Triangular.pdf(x, n)
| `Exponential(n) => Exponential.pdf(x, n)
| `Cauchy(n) => Cauchy.pdf(x, n)
| `Lognormal(n) => Lognormal.pdf(x, n)
| `Uniform(n) => Uniform.pdf(x, n)
| `Beta(n) => Beta.pdf(x, n)
@ -95,42 +138,53 @@ module GenericSimple = {
let inv = (x, dist) =>
switch (dist) {
| `Normal(n) => Normal.inv(x, n)
| `Triangular(n) => Triangular.inv(x, n)
| `Exponential(n) => Exponential.inv(x, n)
| `Cauchy(n) => Cauchy.inv(x, n)
| `Lognormal(n) => Lognormal.inv(x, n)
| `Uniform(n) => Uniform.inv(x, n)
| `Beta(n) => Beta.inv(x, n)
};
let sample = dist =>
switch (dist) {
let sample: dist => float =
fun
| `Normal(n) => Normal.sample(n)
| `Triangular(n) => Triangular.sample(n)
| `Exponential(n) => Exponential.sample(n)
| `Cauchy(n) => Cauchy.sample(n)
| `Lognormal(n) => Lognormal.sample(n)
| `Uniform(n) => Uniform.sample(n)
| `Beta(n) => Beta.sample(n)
};
| `Beta(n) => Beta.sample(n);
let toString = dist =>
switch (dist) {
let toString: dist => string =
fun
| `Triangular(n) => Triangular.toString(n)
| `Exponential(n) => Exponential.toString(n)
| `Cauchy(n) => Cauchy.toString(n)
| `Normal(n) => Normal.toString(n)
| `Lognormal(n) => Lognormal.toString(n)
| `Uniform(n) => Uniform.toString(n)
| `Beta(n) => Beta.toString(n)
};
| `Beta(n) => Beta.toString(n);
let min = dist =>
switch (dist) {
let min: dist => float =
fun
| `Triangular({low}) => low
| `Exponential(n) => Exponential.inv(minCdfValue, n)
| `Cauchy(n) => Cauchy.inv(minCdfValue, n)
| `Normal(n) => Normal.inv(minCdfValue, n)
| `Lognormal(n) => Lognormal.inv(minCdfValue, n)
| `Uniform({low}) => low
| `Beta(n) => Beta.inv(minCdfValue, n)
};
| `Beta(n) => Beta.inv(minCdfValue, n);
let max = dist =>
switch (dist) {
let max: dist => float =
fun
| `Triangular(n) => n.high
| `Exponential(n) => Exponential.inv(maxCdfValue, n)
| `Cauchy(n) => Cauchy.inv(maxCdfValue, n)
| `Normal(n) => Normal.inv(maxCdfValue, n)
| `Lognormal(n) => Lognormal.inv(maxCdfValue, n)
| `Beta(n) => Beta.inv(maxCdfValue, n)
| `Uniform({high}) => high
};
| `Uniform({high}) => high;
let interpolateXs =
(~xSelection: [ | `Linear | `ByWeight]=`Linear, dist: dist, sampleCount) => {