Fixed math around fixed integral calculations

This commit is contained in:
Ozzie Gooen 2020-02-25 19:27:30 +00:00
parent a940fa30b7
commit c30fab22c7
6 changed files with 56 additions and 48 deletions

View File

@ -4,7 +4,7 @@
let timeDist =
DistPlusIngredients.make(
~guesstimatorString="(floor(10 to 15))",
~domain=Complete,
~domain=RightLimited({xPoint: 50.0, excludingProbabilityMass: 0.3}),
~unit=
DistTypes.TimeDistribution({zero: MomentRe.momentNow(), unit: `years}),
(),
@ -25,7 +25,8 @@ let distributions = () =>
{setup(
DistPlusIngredients.make(
~guesstimatorString="mm(5 to 20, floor(normal(20,2)), [.5, .5])",
~domain=Complete,
~domain=
RightLimited({xPoint: 50.0, excludingProbabilityMass: 0.3}),
(),
),
)

View File

@ -2,11 +2,10 @@ module DistPlusChart = {
[@react.component]
let make = (~distPlus: DistTypes.distPlus, ~onHover) => {
open Distributions.DistPlus;
// todo: Change to scaledContinuous and scaledDiscrete
let discrete = distPlus |> T.toDiscrete;
let discrete = distPlus |> T.toScaledDiscrete;
let continuous =
distPlus
|> T.toContinuous
|> T.toScaledContinuous
|> E.O.fmap(Distributions.Continuous.getShape);
let minX = T.minX(distPlus);
let maxX = T.maxX(distPlus);
@ -40,6 +39,7 @@ module IntegralChart = {
<DistributionPlot
minX
maxX
height=100
?continuous
color={`hex("333")}
timeScale
@ -107,15 +107,18 @@ let make = (~distPlus: DistTypes.distPlus) => {
|> E.Float.with2DigitsPrecision
|> ReasonReact.string}
</th>
<th className="px-4 py-2 border ">
{distPlus
|> Distributions.DistPlus.T.Integral.sum(~cache=None)
|> E.Float.with2DigitsPrecision
|> ReasonReact.string}
</th>
</tr>
</tbody>
</table>
<table className="table-auto">
<thead>
<tr>
<th className="px-4 py-2">
{"Y Integral Total" |> ReasonReact.string}
</th>
<th className="px-4 py-2">
{"Continuous Total" |> ReasonReact.string}
</th>
@ -132,12 +135,6 @@ let make = (~distPlus: DistTypes.distPlus) => {
</thead>
<tbody>
<tr>
<th className="px-4 py-2 border ">
{distPlus
|> Distributions.DistPlus.T.Integral.sum(~cache=None)
|> E.Float.with2DigitsPrecision
|> ReasonReact.string}
</th>
<th className="px-4 py-2 border ">
{distPlus
|> Distributions.DistPlus.T.toContinuous

View File

@ -11,8 +11,8 @@ let make =
let toDistPlus =
(
~sampleCount=2000,
~outputXYPoints=2000,
~truncateTo=Some(100),
~outputXYPoints=1500,
~truncateTo=Some(300),
t: distPlusIngredients,
)
: option(distPlus) => {

View File

@ -120,7 +120,7 @@ module MixedPoint = {
let makeContinuous = (continuous: float): t => {continuous, discrete: 0.0};
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),
discrete: fn(t.discrete),
};

View File

@ -202,10 +202,15 @@ module Mixed = {
let scaleContinuous = ({discreteProbabilityMassFraction}: t, continuous) =>
continuous
|> Continuous.T.scaleBy(~scale=1.0 -. discreteProbabilityMassFraction);
|> Continuous.T.scaleToIntegralSum(
~intendedSum=1.0 -. discreteProbabilityMassFraction,
);
let scaleDiscrete = ({discreteProbabilityMassFraction}: t, disrete) =>
disrete |> Discrete.T.scaleBy(~scale=discreteProbabilityMassFraction);
disrete
|> Discrete.T.scaleToIntegralSum(
~intendedSum=discreteProbabilityMassFraction,
);
module T =
Dist({
@ -239,21 +244,38 @@ module Mixed = {
let integral =
(
~cache,
{continuous, discrete, discreteProbabilityMassFraction} as t: t,
{continuous, discrete, discreteProbabilityMassFraction}: t,
) => {
switch (cache) {
| 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 =
continuous
|> Continuous.T.Integral.get(~cache=None)
|> scaleContinuous(t);
|> Continuous.T.scaleBy(~scale=scaleContinuousBy);
let dist =
discrete
|> Discrete.T.Integral.get(~cache=None)
|> Continuous.toLinear
|> E.O.toExn("")
|> Continuous.T.scaleBy(~scale=discreteProbabilityMassFraction);
|> Continuous.T.scaleBy(~scale=scaleDiscreteBy);
let result =
Continuous.make(
XYShape.Combine.combineLinear(
Continuous.getShape(cont), Continuous.getShape(dist), (a, b) =>
@ -261,6 +283,7 @@ module Mixed = {
),
`Linear,
);
result;
};
};
@ -484,7 +507,6 @@ module DistPlus = {
let minX = shapeFn(Shape.T.minX);
let maxX = shapeFn(Shape.T.maxX);
let fromShape = (t, shape): t => update(~shape, t);
// This bit is kind of akward, could probably use rethinking.
let integral = (~cache, t: t) =>
@ -499,14 +521,14 @@ module DistPlus = {
// TODO: Fix this below, obviously. Adjust for limits
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 = {
open DistTypes;
open DistPlus;
type t = DistTypes.distPlus;
@ -529,7 +551,7 @@ module DistPlusTime = {
module Integral = {
include DistPlus.T.Integral;
let xToY = (~cache as _, f: TimeTypes.timeInVector, t: t) => {
let xToY = (f: TimeTypes.timeInVector, t: t) => {
timeInVectorToX(f, t)
|> E.O.fmap(x => DistPlus.T.Integral.xToY(~cache=None, x, t));
};

View File

@ -110,19 +110,8 @@ module Model = {
// TODO: Fixe number that integral is calculated for
let getGlobalCatastropheChance = dateTime => {
GlobalCatastrophe.makeI(MomentRe.momentNow())
|> DistPlusIngredients.toDistPlus(~sampleCount=1000)
|> E.O.bind(
_,
t => {
let foo =
Distributions.DistPlusTime.Integral.xToY(
~cache=None,
Time(dateTime),
t,
);
Some(0.5);
},
);
|> DistPlusIngredients.toDistPlus
|> E.O.bind(_, Distributions.DistPlusTime.Integral.xToY(Time(dateTime)));
};
let make =
@ -151,8 +140,7 @@ module Model = {
| Some({truthValue: false}) => difference
| None =>
let foo =
// getGlobalCatastropheChance(dateTime)
Some(0.5)
getGlobalCatastropheChance(dateTime)
|> E.O.fmap(E.Float.with2DigitsPrecision)
|> E.O.fmap((r: string) =>
"uniform(0,1) > " ++ r ++ " ? " ++ difference ++ ": 0"