From 8c625a680303e633f144136f3d3788bc421b2a12 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Mon, 24 Feb 2020 21:01:29 +0000 Subject: [PATCH] Desparately trying to work for many conditions --- __tests__/Foo/Foo__Test.re | 114 ++++++++++++++++-- showcase/entries/Continuous.re | 12 +- src/components/charts/DistPlusPlot.re | 7 ++ .../charts/DistributionPlot/distPlotD3.js | 2 +- src/distributions/DistPlusIngredients.re | 31 +++-- src/distributions/DistTypes.re | 2 +- src/distributions/Distributions.re | 70 ++++++----- src/distributions/MixedShapeBuilder.re | 23 ++++ src/distributions/XYShape.re | 39 ++++-- src/models/EAFunds.re | 4 +- src/utility/CdfLibrary.js | 13 ++ src/utility/CdfLibrary.re | 9 ++ src/utility/Guesstimator.re | 31 ++--- src/utility/GuesstimatorLibrary.js | 8 +- 14 files changed, 270 insertions(+), 95 deletions(-) diff --git a/__tests__/Foo/Foo__Test.re b/__tests__/Foo/Foo__Test.re index c613d9db..2ed71572 100644 --- a/__tests__/Foo/Foo__Test.re +++ b/__tests__/Foo/Foo__Test.re @@ -3,10 +3,14 @@ open Expect; let shape: DistTypes.xyShape = {xs: [|1., 4., 8.|], ys: [|8., 9., 2.|]}; -let makeTest = (str, item1, item2) => - test(str, () => - expect(item1) |> toEqual(item2) - ); +let makeTest = (~only=false, str, item1, item2) => + only + ? Only.test(str, () => + expect(item1) |> toEqual(item2) + ) + : test(str, () => + expect(item1) |> toEqual(item2) + ); describe("Shape", () => { describe("Continuous", () => { @@ -77,12 +81,20 @@ describe("Shape", () => { { let continuous = make({xs: [|1., 4., 8.|], ys: [|0.1, 5., 1.0|]}, `Stepwise); - continuous |> toLinear |> getShape; + continuous |> toLinear |> E.O.fmap(getShape); }, + Some({ + xs: [|1.00007, 1.00007, 4.0, 4.00007, 8.0, 8.00007|], + ys: [|0.0, 0.1, 0.1, 5.0, 5.0, 1.0|], + }), + ); + makeTest( + "toLinear", { - xs: [|1.00007, 4.0, 4.00007, 8.0, 8.00007|], - ys: [|0.1, 0.1, 5.0, 5.0, 1.0|], + let continuous = make({xs: [|0.0|], ys: [|0.3|]}, `Stepwise); + continuous |> toLinear |> E.O.fmap(getShape); }, + Some({xs: [|0.0|], ys: [|0.3|]}), ); makeTest( "integralXToY", @@ -99,7 +111,13 @@ describe("Shape", () => { T.Integral.xToY(~cache=None, 100.0, continuous), 47.5, ); - makeTest("integralSum", T.Integral.sum(~cache=None, continuous), 47.5); + makeTest( + "integralEndY", + continuous + |> T.scaleToIntegralSum(~intendedSum=1.0) + |> T.Integral.sum(~cache=None), + 1.0, + ); }); describe("Discrete", () => { @@ -166,7 +184,7 @@ describe("Shape", () => { T.Integral.xToY(~cache=None, 6.0, discrete), 0.9, ); - makeTest("integralSum", T.Integral.sum(~cache=None, discrete), 1.0); + makeTest("integralEndY", T.Integral.sum(~cache=None, discrete), 1.0); }); describe("Mixed", () => { @@ -229,6 +247,7 @@ describe("Shape", () => { T.xToY(7., mixed), {discrete: 0.0, continuous: 0.04095904095904096}, ); + makeTest("integralEndY", T.Integral.sum(~cache=None, mixed), 1.0); makeTest( "scaleBy", T.scaleBy(~scale=2.0, mixed), @@ -254,9 +273,10 @@ describe("Shape", () => { T.Integral.get(~cache=None, mixed), Distributions.Continuous.make( { - xs: [|1.00007, 3., 4., 4.00007, 7., 8., 8.00007, 14.|], + xs: [|1.00007, 1.00007, 3., 4., 4.00007, 7., 8., 8.00007, 14.|], ys: [| - 0.15, + 0.0, + 0.0, 0.15, 0.18496503496503497, 0.4349674825174825, @@ -270,4 +290,76 @@ describe("Shape", () => { ), ); }); + + describe("Mixed", () => { + open Distributions.DistPlus; + let discrete: DistTypes.xyShape = { + xs: [|1., 4., 8.|], + ys: [|0.3, 0.5, 0.2|], + }; + let continuous = + Distributions.Continuous.make( + {xs: [|3., 7., 14.|], ys: [|0.058, 0.082, 0.124|]}, + `Linear, + ) + |> Distributions.Continuous.T.scaleToIntegralSum(~intendedSum=1.0); + let mixed = + MixedShapeBuilder.build( + ~continuous, + ~discrete, + ~assumptions={ + continuous: ADDS_TO_CORRECT_PROBABILITY, + discrete: ADDS_TO_CORRECT_PROBABILITY, + discreteProbabilityMass: Some(0.5), + }, + ) + |> E.O.toExn(""); + let distPlus = + Distributions.DistPlus.make( + ~shape=Mixed(mixed), + ~guesstimatorString=None, + (), + ); + makeTest("minX", T.minX(distPlus), Some(1.0)); + makeTest("maxX", T.maxX(distPlus), Some(14.0)); + makeTest( + "xToY at 4.0", + T.xToY(4., distPlus), + {discrete: 0.25, continuous: 0.03196803196803197}, + ); + makeTest( + "xToY at 0.0", + T.xToY(0., distPlus), + {discrete: 0.0, continuous: 0.028971028971028972}, + ); + makeTest( + "xToY at 5.0", + T.xToY(7., distPlus), + {discrete: 0.0, continuous: 0.04095904095904096}, + ); + makeTest("integralEndY", T.Integral.sum(~cache=None, distPlus), 1.0); + makeTest( + "integral", + T.Integral.get(~cache=None, distPlus) |> T.toContinuous, + Some( + Distributions.Continuous.make( + { + xs: [|1.00007, 1.00007, 3., 4., 4.00007, 7., 8., 8.00007, 14.|], + ys: [| + 0.0, + 0.0, + 0.15, + 0.18496503496503497, + 0.4349674825174825, + 0.5398601398601399, + 0.5913086913086913, + 0.6913122927072927, + 1.0, + |], + }, + `Linear, + ), + ), + ); + }); }); \ No newline at end of file diff --git a/showcase/entries/Continuous.re b/showcase/entries/Continuous.re index 585d258c..1f2adebf 100644 --- a/showcase/entries/Continuous.re +++ b/showcase/entries/Continuous.re @@ -1,12 +1,18 @@ // "mm(floor(uniform(30,35)), normal(50,20), [.25,.5])", +// "mm(floor(normal(28,4)), normal(32,2), uniform(20,24), [.5,.2,.1])", +let timeVector: TimeTypes.timeVector = { + zero: MomentRe.momentNow(), + unit: `years, +}; + let timeDist = DistPlusIngredients.make( - ~guesstimatorString="mm(floor(normal(30,2)), normal(39,1), [.5,.5])", + ~guesstimatorString="mm(floor(10 to 15), 10 to 11, [.9,.1])", ~domain=Complete, - ~unit=TimeDistribution({zero: MomentRe.momentNow(), unit: `days}), + ~unit=DistTypes.TimeDistribution(timeVector), (), ) - |> DistPlusIngredients.toDistPlus(~sampleCount=1000); + |> DistPlusIngredients.toDistPlus(~sampleCount=5000, ~outputXYPoints=1000); let distributions = () =>
diff --git a/src/components/charts/DistPlusPlot.re b/src/components/charts/DistPlusPlot.re index d6f9d820..87a3ade8 100644 --- a/src/components/charts/DistPlusPlot.re +++ b/src/components/charts/DistPlusPlot.re @@ -103,9 +103,16 @@ let make = (~distPlus: DistTypes.distPlus) => { |> E.Float.with2DigitsPrecision |> ReasonReact.string} + + {distPlus + |> Distributions.DistPlus.T.Integral.sum(~cache=None) + |> E.Float.with2DigitsPrecision + |> ReasonReact.string} +
; + // chart }; \ No newline at end of file diff --git a/src/components/charts/DistributionPlot/distPlotD3.js b/src/components/charts/DistributionPlot/distPlotD3.js index d737753a..151f79ff 100644 --- a/src/components/charts/DistributionPlot/distPlotD3.js +++ b/src/components/charts/DistributionPlot/distPlotD3.js @@ -320,7 +320,7 @@ export class CdfChartD3 { function mouseover() { const mouse = d3.mouse(this); hoverLine.attr('opacity', 1).attr('x1', mouse[0]).attr('x2', mouse[0]); - const xValue = xScale.invert(mouse[0]).toFixed(2); + const xValue = xScale.invert(mouse[0]); // This used to be here, but doesn't seem important // const xValue = (mouse[0] > range[0] && mouse[0] < range[1]) ? : 0; context.attrs.onHover(xValue); diff --git a/src/distributions/DistPlusIngredients.re b/src/distributions/DistPlusIngredients.re index 417d8fe4..b08fcda1 100644 --- a/src/distributions/DistPlusIngredients.re +++ b/src/distributions/DistPlusIngredients.re @@ -8,22 +8,27 @@ let make = unit, }; -let toDistPlus = (~sampleCount, t: distPlusIngredients): option(distPlus) => { +let toDistPlus = + (~sampleCount=1000, ~outputXYPoints=1000, t: distPlusIngredients) + : option(distPlus) => { let shape = Guesstimator.stringToMixedShape( ~string=t.guesstimatorString, ~sampleCount, + ~outputXYPoints, (), - ) - |> E.O.bind(_, Distributions.Mixed.clean); - shape - |> E.O.fmap(shape => - Distributions.DistPlus.make( - ~shape, - ~domain=t.domain, - ~unit=t.unit, - ~guesstimatorString=None, - (), - ) - ); + ); + Js.log2("Line 21 with shape:", shape); + let ss = + shape + |> E.O.fmap( + Distributions.DistPlus.make( + ~shape=_, + ~domain=t.domain, + ~unit=t.unit, + ~guesstimatorString=None, + (), + ), + ); + ss; }; \ No newline at end of file diff --git a/src/distributions/DistTypes.re b/src/distributions/DistTypes.re index 35173501..d970a824 100644 --- a/src/distributions/DistTypes.re +++ b/src/distributions/DistTypes.re @@ -80,7 +80,7 @@ module DistributionUnit = { module Domain = { let excludedProbabilityMass = (t: domain) => { switch (t) { - | Complete => 1.0 + | Complete => 0.0 | LeftLimited({excludingProbabilityMass}) => excludingProbabilityMass | RightLimited({excludingProbabilityMass}) => excludingProbabilityMass | LeftAndRightLimited( diff --git a/src/distributions/Distributions.re b/src/distributions/Distributions.re index ab9d6c6e..560d5597 100644 --- a/src/distributions/Distributions.re +++ b/src/distributions/Distributions.re @@ -28,7 +28,7 @@ module type dist = { type integral; let integral: (~cache: option(integral), t) => integral; - let integralSum: (~cache: option(integral), t) => float; + let integralEndY: (~cache: option(integral), t) => float; let integralXtoY: (~cache: option(integral), float, t) => float; }; @@ -37,6 +37,11 @@ module Dist = (T: dist) => { type integral = T.integral; let minX = T.minX; let maxX = T.maxX; + let xTotalRange = (t: t) => + switch (minX(t), maxX(t)) { + | (Some(min), Some(max)) => Some(max -. min) + | _ => None + }; let pointwiseFmap = T.pointwiseFmap; let xToY = T.xToY; let toShape = T.toShape; @@ -51,7 +56,7 @@ module Dist = (T: dist) => { type t = T.integral; let get = T.integral; let xToY = T.integralXtoY; - let sum = T.integralSum; + let sum = T.integralEndY; }; // This is suboptimal because it could get the cache but doesn't here. @@ -78,20 +83,24 @@ module Continuous = { (fn, {xyShape, interpolation}: t): option(DistTypes.continuousShape) => fn(xyShape) |> E.O.fmap(make(_, interpolation)); - let toLinear = (t: t): t => + let toLinear = (t: t): option(t) => { switch (t) { - | {interpolation: `Stepwise, xyShape} => { - interpolation: `Linear, - xyShape: xyShape |> XYShape.Range.stepsToContinuous |> E.O.toExt(""), - } - | {interpolation: `Linear, _} => t + | {interpolation: `Stepwise, xyShape} => + xyShape + |> XYShape.Range.stepsToContinuous + |> E.O.fmap(xyShape => make(xyShape, `Linear)) + | {interpolation: `Linear, _} => Some(t) }; + }; + let shapeFn = (fn, t: t) => t |> xyShape |> fn; + + let convertToNewLength = i => + shapeMap(CdfLibrary.Distribution.convertToNewLength(i)); module T = Dist({ type t = DistTypes.continuousShape; type integral = DistTypes.continuousShape; - let shapeFn = (fn, t: t) => t |> xyShape |> fn; let minX = shapeFn(XYShape.minX); let maxX = shapeFn(XYShape.maxX); let pointwiseFmap = (fn, t: t) => @@ -126,7 +135,7 @@ module Continuous = { |> E.O.toExt("This should not have happened") |> fromShape, ); - let integralSum = (~cache, t) => t |> integral(~cache) |> lastY; + let integralEndY = (~cache, t) => t |> integral(~cache) |> lastY; let integralXtoY = (~cache, f, t) => t |> integral(~cache) |> shapeFn(CdfLibrary.Distribution.findY(f)); let toContinuous = t => Some(t); @@ -144,7 +153,7 @@ module Discrete = { let integral = (~cache, t) => cache |> E.O.default(Continuous.make(XYShape.accumulateYs(t), `Stepwise)); - let integralSum = (~cache, t) => + let integralEndY = (~cache, t) => t |> integral(~cache) |> Continuous.lastY; let minX = XYShape.minX; let maxX = XYShape.maxX; @@ -186,8 +195,6 @@ module Mixed = { discrete: {xs: [||], ys: [||]}, } => None - | {continuous, discrete: {xs: [|_|], ys: [|_|]}} => - Some(Continuous(continuous)) | {continuous, discrete: {xs: [||], ys: [||]}} => Some(Continuous(continuous)) | {continuous: {xyShape: {xs: [||], ys: [||]}}, discrete} => @@ -241,7 +248,6 @@ module Mixed = { let toScaledDiscrete = ({discrete} as t: t) => Some(scaleDiscrete(t, discrete)); - // TODO: Add these two directly, once interpolation is added. let integral = ( ~cache, @@ -258,6 +264,7 @@ module Mixed = { discrete |> Discrete.T.Integral.get(~cache=None) |> Continuous.toLinear + |> E.O.toExn("") |> Continuous.T.scaleBy( ~scale=discreteProbabilityMassFraction, ); @@ -274,17 +281,8 @@ module Mixed = { ); }; - // todo: Get last element of actual sum. - let integralSum = (~cache, {discrete, continuous} as t: t) => { - switch (cache) { - | Some(cache) => 3.0 - | None => - scaleDiscreteFn(t, Discrete.T.Integral.sum(~cache=None, discrete)) - +. scaleContinuousFn( - t, - Continuous.T.Integral.sum(~cache=None, continuous), - ) - }; + let integralEndY = (~cache, t: t) => { + integral(~cache, t) |> Continuous.lastY; }; let integralXtoY = (~cache, f, {discrete, continuous} as t: t) => { @@ -381,7 +379,7 @@ module Shape = { ), ); }; - let integralSum = (~cache, t: t) => + let integralEndY = (~cache, t: t) => mapToAll( t, ( @@ -419,6 +417,7 @@ module DistPlus = { type t = DistTypes.distPlus; + let shapeIntegral = shape => Shape.T.Integral.get(~cache=None, shape); let make = ( ~shape, @@ -428,7 +427,7 @@ module DistPlus = { (), ) : t => { - let integral = Shape.T.Integral.get(~cache=None, shape); + let integral = shapeIntegral(shape); {shape, domain, integralCache: integral, unit, guesstimatorString}; }; @@ -448,6 +447,11 @@ module DistPlus = { guesstimatorString: E.O.default(t.guesstimatorString, guesstimatorString), }; + let updateShape = (shape, t) => { + let integralCache = shapeIntegral(shape); + update(~shape, ~integralCache, t); + }; + let domainIncludedProbabilityMass = (t: t) => Domain.includedProbabilityMass(t.domain); @@ -499,15 +503,15 @@ module DistPlus = { let maxX = shapeFn(Shape.T.maxX); let fromShape = (t, shape): t => update(~shape, t); - // todo: adjust for limit, maybe? - let pointwiseFmap = (fn, {shape, _} as t: t): t => - Shape.T.pointwiseFmap(fn, shape) |> fromShape(t); - // This bit is kind of akward, could probably use rethinking. let integral = (~cache as _, t: t) => - fromShape(t, Continuous(t.integralCache)); + updateShape(Continuous(t.integralCache), t); - let integralSum = (~cache as _, t: t) => + // todo: adjust for limit, maybe? + let pointwiseFmap = (fn, {shape, _} as t: t): t => + Shape.T.pointwiseFmap(fn, shape) |> updateShape(_, t); + + let integralEndY = (~cache as _, t: t) => Shape.T.Integral.sum(~cache=Some(t.integralCache), toShape(t)); // TODO: Fix this below, obviously. Adjust for limits diff --git a/src/distributions/MixedShapeBuilder.re b/src/distributions/MixedShapeBuilder.re index 93aea436..cd4e4ca3 100644 --- a/src/distributions/MixedShapeBuilder.re +++ b/src/distributions/MixedShapeBuilder.re @@ -8,6 +8,29 @@ type assumptions = { discreteProbabilityMass: option(float), }; +let buildSimple = (~continuous, ~discrete): option(DistTypes.shape) => { + let cLength = + continuous |> Distributions.Continuous.getShape |> XYShape.xs |> E.A.length; + let dLength = discrete |> XYShape.xs |> E.A.length; + switch (cLength, dLength) { + | (0 | 1, 0) => None + | (0 | 1, _) => Some(Discrete(discrete)) + | (_, 0) => Some(Continuous(continuous)) + | (_, _) => + let discreteProbabilityMassFraction = + Distributions.Discrete.T.Integral.sum(~cache=None, discrete); + let discrete = + Distributions.Discrete.T.scaleToIntegralSum(~intendedSum=1.0, discrete); + let foobar = + Distributions.Mixed.make( + ~continuous, + ~discrete, + ~discreteProbabilityMassFraction, + ) + |> Distributions.Mixed.clean; + foobar; + }; +}; let build = (~continuous, ~discrete, ~assumptions) => switch (assumptions) { | { diff --git a/src/distributions/XYShape.re b/src/distributions/XYShape.re index 0eb6fcfa..0721086d 100644 --- a/src/distributions/XYShape.re +++ b/src/distributions/XYShape.re @@ -47,8 +47,9 @@ module XtoY = { let stepwiseIncremental = (f, t: t) => firstPairAtOrBeforeValue(f, t) |> E.O.fmap(((_, y)) => y); - let stepwiseIfAtX = (f, t: t) => - getBy(t, ((x, _)) => x == f) |> E.O.fmap(((_, y)) => y); + let stepwiseIfAtX = (f: float, t: t) => { + getBy(t, ((x: float, _)) => {x == f}) |> E.O.fmap(((_, y)) => y); + }; // TODO: When Roman's PR comes in, fix this bit. This depends on interpolation, obviously. let linear = (f, t: t) => t |> CdfLibrary.Distribution.findY(f); @@ -208,16 +209,28 @@ module Range = { // TODO: It would be nicer if this the diff didn't change the first element, and also maybe if there were a more elegant way of doing this. let stepsToContinuous = t => { let diff = xTotalRange(t) |> E.O.fmap(r => r *. 0.00001); - switch (diff, E.A.toRanges(Belt.Array.zip(t.xs, t.ys))) { - | (Some(diff), Ok(items)) => - Some( - items - |> Belt.Array.map(_, rangePointAssumingSteps) - |> Belt.Array.unzip - |> fromArray - |> intersperce(t |> xMap(e => e +. diff)), - ) - | _ => None - }; + let items = + switch (diff, E.A.toRanges(Belt.Array.zip(t.xs, t.ys))) { + | (Some(diff), Ok(items)) => + Some( + items + |> Belt.Array.map(_, rangePointAssumingSteps) + |> Belt.Array.unzip + |> fromArray + |> intersperce(t |> xMap(e => e +. diff)), + ) + | _ => Some(t) + }; + let bar = items |> E.O.fmap(zip) |> E.O.bind(_, E.A.get(_, 0)); + let items = + switch (items, bar) { + | (Some(items), Some((0.0, _))) => Some(items) + | (Some(items), Some((firstX, _))) => + let all = E.A.append([|(firstX, 0.0)|], items |> zip); + let foo = all |> Belt.Array.unzip |> fromArray; + Some(foo); + | _ => None + }; + items; }; }; \ No newline at end of file diff --git a/src/models/EAFunds.re b/src/models/EAFunds.re index d21e6d01..1dd3a3df 100644 --- a/src/models/EAFunds.re +++ b/src/models/EAFunds.re @@ -151,7 +151,8 @@ module Model = { | Some({truthValue: false}) => difference | None => let foo = - getGlobalCatastropheChance(dateTime) + // getGlobalCatastropheChance(dateTime) + Some(0.5) |> E.O.fmap(E.Float.with2DigitsPrecision) |> E.O.fmap((r: string) => "uniform(0,1) > " ++ r ++ " ? " ++ difference ++ ": 0" @@ -177,7 +178,6 @@ module Model = { GuesstimatorDist.logNormal(40., 4.), ), ~domain=RightLimited({xPoint: 100., excludingProbabilityMass: 0.3}), - ~unit=TimeDistribution({zero: currentDateTime, unit: `years}), (), ), ) diff --git a/src/utility/CdfLibrary.js b/src/utility/CdfLibrary.js index ab9134de..ffe63322 100644 --- a/src/utility/CdfLibrary.js +++ b/src/utility/CdfLibrary.js @@ -96,6 +96,18 @@ const { let cdf = new Cdf(xs, ys); return cdf.findY(x); } + + /** + * + * @param x + * @param xs + * @param ys + * @returns {number[]} + */ + function convertToNewLength(n, { xs, ys }) { + let dist = new ContinuousDistribution(xs, ys); + return dist.convertToNewLength(n); + } /** * @@ -153,6 +165,7 @@ const { pdfToCdf, findY, findX, + convertToNewLength, mean, scoreNonMarketCdfCdf, differentialEntropy, diff --git a/src/utility/CdfLibrary.re b/src/utility/CdfLibrary.re index 586c7957..329826d9 100644 --- a/src/utility/CdfLibrary.re +++ b/src/utility/CdfLibrary.re @@ -32,9 +32,18 @@ module JS = { [@bs.module "./CdfLibrary.js"] external differentialEntropy: (int, distJs) => distJs = "differentialEntropy"; + + [@bs.module "./CdfLibrary.js"] + external convertToNewLength: (int, distJs) => distJs = "convertToNewLength"; }; module Distribution = { + let convertToNewLength = (int, {xs, _} as dist: DistTypes.xyShape) => + switch (E.A.length(xs)) { + | 0 + | 1 => dist + | _ => dist |> JS.doAsDist(JS.convertToNewLength(int)) + }; let toPdf = dist => dist |> JS.doAsDist(JS.cdfToPdf); let toCdf = dist => dist |> JS.doAsDist(JS.pdfToCdf); let findX = (y, dist) => dist |> JS.distToJs |> JS.findX(y); diff --git a/src/utility/Guesstimator.re b/src/utility/Guesstimator.re index 0122e80e..9fe403bc 100644 --- a/src/utility/Guesstimator.re +++ b/src/utility/Guesstimator.re @@ -16,6 +16,7 @@ module Internals = { discrete, }; + // todo: Force to be fewer samples let toContinous = (r: combined) => continuousGet(r) |> CdfLibrary.JS.jsToDist @@ -25,22 +26,24 @@ module Internals = { discreteGet(r) |> jsToDistDiscrete; [@bs.module "./GuesstimatorLibrary.js"] - external toCombinedFormat: (string, int) => combined = "run"; + external toCombinedFormat: (string, int, int) => combined = "run"; // todo: Format to correct mass, also normalize the pdf. - let toMixedShape = (r: combined): option(DistTypes.mixedShape) => { - let assumptions: MixedShapeBuilder.assumptions = { - continuous: ADDS_TO_1, - discrete: ADDS_TO_CORRECT_PROBABILITY, - discreteProbabilityMass: None, - }; - MixedShapeBuilder.build( - ~continuous=toContinous(r), - ~discrete=toDiscrete(r), - ~assumptions, - ); + let toMixedShape = (r: combined): option(DistTypes.shape) => { + let continuous = + toContinous(r) |> Distributions.Continuous.convertToNewLength(100); + let discrete = toDiscrete(r); + // let continuousProb = + // cont |> Distributions.Continuous.T.Integral.sum(~cache=None); + // let discreteProb = + // d |> Distributions.Discrete.T.Integral.sum(~cache=None); + + let foo = MixedShapeBuilder.buildSimple(~continuous, ~discrete); + foo; }; }; -let stringToMixedShape = (~string, ~sampleCount=1000, ()) => - Internals.toCombinedFormat(string, sampleCount) |> Internals.toMixedShape; \ No newline at end of file +let stringToMixedShape = + (~string, ~sampleCount=1000, ~outputXYPoints=1000, ()) => + Internals.toCombinedFormat(string, sampleCount, outputXYPoints) + |> Internals.toMixedShape; \ No newline at end of file diff --git a/src/utility/GuesstimatorLibrary.js b/src/utility/GuesstimatorLibrary.js index a6e981a1..8b4deef9 100644 --- a/src/utility/GuesstimatorLibrary.js +++ b/src/utility/GuesstimatorLibrary.js @@ -34,7 +34,7 @@ const ratioSize = samples => { }; -const toPdf = (values, sampleCount, min, max) => { +const toPdf = (values, outputResolutionCount, min, max) => { let duplicateSamples = _(values).groupBy().pickBy(x => x.length > 1).keys().value(); let totalLength = _.size(values); let frequencies = duplicateSamples.map(s => ({value: parseFloat(s), percentage: _(values).filter(x => x ==s).size()/totalLength})); @@ -48,13 +48,13 @@ const toPdf = (values, sampleCount, min, max) => { const ratioSize$ = ratioSize(samples); const width = ratioSize$ === 'SMALL' ? 100 : 1; - const pdf = samples.toPdf({ size: sampleCount, width, min, max }); + const pdf = samples.toPdf({ size: outputResolutionCount, width, min, max }); continuous = pdf; } return {continuous, discrete}; }; -let run = (text, sampleCount, inputs=[], min=false, max=false) => { +let run = (text, sampleCount, outputResolutionCount, inputs=[], min=false, max=false) => { let [_error, item] = Guesstimator.parse({ text: "=" + text }); const { parsedInput } = item; const { guesstimateType } = parsedInput; @@ -78,7 +78,7 @@ let run = (text, sampleCount, inputs=[], min=false, max=false) => { } else if (values.length === 1) { update = blankResponse; } else { - update = toPdf(values, sampleCount, min, max); + update = toPdf(values, outputResolutionCount, min, max); } return update; }