Simple restructuring
This commit is contained in:
parent
f844c9cc72
commit
ad0212db39
|
@ -12,7 +12,7 @@ let distributions = () =>
|
|||
<div>
|
||||
<div>
|
||||
<h2> {"Basic Mixed Distribution" |> ReasonReact.string} </h2>
|
||||
{timeDist |> E.O.React.fmapOrNull(distPlus => <DistPlusChart distPlus />)}
|
||||
{timeDist |> E.O.React.fmapOrNull(distPlus => <DistPlusPlot distPlus />)}
|
||||
<h2> {"Simple Continuous" |> ReasonReact.string} </h2>
|
||||
</div>
|
||||
</div>;
|
||||
|
|
|
@ -10,7 +10,7 @@ module DistPlusChart = {
|
|||
let minX = T.minX(distPlus);
|
||||
let maxX = T.maxX(distPlus);
|
||||
let timeScale = distPlus.unit |> DistTypes.DistributionUnit.toJson;
|
||||
<DistributionChart
|
||||
<DistributionPlot
|
||||
minX
|
||||
maxX
|
||||
?discrete
|
||||
|
@ -31,12 +31,11 @@ module IntegralChart = {
|
|||
let continuous =
|
||||
integral
|
||||
|> T.toContinuous
|
||||
|> E.O.fmap(Distributions.Continuous.toLinear)
|
||||
|> E.O.fmap(Distributions.Continuous.getShape);
|
||||
let minX = T.minX(integral);
|
||||
let maxX = T.maxX(integral);
|
||||
let timeScale = distPlus.unit |> DistTypes.DistributionUnit.toJson;
|
||||
<DistributionChart
|
||||
<DistributionPlot
|
||||
minX
|
||||
maxX
|
||||
?continuous
|
|
@ -1,6 +1,6 @@
|
|||
module RawChart = {
|
||||
[@bs.module "./cdfChartReact.js"]
|
||||
external cdfChart: ReasonReact.reactClass = "default";
|
||||
module RawPlot = {
|
||||
[@bs.module "./distPlotReact.js"]
|
||||
external plot: ReasonReact.reactClass = "default";
|
||||
|
||||
type primaryDistribution =
|
||||
option({
|
||||
|
@ -36,7 +36,7 @@ module RawChart = {
|
|||
~children=[||],
|
||||
) =>
|
||||
ReasonReact.wrapJsForReason(
|
||||
~reactClass=cdfChart,
|
||||
~reactClass=plot,
|
||||
~props=
|
||||
makeProps(
|
||||
~height?,
|
||||
|
@ -102,7 +102,7 @@ let make =
|
|||
~timeScale=?,
|
||||
) => {
|
||||
<div className={Styles.graph(color)}>
|
||||
<RawChart
|
||||
<RawPlot
|
||||
?maxX
|
||||
?minX
|
||||
?scale
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { useSize } from 'react-use';
|
||||
import { CdfChartD3 } from './cdfChartD3';
|
||||
import { CdfChartD3 } from './distPlotD3';
|
||||
|
||||
/**
|
||||
* @param min
|
|
@ -8,7 +8,7 @@ let make =
|
|||
unit,
|
||||
};
|
||||
|
||||
let toDistPlus = (~sampleCount, t: distPlusIngredients) => {
|
||||
let toDistPlus = (~sampleCount, t: distPlusIngredients): option(distPlus) => {
|
||||
let shape =
|
||||
Guesstimator.stringToMixedShape(
|
||||
~string=t.guesstimatorString,
|
||||
|
|
|
@ -74,7 +74,7 @@ module Continuous = {
|
|||
};
|
||||
let oShapeMap =
|
||||
(fn, {xyShape, interpolation}: t): option(DistTypes.continuousShape) =>
|
||||
fn(xyShape) |> E.O.fmap(xyShape => make(xyShape, interpolation));
|
||||
fn(xyShape) |> E.O.fmap(make(_, interpolation));
|
||||
|
||||
let toLinear = (t: t): t =>
|
||||
switch (t) {
|
||||
|
@ -90,7 +90,8 @@ module Continuous = {
|
|||
type t = DistTypes.continuousShape;
|
||||
type integral = DistTypes.continuousShape;
|
||||
let shapeFn = (fn, t: t) => t |> xyShape |> fn;
|
||||
// TODO: Obviously fix this, it's terrible
|
||||
// TODO: Obviously fix this, it's terrible. Use interpolation method here.
|
||||
// TODO: Steps could be 1 value, interpolation needs at least 2.
|
||||
let integral = (~cache, t) =>
|
||||
cache
|
||||
|> E.O.default(
|
||||
|
@ -108,7 +109,7 @@ module Continuous = {
|
|||
let pointwiseFmap = (fn, t: t) =>
|
||||
t |> xyShape |> XYShape.pointwiseMap(fn) |> fromShape;
|
||||
let toShape = (t: t): DistTypes.shape => Continuous(t);
|
||||
// TODO: When Roman's PR comes in, fix this bit.
|
||||
// TODO: When Roman's PR comes in, fix this bit. This depends on interpolation, obviously.
|
||||
let xToY = (f, t) =>
|
||||
shapeFn(CdfLibrary.Distribution.findY(f), t)
|
||||
|> DistTypes.MixedPoint.makeContinuous;
|
||||
|
@ -126,6 +127,8 @@ module Discrete = {
|
|||
Dist({
|
||||
type t = DistTypes.discreteShape;
|
||||
type integral = DistTypes.continuousShape;
|
||||
// todo: test this. Remove "stepstoContinuos-move elsewhere"
|
||||
// todo: Make sure this works fine with one value. This is important for step functionality.
|
||||
let integral = (~cache, t) =>
|
||||
cache
|
||||
|> E.O.default(
|
||||
|
@ -138,6 +141,7 @@ module Discrete = {
|
|||
);
|
||||
},
|
||||
);
|
||||
// todo: Fix this with last element
|
||||
let integralSum = (~cache, t) => t |> XYShape.ySum;
|
||||
let minX = XYShape.minX;
|
||||
let maxX = XYShape.maxX;
|
||||
|
@ -145,17 +149,20 @@ module Discrete = {
|
|||
let toShape = (t: t): DistTypes.shape => Discrete(t);
|
||||
let toContinuous = _ => None;
|
||||
let toDiscrete = t => Some(t);
|
||||
let toScaledContinuous = t => None;
|
||||
let toScaledContinuous = _ => None;
|
||||
let toScaledDiscrete = t => Some(t);
|
||||
// todo: Fix this with code that work find recent value and use that instead.
|
||||
let xToY = (f, t) =>
|
||||
CdfLibrary.Distribution.findY(f, t)
|
||||
|> DistTypes.MixedPoint.makeDiscrete;
|
||||
// todo: This should use cache and/or same code as above. FindingY is more complex, should use interpolationType.
|
||||
let integralXtoY = (~cache, f, t) =>
|
||||
t |> XYShape.accumulateYs |> CdfLibrary.Distribution.findY(f);
|
||||
});
|
||||
};
|
||||
|
||||
module Mixed = {
|
||||
type t = DistTypes.mixedShape;
|
||||
let make =
|
||||
(~continuous, ~discrete, ~discreteProbabilityMassFraction)
|
||||
: DistTypes.mixedShape => {
|
||||
|
@ -171,7 +178,8 @@ module Mixed = {
|
|||
discrete: {xs: [||], ys: [||]},
|
||||
} =>
|
||||
None
|
||||
| {discrete: {xs: [|_|], ys: [|_|]}} => None
|
||||
| {continuous, discrete: {xs: [|_|], ys: [|_|]}} =>
|
||||
Some(Continuous(continuous))
|
||||
| {continuous, discrete: {xs: [||], ys: [||]}} =>
|
||||
Some(Continuous(continuous))
|
||||
| {continuous: {xyShape: {xs: [||], ys: [||]}}, discrete} =>
|
||||
|
@ -180,6 +188,7 @@ module Mixed = {
|
|||
};
|
||||
};
|
||||
|
||||
// todo: Put into scaling module
|
||||
let scaleDiscreteFn =
|
||||
({discreteProbabilityMassFraction}: DistTypes.mixedShape, f) =>
|
||||
f *. discreteProbabilityMassFraction;
|
||||
|
@ -188,6 +197,13 @@ module Mixed = {
|
|||
({discreteProbabilityMassFraction}: DistTypes.mixedShape, f) =>
|
||||
f *. (1.0 -. discreteProbabilityMassFraction);
|
||||
|
||||
let scaleContinuous = ({discreteProbabilityMassFraction}: t, continuous) =>
|
||||
continuous
|
||||
|> Continuous.T.scaleBy(~scale=1.0 -. discreteProbabilityMassFraction);
|
||||
|
||||
let scaleDiscrete = ({discreteProbabilityMassFraction}: t, disrete) =>
|
||||
disrete |> Discrete.T.scaleBy(~scale=discreteProbabilityMassFraction);
|
||||
|
||||
module T =
|
||||
Dist({
|
||||
type t = DistTypes.mixedShape;
|
||||
|
@ -211,14 +227,6 @@ module Mixed = {
|
|||
DistTypes.MixedPoint.add(c, d);
|
||||
};
|
||||
|
||||
let scaleContinuous =
|
||||
({discreteProbabilityMassFraction}: t, continuous) =>
|
||||
continuous
|
||||
|> Continuous.T.scaleBy(~scale=1.0 -. discreteProbabilityMassFraction);
|
||||
|
||||
let scaleDiscrete = ({discreteProbabilityMassFraction}: t, disrete) =>
|
||||
disrete |> Discrete.T.scaleBy(~scale=discreteProbabilityMassFraction);
|
||||
|
||||
let toScaledContinuous = ({continuous} as t: t) =>
|
||||
Some(scaleContinuous(t, continuous));
|
||||
|
||||
|
@ -241,10 +249,17 @@ module Mixed = {
|
|||
let dist =
|
||||
discrete
|
||||
|> Discrete.T.Integral.get(~cache=None)
|
||||
|> Continuous.toLinear
|
||||
|> Continuous.T.scaleBy(
|
||||
~scale=discreteProbabilityMassFraction,
|
||||
);
|
||||
dist;
|
||||
Continuous.make(
|
||||
XYShape.combine(
|
||||
Continuous.getShape(cont),
|
||||
Continuous.getShape(dist),
|
||||
),
|
||||
`Linear,
|
||||
);
|
||||
},
|
||||
);
|
||||
};
|
||||
|
@ -268,6 +283,7 @@ module Mixed = {
|
|||
scaleDiscreteFn(t, discrete) +. scaleContinuousFn(t, cont);
|
||||
};
|
||||
|
||||
// TODO: This functionality is kinda weird, because it seems to assume the cdf adds to 1.0 elsewhere, which wouldn't happen here.
|
||||
let pointwiseFmap =
|
||||
(fn, {discrete, continuous, discreteProbabilityMassFraction}: t): t => {
|
||||
{
|
||||
|
@ -285,6 +301,8 @@ module Shape = {
|
|||
type t = DistTypes.shape;
|
||||
type integral = DistTypes.continuousShape;
|
||||
|
||||
// todo: change order of arguments so t goes last.
|
||||
// todo: Think of other name here?
|
||||
let mapToAll = (t: t, (fn1, fn2, fn3)) =>
|
||||
switch (t) {
|
||||
| Mixed(m) => fn1(m)
|
||||
|
@ -388,6 +406,9 @@ module Shape = {
|
|||
|
||||
module DistPlus = {
|
||||
open DistTypes;
|
||||
|
||||
type t = DistTypes.distPlus;
|
||||
|
||||
let make =
|
||||
(
|
||||
~shape,
|
||||
|
@ -396,10 +417,11 @@ module DistPlus = {
|
|||
~unit=UnspecifiedDistribution,
|
||||
(),
|
||||
)
|
||||
: distPlus => {
|
||||
: t => {
|
||||
let integral = Shape.T.Integral.get(~cache=None, shape);
|
||||
{shape, domain, integralCache: integral, unit, guesstimatorString};
|
||||
};
|
||||
|
||||
let update =
|
||||
(
|
||||
~shape=?,
|
||||
|
@ -407,7 +429,7 @@ module DistPlus = {
|
|||
~domain=?,
|
||||
~unit=?,
|
||||
~guesstimatorString=?,
|
||||
t: distPlus,
|
||||
t: t,
|
||||
) => {
|
||||
shape: E.O.default(t.shape, shape),
|
||||
integralCache: E.O.default(t.integralCache, integralCache),
|
||||
|
@ -416,29 +438,32 @@ module DistPlus = {
|
|||
guesstimatorString: E.O.default(t.guesstimatorString, guesstimatorString),
|
||||
};
|
||||
|
||||
let domainIncludedProbabilityMass = (t: t) =>
|
||||
Domain.includedProbabilityMass(t.domain);
|
||||
|
||||
let domainIncludedProbabilityMassAdjustment = (t: t, f) =>
|
||||
f *. Domain.includedProbabilityMass(t.domain);
|
||||
|
||||
let toShape = ({shape, _}: t) => shape;
|
||||
|
||||
let shapeFn = (fn, {shape}: t) => fn(shape);
|
||||
|
||||
module T =
|
||||
Dist({
|
||||
type t = DistTypes.distPlus;
|
||||
type integral = DistTypes.distPlus;
|
||||
let toShape = ({shape, _}: t) => shape;
|
||||
let shapeFn = (fn, t: t) => t |> toShape |> fn;
|
||||
let toShape = toShape;
|
||||
let toContinuous = shapeFn(Shape.T.toContinuous);
|
||||
let toDiscrete = shapeFn(Shape.T.toDiscrete);
|
||||
// todo: Adjust for total mass.
|
||||
|
||||
let domainIncludedProbabilityMass = (t: t) =>
|
||||
Domain.includedProbabilityMass(t.domain);
|
||||
|
||||
let domainIncludedProbabilityMassAdjustment = (t: t, f) =>
|
||||
f *. Domain.includedProbabilityMass(t.domain);
|
||||
|
||||
let toScaledContinuous = (t: t) => {
|
||||
t
|
||||
|> toShape
|
||||
|> Shape.T.toScaledContinuous
|
||||
|> E.O.fmap(
|
||||
Continuous.T.pointwiseFmap(r =>
|
||||
r *. domainIncludedProbabilityMass(t)
|
||||
Continuous.T.pointwiseFmap(
|
||||
domainIncludedProbabilityMassAdjustment(t),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
@ -475,9 +500,41 @@ module DistPlus = {
|
|||
let integralSum = (~cache as _, t: t) =>
|
||||
Shape.T.Integral.sum(~cache=Some(t.integralCache), toShape(t));
|
||||
|
||||
// TODO: Fix this below, obviously. Adjust for limit.
|
||||
// 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));
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
module DistPlusTime = {
|
||||
open DistTypes;
|
||||
open DistPlus;
|
||||
|
||||
type t = DistTypes.distPlus;
|
||||
|
||||
let unitToJson = ({unit}: t) => unit |> DistTypes.DistributionUnit.toJson;
|
||||
|
||||
let timeVector = ({unit}: t) =>
|
||||
switch (unit) {
|
||||
| TimeDistribution(timeVector) => Some(timeVector)
|
||||
| UnspecifiedDistribution => None
|
||||
};
|
||||
|
||||
let timeInVectorToX = (f: TimeTypes.timeInVector, t: t) => {
|
||||
let timeVector = t |> timeVector;
|
||||
timeVector |> E.O.fmap(TimeTypes.RelativeTimePoint.toXValue(_, f));
|
||||
};
|
||||
|
||||
let xToY = (f: TimeTypes.timeInVector, t: t) => {
|
||||
timeInVectorToX(f, t) |> E.O.fmap(DistPlus.T.xToY(_, t));
|
||||
};
|
||||
|
||||
module Integral = {
|
||||
include DistPlus.T.Integral;
|
||||
let xToY = (~cache as _, f: TimeTypes.timeInVector, t: t) => {
|
||||
timeInVectorToX(f, t)
|
||||
|> E.O.fmap(x => DistPlus.T.Integral.xToY(~cache=None, x, t));
|
||||
};
|
||||
};
|
||||
};
|
|
@ -50,11 +50,11 @@ module TimePoint = {
|
|||
MomentRe.diff(timeVector.zero, moment, timeVector.unit);
|
||||
};
|
||||
|
||||
module RelativeTimePoint = {
|
||||
type timeInVector =
|
||||
| Time(MomentRe.Moment.t)
|
||||
| XValue(float);
|
||||
type timeInVector =
|
||||
| Time(MomentRe.Moment.t)
|
||||
| XValue(float);
|
||||
|
||||
module RelativeTimePoint = {
|
||||
let toTime = (timeVector: timeVector, timeInVector: timeInVector) =>
|
||||
switch (timeInVector) {
|
||||
| Time(r) => r
|
||||
|
|
|
@ -23,6 +23,22 @@ let fromArray = ((xs, ys)): t => {xs, ys};
|
|||
let fromArrays = (xs, ys): t => {xs, ys};
|
||||
let pointwiseMap = (fn, t: t): t => {xs: t.xs, ys: t.ys |> E.A.fmap(fn)};
|
||||
|
||||
let compare = (a: float, b: float) => a > b ? 1 : (-1);
|
||||
|
||||
let comparePoints = ((x1: float, y1: float), (x2: float, y2: float)) =>
|
||||
switch (x1 == x2, y1 == y2) {
|
||||
| (false, _) => compare(x1, x2)
|
||||
| (true, false) => compare(y1, y2)
|
||||
| (true, true) => (-1)
|
||||
};
|
||||
|
||||
let combine = (t1: t, t2: t) => {
|
||||
let totalLength = E.A.length(t1.xs) + E.A.length(t2.xs);
|
||||
let array = Belt.Array.concat(zip(t1), zip(t2));
|
||||
Array.sort(comparePoints, array);
|
||||
array |> Belt.Array.unzip |> fromArray;
|
||||
};
|
||||
|
||||
let intersperce = (t1: t, t2: t) => {
|
||||
let items: ref(array((float, float))) = ref([||]);
|
||||
let t1 = zip(t1);
|
||||
|
|
|
@ -22,7 +22,7 @@ let propValue = (t: Prop.Value.t) => {
|
|||
DistPlusIngredients.toDistPlus(~sampleCount=1000, r);
|
||||
switch (newDistribution) {
|
||||
| Some(distribution) =>
|
||||
<div> <DistPlusChart distPlus=distribution /> </div>
|
||||
<div> <DistPlusPlot distPlus=distribution /> </div>
|
||||
| None => "Something went wrong" |> ReasonReact.string
|
||||
};
|
||||
| FloatCdf(_) => <div />
|
||||
|
|
|
@ -109,14 +109,20 @@ module Model = {
|
|||
|
||||
// TODO: Fixe number that integral is calculated for
|
||||
let getGlobalCatastropheChance = dateTime => {
|
||||
let model = GlobalCatastrophe.Model.make(dateTime);
|
||||
switch (model) {
|
||||
| Prop.Value.DistPlusIngredients(distPlusIngredients) =>
|
||||
distPlusIngredients
|
||||
|> DistPlusIngredients.toDistPlus(~sampleCount=1000)
|
||||
|> E.O.fmap(Distributions.DistPlus.T.Integral.xToY(~cache=None, 18.0))
|
||||
| _ => None
|
||||
};
|
||||
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);
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
let make =
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
let guesstimatorString = "20 to 80";
|
||||
let guesstimatorString = "floor(10 to 20)";
|
||||
|
||||
let makeI = (currentDateTime: MomentRe.Moment.t) => {
|
||||
DistPlusIngredients.make(
|
||||
~guesstimatorString,
|
||||
~unit=TimeDistribution({zero: currentDateTime, unit: `years}),
|
||||
(),
|
||||
);
|
||||
};
|
||||
module Model = {
|
||||
let make = (currentDateTime: MomentRe.Moment.t) => {
|
||||
let distPlusIngredients =
|
||||
|
|
Loading…
Reference in New Issue
Block a user