Very simple functionality with multimodals
This commit is contained in:
parent
34a2f28ff8
commit
bc39ce9c67
|
@ -52,8 +52,7 @@ module DemoDist = {
|
|||
|> E.O.fmap(shape => {
|
||||
let distPlus =
|
||||
Distributions.DistPlus.make(
|
||||
~shape=
|
||||
Continuous(Distributions.Continuous.make(`Linear, shape)),
|
||||
~shape,
|
||||
~domain=Complete,
|
||||
~unit=UnspecifiedDistribution,
|
||||
~guesstimatorString=None,
|
||||
|
|
|
@ -142,6 +142,12 @@ module Discrete = {
|
|||
t |> XYShape.T.zip |> XYShape.Zipped.sortByY;
|
||||
let sortedByX = (t: DistTypes.discreteShape) =>
|
||||
t |> XYShape.T.zip |> XYShape.Zipped.sortByX;
|
||||
let empty = XYShape.T.empty;
|
||||
let combine = (fn, t1: DistTypes.discreteShape, t2: DistTypes.discreteShape): DistTypes.discreteShape => {
|
||||
XYShape.Combine.combine(~xsSelection=ALL_XS, ~xToYSelection=XYShape.XtoY.stepwiseIfAtX, ~fn, t1, t2)
|
||||
}
|
||||
let _default0 = ((fn, a,b) => fn(E.O.default(0.0, a), E.O.default(0.0, b)));
|
||||
let reduce = (fn, items) => items |> E.A.fold_left(combine(_default0((fn))), empty);
|
||||
module T =
|
||||
Dist({
|
||||
type t = DistTypes.discreteShape;
|
||||
|
|
|
@ -17,6 +17,7 @@ module T = {
|
|||
type ts = array(xyShape);
|
||||
let xs = (t: t) => t.xs;
|
||||
let ys = (t: t) => t.ys;
|
||||
let empty = ({xs: [||], ys: [||]});
|
||||
let minX = (t: t) => t |> xs |> E.A.Sorted.min |> extImp;
|
||||
let maxX = (t: t) => t |> xs |> E.A.Sorted.max |> extImp;
|
||||
let firstY = (t: t) => t |> ys |> E.A.first |> extImp;
|
||||
|
@ -170,11 +171,6 @@ module Combine = {
|
|||
| ALL_XS
|
||||
| XS_EVENLY_DIVIDED(int);
|
||||
|
||||
type xToYSelection =
|
||||
| LINEAR
|
||||
| STEPWISE_INCREMENTAL
|
||||
| STEPWISE_IF_AT_X;
|
||||
|
||||
let combine =
|
||||
(
|
||||
~xToYSelection: (float, T.t) => 'a,
|
||||
|
|
|
@ -48,6 +48,32 @@ type triangular = {
|
|||
[@bs.meth] "inv": (float, float, float, float) => float,
|
||||
[@bs.meth] "sample": (float, float, float) => float,
|
||||
};
|
||||
|
||||
// Pareto doesn't have sample for some reason
|
||||
type pareto = {
|
||||
.
|
||||
[@bs.meth] "pdf": (float, float, float) => float,
|
||||
[@bs.meth] "cdf": (float, float, float) => float,
|
||||
[@bs.meth] "inv": (float, float, float) => float,
|
||||
};
|
||||
type poisson = {
|
||||
.
|
||||
[@bs.meth] "pdf": (float, float) => float,
|
||||
[@bs.meth] "cdf": (float, float) => float,
|
||||
[@bs.meth] "sample": float => float,
|
||||
};
|
||||
type weibull = {
|
||||
.
|
||||
[@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 binomial = {
|
||||
.
|
||||
[@bs.meth] "pdf": (float, float, float) => float,
|
||||
[@bs.meth] "cdf": (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";
|
||||
|
@ -55,6 +81,10 @@ type triangular = {
|
|||
[@bs.module "jstat"] external exponential: exponential = "exponential";
|
||||
[@bs.module "jstat"] external cauchy: cauchy = "cauchy";
|
||||
[@bs.module "jstat"] external triangular: triangular = "triangular";
|
||||
[@bs.module "jstat"] external poisson: poisson = "poisson";
|
||||
[@bs.module "jstat"] external pareto: pareto = "pareto";
|
||||
[@bs.module "jstat"] external weibull: weibull = "weibull";
|
||||
[@bs.module "jstat"] external binomial: binomial = "binomial";
|
||||
|
||||
[@bs.module "jstat"] external sum: array(float) => float = "sum";
|
||||
[@bs.module "jstat"] external product: array(float) => float = "product";
|
||||
|
|
|
@ -177,6 +177,7 @@ module MathAdtToDistDst = {
|
|||
| Fn({name: "exponential", args}) => exponential(args)
|
||||
| Fn({name: "cauchy", args}) => cauchy(args)
|
||||
| Fn({name: "triangular", args}) => triangular(args)
|
||||
| Value(f) => Ok(`Simple(`Float(f)))
|
||||
| Fn({name: "mm", args}) => {
|
||||
let dists = args |> E.A.fmap(functionParser);
|
||||
let weights =
|
||||
|
@ -195,6 +196,7 @@ module MathAdtToDistDst = {
|
|||
| _ => None,
|
||||
)
|
||||
|> E.A.O.concatSomes;
|
||||
Js.log3("Making dists", dists, weights);
|
||||
multiModal(dists, weights);
|
||||
}
|
||||
| Fn({name}) => Error(name ++ ": function not supported")
|
||||
|
|
|
@ -31,6 +31,8 @@ type triangular = {
|
|||
high: float,
|
||||
};
|
||||
|
||||
type contType = [ | `Continuous | `Discrete];
|
||||
|
||||
type dist = [
|
||||
| `Normal(normal)
|
||||
| `Beta(beta)
|
||||
|
@ -39,6 +41,7 @@ type dist = [
|
|||
| `Exponential(exponential)
|
||||
| `Cauchy(cauchy)
|
||||
| `Triangular(triangular)
|
||||
| `Float(float)
|
||||
];
|
||||
|
||||
type pointwiseAdd = array((dist, float));
|
||||
|
@ -51,6 +54,7 @@ module Exponential = {
|
|||
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};
|
||||
let contType: contType = `Continuous;
|
||||
};
|
||||
|
||||
module Cauchy = {
|
||||
|
@ -59,6 +63,7 @@ module Cauchy = {
|
|||
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};
|
||||
let contType: contType = `Continuous;
|
||||
};
|
||||
|
||||
module Triangular = {
|
||||
|
@ -67,6 +72,7 @@ module Triangular = {
|
|||
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};
|
||||
let contType: contType = `Continuous;
|
||||
};
|
||||
|
||||
module Normal = {
|
||||
|
@ -75,6 +81,7 @@ module Normal = {
|
|||
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};
|
||||
let contType: contType = `Continuous;
|
||||
};
|
||||
|
||||
module Beta = {
|
||||
|
@ -83,6 +90,7 @@ module 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 toString = ({alpha, beta}: t) => {j|Beta($alpha,$beta)|j};
|
||||
let contType: contType = `Continuous;
|
||||
};
|
||||
|
||||
module Lognormal = {
|
||||
|
@ -91,6 +99,7 @@ module Lognormal = {
|
|||
let inv = (p, t: t) => Jstat.lognormal##inv(p, t.mu, t.sigma);
|
||||
let sample = (t: t) => Jstat.lognormal##sample(t.mu, t.sigma);
|
||||
let toString = ({mu, sigma}: t) => {j|Lognormal($mu,$sigma)|j};
|
||||
let contType: contType = `Continuous;
|
||||
let from90PercentCI = (low, high) => {
|
||||
let logLow = Js.Math.log(low);
|
||||
let logHigh = Js.Math.log(high);
|
||||
|
@ -118,6 +127,16 @@ module Uniform = {
|
|||
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 toString = ({low, high}: t) => {j|Uniform($low,$high)|j};
|
||||
let contType: contType = `Continuous;
|
||||
};
|
||||
|
||||
module Float = {
|
||||
type t = float;
|
||||
let pdf = (x, t: t) => x == t ? 1.0 : 0.0;
|
||||
let inv = (p, t: t) => p < t ? 0.0 : 1.0;
|
||||
let sample = (t: t) => t;
|
||||
let toString = Js.Float.toString;
|
||||
let contType: contType = `Discrete;
|
||||
};
|
||||
|
||||
module GenericSimple = {
|
||||
|
@ -133,6 +152,19 @@ module GenericSimple = {
|
|||
| `Lognormal(n) => Lognormal.pdf(x, n)
|
||||
| `Uniform(n) => Uniform.pdf(x, n)
|
||||
| `Beta(n) => Beta.pdf(x, n)
|
||||
| `Float(n) => Float.pdf(x, n)
|
||||
};
|
||||
|
||||
let contType = (dist:dist):contType =>
|
||||
switch (dist) {
|
||||
| `Normal(_) => Normal.contType
|
||||
| `Triangular(_) => Triangular.contType
|
||||
| `Exponential(_) => Exponential.contType
|
||||
| `Cauchy(_) => Cauchy.contType
|
||||
| `Lognormal(_) => Lognormal.contType
|
||||
| `Uniform(_) => Uniform.contType
|
||||
| `Beta(_) => Beta.contType
|
||||
| `Float(_) => Float.contType
|
||||
};
|
||||
|
||||
let inv = (x, dist) =>
|
||||
|
@ -144,6 +176,7 @@ module GenericSimple = {
|
|||
| `Lognormal(n) => Lognormal.inv(x, n)
|
||||
| `Uniform(n) => Uniform.inv(x, n)
|
||||
| `Beta(n) => Beta.inv(x, n)
|
||||
| `Float(n) => Float.inv(x, n)
|
||||
};
|
||||
|
||||
let sample: dist => float =
|
||||
|
@ -154,7 +187,8 @@ module GenericSimple = {
|
|||
| `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)
|
||||
| `Float(n) => Float.sample(n);
|
||||
|
||||
let toString: dist => string =
|
||||
fun
|
||||
|
@ -164,7 +198,8 @@ module GenericSimple = {
|
|||
| `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)
|
||||
| `Float(n) => Float.toString(n);
|
||||
|
||||
let min: dist => float =
|
||||
fun
|
||||
|
@ -174,7 +209,8 @@ module GenericSimple = {
|
|||
| `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)
|
||||
| `Float(n) => n;
|
||||
|
||||
let max: dist => float =
|
||||
fun
|
||||
|
@ -184,7 +220,8 @@ module GenericSimple = {
|
|||
| `Normal(n) => Normal.inv(maxCdfValue, n)
|
||||
| `Lognormal(n) => Lognormal.inv(maxCdfValue, n)
|
||||
| `Beta(n) => Beta.inv(maxCdfValue, n)
|
||||
| `Uniform({high}) => high;
|
||||
| `Uniform({high}) => high
|
||||
| `Float(n) => n;
|
||||
|
||||
let interpolateXs =
|
||||
(~xSelection: [ | `Linear | `ByWeight]=`Linear, dist: dist, sampleCount) => {
|
||||
|
@ -197,10 +234,13 @@ module GenericSimple = {
|
|||
};
|
||||
|
||||
let toShape =
|
||||
(~xSelection: [ | `Linear | `ByWeight]=`Linear, dist: dist, sampleCount) => {
|
||||
(~xSelection: [ | `Linear | `ByWeight]=`Linear, dist: dist, sampleCount)
|
||||
: DistTypes.shape => {
|
||||
let xs = interpolateXs(~xSelection, dist, sampleCount);
|
||||
let ys = xs |> E.A.fmap(r => pdf(r, dist));
|
||||
XYShape.T.fromArrays(xs, ys);
|
||||
XYShape.T.fromArrays(xs, ys)
|
||||
|> Distributions.Continuous.make(`Linear, _)
|
||||
|> Distributions.Continuous.T.toShape;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -212,7 +252,7 @@ module PointwiseAddDistributionsWeighted = {
|
|||
dists |> E.A.fmap(((a, b)) => (a, b /. total));
|
||||
};
|
||||
|
||||
let pdf = (dists: t, x: float) =>
|
||||
let pdf = (x: float, dists: t) =>
|
||||
dists
|
||||
|> E.A.fmap(((e, w)) => GenericSimple.pdf(x, e) *. w)
|
||||
|> E.A.Floats.sum;
|
||||
|
@ -223,7 +263,17 @@ module PointwiseAddDistributionsWeighted = {
|
|||
let max = (dists: t) =>
|
||||
dists |> E.A.fmap(d => d |> fst |> GenericSimple.max) |> E.A.max;
|
||||
|
||||
let toShape = (dists: t, sampleCount: int) => {
|
||||
let discreteShape = (dists:t, sampleCount: int) => {
|
||||
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
|
||||
}
|
||||
|
||||
let continuousShape = (dists:t, sampleCount: int) => {
|
||||
let xs =
|
||||
dists
|
||||
|> E.A.fmap(r =>
|
||||
|
@ -237,8 +287,17 @@ module PointwiseAddDistributionsWeighted = {
|
|||
)
|
||||
|> E.A.concatMany;
|
||||
xs |> Array.fast_sort(compare);
|
||||
let ys = xs |> E.A.fmap(pdf(dists));
|
||||
XYShape.T.fromArrays(xs, ys);
|
||||
let ys = xs |> E.A.fmap(pdf(_, dists));
|
||||
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, ~discrete);
|
||||
shape |> E.O.toExt("")
|
||||
};
|
||||
|
||||
let toString = (dists: t) => {
|
||||
|
|
Loading…
Reference in New Issue
Block a user