squiggle/src/TimeLimitedDomainCdf.re
2020-02-14 21:53:47 +00:00

105 lines
2.7 KiB
ReasonML

type timeUnit = [
| `days
| `hours
| `milliseconds
| `minutes
| `months
| `quarters
| `seconds
| `weeks
| `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 = {
timeVector,
limitedDomainCdf: LimitedDomainCdf.t,
};
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 limitedDomainCdf =
LimitedDomainCdf.fromCdf(distribution, domainMaxX, probabilityAtMaxX);
{timeVector, limitedDomainCdf};
};
let probabilityBeforeDomainMax = (t: t) =>
LimitedDomainCdf.probabilityBeforeDomainMax(t.limitedDomainCdf);
let domainMaxX = (t: t) =>
LimitedDomainCdf.probabilityBeforeDomainMax(t.limitedDomainCdf);
let probability = (t: t, m: MomentRe.Moment.t) => {
RelativeTimePoint.toXValue(t.timeVector, Time(m))
|> LimitedDomainCdf.probability(t.limitedDomainCdf);
};
let probabilityInverse = (t: t, y: float) =>
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) =>
LimitedDomainCdf.cumulativeProbabilityInverse(t.limitedDomainCdf, y)
|> (r => RelativeTimePoint.toTime(t.timeVector, XValue(r)));