Merge remote-tracking branch 'origin/master' into improvements/1087

This commit is contained in:
Roman Galochkin 2020-02-26 08:18:12 +03:00
commit 6a54d24550
13 changed files with 217 additions and 117 deletions

View File

@ -1,10 +1,11 @@
// "mm(floor(uniform(30,35)), normal(50,20), [.25,.5])", // "mm(floor(uniform(30,35)), normal(50,20), [.25,.5])",
// "mm(floor(normal(28,4)), normal(32,2), uniform(20,24), [.5,.2,.1])", // "mm(floor(normal(28,4)), normal(32,2), uniform(20,24), [.5,.2,.1])",
// "mm(5 to 20, floor(normal(20,2)), [.5, .5])",
let timeDist = let timeDist =
DistPlusIngredients.make( DistPlusIngredients.make(
~guesstimatorString="mm(floor(10 to 15), 10 to 11, [.9,.1])", ~guesstimatorString="(floor(10 to 15))",
~domain=Complete, ~domain=RightLimited({xPoint: 50.0, excludingProbabilityMass: 0.3}),
~unit= ~unit=
DistTypes.TimeDistribution({zero: MomentRe.momentNow(), unit: `years}), DistTypes.TimeDistribution({zero: MomentRe.momentNow(), unit: `years}),
(), (),
@ -12,7 +13,11 @@ let timeDist =
let setup = dist => let setup = dist =>
dist dist
|> DistPlusIngredients.toDistPlus(~sampleCount=5000, ~outputXYPoints=1000); |> DistPlusIngredients.toDistPlus(
~sampleCount=10000,
~outputXYPoints=2000,
~truncateTo=Some(1000),
);
let distributions = () => let distributions = () =>
<div> <div>
@ -20,8 +25,10 @@ let distributions = () =>
<h2> {"Single-Discrete" |> ReasonReact.string} </h2> <h2> {"Single-Discrete" |> ReasonReact.string} </h2>
{setup( {setup(
DistPlusIngredients.make( DistPlusIngredients.make(
~guesstimatorString="8 to 12, [.5,.5])", ~guesstimatorString=
~domain=Complete, "uniform(0,1) > 0.036 ? lognormal(6.652, -0.41): 0",
~domain=
RightLimited({xPoint: 50.0, excludingProbabilityMass: 0.3}),
(), (),
), ),
) )

View File

@ -2,13 +2,18 @@ module DistPlusChart = {
[@react.component] [@react.component]
let make = (~distPlus: DistTypes.distPlus, ~onHover) => { let make = (~distPlus: DistTypes.distPlus, ~onHover) => {
open Distributions.DistPlus; open Distributions.DistPlus;
// todo: Change to scaledContinuous and scaledDiscrete let discrete = distPlus |> T.toScaledDiscrete;
let discrete = distPlus |> T.toDiscrete;
let continuous = let continuous =
distPlus distPlus
|> T.toContinuous |> T.toScaledContinuous
|> E.O.fmap(Distributions.Continuous.getShape); |> E.O.fmap(Distributions.Continuous.getShape);
let minX = T.minX(distPlus); let range = T.xTotalRange(distPlus);
let minX =
switch (T.minX(distPlus), range) {
| (Some(min), Some(range)) => Some(min -. range *. 0.001)
| _ => None
};
let maxX = T.maxX(distPlus); let maxX = T.maxX(distPlus);
let timeScale = distPlus.unit |> DistTypes.DistributionUnit.toJson; let timeScale = distPlus.unit |> DistTypes.DistributionUnit.toJson;
<DistributionPlot <DistributionPlot
@ -34,13 +39,18 @@ module IntegralChart = {
integral integral
|> Distributions.Continuous.toLinear |> Distributions.Continuous.toLinear
|> E.O.fmap(Distributions.Continuous.getShape); |> E.O.fmap(Distributions.Continuous.getShape);
let minX = integral |> Distributions.Continuous.T.minX; let range = T.xTotalRange(distPlus);
let minX =
switch (T.minX(distPlus), range) {
| (Some(min), Some(range)) => Some(min -. range *. 0.001)
| _ => None
};
let maxX = integral |> Distributions.Continuous.T.maxX; let maxX = integral |> Distributions.Continuous.T.maxX;
let timeScale = distPlus.unit |> DistTypes.DistributionUnit.toJson; let timeScale = distPlus.unit |> DistTypes.DistributionUnit.toJson;
Js.log3("HIHI", continuous, distPlus);
<DistributionPlot <DistributionPlot
minX minX
maxX maxX
height=100
?continuous ?continuous
color={`hex("333")} color={`hex("333")}
timeScale timeScale
@ -78,6 +88,9 @@ let make = (~distPlus: DistTypes.distPlus) => {
<th className="px-4 py-2"> <th className="px-4 py-2">
{"Y Integral to Point" |> ReasonReact.string} {"Y Integral to Point" |> ReasonReact.string}
</th> </th>
<th className="px-4 py-2">
{"Y Integral Total" |> ReasonReact.string}
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -114,6 +127,64 @@ let make = (~distPlus: DistTypes.distPlus) => {
</tr> </tr>
</tbody> </tbody>
</table> </table>
<table className="table-auto">
<thead>
<tr>
<th className="px-4 py-2">
{"Continuous Total" |> ReasonReact.string}
</th>
<th className="px-4 py-2">
{"Scaled Continuous Total" |> ReasonReact.string}
</th>
<th className="px-4 py-2">
{"Discrete Total" |> ReasonReact.string}
</th>
<th className="px-4 py-2">
{"Scaled Discrete Total" |> ReasonReact.string}
</th>
</tr>
</thead>
<tbody>
<tr>
<th className="px-4 py-2 border ">
{distPlus
|> Distributions.DistPlus.T.toContinuous
|> E.O.fmap(
Distributions.Continuous.T.Integral.sum(~cache=None),
)
|> E.O.fmap(E.Float.with2DigitsPrecision)
|> E.O.default("")
|> ReasonReact.string}
</th>
<th className="px-4 py-2 border ">
{distPlus
|> Distributions.DistPlus.T.toScaledContinuous
|> E.O.fmap(
Distributions.Continuous.T.Integral.sum(~cache=None),
)
|> E.O.fmap(E.Float.with2DigitsPrecision)
|> E.O.default("")
|> ReasonReact.string}
</th>
<th className="px-4 py-2 border ">
{distPlus
|> Distributions.DistPlus.T.toDiscrete
|> E.O.fmap(Distributions.Discrete.T.Integral.sum(~cache=None))
|> E.O.fmap(E.Float.with2DigitsPrecision)
|> E.O.default("")
|> ReasonReact.string}
</th>
<th className="px-4 py-2 border ">
{distPlus
|> Distributions.DistPlus.T.toScaledDiscrete
|> E.O.fmap(Distributions.Discrete.T.Integral.sum(~cache=None))
|> E.O.fmap(E.Float.with2DigitsPrecision)
|> E.O.default("")
|> ReasonReact.string}
</th>
</tr>
</tbody>
</table>
<div /> <div />
</div>; </div>;
// chart // chart

View File

@ -40,8 +40,8 @@ function CdfChartReact(props) {
.minX(props.minX) .minX(props.minX)
.onHover(props.onHover) .onHover(props.onHover)
.marginBottom(props.marginBottom || 15) .marginBottom(props.marginBottom || 15)
.marginLeft(5) .marginLeft(30)
.marginRight(5) .marginRight(30)
.marginTop(5) .marginTop(5)
.showDistributionLines(props.showDistributionLines) .showDistributionLines(props.showDistributionLines)
.showDistributionYAxis(props.showDistributionYAxis) .showDistributionYAxis(props.showDistributionYAxis)

View File

@ -9,13 +9,19 @@ let make =
}; };
let toDistPlus = let toDistPlus =
(~sampleCount=1000, ~outputXYPoints=1000, t: distPlusIngredients) (
~sampleCount=2000,
~outputXYPoints=1500,
~truncateTo=Some(300),
t: distPlusIngredients,
)
: option(distPlus) => { : option(distPlus) => {
let shape = let shape =
Guesstimator.stringToMixedShape( Guesstimator.stringToMixedShape(
~string=t.guesstimatorString, ~string=t.guesstimatorString,
~sampleCount, ~sampleCount,
~outputXYPoints, ~outputXYPoints,
~truncateTo,
(), (),
); );
let distPlus = let distPlus =

View File

@ -120,7 +120,7 @@ module MixedPoint = {
let makeContinuous = (continuous: float): t => {continuous, discrete: 0.0}; let makeContinuous = (continuous: float): t => {continuous, discrete: 0.0};
let makeDiscrete = (discrete: float): t => {continuous: 0.0, discrete}; let makeDiscrete = (discrete: float): t => {continuous: 0.0, discrete};
let fmap = (fn, t: t) => { let fmap = (fn: float => float, t: t) => {
continuous: fn(t.continuous), continuous: fn(t.continuous),
discrete: fn(t.discrete), discrete: fn(t.discrete),
}; };

View File

@ -127,14 +127,15 @@ module Continuous = {
// }; // };
let integral = (~cache, t) => let integral = (~cache, t) =>
cache switch (cache) {
|> E.O.default( | Some(cache) => cache
t | None =>
|> xyShape t
|> XYShape.Range.integrateWithTriangles |> xyShape
|> E.O.toExt("This should not have happened") |> XYShape.Range.integrateWithTriangles
|> fromShape, |> E.O.toExt("This should not have happened")
); |> fromShape
};
let integralEndY = (~cache, t) => t |> integral(~cache) |> lastY; let integralEndY = (~cache, t) => t |> integral(~cache) |> lastY;
let integralXtoY = (~cache, f, t) => let integralXtoY = (~cache, f, t) =>
t |> integral(~cache) |> shapeFn(CdfLibrary.Distribution.findY(f)); t |> integral(~cache) |> shapeFn(CdfLibrary.Distribution.findY(f));
@ -151,8 +152,10 @@ module Discrete = {
type t = DistTypes.discreteShape; type t = DistTypes.discreteShape;
type integral = DistTypes.continuousShape; type integral = DistTypes.continuousShape;
let integral = (~cache, t) => let integral = (~cache, t) =>
cache switch (cache) {
|> E.O.default(Continuous.make(XYShape.accumulateYs(t), `Stepwise)); | Some(c) => c
| None => Continuous.make(XYShape.accumulateYs(t), `Stepwise)
};
let integralEndY = (~cache, t) => let integralEndY = (~cache, t) =>
t |> integral(~cache) |> Continuous.lastY; t |> integral(~cache) |> Continuous.lastY;
let minX = XYShape.minX; let minX = XYShape.minX;
@ -188,21 +191,6 @@ module Mixed = {
discreteProbabilityMassFraction, discreteProbabilityMassFraction,
}; };
let clean = (t: DistTypes.mixedShape): option(DistTypes.shape) => {
switch (t) {
| {
continuous: {xyShape: {xs: [||], ys: [||]}},
discrete: {xs: [||], ys: [||]},
} =>
None
| {continuous, discrete: {xs: [||], ys: [||]}} =>
Some(Continuous(continuous))
| {continuous: {xyShape: {xs: [||], ys: [||]}}, discrete} =>
Some(Discrete(discrete))
| shape => Some(Mixed(shape))
};
};
// todo: Put into scaling module // todo: Put into scaling module
let scaleDiscreteFn = let scaleDiscreteFn =
({discreteProbabilityMassFraction}: DistTypes.mixedShape, f) => ({discreteProbabilityMassFraction}: DistTypes.mixedShape, f) =>
@ -214,17 +202,23 @@ module Mixed = {
let scaleContinuous = ({discreteProbabilityMassFraction}: t, continuous) => let scaleContinuous = ({discreteProbabilityMassFraction}: t, continuous) =>
continuous continuous
|> Continuous.T.scaleBy(~scale=1.0 -. discreteProbabilityMassFraction); |> Continuous.T.scaleToIntegralSum(
~intendedSum=1.0 -. discreteProbabilityMassFraction,
);
let scaleDiscrete = ({discreteProbabilityMassFraction}: t, disrete) => let scaleDiscrete = ({discreteProbabilityMassFraction}: t, disrete) =>
disrete |> Discrete.T.scaleBy(~scale=discreteProbabilityMassFraction); disrete
|> Discrete.T.scaleToIntegralSum(
~intendedSum=discreteProbabilityMassFraction,
);
module T = module T =
Dist({ Dist({
type t = DistTypes.mixedShape; type t = DistTypes.mixedShape;
type integral = DistTypes.continuousShape; type integral = DistTypes.continuousShape;
let minX = ({continuous, discrete}: t) => let minX = ({continuous, discrete}: t) => {
min(Continuous.T.minX(continuous), Discrete.T.minX(discrete)); min(Continuous.T.minX(continuous), Discrete.T.minX(discrete));
};
let maxX = ({continuous, discrete}: t) => let maxX = ({continuous, discrete}: t) =>
max(Continuous.T.maxX(continuous), Discrete.T.maxX(discrete)); max(Continuous.T.maxX(continuous), Discrete.T.maxX(discrete));
let toShape = (t: t): DistTypes.shape => Mixed(t); let toShape = (t: t): DistTypes.shape => Mixed(t);
@ -251,34 +245,47 @@ module Mixed = {
let integral = let integral =
( (
~cache, ~cache,
{continuous, discrete, discreteProbabilityMassFraction} as t: t, {continuous, discrete, discreteProbabilityMassFraction}: t,
) => { ) => {
cache switch (cache) {
|> E.O.default( | Some(cache) => cache
{ | None =>
let cont = let scaleContinuousBy =
continuous (1.0 -. discreteProbabilityMassFraction)
|> Continuous.T.Integral.get(~cache=None) /. (continuous |> Continuous.T.Integral.sum(~cache=None));
|> scaleContinuous(t);
let dist = let scaleDiscreteBy =
discrete discreteProbabilityMassFraction
|> Discrete.T.Integral.get(~cache=None) /. (
|> Continuous.toLinear discrete
|> E.O.toExn("") |> Discrete.T.Integral.get(~cache=None)
|> Continuous.T.scaleBy( |> Continuous.toLinear
~scale=discreteProbabilityMassFraction, |> E.O.fmap(Continuous.lastY)
); |> E.O.toExn("")
Continuous.make( );
XYShape.Combine.combineLinear(
Continuous.getShape(cont), let cont =
Continuous.getShape(dist), continuous
(a, b) => |> Continuous.T.Integral.get(~cache=None)
a +. b |> Continuous.T.scaleBy(~scale=scaleContinuousBy);
),
`Linear, let dist =
); discrete
}, |> Discrete.T.Integral.get(~cache=None)
); |> Continuous.toLinear
|> E.O.toExn("")
|> Continuous.T.scaleBy(~scale=scaleDiscreteBy);
let result =
Continuous.make(
XYShape.Combine.combineLinear(
Continuous.getShape(cont), Continuous.getShape(dist), (a, b) =>
a +. b
),
`Linear,
);
result;
};
}; };
let integralEndY = (~cache, t: t) => { let integralEndY = (~cache, t: t) => {
@ -501,7 +508,6 @@ module DistPlus = {
let minX = shapeFn(Shape.T.minX); let minX = shapeFn(Shape.T.minX);
let maxX = shapeFn(Shape.T.maxX); let maxX = shapeFn(Shape.T.maxX);
let fromShape = (t, shape): t => update(~shape, t);
// This bit is kind of akward, could probably use rethinking. // This bit is kind of akward, could probably use rethinking.
let integral = (~cache, t: t) => let integral = (~cache, t: t) =>
@ -516,14 +522,14 @@ module DistPlus = {
// TODO: Fix this below, obviously. Adjust for limits // TODO: Fix this below, obviously. Adjust for limits
let integralXtoY = (~cache as _, f, t: t) => { let integralXtoY = (~cache as _, f, t: t) => {
Shape.T.Integral.xToY(~cache=Some(t.integralCache), f, toShape(t)); Shape.T.Integral.xToY(~cache=Some(t.integralCache), f, toShape(t))
|> domainIncludedProbabilityMassAdjustment(t);
}; };
}); });
}; };
module DistPlusTime = { module DistPlusTime = {
open DistTypes; open DistTypes;
open DistPlus;
type t = DistTypes.distPlus; type t = DistTypes.distPlus;
@ -546,7 +552,7 @@ module DistPlusTime = {
module Integral = { module Integral = {
include DistPlus.T.Integral; include DistPlus.T.Integral;
let xToY = (~cache as _, f: TimeTypes.timeInVector, t: t) => { let xToY = (f: TimeTypes.timeInVector, t: t) => {
timeInVectorToX(f, t) timeInVectorToX(f, t)
|> E.O.fmap(x => DistPlus.T.Integral.xToY(~cache=None, x, t)); |> E.O.fmap(x => DistPlus.T.Integral.xToY(~cache=None, x, t));
}; };

View File

@ -21,16 +21,21 @@ let buildSimple = (~continuous, ~discrete): option(DistTypes.shape) => {
Distributions.Discrete.T.Integral.sum(~cache=None, discrete); Distributions.Discrete.T.Integral.sum(~cache=None, discrete);
let discrete = let discrete =
Distributions.Discrete.T.scaleToIntegralSum(~intendedSum=1.0, discrete); Distributions.Discrete.T.scaleToIntegralSum(~intendedSum=1.0, discrete);
let foobar = let continuous =
Distributions.Continuous.T.scaleToIntegralSum(
~intendedSum=1.0,
continuous,
);
let mixedDist =
Distributions.Mixed.make( Distributions.Mixed.make(
~continuous, ~continuous,
~discrete, ~discrete,
~discreteProbabilityMassFraction, ~discreteProbabilityMassFraction,
) );
|> Distributions.Mixed.clean; Some(Mixed(mixedDist));
foobar;
}; };
}; };
let build = (~continuous, ~discrete, ~assumptions) => let build = (~continuous, ~discrete, ~assumptions) =>
switch (assumptions) { switch (assumptions) {
| { | {

View File

@ -63,8 +63,9 @@ module RelativeTimePoint = {
|> MomentRe.Moment.add(~duration=MomentRe.duration(r, timeVector.unit)) |> MomentRe.Moment.add(~duration=MomentRe.duration(r, timeVector.unit))
}; };
let _timeToX = (time, timeStart, timeUnit) => let _timeToX = (time, timeStart, timeUnit) => {
MomentRe.diff(timeStart, time, timeUnit); MomentRe.diff(time, timeStart, timeUnit);
};
let toXValue = (timeVector: timeVector, timeInVector: timeInVector) => let toXValue = (timeVector: timeVector, timeInVector: timeInVector) =>
switch (timeInVector) { switch (timeInVector) {

View File

@ -17,12 +17,20 @@ let propValue = (t: Prop.Value.t) => {
switch (t) { switch (t) {
| SelectSingle(r) => r |> ReasonReact.string | SelectSingle(r) => r |> ReasonReact.string
| ConditionalArray(r) => "Array" |> ReasonReact.string | ConditionalArray(r) => "Array" |> ReasonReact.string
| DistPlusIngredients(r) => | DistPlusIngredients((r: DistTypes.distPlusIngredients)) =>
let newDistribution = let newDistribution =
DistPlusIngredients.toDistPlus(~sampleCount=1000, r); DistPlusIngredients.toDistPlus(
~sampleCount=2000,
~outputXYPoints=2000,
~truncateTo=Some(100),
r,
);
switch (newDistribution) { switch (newDistribution) {
| Some(distribution) => | Some(distribution) =>
<div> <DistPlusPlot distPlus=distribution /> </div> <div>
<DistPlusPlot distPlus=distribution />
{r.guesstimatorString |> ReasonReact.string}
</div>
| None => "Something went wrong" |> ReasonReact.string | None => "Something went wrong" |> ReasonReact.string
}; };
| FloatCdf(_) => <div /> | FloatCdf(_) => <div />

View File

@ -70,14 +70,14 @@ module Model = {
}; };
let yearlyMeanGrowthRateIfNotClosed = (group: group): yearlyNumericDiff => { let yearlyMeanGrowthRateIfNotClosed = (group: group): yearlyNumericDiff => {
{meanDiff: 1.1, stdDiff: 1.1}; {meanDiff: 1.1, stdDiff: 1.08};
}; };
let calculateDifference = let calculateDifference =
(currentValue, dateTime, currentDateTime, y: yearlyNumericDiff) => { (currentValue, dateTime, currentDateTime, y: yearlyNumericDiff) => {
let yearDiff = MomentRe.diff(dateTime, currentDateTime, `days) /. 365.; let yearDiff = MomentRe.diff(dateTime, currentDateTime, `days) /. 365.;
let meanDiff = Js.Math.pow_float(~base=y.meanDiff, ~exp=yearDiff); let meanDiff = Js.Math.pow_float(~base=y.meanDiff, ~exp=yearDiff);
let stdDevDiff = Js.Math.pow_float(~base=y.meanDiff, ~exp=yearDiff); let stdDevDiff = Js.Math.pow_float(~base=y.stdDiff, ~exp=yearDiff);
GuesstimatorDist.logNormal( GuesstimatorDist.logNormal(
currentValue *. meanDiff, currentValue *. meanDiff,
firstYearStdDev *. stdDevDiff, firstYearStdDev *. stdDevDiff,
@ -110,19 +110,8 @@ module Model = {
// TODO: Fixe number that integral is calculated for // TODO: Fixe number that integral is calculated for
let getGlobalCatastropheChance = dateTime => { let getGlobalCatastropheChance = dateTime => {
GlobalCatastrophe.makeI(MomentRe.momentNow()) GlobalCatastrophe.makeI(MomentRe.momentNow())
|> DistPlusIngredients.toDistPlus(~sampleCount=1000) |> DistPlusIngredients.toDistPlus
|> E.O.bind( |> E.O.bind(_, Distributions.DistPlusTime.Integral.xToY(Time(dateTime)));
_,
t => {
let foo =
Distributions.DistPlusTime.Integral.xToY(
~cache=None,
Time(dateTime),
t,
);
Some(0.5);
},
);
}; };
let make = let make =
@ -151,8 +140,7 @@ module Model = {
| Some({truthValue: false}) => difference | Some({truthValue: false}) => difference
| None => | None =>
let foo = let foo =
// getGlobalCatastropheChance(dateTime) getGlobalCatastropheChance(dateTime)
Some(0.5)
|> E.O.fmap(E.Float.with2DigitsPrecision) |> E.O.fmap(E.Float.with2DigitsPrecision)
|> E.O.fmap((r: string) => |> E.O.fmap((r: string) =>
"uniform(0,1) > " ++ r ++ " ? " ++ difference ++ ": 0" "uniform(0,1) > " ++ r ++ " ? " ++ difference ++ ": 0"
@ -175,8 +163,9 @@ module Model = {
~guesstimatorString= ~guesstimatorString=
GuesstimatorDist.min( GuesstimatorDist.min(
GlobalCatastrophe.guesstimatorString, GlobalCatastrophe.guesstimatorString,
GuesstimatorDist.logNormal(40., 4.), GuesstimatorDist.logNormal(20., 2.),
), ),
~unit=TimeDistribution({zero: currentDateTime, unit: `years}),
~domain=RightLimited({xPoint: 100., excludingProbabilityMass: 0.3}), ~domain=RightLimited({xPoint: 100., excludingProbabilityMass: 0.3}),
(), (),
), ),

View File

@ -1,21 +1,16 @@
let guesstimatorString = "floor(10 to 20)"; let guesstimatorString = "uniform(1, 100)";
let makeI = (currentDateTime: MomentRe.Moment.t) => { let makeI = (currentDateTime: MomentRe.Moment.t) => {
DistPlusIngredients.make( DistPlusIngredients.make(
~guesstimatorString, ~guesstimatorString,
~unit=TimeDistribution({zero: currentDateTime, unit: `years}), ~unit=TimeDistribution({zero: currentDateTime, unit: `years}),
~domain=RightLimited({xPoint: 300.0, excludingProbabilityMass: 0.3}),
(), (),
); );
}; };
module Model = { module Model = {
let make = (currentDateTime: MomentRe.Moment.t) => { let make = (currentDateTime: MomentRe.Moment.t) => {
let distPlusIngredients = Prop.Value.DistPlusIngredients(makeI(currentDateTime));
DistPlusIngredients.make(
~guesstimatorString,
~unit=TimeDistribution({zero: currentDateTime, unit: `years}),
(),
);
Prop.Value.DistPlusIngredients(distPlusIngredients);
}; };
}; };

View File

@ -29,9 +29,15 @@ module Internals = {
external toCombinedFormat: (string, int, int) => combined = "run"; external toCombinedFormat: (string, int, int) => combined = "run";
// todo: Format to correct mass, also normalize the pdf. // todo: Format to correct mass, also normalize the pdf.
let toMixedShape = (r: combined): option(DistTypes.shape) => { let toMixedShape =
(~truncateTo=Some(500), r: combined): option(DistTypes.shape) => {
let continuous = toContinous(r);
let continuous = let continuous =
toContinous(r) |> Distributions.Continuous.convertToNewLength(100); switch (truncateTo) {
| Some(t) =>
continuous |> Distributions.Continuous.convertToNewLength(t)
| None => continuous
};
let discrete = toDiscrete(r); let discrete = toDiscrete(r);
// let continuousProb = // let continuousProb =
// cont |> Distributions.Continuous.T.Integral.sum(~cache=None); // cont |> Distributions.Continuous.T.Integral.sum(~cache=None);
@ -44,6 +50,12 @@ module Internals = {
}; };
let stringToMixedShape = let stringToMixedShape =
(~string, ~sampleCount=1000, ~outputXYPoints=1000, ()) => (
~string,
~sampleCount=3000,
~outputXYPoints=3000,
~truncateTo=Some(500),
(),
) =>
Internals.toCombinedFormat(string, sampleCount, outputXYPoints) Internals.toCombinedFormat(string, sampleCount, outputXYPoints)
|> Internals.toMixedShape; |> Internals.toMixedShape(~truncateTo);

View File

@ -13,9 +13,9 @@ const minMaxRatio = (minValue, maxValue) => {
return 'SMALL'; return 'SMALL';
} }
const ratio = maxValue / minValue; const ratio = maxValue / minValue;
if (ratio < 100000) { if (ratio < 10000) {
return 'SMALL'; return 'SMALL';
} else if (ratio < 10000000) { } else if (ratio < 1000000) {
return 'MEDIUM'; return 'MEDIUM';
} else { } else {
return 'LARGE'; return 'LARGE';
@ -42,11 +42,11 @@ const toPdf = (values, outputResolutionCount, min, max) => {
let discrete = {xs: frequencies.map(f => f.value), ys: frequencies.map(f => f.percentage)}; let discrete = {xs: frequencies.map(f => f.value), ys: frequencies.map(f => f.percentage)};
let continuous = {ys: [], xs: []}; let continuous = {ys: [], xs: []};
if (continuousSamples.length > 1){ if (continuousSamples.length > 20){
const samples = new Samples(continuousSamples); const samples = new Samples(continuousSamples);
const ratioSize$ = ratioSize(samples); const ratioSize$ = ratioSize(samples);
const width = ratioSize$ === 'SMALL' ? 100 : 1; const width = ratioSize$ === 'SMALL' ? 60 : 1;
const pdf = samples.toPdf({ size: outputResolutionCount, width, min, max }); const pdf = samples.toPdf({ size: outputResolutionCount, width, min, max });
continuous = pdf; continuous = pdf;