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 = let timeDist =
DistPlusIngredients.make( DistPlusIngredients.make(
~guesstimatorString="(floor(10 to 15))", ~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}),
(), (),
@ -25,7 +25,8 @@ let distributions = () =>
{setup( {setup(
DistPlusIngredients.make( DistPlusIngredients.make(
~guesstimatorString="mm(5 to 20, floor(normal(20,2)), [.5, .5])", ~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] [@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 minX = T.minX(distPlus);
let maxX = T.maxX(distPlus); let maxX = T.maxX(distPlus);
@ -40,6 +39,7 @@ module IntegralChart = {
<DistributionPlot <DistributionPlot
minX minX
maxX maxX
height=100
?continuous ?continuous
color={`hex("333")} color={`hex("333")}
timeScale timeScale
@ -107,15 +107,18 @@ let make = (~distPlus: DistTypes.distPlus) => {
|> E.Float.with2DigitsPrecision |> E.Float.with2DigitsPrecision
|> ReasonReact.string} |> ReasonReact.string}
</th> </th>
<th className="px-4 py-2 border ">
{distPlus
|> Distributions.DistPlus.T.Integral.sum(~cache=None)
|> E.Float.with2DigitsPrecision
|> ReasonReact.string}
</th>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<table className="table-auto"> <table className="table-auto">
<thead> <thead>
<tr> <tr>
<th className="px-4 py-2">
{"Y Integral Total" |> ReasonReact.string}
</th>
<th className="px-4 py-2"> <th className="px-4 py-2">
{"Continuous Total" |> ReasonReact.string} {"Continuous Total" |> ReasonReact.string}
</th> </th>
@ -132,12 +135,6 @@ let make = (~distPlus: DistTypes.distPlus) => {
</thead> </thead>
<tbody> <tbody>
<tr> <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 "> <th className="px-4 py-2 border ">
{distPlus {distPlus
|> Distributions.DistPlus.T.toContinuous |> Distributions.DistPlus.T.toContinuous

View File

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

@ -202,10 +202,15 @@ 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({
@ -239,28 +244,46 @@ module Mixed = {
let integral = let integral =
( (
~cache, ~cache,
{continuous, discrete, discreteProbabilityMassFraction} as t: t, {continuous, discrete, discreteProbabilityMassFraction}: t,
) => { ) => {
switch (cache) { switch (cache) {
| Some(cache) => cache | Some(cache) => cache
| None => | 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(~scale=discreteProbabilityMassFraction); |> Continuous.T.scaleBy(~scale=scaleDiscreteBy);
Continuous.make(
XYShape.Combine.combineLinear( let result =
Continuous.getShape(cont), Continuous.getShape(dist), (a, b) => Continuous.make(
a +. b XYShape.Combine.combineLinear(
), Continuous.getShape(cont), Continuous.getShape(dist), (a, b) =>
`Linear, a +. b
); ),
`Linear,
);
result;
}; };
}; };
@ -484,7 +507,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) =>
@ -499,14 +521,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;
@ -529,7 +551,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

@ -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"