Added normal from90PercentCI for distributions that are at 0 or below

This commit is contained in:
Ozzie Gooen 2020-04-30 11:18:33 +01:00
parent 77c9ce09be
commit 5129ff20d5
2 changed files with 68 additions and 43 deletions

View File

@ -111,12 +111,12 @@ module MathAdtToDistDst = {
let to_: array(arg) => result(SymbolicDist.bigDist, string) =
fun
| [|Value(low), Value(high)|] when low <= 0.0 && low < high=> {
Ok(`Simple(SymbolicDist.Normal.from90PercentCI(low, high)));
}
| [|Value(low), Value(high)|] when low < high => {
Ok(`Simple(SymbolicDist.Lognormal.from90PercentCI(low, high)));
}
| [|Value(low), _|] when low <= 0.0 => {
Error("Low value cannot be less than 0.");
}
| [|Value(_), Value(_)|] =>
Error("Low value must be less than high value.")
| _ => Error("Wrong number of variables in lognormal distribution");

View File

@ -31,7 +31,10 @@ type triangular = {
high: float,
};
type continuousShape = {pdf: DistTypes.continuousShape, cdf: DistTypes.continuousShape}
type continuousShape = {
pdf: DistTypes.continuousShape,
cdf: DistTypes.continuousShape,
};
type contType = [ | `Continuous | `Discrete];
@ -53,12 +56,14 @@ type bigDist = [ | `Simple(dist) | `PointwiseCombination(pointwiseAdd)];
module ContinuousShape = {
type t = continuousShape;
let make = (pdf, cdf):t => ({pdf, cdf});
let pdf = (x, t: t) => Distributions.Continuous.T.xToY(x,t.pdf).continuous
let inv = (p, t: t) => Distributions.Continuous.T.xToY(p,t.pdf).continuous
let make = (pdf, cdf): t => {pdf, cdf};
let pdf = (x, t: t) =>
Distributions.Continuous.T.xToY(x, t.pdf).continuous;
let inv = (p, t: t) =>
Distributions.Continuous.T.xToY(p, t.pdf).continuous;
// TODO: Fix the sampling, to have it work correctly.
let sample = (t: t) => 3.0;
let toString = (t) => {j|CustomContinuousShape|j};
let toString = t => {j|CustomContinuousShape|j};
let contType: contType = `Continuous;
};
@ -92,6 +97,12 @@ module Triangular = {
module Normal = {
type t = normal;
let pdf = (x, t: t) => Jstat.normal##pdf(x, t.mean, t.stdev);
let from90PercentCI = (low, high) => {
let mean = E.A.Floats.mean([|low, high|]);
let stdev = (high -. low) /. 1.645;
`Normal({mean, stdev});
};
let inv = (p, t: t) => Jstat.normal##inv(p, t.mean, t.stdev);
let sample = (t: t) => Jstat.normal##sample(t.mean, t.stdev);
let toString = ({mean, stdev}: t) => {j|Normal($mean,$stdev)|j};
@ -206,7 +217,7 @@ module GenericSimple = {
| `Uniform(n) => Uniform.sample(n)
| `Beta(n) => Beta.sample(n)
| `Float(n) => Float.sample(n)
| `ContinuousShape(n) => ContinuousShape.sample(n)
| `ContinuousShape(n) => ContinuousShape.sample(n);
let toString: dist => string =
fun
@ -218,7 +229,7 @@ module GenericSimple = {
| `Uniform(n) => Uniform.toString(n)
| `Beta(n) => Beta.toString(n)
| `Float(n) => Float.toString(n)
| `ContinuousShape(n) => ContinuousShape.toString(n)
| `ContinuousShape(n) => ContinuousShape.toString(n);
let min: dist => float =
fun
@ -259,14 +270,13 @@ module GenericSimple = {
: DistTypes.shape => {
switch (dist) {
| `ContinuousShape(n) => n.pdf |> Distributions.Continuous.T.toShape
| dist => {
| dist =>
let xs = interpolateXs(~xSelection, dist, sampleCount);
let ys = xs |> E.A.fmap(r => pdf(r, dist));
XYShape.T.fromArrays(xs, ys)
|> Distributions.Continuous.make(`Linear, _)
|> Distributions.Continuous.T.toShape;
}
}
};
};
};
@ -290,14 +300,23 @@ module PointwiseAddDistributionsWeighted = {
dists |> E.A.fmap(d => d |> fst |> GenericSimple.max) |> E.A.max;
let discreteShape = (dists: t, sampleCount: int) => {
let discrete = dists |> E.A.fmap((((r,e)) => r |> fun
let discrete =
dists
|> E.A.fmap(((r, e)) =>
r
|> (
fun
| `Float(r) => Some((r, e))
| _ => None
)) |> E.A.O.concatSomes
|> E.A.fmap(((x, y)):DistTypes.xyShape => ({xs: [|x|], ys: [|y|]}))
|> Distributions.Discrete.reduce((+.))
discrete
}
)
)
|> E.A.O.concatSomes
|> E.A.fmap(((x, y)) =>
({xs: [|x|], ys: [|y|]}: DistTypes.xyShape)
)
|> Distributions.Discrete.reduce((+.));
discrete;
};
let continuousShape = (dists: t, sampleCount: int) => {
let xs =
@ -314,16 +333,22 @@ module PointwiseAddDistributionsWeighted = {
|> E.A.concatMany;
xs |> Array.fast_sort(compare);
let ys = xs |> E.A.fmap(pdf(_, dists));
XYShape.T.fromArrays(xs, ys)
|> Distributions.Continuous.make(`Linear, _)
}
XYShape.T.fromArrays(xs, ys) |> Distributions.Continuous.make(`Linear, _);
};
let toShape = (dists: t, sampleCount: int) => {
let normalized = normalizeWeights(dists);
let continuous = normalized |> E.A.filter(((r,_)) => GenericSimple.contType(r) == `Continuous) |> continuousShape(_, sampleCount);
let discrete = normalized |> E.A.filter(((r,_)) => GenericSimple.contType(r) == `Discrete) |> discreteShape(_, sampleCount);
let shape = MixedShapeBuilder.buildSimple(~continuous=Some(continuous), ~discrete);
shape |> E.O.toExt("")
let continuous =
normalized
|> E.A.filter(((r, _)) => GenericSimple.contType(r) == `Continuous)
|> continuousShape(_, sampleCount);
let discrete =
normalized
|> E.A.filter(((r, _)) => GenericSimple.contType(r) == `Discrete)
|> discreteShape(_, sampleCount);
let shape =
MixedShapeBuilder.buildSimple(~continuous=Some(continuous), ~discrete);
shape |> E.O.toExt("");
};
let toString = (dists: t) => {