From ab9c8726d69196f63f0c939167b14aca48ee5e79 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 15 Feb 2020 16:29:23 +0000 Subject: [PATCH] Simple mixed distribution --- src/LimitedDomainCdf.re | 11 +++-- src/TimeLimitedDomainCdf.re | 2 +- src/lib/Prop.re | 25 +++++++--- src/lib/Types.re | 92 +++++++++++++++++++++---------------- src/utility/CdfLibrary.re | 8 ++-- 5 files changed, 84 insertions(+), 54 deletions(-) diff --git a/src/LimitedDomainCdf.re b/src/LimitedDomainCdf.re index 9cf7d18f..675304a3 100644 --- a/src/LimitedDomainCdf.re +++ b/src/LimitedDomainCdf.re @@ -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), }; diff --git a/src/TimeLimitedDomainCdf.re b/src/TimeLimitedDomainCdf.re index 78aee494..f19067b9 100644 --- a/src/TimeLimitedDomainCdf.re +++ b/src/TimeLimitedDomainCdf.re @@ -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)], ) diff --git a/src/lib/Prop.re b/src/lib/Prop.re index 1eba0bd3..54841316 100644 --- a/src/lib/Prop.re +++ b/src/lib/Prop.re @@ -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; <> - Types.toJs} /> + Types.ContinuousDistribution.toJs} /> 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; - <> Types.toJs} /> ; + let cdf: Types.ContinuousDistribution.t = + r.limitedDomainCdf.distribution; + <> + Types.ContinuousDistribution.toJs} /> + ; | FloatCdf(r) => - let cdf: Types.distribution = + let cdf: Types.ContinuousDistribution.t = CdfLibrary.Distribution.fromString(r, 2000); <> CdfLibrary.Distribution.toPdf |> Types.toJs} + data={ + cdf + |> CdfLibrary.Distribution.toPdf + |> Types.ContinuousDistribution.toJs + } /> {r |> ReasonReact.string} ; diff --git a/src/lib/Types.re b/src/lib/Types.re index fb7ace63..81eea880 100644 --- a/src/lib/Types.re +++ b/src/lib/Types.re @@ -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 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); + }; +}; - 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); +module MixedDistribution = { + type distribution = { + discrete: DiscreteDistribution.t, + continuous: ContinuousDistribution.t, + }; }; \ No newline at end of file diff --git a/src/utility/CdfLibrary.re b/src/utility/CdfLibrary.re index 4ea68560..1bcf4c37 100644 --- a/src/utility/CdfLibrary.re +++ b/src/utility/CdfLibrary.re @@ -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";