105 lines
2.7 KiB
ReasonML
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))); |