From 9e5561a7b8c523586418689fc32cd2ae13f659cd Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Tue, 18 Feb 2020 13:23:02 +0000 Subject: [PATCH] Beginning of massWithin functionality --- showcase/entries/Continuous.re | 9 ++--- .../charts/GenericDistributionChart.re | 3 +- src/core/GenericDistribution.re | 15 +++++++- src/core/Shape.re | 34 +++++++++++++++++++ src/models/EAFunds.re | 2 ++ src/utility/GuesstimatorLibrary.js | 4 +-- 6 files changed, 59 insertions(+), 8 deletions(-) diff --git a/showcase/entries/Continuous.re b/showcase/entries/Continuous.re index 832d6789..d2546cbf 100644 --- a/showcase/entries/Continuous.re +++ b/showcase/entries/Continuous.re @@ -7,13 +7,14 @@ let data: DistributionTypes.xyShape = { let mixedDist = GenericDistribution.make( - ~generationSource=GuesstimatorString("mm(3, normal(5,1), [.5,.5])"), + ~generationSource= + GuesstimatorString("mm(uniform(10,12), normal(5,1), [.5,.5])"), ~probabilityType=Pdf, ~domain=Complete, ~unit=Unspecified, (), ) - |> GenericDistribution.renderIfNeeded(~sampleCount=3000); + |> GenericDistribution.renderIfNeeded(~sampleCount=1000); let timeDist = GenericDistribution.make( @@ -23,7 +24,7 @@ let timeDist = ~unit=Time({zero: MomentRe.momentNow(), unit: `years}), (), ) - |> GenericDistribution.renderIfNeeded(~sampleCount=3000); + |> GenericDistribution.renderIfNeeded(~sampleCount=1000); let domainLimitedDist = GenericDistribution.make( @@ -33,7 +34,7 @@ let domainLimitedDist = ~unit=Unspecified, (), ) - |> GenericDistribution.renderIfNeeded(~sampleCount=3000); + |> GenericDistribution.renderIfNeeded(~sampleCount=1000); let distributions = () =>
diff --git a/src/components/charts/GenericDistributionChart.re b/src/components/charts/GenericDistributionChart.re index c7d2fa85..ba705b81 100644 --- a/src/components/charts/GenericDistributionChart.re +++ b/src/components/charts/GenericDistributionChart.re @@ -61,7 +61,8 @@ let make = (~dist) => { ), }) =>
- Shape.Continuous.toPdf} /> + + Shape.XYShape.integral} /> {d |> Shape.Discrete.scaleYToTotal(f) |> Shape.Discrete.render}
| _ =>
diff --git a/src/core/GenericDistribution.re b/src/core/GenericDistribution.re index 515382e6..0bc74c30 100644 --- a/src/core/GenericDistribution.re +++ b/src/core/GenericDistribution.re @@ -31,4 +31,17 @@ let renderIfNeeded = ); | Shape(_) => Some(t) }; -}; \ No newline at end of file +} /* }*/; + +// let getTimeY = +// (t: genericDistribution, point: TimeTypes.RelativeTimePoint.timeInVector) => { +// switch (t) { +// | { +// generationSource: Shape(shape), +// probabilityType: Pdf, +// unit: Time(timeVector), +// } => +// TimeTypes.RelativeTimePoint.toXValue(timeVector, point) +// |> E.O.fmap(x => Shape.Mixed.getY(t, x)) +// | _ => 2.0 +// }; \ No newline at end of file diff --git a/src/core/Shape.re b/src/core/Shape.re index 7d0ebe06..e2df2f5f 100644 --- a/src/core/Shape.re +++ b/src/core/Shape.re @@ -6,6 +6,10 @@ let _lastElement = (a: array('a)) => | n => Belt.Array.get(a, n - 1) }; +type pointInRange = + | Unbounded + | X(float); + module XYShape = { type t = xyShape; @@ -37,8 +41,19 @@ module XYShape = { fromArrays(xs, ys); }; + let getY = (t: t, x: float) => x; + let integral = transverse((aCurrent, aLast) => aCurrent +. aLast); let derivative = transverse((aCurrent, aLast) => aCurrent -. aLast); + + let massWithin = (t: t, left: pointInRange, right: pointInRange) => { + switch (left, right) { + | (Unbounded, Unbounded) => t |> ySum + | (Unbounded, X(f)) => t |> integral |> getY(_, f) + | (X(f), Unbounded) => ySum(t) -. getY(integral(t), f) + | (X(l), X(r)) => getY(integral(t), r) -. getY(integral(t), l) + }; + }; }; module Continuous = { @@ -99,6 +114,25 @@ module Mixed = { }; }; +module Any = { + type t = DistributionTypes.pointsType; + + let x = (t: t, x: float) => + switch (t) { + | Mixed(m) => `mixed(Mixed.getY(m, x)) + | Discrete(discreteShape) => `discrete(Discrete.findY(x, discreteShape)) + | Continuous(continuousShape) => + `continuous(Continuous.findY(x, continuousShape)) + }; + + let massInRange = (t: t, left: pointInRange, right: pointInRange) => + switch (t) { + | Mixed(m) => 3.0 + | Discrete(discreteShape) => 2.0 + | Continuous(continuousShape) => 3.0 + }; +}; + module DomainMixed = { type t = { mixedShape, diff --git a/src/models/EAFunds.re b/src/models/EAFunds.re index f498fb32..d90ca05d 100644 --- a/src/models/EAFunds.re +++ b/src/models/EAFunds.re @@ -126,12 +126,14 @@ module Model = { currentDateTime, yearlyMeanGrowthRateIfNotClosed(group), ); + let str = switch (xRisk) { | Some({truthValue: true}) => "0" | Some({truthValue: false}) => difference | None => "uniform(0,1) > .3 ? " ++ difference ++ ": 0" }; + let genericDistribution = GenericDistribution.make( ~generationSource=GuesstimatorString(str), diff --git a/src/utility/GuesstimatorLibrary.js b/src/utility/GuesstimatorLibrary.js index 7037dc46..80afdc8d 100644 --- a/src/utility/GuesstimatorLibrary.js +++ b/src/utility/GuesstimatorLibrary.js @@ -48,8 +48,8 @@ const toPdf = (values, sampleCount, min, max) => { const ratioSize$ = ratioSize(samples); const width = ratioSize$ === 'SMALL' ? 20 : 1; - const cdf = samples.toCdf({ size: sampleCount, width, min, max }); - continuous = cdf; + const pdf = samples.toPdf({ size: sampleCount, width, min, max }); + continuous = pdf; } return {continuous, discrete}; };