Simple mixed distribution

This commit is contained in:
Ozzie Gooen 2020-02-15 16:29:23 +00:00
parent 5bd66be29e
commit ab9c8726d6
5 changed files with 84 additions and 54 deletions

View File

@ -1,12 +1,17 @@
type t = {
distribution: Types.distribution,
distribution: Types.ContinuousDistribution.t,
domainMaxX: float,
};
let make = (~distribution, ~domainMaxX): t => {distribution, domainMaxX};
let fromCdf = (cdf: Types.cdf, domainMaxX: float, probabilityAtMaxX: float) => {
let distribution: Types.distribution = {
let fromCdf =
(
cdf: Types.ContinuousDistribution.t,
domainMaxX: float,
probabilityAtMaxX: float,
) => {
let distribution: Types.ContinuousDistribution.t = {
xs: cdf.xs,
ys: cdf.ys |> E.A.fmap(r => r *. probabilityAtMaxX),
};

View File

@ -66,7 +66,7 @@ type t = {
let make =
(
~timeVector: timeVector,
~distribution: Types.distribution,
~distribution: Types.ContinuousDistribution.t,
~probabilityAtMaxX: float,
~maxX: [ | `time(MomentRe.Moment.t) | `x(float)],
)

View File

@ -17,7 +17,7 @@ module Value = {
| Conditional(conditional)
| TimeLimitedDomainCdf(TimeLimitedDomainCdf.t)
| TimeLimitedDomainCdfLazy(
(string => Types.distribution) => TimeLimitedDomainCdf.t,
(string => Types.ContinuousDistribution.t) => TimeLimitedDomainCdf.t,
)
| ConditionalArray(array(conditional))
| FloatCdf(string);
@ -59,23 +59,34 @@ module Value = {
let timeLimited = r(CdfLibrary.Distribution.fromString(_, 1000));
let cdf = timeLimited.limitedDomainCdf.distribution;
<>
<Chart height=100 data={cdf |> Types.toJs} />
<Chart height=100 data={cdf |> Types.ContinuousDistribution.toJs} />
<Chart
height=100
data={cdf |> CdfLibrary.Distribution.toPdf |> Types.toJs}
data={
cdf
|> CdfLibrary.Distribution.toPdf
|> Types.ContinuousDistribution.toJs
}
/>
{FloatCdf.logNormal(50., 20.) |> ReasonReact.string}
</>;
| TimeLimitedDomainCdf(r) =>
let cdf: Types.distribution = r.limitedDomainCdf.distribution;
<> <Chart height=100 data={cdf |> Types.toJs} /> </>;
let cdf: Types.ContinuousDistribution.t =
r.limitedDomainCdf.distribution;
<>
<Chart height=100 data={cdf |> Types.ContinuousDistribution.toJs} />
</>;
| FloatCdf(r) =>
let cdf: Types.distribution =
let cdf: Types.ContinuousDistribution.t =
CdfLibrary.Distribution.fromString(r, 2000);
<>
<Chart
height=100
data={cdf |> CdfLibrary.Distribution.toPdf |> Types.toJs}
data={
cdf
|> CdfLibrary.Distribution.toPdf
|> Types.ContinuousDistribution.toJs
}
/>
{r |> ReasonReact.string}
</>;

View File

@ -1,54 +1,66 @@
type distribution = {
xs: array(float),
ys: array(float),
};
let toJs = (t: distribution) => {
{"xs": t.xs, "ys": t.ys};
};
let toComponentsDist = (d: distribution): ForetoldComponents.Types.Dist.t => {
xs: d.xs,
ys: d.ys,
};
type pdf = distribution;
type cdf = distribution;
let foo = (b: pdf) => 3.9;
let bar: cdf = {xs: [||], ys: [||]};
let cc = foo(bar);
module LimitedDomainCdf = {
module ContinuousDistribution = {
type t = {
distribution,
domainMaxX: float,
xs: array(float),
ys: array(float),
};
let fromCdf = (cdf: cdf, domainMaxX: float, probabilityAtMaxX: float) => {
let distribution: distribution = {
xs: cdf.xs,
ys: cdf.ys |> E.A.fmap(r => r *. probabilityAtMaxX),
};
{distribution, domainMaxX};
let toJs = (t: t) => {
{"xs": t.xs, "ys": t.ys};
};
let toComponentsDist = (d: t): ForetoldComponents.Types.Dist.t => {
xs: d.xs,
ys: d.ys,
};
type pdf = t;
type cdf = t;
};
module DiscreteDistribution = {
type t = {
xs: array(float),
ys: array(float),
};
let fromArray = (xs, ys) => {xs, ys};
let _lastElement = (a: array('a)) =>
switch (Belt.Array.size(a)) {
| 0 => None
| n => Belt.Array.get(a, n)
};
let probabilityBeforeDomainMax = (t: t) => _lastElement(t.distribution.ys);
let derivative = (p: t) => {
let (xs, ys) =
Belt.Array.zip(p.xs, p.ys)
->Belt.Array.reduce([||], (items, (x, y)) =>
switch (_lastElement(items)) {
| Some((_, yLast)) => [|(x, y -. yLast)|]
| None => [|(x, y)|]
}
)
|> Belt.Array.unzip;
fromArray(xs, ys);
};
let chanceByX = (t: t) => t.distribution;
let domainMaxX = (t: t) => t.domainMaxX;
// let probabilityDistribution = (t: t) =>
// t.distribution |> CdfLibrary.Distribution.toPdf;
// let probability = (t: t, xPoint: float) =>
// CdfLibrary.Distribution.findY(xPoint, probabilityDistribution(t));
// let cumulativeProbability = (t: t, xPoint: float) =>
// CdfLibrary.Distribution.findY(xPoint, t.distribution);
let integral = (p: t) => {
let (xs, ys) =
Belt.Array.zip(p.xs, p.ys)
->Belt.Array.reduce([||], (items, (x, y)) =>
switch (_lastElement(items)) {
| Some((_, yLast)) => [|(x, y +. yLast)|]
| None => [|(x, y)|]
}
)
|> Belt.Array.unzip;
fromArray(xs, ys);
};
};
module MixedDistribution = {
type distribution = {
discrete: DiscreteDistribution.t,
continuous: ContinuousDistribution.t,
};
};

View File

@ -5,14 +5,16 @@ module JS = {
ys: array(float),
};
let distToJs = (d: Types.distribution) => distJs(~xs=d.xs, ~ys=d.ys);
let distToJs = (d: Types.ContinuousDistribution.t) =>
distJs(~xs=d.xs, ~ys=d.ys);
let jsToDist = (d: distJs): Types.distribution => {
let jsToDist = (d: distJs): Types.ContinuousDistribution.t => {
xs: xsGet(d),
ys: ysGet(d),
};
let doAsDist = (f, d: Types.distribution) => d |> distToJs |> f |> jsToDist;
let doAsDist = (f, d: Types.ContinuousDistribution.t) =>
d |> distToJs |> f |> jsToDist;
[@bs.module "./CdfLibrary.js"]
external cdfToPdf: distJs => distJs = "cdfToPdf";