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, domainMaxX: float,
}; };
let make = (~distribution, ~domainMaxX): t => {distribution, domainMaxX};
let fromCdf = (cdf: Types.cdf, domainMaxX: float, probabilityAtMaxX: float) => { let fromCdf = (cdf: Types.cdf, domainMaxX: float, probabilityAtMaxX: float) => {
let distribution: Types.distribution = { let distribution: Types.distribution = {
xs: cdf.xs, xs: cdf.xs,

View File

@ -10,45 +10,75 @@ type timeUnit = [
| `years | `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 = { type t = {
timeUnit, timeVector,
timeStart: MomentRe.Moment.t,
limitedDomainCdf: LimitedDomainCdf.t, limitedDomainCdf: LimitedDomainCdf.t,
}; };
module XSpecification = { let make =
type xSpecification = (
| Time(MomentRe.Moment.t) ~timeVector: timeVector,
| DifferenceFromStart(float, timeUnit) ~distribution: Types.distribution,
| CdfXCoordinate(float); ~probabilityAtMaxX: float,
~maxX: [ | `time(MomentRe.Moment.t) | `x(float)],
let toTime = (t: t, xSpecification: xSpecification) => )
switch (xSpecification) { : t => {
| Time(r) => r let domainMaxX =
| DifferenceFromStart(r, unit) => switch (maxX) {
t.timeStart | `time(m) => TimePoint.fromMoment(timeVector, m)
|> MomentRe.Moment.add(~duration=MomentRe.duration(r, unit)) | `x(r) => r
| CdfXCoordinate(r) =>
t.timeStart
|> MomentRe.Moment.add(~duration=MomentRe.duration(r, t.timeUnit))
}; };
let limitedDomainCdf =
let rec toCdfXCoordinate = (t: t, xSpecification: xSpecification) => LimitedDomainCdf.fromCdf(distribution, domainMaxX, probabilityAtMaxX);
switch (xSpecification) { {timeVector, limitedDomainCdf};
| 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 probabilityBeforeDomainMax = (t: t) => let probabilityBeforeDomainMax = (t: t) =>
@ -57,18 +87,19 @@ let probabilityBeforeDomainMax = (t: t) =>
let domainMaxX = (t: t) => let domainMaxX = (t: t) =>
LimitedDomainCdf.probabilityBeforeDomainMax(t.limitedDomainCdf); LimitedDomainCdf.probabilityBeforeDomainMax(t.limitedDomainCdf);
let probability = (t: t, x: XSpecification.xSpecification) => let probability = (t: t, m: MomentRe.Moment.t) => {
LimitedDomainCdf.probability( RelativeTimePoint.toXValue(t.timeVector, Time(m))
t.limitedDomainCdf, |> LimitedDomainCdf.probability(t.limitedDomainCdf);
XSpecification.toCdfXCoordinate(t, x), };
);
let probabilityInverse = (t: t, y: float) => 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) => 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) | FloatPoint(float)
| Probability(float) | Probability(float)
| Conditional(conditional) | Conditional(conditional)
| TimeLimitedDomainCdf(TimeLimitedDomainCdf.t)
| ConditionalArray(array(conditional)) | ConditionalArray(array(conditional))
| FloatCdf(string); | FloatCdf(string);
@ -27,6 +28,7 @@ module Value = {
} }
| SelectSingle(r) => r | SelectSingle(r) => r
| FloatCdf(r) => r | FloatCdf(r) => r
| TimeLimitedDomainCdf(_) => ""
| Probability(r) => (r *. 100. |> Js.Float.toFixed) ++ "%" | Probability(r) => (r *. 100. |> Js.Float.toFixed) ++ "%"
| DateTime(r) => r |> MomentRe.Moment.defaultFormat | DateTime(r) => r |> MomentRe.Moment.defaultFormat
| FloatPoint(r) => r |> Js.Float.toFixed | FloatPoint(r) => r |> Js.Float.toFixed
@ -49,6 +51,9 @@ module Value = {
| SelectSingle(r) => r |> ReasonReact.string | SelectSingle(r) => r |> ReasonReact.string
| ConditionalArray(r) => "Array" |> ReasonReact.string | ConditionalArray(r) => "Array" |> ReasonReact.string
| Conditional(r) => r.name |> 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) => | FloatCdf(r) =>
let cdf: Types.distribution = let cdf: Types.distribution =
CdfLibrary.Distribution.fromString(r, 2000); CdfLibrary.Distribution.fromString(r, 2000);

View File

@ -1,7 +1,15 @@
module Model = { module Model = {
let make = (dateTime: MomentRe.Moment.t, currentDateTime: MomentRe.Moment.t) => { let make = (currentDateTime: MomentRe.Moment.t) => {
let yearDiff = MomentRe.diff(dateTime, currentDateTime, `days) /. 365.; let yearsFromNow = "normal(50,30)";
Prop.Value.Probability(0.001 *. yearDiff); 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) => { let run = (p: Prop.Combo.t) => {
switch (Prop.Combo.InputValues.toValueArray(p)) { switch (Prop.Combo.InputValues.toValueArray(p)) {
| [|Some(DateTime(intendedYear)), Some(DateTime(currentYear))|] => | [|Some(DateTime(currentYear))|] => Some(Model.make(currentYear))
Some(Model.make(intendedYear, currentYear))
| _ => None | _ => 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.", description: "The chances of having at least one catastrophe per year in the future, assuming no other catastrophe until then.",
version: "1.0.0", version: "1.0.0",
author: "Ozzie Gooen", author: "Ozzie Gooen",
inputTypes: [| inputTypes: [|TypeWithMetadata.currentYear|],
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,
|],
outputTypes: [||], outputTypes: [||],
run, run,
}; };