From 49b78ae814eff5d7e5eff9629f7d94f474e05261 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Wed, 18 Mar 2020 20:50:01 +0000 Subject: [PATCH] Added smarter truncator --- src/components/DistBuilder.re | 4 ++-- src/distributions/DistPlusIngredients.re | 7 +++++-- src/distributions/Distributions.re | 20 ++++++++++++++------ src/distributions/XYShape.re | 7 +++++++ src/utility/Guesstimator.re | 9 --------- 5 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/components/DistBuilder.re b/src/components/DistBuilder.re index abc02f74..bfcbcb51 100644 --- a/src/components/DistBuilder.re +++ b/src/components/DistBuilder.re @@ -151,7 +151,7 @@ let make = () => { ~schema, ~onSubmit=({state}) => {None}, ~initialState={ - guesstimatorString: "mm(40 to 80, floor(50 to 80), [.5,.5])", + guesstimatorString: "40 to 8000", domainType: "Complete", xPoint: "50.0", xPoint2: "60.0", @@ -162,7 +162,7 @@ let make = () => { unit: "days", sampleCount: "10000", outputXYPoints: "500", - truncateTo: "0", + truncateTo: "100", kernelWidth: "5", }, (), diff --git a/src/distributions/DistPlusIngredients.re b/src/distributions/DistPlusIngredients.re index c2a8b882..86fd10f3 100644 --- a/src/distributions/DistPlusIngredients.re +++ b/src/distributions/DistPlusIngredients.re @@ -23,7 +23,6 @@ let toDistPlus = ~sampleCount, ~outputXYPoints, ~kernelWidth, - ~truncateTo, (), ); let distPlus = @@ -40,5 +39,9 @@ let toDistPlus = |> E.O.fmap( Distributions.DistPlus.T.scaleToIntegralSum(~intendedSum=1.0), ); - distPlus; + switch (truncateTo, distPlus) { + | (Some(t), Some(d)) => Some(d |> Distributions.DistPlus.T.truncate(t)) + | (None, Some(d)) => Some(d) + | _ => None + }; }; \ No newline at end of file diff --git a/src/distributions/Distributions.re b/src/distributions/Distributions.re index e044bb8f..be95b200 100644 --- a/src/distributions/Distributions.re +++ b/src/distributions/Distributions.re @@ -16,10 +16,10 @@ let max = (f1: option(float), f2: option(float)) => module type dist = { type t; + type integral; let minX: t => option(float); let maxX: t => option(float); let pointwiseFmap: (float => float, t) => t; - let truncate: (int, t) => t; let xToY: (float, t) => DistTypes.mixedPoint; let toShape: t => DistTypes.shape; let toContinuous: t => option(DistTypes.continuousShape); @@ -27,8 +27,8 @@ module type dist = { let toScaledContinuous: t => option(DistTypes.continuousShape); let toScaledDiscrete: t => option(DistTypes.discreteShape); let toDiscreteProbabilityMass: t => float; + let truncate: (~cache: option(integral)=?, int, t) => t; - type integral; let integral: (~cache: option(integral), t) => integral; let integralEndY: (~cache: option(integral), t) => float; let integralXtoY: (~cache: option(integral), float, t) => float; @@ -112,7 +112,6 @@ module Continuous = { let toDiscreteProbabilityMass = _ => 0.0; let pointwiseFmap = (fn, t: t) => t |> xyShape |> XYShape.T.pointwiseMap(fn) |> fromShape; - let truncate = i => shapeMap(XYShape.T.convertToNewLength(i)); let toShape = (t: t): DistTypes.shape => Continuous(t); let xToY = (f, {interpolation, xyShape}: t) => switch (interpolation) { @@ -144,6 +143,14 @@ module Continuous = { |> E.O.toExt("This should not have happened") |> fromShape }; + let truncate = (~cache=None, i, t) => + t + |> shapeMap( + XYShape.T.convertToNewLengthByProbabilityMass( + i, + integral(~cache, t).xyShape, + ), + ); let integralEndY = (~cache, t) => t |> integral(~cache) |> lastY; let integralXtoY = (~cache, f, t) => t |> integral(~cache) |> shapeFn(XYShape.T.findY(f)); @@ -185,7 +192,7 @@ module Discrete = { let toDiscrete = t => Some(t); let toScaledContinuous = _ => None; let toScaledDiscrete = t => Some(t); - let truncate = (i, t: t): DistTypes.discreteShape => + let truncate = (~cache=None, i, t: t): DistTypes.discreteShape => t |> XYShape.T.zip |> XYShape.T.Zipped.sortByY @@ -267,6 +274,7 @@ module Mixed = { let truncate = ( + ~cache=None, count, {discrete, continuous, discreteProbabilityMassFraction} as t: t, ) @@ -414,7 +422,7 @@ module Shape = { ), ); - let truncate = (i, t: t) => + let truncate = (~cache=None, i, t: t) => fmap( t, ( @@ -603,7 +611,7 @@ module DistPlus = { let integral = (~cache, t: t) => updateShape(Continuous(t.integralCache), t); - let truncate = (i, t) => + let truncate = (~cache=None, i, t) => updateShape(t |> toShape |> Shape.T.truncate(i), t); // todo: adjust for limit, maybe? let pointwiseFmap = (fn, {shape, _} as t: t): t => diff --git a/src/distributions/XYShape.re b/src/distributions/XYShape.re index 6198617d..7cc80525 100644 --- a/src/distributions/XYShape.re +++ b/src/distributions/XYShape.re @@ -112,6 +112,13 @@ module T = { ); }; + let convertToNewLengthByProbabilityMass = + (newLength: int, integral: t, t: t): DistTypes.xyShape => { + Functions.range(0.0, 1.0, newLength) + |> E.A.fmap(findX(_, integral)) + |> convertWithAlternativeXs(_, t); + }; + module XtoY = { let stepwiseIncremental = (f, t: t) => firstPairAtOrBeforeValue(f, t) |> E.O.fmap(((_, y)) => y); diff --git a/src/utility/Guesstimator.re b/src/utility/Guesstimator.re index 02e45353..168810eb 100644 --- a/src/utility/Guesstimator.re +++ b/src/utility/Guesstimator.re @@ -184,11 +184,9 @@ let toMixed = ~sampleCount=3000, ~outputXYPoints=3000, ~kernelWidth=10, - ~truncateTo=Some(500), ~cuttoff=0.995, (), ) => { - // let truncateTo = None; let start = Js.Date.now(); let timeMessage = message => Js.log2(message, Js.Date.now() -. start); timeMessage("Starting"); @@ -215,12 +213,5 @@ let toMixed = let continuous = pdf |> Distributions.Continuous.fromShape; let shape = MixedShapeBuilder.buildSimple(~continuous, ~discrete); timeMessage("Finished shape"); - let shape = - switch (truncateTo, shape) { - | (Some(trunctate), Some(shape)) => - Some(shape |> Distributions.Shape.T.truncate(trunctate)) - | (None, Some(shape)) => Some(shape) - | _ => None - }; shape; }; \ No newline at end of file