Show graph of TimeLimitedDomainCdf

This commit is contained in:
Ozzie Gooen 2020-02-14 21:53:47 +00:00
parent 5970f46c06
commit 320ed0d477
4 changed files with 96 additions and 81 deletions

View File

@ -3,6 +3,8 @@ type t = {
domainMaxX: float,
};
let make = (~distribution, ~domainMaxX): t => {distribution, domainMaxX};
let fromCdf = (cdf: Types.cdf, domainMaxX: float, probabilityAtMaxX: float) => {
let distribution: Types.distribution = {
xs: cdf.xs,

View File

@ -10,45 +10,75 @@ type timeUnit = [
| `years
];
type timeVector = {
zero: MomentRe.Moment.t,
unit: timeUnit,
};
type timePoint = {
timeVector,
value: float,
};
module TimePoint = {
let fromTimeVector = (timeVector, value): timePoint => {timeVector, value};
let toMoment = (timePoint: timePoint) => {
timePoint.timeVector.zero
|> MomentRe.Moment.add(
~duration=
MomentRe.duration(timePoint.value, timePoint.timeVector.unit),
);
};
let fromMoment = (timeVector: timeVector, moment: MomentRe.Moment.t) =>
MomentRe.diff(timeVector.zero, moment, timeVector.unit);
};
module RelativeTimePoint = {
type timeInVector =
| Time(MomentRe.Moment.t)
| XValue(float);
let toTime = (timeVector: timeVector, timeInVector: timeInVector) =>
switch (timeInVector) {
| Time(r) => r
| XValue(r) =>
timeVector.zero
|> MomentRe.Moment.add(~duration=MomentRe.duration(r, timeVector.unit))
};
let _timeToX = (time, timeStart, timeUnit) =>
MomentRe.diff(timeStart, time, timeUnit);
let toXValue = (timeVector: timeVector, timeInVector: timeInVector) =>
switch (timeInVector) {
| Time(r) => _timeToX(r, timeVector.zero, timeVector.unit)
| XValue(r) => r
};
};
type t = {
timeUnit,
timeStart: MomentRe.Moment.t,
timeVector,
limitedDomainCdf: LimitedDomainCdf.t,
};
module XSpecification = {
type xSpecification =
| Time(MomentRe.Moment.t)
| DifferenceFromStart(float, timeUnit)
| CdfXCoordinate(float);
let toTime = (t: t, xSpecification: xSpecification) =>
switch (xSpecification) {
| Time(r) => r
| DifferenceFromStart(r, unit) =>
t.timeStart
|> MomentRe.Moment.add(~duration=MomentRe.duration(r, unit))
| CdfXCoordinate(r) =>
t.timeStart
|> MomentRe.Moment.add(~duration=MomentRe.duration(r, t.timeUnit))
let make =
(
~timeVector: timeVector,
~distribution: Types.distribution,
~probabilityAtMaxX: float,
~maxX: [ | `time(MomentRe.Moment.t) | `x(float)],
)
: t => {
let domainMaxX =
switch (maxX) {
| `time(m) => TimePoint.fromMoment(timeVector, m)
| `x(r) => r
};
let rec toCdfXCoordinate = (t: t, xSpecification: xSpecification) =>
switch (xSpecification) {
| Time(r) => MomentRe.diff(t.timeStart, r, t.timeUnit)
| DifferenceFromStart(r, unit) =>
let newTime = toTime(t, DifferenceFromStart(r, unit));
toCdfXCoordinate(t, Time(newTime));
| CdfXCoordinate(r) => r
};
let fromDifference = (~t: t, ~duration: float, ~unit=t.timeUnit, ()) =>
Time(
MomentRe.Moment.add(
~duration=MomentRe.duration(duration, unit),
t.timeStart,
),
);
let limitedDomainCdf =
LimitedDomainCdf.fromCdf(distribution, domainMaxX, probabilityAtMaxX);
{timeVector, limitedDomainCdf};
};
let probabilityBeforeDomainMax = (t: t) =>
@ -57,18 +87,19 @@ let probabilityBeforeDomainMax = (t: t) =>
let domainMaxX = (t: t) =>
LimitedDomainCdf.probabilityBeforeDomainMax(t.limitedDomainCdf);
let probability = (t: t, x: XSpecification.xSpecification) =>
LimitedDomainCdf.probability(
t.limitedDomainCdf,
XSpecification.toCdfXCoordinate(t, x),
);
let probability = (t: t, m: MomentRe.Moment.t) => {
RelativeTimePoint.toXValue(t.timeVector, Time(m))
|> LimitedDomainCdf.probability(t.limitedDomainCdf);
};
let probabilityInverse = (t: t, y: float) =>
XSpecification.CdfXCoordinate(
LimitedDomainCdf.probabilityInverse(t.limitedDomainCdf, y),
);
LimitedDomainCdf.probabilityInverse(t.limitedDomainCdf, y)
|> (r => RelativeTimePoint.toTime(t.timeVector, XValue(r)));
let cumulativeProbability = (t: t, m: MomentRe.Moment.t) =>
RelativeTimePoint.toXValue(t.timeVector, Time(m))
|> LimitedDomainCdf.cumulativeProbability(t.limitedDomainCdf);
let cumulativeProbabilityInverse = (t: t, y: float) =>
XSpecification.CdfXCoordinate(
LimitedDomainCdf.cumulativeProbabilityInverse(t.limitedDomainCdf, y),
);
LimitedDomainCdf.cumulativeProbabilityInverse(t.limitedDomainCdf, y)
|> (r => RelativeTimePoint.toTime(t.timeVector, XValue(r)));

View File

@ -15,6 +15,7 @@ module Value = {
| FloatPoint(float)
| Probability(float)
| Conditional(conditional)
| TimeLimitedDomainCdf(TimeLimitedDomainCdf.t)
| ConditionalArray(array(conditional))
| FloatCdf(string);
@ -27,6 +28,7 @@ module Value = {
}
| SelectSingle(r) => r
| FloatCdf(r) => r
| TimeLimitedDomainCdf(_) => ""
| Probability(r) => (r *. 100. |> Js.Float.toFixed) ++ "%"
| DateTime(r) => r |> MomentRe.Moment.defaultFormat
| FloatPoint(r) => r |> Js.Float.toFixed
@ -49,6 +51,9 @@ module Value = {
| SelectSingle(r) => r |> ReasonReact.string
| ConditionalArray(r) => "Array" |> ReasonReact.string
| Conditional(r) => r.name |> ReasonReact.string
| TimeLimitedDomainCdf(r) =>
let cdf: Types.distribution = r.limitedDomainCdf.distribution;
<> <Chart height=100 data={cdf |> Types.toJs} /> </>;
| FloatCdf(r) =>
let cdf: Types.distribution =
CdfLibrary.Distribution.fromString(r, 2000);

View File

@ -1,7 +1,15 @@
module Model = {
let make = (dateTime: MomentRe.Moment.t, currentDateTime: MomentRe.Moment.t) => {
let yearDiff = MomentRe.diff(dateTime, currentDateTime, `days) /. 365.;
Prop.Value.Probability(0.001 *. yearDiff);
let make = (currentDateTime: MomentRe.Moment.t) => {
let yearsFromNow = "normal(50,30)";
let dist = CdfLibrary.Distribution.fromString(yearsFromNow, 1000);
let timeLimitedDomain =
TimeLimitedDomainCdf.make(
~timeVector={zero: currentDateTime, unit: `years},
~distribution=dist,
~probabilityAtMaxX=0.7,
~maxX=`x(200.),
);
Prop.Value.TimeLimitedDomainCdf(timeLimitedDomain);
};
};
@ -10,8 +18,7 @@ module Interface = {
let run = (p: Prop.Combo.t) => {
switch (Prop.Combo.InputValues.toValueArray(p)) {
| [|Some(DateTime(intendedYear)), Some(DateTime(currentYear))|] =>
Some(Model.make(intendedYear, currentYear))
| [|Some(DateTime(currentYear))|] => Some(Model.make(currentYear))
| _ => None
};
};
@ -22,37 +29,7 @@ module Interface = {
description: "The chances of having at least one catastrophe per year in the future, assuming no other catastrophe until then.",
version: "1.0.0",
author: "Ozzie Gooen",
inputTypes: [|
TypeWithMetadata.make(
~name=dayKey,
~type_=
DateTime({
default:
Some(
MomentRe.Moment.add(
~duration=MomentRe.duration(5., `years),
MomentRe.momentNow(),
),
),
min:
Some(
MomentRe.Moment.subtract(
~duration=MomentRe.duration(20., `years),
MomentRe.momentNow(),
),
),
max:
Some(
MomentRe.Moment.add(
~duration=MomentRe.duration(20., `years),
MomentRe.momentNow(),
),
),
}),
(),
),
TypeWithMetadata.currentYear,
|],
inputTypes: [|TypeWithMetadata.currentYear|],
outputTypes: [||],
run,
};