From f247f65478ed608186a586245ac434176a6b9afe Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 19 Apr 2020 21:04:50 +0100 Subject: [PATCH] Minor cleanup of mean and variance --- __tests__/Distributions__Test.re | 12 +- src/components/charts/DistPlusPlot.re | 148 +++++++++++---------- src/distPlus/distribution/Distributions.re | 62 ++++----- src/distPlus/distribution/XYShape.re | 9 +- 4 files changed, 121 insertions(+), 110 deletions(-) diff --git a/__tests__/Distributions__Test.re b/__tests__/Distributions__Test.re index aed93c8c..d83c1ac2 100644 --- a/__tests__/Distributions__Test.re +++ b/__tests__/Distributions__Test.re @@ -194,10 +194,10 @@ describe("Shape", () => { 0.9, ); makeTest("integralEndY", T.Integral.sum(~cache=None, discrete), 1.0); - makeTest("mean", T.getMean(discrete), 3.9); + makeTest("mean", T.mean(discrete), 3.9); makeTestCloseEquality( "variance", - T.getVariance(discrete), + T.variance(discrete), 5.89, ~digits=7, ); @@ -393,25 +393,25 @@ describe("Shape", () => { makeTestCloseEquality( "Mean of a normal", - T.getMean(normalShape), + T.mean(normalShape), mean, ~digits=2, ); makeTestCloseEquality( "Variance of a normal", - T.getVariance(normalShape), + T.variance(normalShape), variance, ~digits=1, ); makeTestCloseEquality( "Mean of a lognormal", - T.getMean(lognormalShape), + T.mean(lognormalShape), mean, ~digits=2, ); makeTestCloseEquality( "Variance of a lognormal", - T.getVariance(lognormalShape), + T.variance(lognormalShape), variance, ~digits=0, ); diff --git a/src/components/charts/DistPlusPlot.re b/src/components/charts/DistPlusPlot.re index b828eeb6..bfa40434 100644 --- a/src/components/charts/DistPlusPlot.re +++ b/src/components/charts/DistPlusPlot.re @@ -124,73 +124,87 @@ let table = (distPlus, x) => { ; }; let percentiles = distPlus => { - - - - - - - - - - - - - - - - - - - - - - - - - - -
{"1" |> ReasonReact.string} {"5" |> ReasonReact.string} {"25" |> ReasonReact.string} {"50" |> ReasonReact.string} {"75" |> ReasonReact.string} {"95" |> ReasonReact.string} {"99" |> ReasonReact.string}
- {distPlus - |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.01) - |> showFloat} - - {distPlus - |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.05) - |> showFloat} - - {distPlus - |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.25) - |> showFloat} - - {distPlus - |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.5) - |> showFloat} - - {distPlus - |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.75) - |> showFloat} - - {distPlus - |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.95) - |> showFloat} - - {distPlus - |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.99) - |> showFloat} - - {distPlus - |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.999) - |> showFloat} - - {distPlus - |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.9999) - |> showFloat} - - {distPlus - |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.99999) - |> showFloat} -
; +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
{"1" |> ReasonReact.string} {"5" |> ReasonReact.string} {"25" |> ReasonReact.string} {"50" |> ReasonReact.string} {"75" |> ReasonReact.string} {"95" |> ReasonReact.string} {"99" |> ReasonReact.string} {"99.999" |> ReasonReact.string}
+ {distPlus + |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.01) + |> showFloat} + + {distPlus + |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.05) + |> showFloat} + + {distPlus + |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.25) + |> showFloat} + + {distPlus + |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.5) + |> showFloat} + + {distPlus + |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.75) + |> showFloat} + + {distPlus + |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.95) + |> showFloat} + + {distPlus + |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.99) + |> showFloat} + + {distPlus + |> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.99999) + |> showFloat} +
+ + + + + + + + + + + + + + +
{"mean" |> ReasonReact.string} + {"standard deviation" |> ReasonReact.string} + {"variance" |> ReasonReact.string}
+ {distPlus |> Distributions.DistPlus.T.mean |> showFloat} + + {distPlus |> Distributions.DistPlus.T.variance |> showFloat} +
+
; }; let adjustBoth = discreteProbabilityMass => { diff --git a/src/distPlus/distribution/Distributions.re b/src/distPlus/distribution/Distributions.re index a97132d7..2472f2ab 100644 --- a/src/distPlus/distribution/Distributions.re +++ b/src/distPlus/distribution/Distributions.re @@ -18,8 +18,8 @@ module type dist = { let integralXtoY: (~cache: option(integral), float, t) => float; let integralYtoX: (~cache: option(integral), float, t) => float; - let getMean: t => float; - let getVariance: t => float; + let mean: t => float; + let variance: t => float; }; module Dist = (T: dist) => { @@ -38,8 +38,8 @@ module Dist = (T: dist) => { let toDiscrete = T.toDiscrete; let toScaledContinuous = T.toScaledContinuous; let toScaledDiscrete = T.toScaledDiscrete; - let getMean = T.getMean; - let getVariance = T.getVariance; + let mean = T.mean; + let variance = T.variance; // TODO: Move this to each class, have use integral to produce integral in DistPlus class. let scaleBy = (~scale=1.0, t: t) => t |> mapY((r: float) => r *. scale); @@ -141,7 +141,7 @@ module Continuous = { let toScaledContinuous = t => Some(t); let toScaledDiscrete = _ => None; - let getMean = (t: t) => { + let mean = (t: t) => { let indefiniteIntegralStepwise = (p, h1) => h1 *. p ** 2.0 /. 2.0; let indefiniteIntegralLinear = (p, a, b) => a *. p ** 2.0 /. 2.0 +. b *. p ** 3.0 /. 3.0; @@ -151,10 +151,10 @@ module Continuous = { t, ); }; - let getVariance = (t: t): float => + let variance = (t: t): float => XYShape.Analysis.getVarianceDangerously( t, - getMean, + mean, XYShape.Analysis.getMeanOfSquaresContinuousShape, ); }); @@ -229,12 +229,12 @@ module Discrete = { |> Continuous.getShape |> XYShape.YtoX.linear(f); - let getMean = (t: t): float => + let mean = (t: t): float => E.A.reducei(t.xs, 0.0, (acc, x, i) => acc +. x *. t.ys[i]); - let getVariance = (t: t): float => { + let variance = (t: t): float => { let getMeanOfSquares = t => - getMean(XYShape.Analysis.squareXYShape(t)); - XYShape.Analysis.getVarianceDangerously(t, getMean, getMeanOfSquares); + mean(XYShape.Analysis.squareXYShape(t)); + XYShape.Analysis.getVarianceDangerously(t, mean, getMeanOfSquares); }; }); }; @@ -408,36 +408,36 @@ module Mixed = { }; }; - let getMean = (t: t): float => { + let mean = (t: t): float => { let discreteProbabilityMassFraction = t.discreteProbabilityMassFraction; switch (discreteProbabilityMassFraction) { - | 1.0 => Discrete.T.getMean(t.discrete) - | 0.0 => Continuous.T.getMean(t.continuous) + | 1.0 => Discrete.T.mean(t.discrete) + | 0.0 => Continuous.T.mean(t.continuous) | _ => - Discrete.T.getMean(t.discrete) + Discrete.T.mean(t.discrete) *. discreteProbabilityMassFraction - +. Continuous.T.getMean(t.continuous) + +. Continuous.T.mean(t.continuous) *. (1.0 -. discreteProbabilityMassFraction) }; }; - let getVariance = (t: t): float => { + let variance = (t: t): float => { let discreteProbabilityMassFraction = t.discreteProbabilityMassFraction; let getMeanOfSquares = (t: t) => { - Discrete.T.getMean(XYShape.Analysis.squareXYShape(t.discrete)) + Discrete.T.mean(XYShape.Analysis.squareXYShape(t.discrete)) *. t.discreteProbabilityMassFraction +. XYShape.Analysis.getMeanOfSquaresContinuousShape(t.continuous) *. (1.0 -. t.discreteProbabilityMassFraction); }; switch (discreteProbabilityMassFraction) { - | 1.0 => Discrete.T.getVariance(t.discrete) - | 0.0 => Continuous.T.getVariance(t.continuous) + | 1.0 => Discrete.T.variance(t.discrete) + | 0.0 => Continuous.T.variance(t.continuous) | _ => XYShape.Analysis.getVarianceDangerously( t, - getMean, + mean, getMeanOfSquares, ) }; @@ -547,18 +547,18 @@ module Shape = { Continuous.T.mapY(fn), )); - let getMean = (t: t): float => + let mean = (t: t): float => switch (t) { - | Mixed(m) => Mixed.T.getMean(m) - | Discrete(m) => Discrete.T.getMean(m) - | Continuous(m) => Continuous.T.getMean(m) + | Mixed(m) => Mixed.T.mean(m) + | Discrete(m) => Discrete.T.mean(m) + | Continuous(m) => Continuous.T.mean(m) }; - let getVariance = (t: t): float => + let variance = (t: t): float => switch (t) { - | Mixed(m) => Mixed.T.getVariance(m) - | Discrete(m) => Discrete.T.getVariance(m) - | Continuous(m) => Continuous.T.getVariance(m) + | Mixed(m) => Mixed.T.variance(m) + | Discrete(m) => Discrete.T.variance(m) + | Continuous(m) => Continuous.T.variance(m) }; }); }; @@ -674,8 +674,8 @@ module DistPlus = { let integralYtoX = (~cache as _, f, t: t) => { Shape.T.Integral.yToX(~cache=Some(t.integralCache), f, toShape(t)); }; - let getMean = (t: t) => Shape.T.getMean(t.shape); - let getVariance = (t: t) => Shape.T.getVariance(t.shape); + let mean = (t: t) => Shape.T.mean(t.shape); + let variance = (t: t) => Shape.T.variance(t.shape); }); }; diff --git a/src/distPlus/distribution/XYShape.re b/src/distPlus/distribution/XYShape.re index 9ec5a2b2..aeed1bae 100644 --- a/src/distPlus/distribution/XYShape.re +++ b/src/distPlus/distribution/XYShape.re @@ -347,14 +347,11 @@ module Analysis = { }; let getVarianceDangerously = - (t: 't, getMean: 't => float, getMeanOfSquares: 't => float): float => { - let meanSquared = getMean(t) ** 2.0; + (t: 't, mean: 't => float, getMeanOfSquares: 't => float): float => { + let meanSquared = mean(t) ** 2.0; let meanOfSquares = getMeanOfSquares(t); meanOfSquares -. meanSquared; }; - let squareXYShape = (t): DistTypes.xyShape => { - ...t, - xs: E.A.fmap(x => x ** 2.0, t.xs), - }; + let squareXYShape = T.mapX(x => x ** 2.0) }; \ No newline at end of file