Simple refactoring too add functionality in Shape.re
This commit is contained in:
parent
5de75a402b
commit
61645243f9
33
src/Experimental/LimitedDomainCdf.re
Normal file
33
src/Experimental/LimitedDomainCdf.re
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// type t = {
|
||||||
|
// distribution: Types.ContinuousDistribution.t,
|
||||||
|
// domainMaxX: float,
|
||||||
|
// };
|
||||||
|
// let make = (~distribution, ~domainMaxX): t => {distribution, domainMaxX};
|
||||||
|
// 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),
|
||||||
|
// };
|
||||||
|
// {distribution, domainMaxX};
|
||||||
|
// };
|
||||||
|
// 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 domainMaxX = (t: t) => t.domainMaxX /* CdfLibrary.Distribution.findX(yPoint, t.distribution)*/;
|
||||||
|
// let probabilityDistribution = (t: t) =>
|
||||||
|
// t.distribution |> CdfLibrary.Distribution.toPdf;
|
||||||
|
// let probability = (t: t, xPoint: float) =>
|
||||||
|
// CdfLibrary.Distribution.findY(xPoint, probabilityDistribution(t));
|
||||||
|
// let probabilityInverse = (t: t, yPoint: float) =>
|
||||||
|
// CdfLibrary.Distribution.findX(yPoint, probabilityDistribution(t));
|
||||||
|
// let cumulativeProbability = (t: t, xPoint: float) =>
|
||||||
|
// CdfLibrary.Distribution.findY(xPoint, t.distribution);
|
||||||
|
/* let cumulativeProbabilityInverse = (t: t, yPoint: float) =*/
|
38
src/Experimental/TimeLimitedDomainCdf.re
Normal file
38
src/Experimental/TimeLimitedDomainCdf.re
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// open TimeTypes;
|
||||||
|
// type t = {
|
||||||
|
// timeVector,
|
||||||
|
// limitedDomainCdf: LimitedDomainCdf.t,
|
||||||
|
// };
|
||||||
|
// let make =
|
||||||
|
// (
|
||||||
|
// ~timeVector: timeVector,
|
||||||
|
// ~distribution: Types.ContinuousDistribution.t,
|
||||||
|
// ~probabilityAtMaxX: float,
|
||||||
|
// ~maxX: [ | `time(MomentRe.Moment.t) | `x(float)],
|
||||||
|
// )
|
||||||
|
// : t => {
|
||||||
|
// let domainMaxX =
|
||||||
|
// switch (maxX) {
|
||||||
|
// | `time(m) => TimePoint.fromMoment(timeVector, m)
|
||||||
|
// | `x(r) => r
|
||||||
|
// };
|
||||||
|
// let limitedDomainCdf =
|
||||||
|
// LimitedDomainCdf.fromCdf(distribution, domainMaxX, probabilityAtMaxX);
|
||||||
|
// {timeVector, limitedDomainCdf};
|
||||||
|
// };
|
||||||
|
// let probabilityBeforeDomainMax = (t: t) =>
|
||||||
|
// LimitedDomainCdf.probabilityBeforeDomainMax(t.limitedDomainCdf);
|
||||||
|
// let domainMaxX = (t: t) =>
|
||||||
|
// LimitedDomainCdf.probabilityBeforeDomainMax(t.limitedDomainCdf) /* |> (r => RelativeTimePoint.toTime(t.timeVector, XValue(r)))*/;
|
||||||
|
// let probability = (t: t, m: MomentRe.Moment.t) => {
|
||||||
|
// RelativeTimePoint.toXValue(t.timeVector, Time(m))
|
||||||
|
// |> LimitedDomainCdf.probability(t.limitedDomainCdf);
|
||||||
|
// };
|
||||||
|
// let probabilityInverse = (t: t, y: float) =>
|
||||||
|
// LimitedDomainCdf.probabilityInverse(t.limitedDomainCdf, y)
|
||||||
|
// |> (r => RelativeTimePoint.toTime(t.timeVector, XValue(r)));
|
||||||
|
// let cumulativeProbability = (t: t, m: MomentRe.Moment.t) =>
|
||||||
|
// RelativeTimePoint.toXValue(t.timeVector, Time(m))
|
||||||
|
// |> LimitedDomainCdf.cumulativeProbability(t.limitedDomainCdf);
|
||||||
|
// let cumulativeProbabilityInverse = (t: t, y: float) =>
|
||||||
|
/* LimitedDomainCdf.cumulativeProbabilityInverse(t.limitedDomainCdf, y*/
|
|
@ -1,43 +0,0 @@
|
||||||
type t = {
|
|
||||||
distribution: Types.ContinuousDistribution.t,
|
|
||||||
domainMaxX: float,
|
|
||||||
};
|
|
||||||
|
|
||||||
let make = (~distribution, ~domainMaxX): t => {distribution, domainMaxX};
|
|
||||||
|
|
||||||
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),
|
|
||||||
};
|
|
||||||
{distribution, domainMaxX};
|
|
||||||
};
|
|
||||||
|
|
||||||
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 domainMaxX = (t: t) => t.domainMaxX /* CdfLibrary.Distribution.findX(yPoint, t.distribution)*/;
|
|
||||||
|
|
||||||
// let probabilityDistribution = (t: t) =>
|
|
||||||
// t.distribution |> CdfLibrary.Distribution.toPdf;
|
|
||||||
|
|
||||||
// let probability = (t: t, xPoint: float) =>
|
|
||||||
// CdfLibrary.Distribution.findY(xPoint, probabilityDistribution(t));
|
|
||||||
|
|
||||||
// let probabilityInverse = (t: t, yPoint: float) =>
|
|
||||||
// CdfLibrary.Distribution.findX(yPoint, probabilityDistribution(t));
|
|
||||||
|
|
||||||
// let cumulativeProbability = (t: t, xPoint: float) =>
|
|
||||||
// CdfLibrary.Distribution.findY(xPoint, t.distribution);
|
|
||||||
|
|
||||||
// let cumulativeProbabilityInverse = (t: t, yPoint: float) =>
|
|
|
@ -1,46 +0,0 @@
|
||||||
open TimeTypes;
|
|
||||||
|
|
||||||
type t = {
|
|
||||||
timeVector,
|
|
||||||
limitedDomainCdf: LimitedDomainCdf.t,
|
|
||||||
};
|
|
||||||
|
|
||||||
let make =
|
|
||||||
(
|
|
||||||
~timeVector: timeVector,
|
|
||||||
~distribution: Types.ContinuousDistribution.t,
|
|
||||||
~probabilityAtMaxX: float,
|
|
||||||
~maxX: [ | `time(MomentRe.Moment.t) | `x(float)],
|
|
||||||
)
|
|
||||||
: t => {
|
|
||||||
let domainMaxX =
|
|
||||||
switch (maxX) {
|
|
||||||
| `time(m) => TimePoint.fromMoment(timeVector, m)
|
|
||||||
| `x(r) => r
|
|
||||||
};
|
|
||||||
let limitedDomainCdf =
|
|
||||||
LimitedDomainCdf.fromCdf(distribution, domainMaxX, probabilityAtMaxX);
|
|
||||||
{timeVector, limitedDomainCdf};
|
|
||||||
};
|
|
||||||
|
|
||||||
let probabilityBeforeDomainMax = (t: t) =>
|
|
||||||
LimitedDomainCdf.probabilityBeforeDomainMax(t.limitedDomainCdf);
|
|
||||||
|
|
||||||
let domainMaxX = (t: t) =>
|
|
||||||
LimitedDomainCdf.probabilityBeforeDomainMax(t.limitedDomainCdf) /* |> (r => RelativeTimePoint.toTime(t.timeVector, XValue(r)))*/;
|
|
||||||
|
|
||||||
// let probability = (t: t, m: MomentRe.Moment.t) => {
|
|
||||||
// RelativeTimePoint.toXValue(t.timeVector, Time(m))
|
|
||||||
// |> LimitedDomainCdf.probability(t.limitedDomainCdf);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let probabilityInverse = (t: t, y: float) =>
|
|
||||||
// LimitedDomainCdf.probabilityInverse(t.limitedDomainCdf, y)
|
|
||||||
// |> (r => RelativeTimePoint.toTime(t.timeVector, XValue(r)));
|
|
||||||
|
|
||||||
// let cumulativeProbability = (t: t, m: MomentRe.Moment.t) =>
|
|
||||||
// RelativeTimePoint.toXValue(t.timeVector, Time(m))
|
|
||||||
// |> LimitedDomainCdf.cumulativeProbability(t.limitedDomainCdf);
|
|
||||||
|
|
||||||
// let cumulativeProbabilityInverse = (t: t, y: float) =>
|
|
||||||
// LimitedDomainCdf.cumulativeProbabilityInverse(t.limitedDomainCdf, y)
|
|
|
@ -9,15 +9,13 @@ type domain =
|
||||||
| RightLimited(domainLimit)
|
| RightLimited(domainLimit)
|
||||||
| LeftAndRightLimited(domainLimit, domainLimit);
|
| LeftAndRightLimited(domainLimit, domainLimit);
|
||||||
|
|
||||||
type continuousShape = {
|
type xyShape = {
|
||||||
xs: array(float),
|
xs: array(float),
|
||||||
ys: array(float),
|
ys: array(float),
|
||||||
};
|
};
|
||||||
|
type continuousShape = xyShape;
|
||||||
|
|
||||||
type discreteShape = {
|
type discreteShape = xyShape;
|
||||||
xs: array(float),
|
|
||||||
ys: array(float),
|
|
||||||
};
|
|
||||||
|
|
||||||
type mixedShape = {
|
type mixedShape = {
|
||||||
continuous: continuousShape,
|
continuous: continuousShape,
|
||||||
|
|
63
src/lib/MixedShapeBuilder.re
Normal file
63
src/lib/MixedShapeBuilder.re
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
type assumption =
|
||||||
|
| ADDS_TO_1
|
||||||
|
| ADDS_TO_CORRECT_PROBABILITY;
|
||||||
|
type assumptions = {
|
||||||
|
continuous: assumption,
|
||||||
|
discrete: assumption,
|
||||||
|
discreteProbabilityMass: option(float),
|
||||||
|
};
|
||||||
|
let build = (~continuous, ~discrete, ~assumptions) =>
|
||||||
|
switch (assumptions) {
|
||||||
|
| {
|
||||||
|
continuous: ADDS_TO_CORRECT_PROBABILITY,
|
||||||
|
discrete: ADDS_TO_CORRECT_PROBABILITY,
|
||||||
|
discreteProbabilityMass: Some(r),
|
||||||
|
} =>
|
||||||
|
// TODO: Fix this, it's wrong :(
|
||||||
|
Some(
|
||||||
|
Shape.Mixed.make(
|
||||||
|
~continuous,
|
||||||
|
~discrete,
|
||||||
|
~discreteProbabilityMassFraction=r,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
| {
|
||||||
|
continuous: ADDS_TO_1,
|
||||||
|
discrete: ADDS_TO_1,
|
||||||
|
discreteProbabilityMass: Some(r),
|
||||||
|
} =>
|
||||||
|
Some(
|
||||||
|
Shape.Mixed.make(
|
||||||
|
~continuous,
|
||||||
|
~discrete,
|
||||||
|
~discreteProbabilityMassFraction=r,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
| {
|
||||||
|
continuous: ADDS_TO_1,
|
||||||
|
discrete: ADDS_TO_1,
|
||||||
|
discreteProbabilityMass: None,
|
||||||
|
} =>
|
||||||
|
None
|
||||||
|
| {
|
||||||
|
continuous: ADDS_TO_CORRECT_PROBABILITY,
|
||||||
|
discrete: ADDS_TO_1,
|
||||||
|
discreteProbabilityMass: None,
|
||||||
|
} =>
|
||||||
|
None
|
||||||
|
| {
|
||||||
|
continuous: ADDS_TO_1,
|
||||||
|
discrete: ADDS_TO_CORRECT_PROBABILITY,
|
||||||
|
discreteProbabilityMass: None,
|
||||||
|
} =>
|
||||||
|
let discreteProbabilityMassFraction = Shape.Discrete.ySum(discrete);
|
||||||
|
let discrete = Shape.Discrete.scaleYToTotal(1.0, discrete);
|
||||||
|
Some(
|
||||||
|
Shape.Mixed.make(
|
||||||
|
~continuous,
|
||||||
|
~discrete,
|
||||||
|
~discreteProbabilityMassFraction,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
| _ => None
|
||||||
|
};
|
|
@ -16,10 +16,6 @@ module Value = {
|
||||||
| Probability(float)
|
| Probability(float)
|
||||||
| Conditional(conditional)
|
| Conditional(conditional)
|
||||||
| GenericDistribution(DistributionTypes.genericDistribution)
|
| GenericDistribution(DistributionTypes.genericDistribution)
|
||||||
| TimeLimitedDomainCdf(TimeLimitedDomainCdf.t)
|
|
||||||
| TimeLimitedDomainCdfLazy(
|
|
||||||
(string => Types.ContinuousDistribution.t) => TimeLimitedDomainCdf.t,
|
|
||||||
)
|
|
||||||
| ConditionalArray(array(conditional))
|
| ConditionalArray(array(conditional))
|
||||||
| FloatCdf(string);
|
| FloatCdf(string);
|
||||||
|
|
||||||
|
@ -33,8 +29,6 @@ module Value = {
|
||||||
| SelectSingle(r) => r
|
| SelectSingle(r) => r
|
||||||
| FloatCdf(r) => r
|
| FloatCdf(r) => r
|
||||||
| GenericDistribution(_) => ""
|
| GenericDistribution(_) => ""
|
||||||
| TimeLimitedDomainCdf(_) => ""
|
|
||||||
| TimeLimitedDomainCdfLazy(_) => ""
|
|
||||||
| Probability(r) => (r *. 100. |> Js.Float.toFixed) ++ "%"
|
| Probability(r) => (r *. 100. |> Js.Float.toFixed) ++ "%"
|
||||||
| DateTime(r) => r |> MomentRe.Moment.defaultFormat
|
| DateTime(r) => r |> MomentRe.Moment.defaultFormat
|
||||||
| FloatPoint(r) => r |> Js.Float.toFixed
|
| FloatPoint(r) => r |> Js.Float.toFixed
|
||||||
|
@ -78,13 +72,6 @@ module Value = {
|
||||||
| None => "Something went wrong" |> ReasonReact.string
|
| None => "Something went wrong" |> ReasonReact.string
|
||||||
| _ => <div />
|
| _ => <div />
|
||||||
};
|
};
|
||||||
| TimeLimitedDomainCdfLazy(_) => <div />
|
|
||||||
| TimeLimitedDomainCdf(r) =>
|
|
||||||
let cdf: Types.ContinuousDistribution.t =
|
|
||||||
r.limitedDomainCdf.distribution;
|
|
||||||
<>
|
|
||||||
<Chart height=100 data={cdf |> Types.ContinuousDistribution.toJs} />
|
|
||||||
</>;
|
|
||||||
| FloatCdf(_) => <div />
|
| FloatCdf(_) => <div />
|
||||||
| Probability(r) =>
|
| Probability(r) =>
|
||||||
(r *. 100. |> Js.Float.toFixed) ++ "%" |> ReasonReact.string
|
(r *. 100. |> Js.Float.toFixed) ++ "%" |> ReasonReact.string
|
||||||
|
|
145
src/lib/Shape.re
145
src/lib/Shape.re
|
@ -1,10 +1,46 @@
|
||||||
open DistributionTypes;
|
open DistributionTypes;
|
||||||
|
|
||||||
module Continuous = {
|
let _lastElement = (a: array('a)) =>
|
||||||
let fromArrays = (xs, ys): continuousShape => {xs, ys};
|
switch (Belt.Array.size(a)) {
|
||||||
let toJs = (t: continuousShape) => {
|
| 0 => None
|
||||||
|
| n => Belt.Array.get(a, n)
|
||||||
|
};
|
||||||
|
|
||||||
|
module XYShape = {
|
||||||
|
type t = xyShape;
|
||||||
|
|
||||||
|
let toJs = (t: t) => {
|
||||||
{"xs": t.xs, "ys": t.ys};
|
{"xs": t.xs, "ys": t.ys};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let fmap = (t: t, y): t => {xs: t.xs, ys: t.ys |> E.A.fmap(y)};
|
||||||
|
let yFold = (fn, t: t) => {
|
||||||
|
E.A.fold_left(fn, 0., t.ys);
|
||||||
|
};
|
||||||
|
let ySum = yFold((a, b) => a +. b);
|
||||||
|
|
||||||
|
let fromArrays = (xs, ys): t => {xs, ys};
|
||||||
|
|
||||||
|
let transverse = (fn, p: t) => {
|
||||||
|
let (xs, ys) =
|
||||||
|
Belt.Array.zip(p.xs, p.ys)
|
||||||
|
->Belt.Array.reduce([||], (items, (x, y)) =>
|
||||||
|
switch (_lastElement(items)) {
|
||||||
|
| Some((_, yLast)) => [|(x, fn(y, yLast))|]
|
||||||
|
| None => [|(x, y)|]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|> Belt.Array.unzip;
|
||||||
|
fromArrays(xs, ys);
|
||||||
|
};
|
||||||
|
|
||||||
|
let derivative = transverse((aCurrent, aLast) => aCurrent -. aLast);
|
||||||
|
let integral = transverse((aCurrent, aLast) => aCurrent +. aLast);
|
||||||
|
};
|
||||||
|
|
||||||
|
module Continuous = {
|
||||||
|
let fromArrays = XYShape.fromArrays;
|
||||||
|
let toJs = XYShape.toJs;
|
||||||
let toPdf = CdfLibrary.Distribution.toPdf;
|
let toPdf = CdfLibrary.Distribution.toPdf;
|
||||||
let toCdf = CdfLibrary.Distribution.toCdf;
|
let toCdf = CdfLibrary.Distribution.toCdf;
|
||||||
let findX = CdfLibrary.Distribution.findX;
|
let findX = CdfLibrary.Distribution.findX;
|
||||||
|
@ -13,47 +49,14 @@ module Continuous = {
|
||||||
|
|
||||||
module Discrete = {
|
module Discrete = {
|
||||||
type t = discreteShape;
|
type t = discreteShape;
|
||||||
let fromArrays = (xs, ys): discreteShape => {xs, ys};
|
let fromArrays = XYShape.fromArrays;
|
||||||
let _lastElement = (a: array('a)) =>
|
let toJs = XYShape.toJs;
|
||||||
switch (Belt.Array.size(a)) {
|
let ySum = XYShape.ySum;
|
||||||
| 0 => None
|
let zip = t => Belt.Array.zip(t.xs, t.ys);
|
||||||
| n => Belt.Array.get(a, n)
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
fromArrays(xs, ys);
|
|
||||||
};
|
|
||||||
|
|
||||||
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)) => E.A.append(items, [|(x, y +. yLast)|])
|
|
||||||
| None => [|(x, y)|]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|> Belt.Array.unzip;
|
|
||||||
fromArrays(xs, ys);
|
|
||||||
};
|
|
||||||
|
|
||||||
let ySum = (t: t) => {
|
|
||||||
E.A.fold_left((a, b) => a +. b, 0., t.ys);
|
|
||||||
};
|
|
||||||
|
|
||||||
let scaleYToTotal = (totalDesired, t: t): t => {
|
let scaleYToTotal = (totalDesired, t: t): t => {
|
||||||
let currentSum = ySum(t);
|
let difference = totalDesired /. ySum(t);
|
||||||
let difference = totalDesired /. currentSum;
|
XYShape.fmap(t, y => y *. difference);
|
||||||
{xs: t.xs, ys: t.ys |> E.A.fmap(y => y *. difference)};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let render = (t: t) =>
|
let render = (t: t) =>
|
||||||
|
@ -67,6 +70,12 @@ module Discrete = {
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|> ReasonReact.array;
|
|> ReasonReact.array;
|
||||||
|
|
||||||
|
let findY = (x: float, t: t) =>
|
||||||
|
switch (E.A.getBy(zip(t), ((ix, _)) => ix == x)) {
|
||||||
|
| Some((_, y)) => y
|
||||||
|
| None => 0.
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
module Mixed = {
|
module Mixed = {
|
||||||
|
@ -75,56 +84,4 @@ module Mixed = {
|
||||||
discrete,
|
discrete,
|
||||||
discreteProbabilityMassFraction,
|
discreteProbabilityMassFraction,
|
||||||
};
|
};
|
||||||
|
|
||||||
module Builder = {
|
|
||||||
type assumption =
|
|
||||||
| ADDS_TO_1
|
|
||||||
| ADDS_TO_CORRECT_PROBABILITY;
|
|
||||||
type assumptions = {
|
|
||||||
continuous: assumption,
|
|
||||||
discrete: assumption,
|
|
||||||
discreteProbabilityMass: option(float),
|
|
||||||
};
|
|
||||||
let build = (~continuous, ~discrete, ~assumptions) =>
|
|
||||||
switch (assumptions) {
|
|
||||||
| {
|
|
||||||
continuous: ADDS_TO_CORRECT_PROBABILITY,
|
|
||||||
discrete: ADDS_TO_CORRECT_PROBABILITY,
|
|
||||||
discreteProbabilityMass: Some(r),
|
|
||||||
} =>
|
|
||||||
// TODO: Fix this, it's wrong :(
|
|
||||||
Some(
|
|
||||||
make(~continuous, ~discrete, ~discreteProbabilityMassFraction=r),
|
|
||||||
)
|
|
||||||
| {
|
|
||||||
continuous: ADDS_TO_1,
|
|
||||||
discrete: ADDS_TO_1,
|
|
||||||
discreteProbabilityMass: Some(r),
|
|
||||||
} =>
|
|
||||||
Some(
|
|
||||||
make(~continuous, ~discrete, ~discreteProbabilityMassFraction=r),
|
|
||||||
)
|
|
||||||
| {
|
|
||||||
continuous: ADDS_TO_1,
|
|
||||||
discrete: ADDS_TO_1,
|
|
||||||
discreteProbabilityMass: None,
|
|
||||||
} =>
|
|
||||||
None
|
|
||||||
| {
|
|
||||||
continuous: ADDS_TO_CORRECT_PROBABILITY,
|
|
||||||
discrete: ADDS_TO_1,
|
|
||||||
discreteProbabilityMass: None,
|
|
||||||
} =>
|
|
||||||
None
|
|
||||||
| {
|
|
||||||
continuous: ADDS_TO_1,
|
|
||||||
discrete: ADDS_TO_CORRECT_PROBABILITY,
|
|
||||||
discreteProbabilityMass: None,
|
|
||||||
} =>
|
|
||||||
let discreteProbabilityMassFraction = Discrete.ySum(discrete);
|
|
||||||
let discrete = Discrete.scaleYToTotal(1.0, discrete);
|
|
||||||
Some(make(~continuous, ~discrete, ~discreteProbabilityMassFraction));
|
|
||||||
| _ => None
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
|
@ -1,66 +0,0 @@
|
||||||
module ContinuousDistribution = {
|
|
||||||
type t = {
|
|
||||||
xs: array(float),
|
|
||||||
ys: array(float),
|
|
||||||
};
|
|
||||||
|
|
||||||
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 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 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 t = {
|
|
||||||
discrete: DiscreteDistribution.t,
|
|
||||||
continuous: ContinuousDistribution.t,
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -129,15 +129,7 @@ module Model = {
|
||||||
(),
|
(),
|
||||||
);
|
);
|
||||||
Prop.Value.GenericDistribution(genericDistribution);
|
Prop.Value.GenericDistribution(genericDistribution);
|
||||||
| CHANCE_OF_EXISTENCE =>
|
| CHANCE_OF_EXISTENCE => Prop.Value.Probability(0.3)
|
||||||
let lazyDistribution = r =>
|
|
||||||
TimeLimitedDomainCdf.make(
|
|
||||||
~timeVector={zero: currentDateTime, unit: `years},
|
|
||||||
~distribution=r(FloatCdf.logNormal(10., 2.)),
|
|
||||||
~probabilityAtMaxX=0.7,
|
|
||||||
~maxX=`x(200.),
|
|
||||||
);
|
|
||||||
Prop.Value.TimeLimitedDomainCdfLazy(lazyDistribution);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
// ~generationSource=GuesstimatorString(FloatCdf.logNormal(20., 3.)),
|
// ~generationSource=GuesstimatorString(,
|
||||||
module Model = {
|
module Model = {
|
||||||
let make = (currentDateTime: MomentRe.Moment.t) => {
|
let make = (currentDateTime: MomentRe.Moment.t) => {
|
||||||
let genericDistribution =
|
let genericDistribution =
|
||||||
GenericDistribution.make(
|
GenericDistribution.make(
|
||||||
~generationSource=
|
~generationSource=GuesstimatorString(FloatCdf.logNormal(20., 3.)),
|
||||||
GuesstimatorString("mm(floor(10 to 15), 20 to 30, [.5,.5])"),
|
|
||||||
~probabilityType=Cdf,
|
~probabilityType=Cdf,
|
||||||
~domain=RightLimited({xPoint: 200., excludingProbabilityMass: 0.3}),
|
~domain=RightLimited({xPoint: 200., excludingProbabilityMass: 0.3}),
|
||||||
~unit=Time({zero: currentDateTime, unit: `years}),
|
~unit=Time({zero: currentDateTime, unit: `years}),
|
||||||
|
|
|
@ -25,12 +25,12 @@ module Internals = {
|
||||||
external toCombinedFormat: (string, int) => combined = "run";
|
external toCombinedFormat: (string, int) => combined = "run";
|
||||||
|
|
||||||
let toMixedShape = (r: combined): option(DistributionTypes.mixedShape) => {
|
let toMixedShape = (r: combined): option(DistributionTypes.mixedShape) => {
|
||||||
let assumptions: Shape.Mixed.Builder.assumptions = {
|
let assumptions: MixedShapeBuilder.assumptions = {
|
||||||
continuous: ADDS_TO_1,
|
continuous: ADDS_TO_1,
|
||||||
discrete: ADDS_TO_CORRECT_PROBABILITY,
|
discrete: ADDS_TO_CORRECT_PROBABILITY,
|
||||||
discreteProbabilityMass: None,
|
discreteProbabilityMass: None,
|
||||||
};
|
};
|
||||||
Shape.Mixed.Builder.build(
|
MixedShapeBuilder.build(
|
||||||
~continuous=toContinous(r),
|
~continuous=toContinous(r),
|
||||||
~discrete=toDiscrete(r),
|
~discrete=toDiscrete(r),
|
||||||
~assumptions,
|
~assumptions,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user