module type dist = { type t type integral let minX: t => float let maxX: t => float let mapY: ( ~integralSumCacheFn: float => option=?, ~integralCacheFn: PointSetTypes.continuousShape => option=?, ~fn: float => float, t, ) => t let mapYResult: ( ~integralSumCacheFn: float => option=?, ~integralCacheFn: PointSetTypes.continuousShape => option=?, ~fn: float => result, t, ) => result let xToY: (float, t) => PointSetTypes.mixedPoint let toPointSetDist: t => PointSetTypes.pointSetDist let toContinuous: t => option let toDiscrete: t => option let normalize: t => t let toDiscreteProbabilityMassFraction: t => float let downsample: (int, t) => t let truncate: (option, option, t) => t let updateIntegralCache: (option, t) => t let integral: t => integral let integralEndY: t => float let integralXtoY: (float, t) => float let integralYtoX: (float, t) => float let mean: t => float let variance: t => float let klDivergence: (t, t) => result } module Dist = (T: dist) => { type t = T.t type integral = T.integral let minX = T.minX let maxX = T.maxX let integral = T.integral let xTotalRange = (t: t) => maxX(t) -. minX(t) let mapY = T.mapY let mapYResult = T.mapYResult let xToY = T.xToY let downsample = T.downsample let toPointSetDist = T.toPointSetDist let toDiscreteProbabilityMassFraction = T.toDiscreteProbabilityMassFraction let toContinuous = T.toContinuous let toDiscrete = T.toDiscrete let normalize = T.normalize let truncate = T.truncate let mean = T.mean let variance = T.variance let integralEndY = T.integralEndY let klDivergence = T.klDivergence let updateIntegralCache = T.updateIntegralCache module Integral = { type t = T.integral let get = T.integral let xToY = T.integralXtoY let yToX = T.integralYtoX let sum = T.integralEndY } } module Common = { let combineIntegralSums = ( combineFn: (float, float) => option, t1IntegralSumCache: option, t2IntegralSumCache: option, ) => switch (t1IntegralSumCache, t2IntegralSumCache) { | (None, _) | (_, None) => None | (Some(s1), Some(s2)) => combineFn(s1, s2) } let combineIntegrals = ( combineFn: ( PointSetTypes.continuousShape, PointSetTypes.continuousShape, ) => option, t1IntegralCache: option, t2IntegralCache: option, ) => switch (t1IntegralCache, t2IntegralCache) { | (None, _) | (_, None) => None | (Some(s1), Some(s2)) => combineFn(s1, s2) } }