Merge remote-tracking branch 'origin/master' into improvements/1087
This commit is contained in:
commit
6a54d24550
|
@ -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}),
|
||||||
(),
|
(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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),
|
||||||
};
|
};
|
||||||
|
|
|
@ -127,14 +127,15 @@ module Continuous = {
|
||||||
// };
|
// };
|
||||||
|
|
||||||
let integral = (~cache, t) =>
|
let integral = (~cache, t) =>
|
||||||
cache
|
switch (cache) {
|
||||||
|> E.O.default(
|
| Some(cache) => cache
|
||||||
|
| None =>
|
||||||
t
|
t
|
||||||
|> xyShape
|
|> xyShape
|
||||||
|> XYShape.Range.integrateWithTriangles
|
|> XYShape.Range.integrateWithTriangles
|
||||||
|> E.O.toExt("This should not have happened")
|
|> E.O.toExt("This should not have happened")
|
||||||
|> fromShape,
|
|> 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 scaleContinuousBy =
|
||||||
|
(1.0 -. discreteProbabilityMassFraction)
|
||||||
|
/. (continuous |> Continuous.T.Integral.sum(~cache=None));
|
||||||
|
|
||||||
|
let scaleDiscreteBy =
|
||||||
|
discreteProbabilityMassFraction
|
||||||
|
/. (
|
||||||
|
discrete
|
||||||
|
|> Discrete.T.Integral.get(~cache=None)
|
||||||
|
|> Continuous.toLinear
|
||||||
|
|> E.O.fmap(Continuous.lastY)
|
||||||
|
|> E.O.toExn("")
|
||||||
|
);
|
||||||
|
|
||||||
let cont =
|
let cont =
|
||||||
continuous
|
continuous
|
||||||
|> Continuous.T.Integral.get(~cache=None)
|
|> Continuous.T.Integral.get(~cache=None)
|
||||||
|> scaleContinuous(t);
|
|> Continuous.T.scaleBy(~scale=scaleContinuousBy);
|
||||||
|
|
||||||
let dist =
|
let dist =
|
||||||
discrete
|
discrete
|
||||||
|> Discrete.T.Integral.get(~cache=None)
|
|> Discrete.T.Integral.get(~cache=None)
|
||||||
|> Continuous.toLinear
|
|> Continuous.toLinear
|
||||||
|> E.O.toExn("")
|
|> E.O.toExn("")
|
||||||
|> Continuous.T.scaleBy(
|
|> Continuous.T.scaleBy(~scale=scaleDiscreteBy);
|
||||||
~scale=discreteProbabilityMassFraction,
|
|
||||||
);
|
let result =
|
||||||
Continuous.make(
|
Continuous.make(
|
||||||
XYShape.Combine.combineLinear(
|
XYShape.Combine.combineLinear(
|
||||||
Continuous.getShape(cont),
|
Continuous.getShape(cont), Continuous.getShape(dist), (a, b) =>
|
||||||
Continuous.getShape(dist),
|
|
||||||
(a, b) =>
|
|
||||||
a +. b
|
a +. b
|
||||||
),
|
),
|
||||||
`Linear,
|
`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));
|
||||||
};
|
};
|
||||||
|
|
|
@ -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) {
|
||||||
| {
|
| {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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 />
|
||||||
|
|
|
@ -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}),
|
||||||
(),
|
(),
|
||||||
),
|
),
|
||||||
|
|
|
@ -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);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user