Simple module-functor work
This commit is contained in:
parent
da172bfa94
commit
0d2c53eca4
|
@ -14,38 +14,15 @@ let max = (f1: option(float), f2: option(float)) =>
|
|||
| (None, None) => None
|
||||
};
|
||||
|
||||
type mixedPoint = {
|
||||
continuous: float,
|
||||
discrete: float,
|
||||
};
|
||||
|
||||
module MixedPoint = {
|
||||
type t = mixedPoint;
|
||||
let toContinuousValue = (t: t) => t.continuous;
|
||||
let toDiscreteValue = (t: t) => t.discrete;
|
||||
let makeContinuous = (continuous: float): t => {continuous, discrete: 0.0};
|
||||
let makeDiscrete = (discrete: float): t => {continuous: 0.0, discrete};
|
||||
|
||||
let fmap = (fn, t: t) => {
|
||||
continuous: fn(t.continuous),
|
||||
discrete: fn(t.discrete),
|
||||
};
|
||||
|
||||
let combine2 = (fn, c: t, d: t): t => {
|
||||
continuous: fn(c.continuous, d.continuous),
|
||||
discrete: fn(c.discrete, d.discrete),
|
||||
};
|
||||
|
||||
let add = combine2((a, b) => a +. b);
|
||||
};
|
||||
|
||||
module type dist = {
|
||||
type t;
|
||||
let minX: t => option(float);
|
||||
let maxX: t => option(float);
|
||||
let pointwiseFmap: (float => float, t) => t;
|
||||
let xToY: (float, t) => mixedPoint;
|
||||
let shape: t => DistributionTypes.shape;
|
||||
let xToY: (float, t) => DistributionTypes.mixedPoint;
|
||||
let toShape: t => DistributionTypes.shape;
|
||||
let toContinuous: t => option(DistributionTypes.continuousShape);
|
||||
let toDiscrete: t => option(DistributionTypes.discreteShape);
|
||||
|
||||
type integral;
|
||||
let integral: (~cache: option(integral), t) => integral;
|
||||
|
@ -60,7 +37,11 @@ module Dist = (T: dist) => {
|
|||
let maxX = T.maxX;
|
||||
let pointwiseFmap = T.pointwiseFmap;
|
||||
let xToY = T.xToY;
|
||||
let shape = T.shape;
|
||||
let toShape = T.toShape;
|
||||
let toContinuous = T.toContinuous;
|
||||
let toDiscrete = T.toDiscrete;
|
||||
let scaleBy = (~scale=1.0, t: t) =>
|
||||
t |> pointwiseFmap((r: float) => r *. scale);
|
||||
|
||||
module Integral = {
|
||||
type t = T.integral;
|
||||
|
@ -70,228 +51,285 @@ module Dist = (T: dist) => {
|
|||
};
|
||||
};
|
||||
|
||||
module Continuous =
|
||||
Dist({
|
||||
type t = DistributionTypes.continuousShape;
|
||||
type integral = DistributionTypes.continuousShape;
|
||||
let make = (shape, interpolation): t => {shape, interpolation};
|
||||
let fromShape = shape => make(shape, `Linear);
|
||||
let shape = (t: t) => t.shape;
|
||||
let shapeFn = (fn, t: t) => t |> shape |> fn;
|
||||
let shape = (t: t) => t.shape;
|
||||
let integral = (~cache, t) =>
|
||||
cache
|
||||
|> E.O.default(
|
||||
t
|
||||
|> shape
|
||||
|> XYShape.Range.integrateWithTriangles
|
||||
|> E.O.toExt("")
|
||||
|> fromShape,
|
||||
);
|
||||
// This seems wrong, we really want the ending bit, I'd assume
|
||||
let integralSum = (~cache, t) =>
|
||||
t |> integral(~cache) |> shape |> XYShape.ySum;
|
||||
let minX = shapeFn(XYShape.minX);
|
||||
let maxX = shapeFn(XYShape.maxX);
|
||||
let pointwiseFmap = (fn, t: t) =>
|
||||
t |> shape |> XYShape.pointwiseMap(fn) |> fromShape;
|
||||
let shape = (t: t): DistributionTypes.shape => Continuous(t);
|
||||
let xToY = (f, t) =>
|
||||
shapeFn(CdfLibrary.Distribution.findY(f), t)
|
||||
|> MixedPoint.makeContinuous;
|
||||
let integralXtoY = (~cache, f, t) =>
|
||||
t |> integral(~cache) |> shapeFn(CdfLibrary.Distribution.findY(f));
|
||||
});
|
||||
module Continuous = {
|
||||
type t = DistributionTypes.continuousShape;
|
||||
let xyShape = (t: t) => t.xyShape;
|
||||
let getShape = (t: t) => t.xyShape;
|
||||
let interpolation = (t: t) => t.interpolation;
|
||||
let make = (xyShape, interpolation): t => {xyShape, interpolation};
|
||||
let fromShape = xyShape => make(xyShape, `Linear);
|
||||
let shapeMap = (fn, {xyShape, interpolation}: t): t => {
|
||||
xyShape: fn(xyShape),
|
||||
interpolation,
|
||||
};
|
||||
let oShapeMap =
|
||||
(fn, {xyShape, interpolation}: t)
|
||||
: option(DistributionTypes.continuousShape) =>
|
||||
fn(xyShape) |> E.O.fmap(xyShape => make(xyShape, interpolation));
|
||||
|
||||
module Discrete =
|
||||
Dist({
|
||||
type t = DistributionTypes.discreteShape;
|
||||
type integral = DistributionTypes.continuousShape;
|
||||
let integral = (~cache, t) =>
|
||||
cache
|
||||
|> E.O.default(t |> XYShape.accumulateYs |> Shape.Continuous.fromShape);
|
||||
let integralSum = (~cache, t) => t |> XYShape.ySum;
|
||||
let minX = XYShape.minX;
|
||||
let maxX = XYShape.maxX;
|
||||
let pointwiseFmap = XYShape.pointwiseMap;
|
||||
let shape = (t: t): DistributionTypes.shape => Discrete(t);
|
||||
let xToY = (f, t) =>
|
||||
CdfLibrary.Distribution.findY(f, t) |> MixedPoint.makeDiscrete;
|
||||
let integralXtoY = (~cache, f, t) =>
|
||||
t |> XYShape.accumulateYs |> CdfLibrary.Distribution.findY(f);
|
||||
});
|
||||
module T =
|
||||
Dist({
|
||||
type t = DistributionTypes.continuousShape;
|
||||
type integral = DistributionTypes.continuousShape;
|
||||
let shapeFn = (fn, t: t) => t |> xyShape |> fn;
|
||||
let integral = (~cache, t) =>
|
||||
cache
|
||||
|> E.O.default(
|
||||
t
|
||||
|> xyShape
|
||||
|> XYShape.Range.integrateWithTriangles
|
||||
|> E.O.toExt("")
|
||||
|> fromShape,
|
||||
);
|
||||
// This seems wrong, we really want the ending bit, I'd assume
|
||||
let integralSum = (~cache, t) =>
|
||||
t |> integral(~cache) |> xyShape |> XYShape.ySum;
|
||||
let minX = shapeFn(XYShape.minX);
|
||||
let maxX = shapeFn(XYShape.maxX);
|
||||
let pointwiseFmap = (fn, t: t) =>
|
||||
t |> xyShape |> XYShape.pointwiseMap(fn) |> fromShape;
|
||||
let toShape = (t: t): DistributionTypes.shape => Continuous(t);
|
||||
let xToY = (f, t) =>
|
||||
shapeFn(CdfLibrary.Distribution.findY(f), t)
|
||||
|> DistributionTypes.MixedPoint.makeContinuous;
|
||||
let integralXtoY = (~cache, f, t) =>
|
||||
t |> integral(~cache) |> shapeFn(CdfLibrary.Distribution.findY(f));
|
||||
let toContinuous = t => Some(t);
|
||||
let toDiscrete = _ => None;
|
||||
});
|
||||
};
|
||||
|
||||
module Mixed =
|
||||
Dist({
|
||||
type t = DistributionTypes.mixedShape;
|
||||
type integral = DistributionTypes.continuousShape;
|
||||
let minX = ({continuous, discrete}: t) =>
|
||||
min(Continuous.minX(continuous), Discrete.minX(discrete));
|
||||
let maxX = ({continuous, discrete}: t) =>
|
||||
max(Continuous.maxX(continuous), Discrete.maxX(discrete));
|
||||
let shape = (t: t): DistributionTypes.shape => Mixed(t);
|
||||
let xToY =
|
||||
(f, {discrete, continuous, discreteProbabilityMassFraction}: t) => {
|
||||
let c =
|
||||
continuous
|
||||
|> Continuous.xToY(f)
|
||||
|> MixedPoint.fmap(e => e *. (1. -. discreteProbabilityMassFraction));
|
||||
let d =
|
||||
module Discrete = {
|
||||
module T =
|
||||
Dist({
|
||||
type t = DistributionTypes.discreteShape;
|
||||
type integral = DistributionTypes.continuousShape;
|
||||
let integral = (~cache, t) =>
|
||||
cache
|
||||
|> E.O.default(t |> XYShape.accumulateYs |> Continuous.fromShape);
|
||||
let integralSum = (~cache, t) => t |> XYShape.ySum;
|
||||
let minX = XYShape.minX;
|
||||
let maxX = XYShape.maxX;
|
||||
let pointwiseFmap = XYShape.pointwiseMap;
|
||||
let toShape = (t: t): DistributionTypes.shape => Discrete(t);
|
||||
let toContinuous = _ => None;
|
||||
let toDiscrete = t => Some(t);
|
||||
let xToY = (f, t) =>
|
||||
CdfLibrary.Distribution.findY(f, t)
|
||||
|> DistributionTypes.MixedPoint.makeDiscrete;
|
||||
let integralXtoY = (~cache, f, t) =>
|
||||
t |> XYShape.accumulateYs |> CdfLibrary.Distribution.findY(f);
|
||||
});
|
||||
};
|
||||
|
||||
module Mixed = {
|
||||
module T =
|
||||
Dist({
|
||||
type t = DistributionTypes.mixedShape;
|
||||
type integral = DistributionTypes.continuousShape;
|
||||
let minX = ({continuous, discrete}: t) =>
|
||||
min(Continuous.T.minX(continuous), Discrete.T.minX(discrete));
|
||||
let maxX = ({continuous, discrete}: t) =>
|
||||
max(Continuous.T.maxX(continuous), Discrete.T.maxX(discrete));
|
||||
let toShape = (t: t): DistributionTypes.shape => Mixed(t);
|
||||
let toContinuous = ({continuous}: t) => Some(continuous);
|
||||
let toDiscrete = ({discrete}: t) => Some(discrete);
|
||||
let xToY =
|
||||
(f, {discrete, continuous, discreteProbabilityMassFraction}: t) => {
|
||||
let c =
|
||||
continuous
|
||||
|> Continuous.T.xToY(f)
|
||||
|> DistributionTypes.MixedPoint.fmap(e =>
|
||||
e *. (1. -. discreteProbabilityMassFraction)
|
||||
);
|
||||
let d =
|
||||
discrete
|
||||
|> Discrete.T.xToY(f)
|
||||
|> DistributionTypes.MixedPoint.fmap(e =>
|
||||
e *. discreteProbabilityMassFraction
|
||||
);
|
||||
DistributionTypes.MixedPoint.add(c, d);
|
||||
};
|
||||
|
||||
// todo: FixMe
|
||||
let scaledContinuousComponent =
|
||||
({continuous, discreteProbabilityMassFraction}: t)
|
||||
: option(DistributionTypes.continuousShape) =>
|
||||
Some(continuous);
|
||||
|
||||
let scaledDiscreteComponent =
|
||||
({discrete, discreteProbabilityMassFraction}: t)
|
||||
: DistributionTypes.continuousShape =>
|
||||
Continuous.make(
|
||||
Discrete.T.pointwiseFmap(
|
||||
f => f *. discreteProbabilityMassFraction,
|
||||
discrete,
|
||||
),
|
||||
`Stepwise,
|
||||
);
|
||||
|
||||
// TODO: Add these two directly, once interpolation is added.
|
||||
let integral = (~cache, t) => {
|
||||
// let cont = scaledContinuousComponent(t);
|
||||
// let discrete = scaledDiscreteComponent(t);
|
||||
switch (cache) {
|
||||
| Some(cache) => cache
|
||||
| None => scaledContinuousComponent(t) |> E.O.toExt("")
|
||||
};
|
||||
};
|
||||
|
||||
let integralSum =
|
||||
(
|
||||
~cache,
|
||||
{discrete, continuous, discreteProbabilityMassFraction}: t,
|
||||
) => {
|
||||
switch (cache) {
|
||||
| Some(cache) => 3.0
|
||||
| None =>
|
||||
Discrete.T.Integral.sum(~cache=None, discrete)
|
||||
*. discreteProbabilityMassFraction
|
||||
+. Continuous.T.Integral.sum(~cache=None, continuous)
|
||||
*. (1.0 -. discreteProbabilityMassFraction)
|
||||
};
|
||||
};
|
||||
|
||||
let integralXtoY =
|
||||
(
|
||||
~cache,
|
||||
f,
|
||||
{discrete, continuous, discreteProbabilityMassFraction}: t,
|
||||
) => {
|
||||
let cont = Continuous.T.Integral.xToY(~cache, f, continuous);
|
||||
let discrete = Discrete.T.Integral.xToY(~cache, f, discrete);
|
||||
discrete
|
||||
|> Discrete.xToY(f)
|
||||
|> MixedPoint.fmap(e => e *. discreteProbabilityMassFraction);
|
||||
MixedPoint.add(c, d);
|
||||
};
|
||||
|
||||
let scaledContinuousComponent =
|
||||
({continuous, discreteProbabilityMassFraction}: t)
|
||||
: option(DistributionTypes.continuousShape) => {
|
||||
Shape.Continuous.scalePdf(
|
||||
~scaleTo=1.0 -. discreteProbabilityMassFraction,
|
||||
continuous,
|
||||
);
|
||||
};
|
||||
|
||||
let scaledDiscreteComponent =
|
||||
({discrete, discreteProbabilityMassFraction}: t)
|
||||
: DistributionTypes.continuousShape =>
|
||||
Shape.Continuous.make(
|
||||
Discrete.pointwiseFmap(
|
||||
f => f *. discreteProbabilityMassFraction,
|
||||
discrete,
|
||||
),
|
||||
`Stepwise,
|
||||
);
|
||||
|
||||
// TODO: Add these two directly, once interpolation is added.
|
||||
let integral = (~cache, t) => {
|
||||
// let cont = scaledContinuousComponent(t);
|
||||
// let discrete = scaledDiscreteComponent(t);
|
||||
switch (cache) {
|
||||
| Some(cache) => cache
|
||||
| None => scaledContinuousComponent(t) |> E.O.toExt("")
|
||||
};
|
||||
};
|
||||
|
||||
let integralSum =
|
||||
(~cache, {discrete, continuous, discreteProbabilityMassFraction}: t) => {
|
||||
switch (cache) {
|
||||
| Some(cache) => 3.0
|
||||
| None =>
|
||||
Discrete.Integral.sum(~cache=None, discrete)
|
||||
*. discreteProbabilityMassFraction
|
||||
+. Continuous.Integral.sum(~cache=None, continuous)
|
||||
*. (1.0 -. discreteProbabilityMassFraction)
|
||||
};
|
||||
};
|
||||
|
||||
let integralXtoY =
|
||||
(
|
||||
~cache,
|
||||
f,
|
||||
{discrete, continuous, discreteProbabilityMassFraction}: t,
|
||||
) => {
|
||||
let cont = Continuous.Integral.xToY(~cache, f, continuous);
|
||||
let discrete = Discrete.Integral.xToY(~cache, f, discrete);
|
||||
discrete
|
||||
*. discreteProbabilityMassFraction
|
||||
+. cont
|
||||
*. (1.0 -. discreteProbabilityMassFraction);
|
||||
};
|
||||
|
||||
let pointwiseFmap =
|
||||
(fn, {discrete, continuous, discreteProbabilityMassFraction}: t): t => {
|
||||
{
|
||||
discrete: Discrete.pointwiseFmap(fn, discrete),
|
||||
continuous: Continuous.pointwiseFmap(fn, continuous),
|
||||
discreteProbabilityMassFraction,
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
module Shape =
|
||||
Dist({
|
||||
type t = DistributionTypes.shape;
|
||||
type integral = DistributionTypes.continuousShape;
|
||||
|
||||
let mapToAll = (t: t, (fn1, fn2, fn3)) =>
|
||||
switch (t) {
|
||||
| Mixed(m) => fn1(m)
|
||||
| Discrete(m) => fn2(m)
|
||||
| Continuous(m) => fn3(m)
|
||||
+. cont
|
||||
*. (1.0 -. discreteProbabilityMassFraction);
|
||||
};
|
||||
|
||||
let fmap = (t: t, (fn1, fn2, fn3)): t =>
|
||||
switch (t) {
|
||||
| Mixed(m) => Mixed(fn1(m))
|
||||
| Discrete(m) => Discrete(fn2(m))
|
||||
| Continuous(m) => Continuous(fn3(m))
|
||||
let pointwiseFmap =
|
||||
(fn, {discrete, continuous, discreteProbabilityMassFraction}: t): t => {
|
||||
{
|
||||
discrete: Discrete.T.pointwiseFmap(fn, discrete),
|
||||
continuous: Continuous.T.pointwiseFmap(fn, continuous),
|
||||
discreteProbabilityMassFraction,
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
let xToY = (f, t) =>
|
||||
mapToAll(t, (Mixed.xToY(f), Discrete.xToY(f), Continuous.xToY(f)));
|
||||
let shape = (t: t) => t;
|
||||
let minX = (t: t) =>
|
||||
mapToAll(t, (Mixed.minX, Discrete.minX, Continuous.minX));
|
||||
let integral = (~cache, t: t) =>
|
||||
mapToAll(
|
||||
t,
|
||||
(
|
||||
Mixed.Integral.get(~cache),
|
||||
Discrete.Integral.get(~cache),
|
||||
Continuous.Integral.get(~cache),
|
||||
),
|
||||
);
|
||||
let integralSum = (~cache, t: t) =>
|
||||
mapToAll(
|
||||
t,
|
||||
(
|
||||
Mixed.Integral.sum(~cache),
|
||||
Discrete.Integral.sum(~cache),
|
||||
Continuous.Integral.sum(~cache),
|
||||
),
|
||||
);
|
||||
let integralXtoY = (~cache, f, t) => {
|
||||
mapToAll(
|
||||
t,
|
||||
(
|
||||
Mixed.Integral.xToY(~cache, f),
|
||||
Discrete.Integral.xToY(~cache, f),
|
||||
Continuous.Integral.xToY(~cache, f),
|
||||
),
|
||||
);
|
||||
};
|
||||
let maxX = (t: t) =>
|
||||
mapToAll(t, (Mixed.minX, Discrete.minX, Continuous.minX));
|
||||
let pointwiseFmap = (fn, t: t) =>
|
||||
fmap(
|
||||
t,
|
||||
(
|
||||
Mixed.pointwiseFmap(fn),
|
||||
Discrete.pointwiseFmap(fn),
|
||||
Continuous.pointwiseFmap(fn),
|
||||
),
|
||||
);
|
||||
});
|
||||
module Shape = {
|
||||
module T =
|
||||
Dist({
|
||||
type t = DistributionTypes.shape;
|
||||
type integral = DistributionTypes.continuousShape;
|
||||
|
||||
module WithMetadata =
|
||||
Dist({
|
||||
type t = DistributionTypes.complexPower;
|
||||
type integral = DistributionTypes.complexPower;
|
||||
let shape = ({shape, _}: t) => shape;
|
||||
let xToY = (f, t: t) => t |> shape |> Shape.xToY(f);
|
||||
let minX = (t: t) => t |> shape |> Shape.minX;
|
||||
let maxX = (t: t) => t |> shape |> Shape.maxX;
|
||||
let fromShape = (shape, t): t => DistributionTypes.update(~shape, t);
|
||||
let pointwiseFmap = (fn, {shape, _} as t: t): t =>
|
||||
fromShape(Shape.pointwiseFmap(fn, shape), t);
|
||||
let mapToAll = (t: t, (fn1, fn2, fn3)) =>
|
||||
switch (t) {
|
||||
| Mixed(m) => fn1(m)
|
||||
| Discrete(m) => fn2(m)
|
||||
| Continuous(m) => fn3(m)
|
||||
};
|
||||
|
||||
let integral = (~cache as _, t: t) =>
|
||||
fromShape(Continuous(t.integralCache), t);
|
||||
let integralSum = (~cache as _, t: t) =>
|
||||
t |> shape |> Shape.Integral.sum(~cache=Some(t.integralCache));
|
||||
// TODO: Fix this below, obviously.
|
||||
let integralXtoY = (~cache as _, f, t) => {
|
||||
1337.0;
|
||||
};
|
||||
});
|
||||
let fmap = (t: t, (fn1, fn2, fn3)): t =>
|
||||
switch (t) {
|
||||
| Mixed(m) => Mixed(fn1(m))
|
||||
| Discrete(m) => Discrete(fn2(m))
|
||||
| Continuous(m) => Continuous(fn3(m))
|
||||
};
|
||||
|
||||
let xToY = (f, t) =>
|
||||
mapToAll(
|
||||
t,
|
||||
(Mixed.T.xToY(f), Discrete.T.xToY(f), Continuous.T.xToY(f)),
|
||||
);
|
||||
let toShape = (t: t) => t;
|
||||
let toContinuous = (t: t) =>
|
||||
mapToAll(
|
||||
t,
|
||||
(
|
||||
Mixed.T.toContinuous,
|
||||
Discrete.T.toContinuous,
|
||||
Continuous.T.toContinuous,
|
||||
),
|
||||
);
|
||||
let toDiscrete = (t: t) =>
|
||||
mapToAll(
|
||||
t,
|
||||
(
|
||||
Mixed.T.toDiscrete,
|
||||
Discrete.T.toDiscrete,
|
||||
Continuous.T.toDiscrete,
|
||||
),
|
||||
);
|
||||
let minX = (t: t) =>
|
||||
mapToAll(t, (Mixed.T.minX, Discrete.T.minX, Continuous.T.minX));
|
||||
let integral = (~cache, t: t) =>
|
||||
mapToAll(
|
||||
t,
|
||||
(
|
||||
Mixed.T.Integral.get(~cache),
|
||||
Discrete.T.Integral.get(~cache),
|
||||
Continuous.T.Integral.get(~cache),
|
||||
),
|
||||
);
|
||||
let integralSum = (~cache, t: t) =>
|
||||
mapToAll(
|
||||
t,
|
||||
(
|
||||
Mixed.T.Integral.sum(~cache),
|
||||
Discrete.T.Integral.sum(~cache),
|
||||
Continuous.T.Integral.sum(~cache),
|
||||
),
|
||||
);
|
||||
let integralXtoY = (~cache, f, t) => {
|
||||
mapToAll(
|
||||
t,
|
||||
(
|
||||
Mixed.T.Integral.xToY(~cache, f),
|
||||
Discrete.T.Integral.xToY(~cache, f),
|
||||
Continuous.T.Integral.xToY(~cache, f),
|
||||
),
|
||||
);
|
||||
};
|
||||
let maxX = (t: t) =>
|
||||
mapToAll(t, (Mixed.T.minX, Discrete.T.minX, Continuous.T.minX));
|
||||
let pointwiseFmap = (fn, t: t) =>
|
||||
fmap(
|
||||
t,
|
||||
(
|
||||
Mixed.T.pointwiseFmap(fn),
|
||||
Discrete.T.pointwiseFmap(fn),
|
||||
Continuous.T.pointwiseFmap(fn),
|
||||
),
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
module WithMetadata = {
|
||||
module T =
|
||||
Dist({
|
||||
type t = DistributionTypes.complexPower;
|
||||
type integral = DistributionTypes.complexPower;
|
||||
let toShape = ({shape, _}: t) => shape;
|
||||
let toContinuous = (t: t) => t |> toShape |> Shape.T.toContinuous;
|
||||
let toDiscrete = (t: t) => t |> toShape |> Shape.T.toDiscrete;
|
||||
// todo: adjust for limit, and the fact that total mass is lower.
|
||||
let xToY = (f, t: t) => t |> toShape |> Shape.T.xToY(f);
|
||||
let minX = (t: t) => t |> toShape |> Shape.T.minX;
|
||||
let maxX = (t: t) => t |> toShape |> Shape.T.maxX;
|
||||
let fromShape = (shape, t): t => DistributionTypes.update(~shape, t);
|
||||
// todo: adjust for limit
|
||||
let pointwiseFmap = (fn, {shape, _} as t: t): t =>
|
||||
fromShape(Shape.T.pointwiseFmap(fn, shape), t);
|
||||
|
||||
let integral = (~cache as _, t: t) =>
|
||||
fromShape(Continuous(t.integralCache), t);
|
||||
let integralSum = (~cache as _, t: t) =>
|
||||
t |> toShape |> Shape.T.Integral.sum(~cache=Some(t.integralCache));
|
||||
// TODO: Fix this below, obviously. Adjust for limit.
|
||||
let integralXtoY = (~cache as _, f, t) => {
|
||||
1337.0;
|
||||
};
|
||||
});
|
||||
};
|
|
@ -17,21 +17,10 @@ type xyShape = {
|
|||
type interpolationMethod = [ | `Stepwise | `Linear];
|
||||
|
||||
type continuousShape = {
|
||||
shape: xyShape,
|
||||
xyShape,
|
||||
interpolation: interpolationMethod,
|
||||
};
|
||||
|
||||
module ContinuousShape = {
|
||||
type t = continuousShape;
|
||||
let shape = (t: t) => t.shape;
|
||||
let interpolation = (t: t) => t.interpolation;
|
||||
let make = (shape, interpolation) => {shape, interpolation};
|
||||
let shapeMap = ({shape, interpolation}: t, fn) => {
|
||||
shape: fn(shape),
|
||||
interpolation,
|
||||
};
|
||||
};
|
||||
|
||||
type discreteShape = xyShape;
|
||||
|
||||
type mixedShape = {
|
||||
|
@ -111,4 +100,29 @@ module DistributionUnit = {
|
|||
)
|
||||
| _ => Js.Null.fromOption(None)
|
||||
};
|
||||
};
|
||||
|
||||
type mixedPoint = {
|
||||
continuous: float,
|
||||
discrete: float,
|
||||
};
|
||||
|
||||
module MixedPoint = {
|
||||
type t = mixedPoint;
|
||||
let toContinuousValue = (t: t) => t.continuous;
|
||||
let toDiscreteValue = (t: t) => t.discrete;
|
||||
let makeContinuous = (continuous: float): t => {continuous, discrete: 0.0};
|
||||
let makeDiscrete = (discrete: float): t => {continuous: 0.0, discrete};
|
||||
|
||||
let fmap = (fn, t: t) => {
|
||||
continuous: fn(t.continuous),
|
||||
discrete: fn(t.discrete),
|
||||
};
|
||||
|
||||
let combine2 = (fn, c: t, d: t): t => {
|
||||
continuous: fn(c.continuous, d.continuous),
|
||||
discrete: fn(c.discrete, d.discrete),
|
||||
};
|
||||
|
||||
let add = combine2((a, b) => a +. b);
|
||||
};
|
|
@ -6,18 +6,20 @@ type pointInRange =
|
|||
|
||||
module Continuous = {
|
||||
type t = continuousShape;
|
||||
let shape = (t: t) => t.shape;
|
||||
let getShape = (t: t) => t.shape;
|
||||
let xyShape = (t: t) => t.xyShape;
|
||||
let getShape = (t: t) => t.xyShape;
|
||||
let interpolation = (t: t) => t.interpolation;
|
||||
let make = (shape, interpolation) => {shape, interpolation};
|
||||
let fromShape = shape => make(shape, `Linear);
|
||||
let shapeMap = (fn, {shape, interpolation}: t) => {
|
||||
shape: fn(shape),
|
||||
let make = (xyShape, interpolation): t => {xyShape, interpolation};
|
||||
let fromShape = xyShape => make(xyShape, `Linear);
|
||||
let shapeMap = (fn, {xyShape, interpolation}: t): t => {
|
||||
xyShape: fn(xyShape),
|
||||
interpolation,
|
||||
};
|
||||
let oShapeMap = (fn, {shape, interpolation}: t) =>
|
||||
fn(shape) |> E.O.fmap(shape => {shape, interpolation});
|
||||
let shapeFn = (fn, t: t) => t |> shape |> fn;
|
||||
let oShapeMap =
|
||||
(fn, {xyShape, interpolation}: t)
|
||||
: option(DistributionTypes.continuousShape) =>
|
||||
fn(xyShape) |> E.O.fmap(xyShape => make(xyShape, interpolation));
|
||||
let shapeFn = (fn, t: t) => t |> xyShape |> fn;
|
||||
let minX = shapeFn(XYShape.minX);
|
||||
let maxX = shapeFn(XYShape.maxX);
|
||||
let findX = y => shapeFn(CdfLibrary.Distribution.findX(y));
|
||||
|
@ -29,15 +31,18 @@ module Continuous = {
|
|||
let findIntegralY = (f, t) => {
|
||||
t
|
||||
|> toCdf
|
||||
|> E.O.fmap(shape)
|
||||
|> E.O.fmap(xyShape)
|
||||
|> E.O.fmap(CdfLibrary.Distribution.findY(f));
|
||||
};
|
||||
let normalizeCdf = (continuousShape: continuousShape) =>
|
||||
continuousShape |> shape |> XYShape.scaleCdfTo(~scaleTo=1.0) |> fromShape;
|
||||
continuousShape
|
||||
|> xyShape
|
||||
|> XYShape.scaleCdfTo(~scaleTo=1.0)
|
||||
|> fromShape;
|
||||
let scalePdf = (~scaleTo=1.0, continuousShape: continuousShape) => {
|
||||
switch (toCdf(continuousShape)) {
|
||||
| Some({shape}) =>
|
||||
XYShape.scaleCdfTo(~scaleTo, shape)
|
||||
| Some({xyShape}) =>
|
||||
XYShape.scaleCdfTo(~scaleTo, xyShape)
|
||||
|> XYShape.Range.derivative
|
||||
|> E.O.fmap(fromShape)
|
||||
| _ => None
|
||||
|
@ -162,14 +167,14 @@ module Mixed = {
|
|||
let clean = (t: DistributionTypes.mixedShape) =>
|
||||
switch (t) {
|
||||
| {
|
||||
continuous: {shape: {xs: [||], ys: [||]}},
|
||||
continuous: {xyShape: {xs: [||], ys: [||]}},
|
||||
discrete: {xs: [||], ys: [||]},
|
||||
} =>
|
||||
None
|
||||
| {discrete: {xs: [|_|], ys: [|_|]}} => None
|
||||
| {continuous, discrete: {xs: [||], ys: [||]}} =>
|
||||
Some(Continuous(continuous))
|
||||
| {continuous: {shape: {xs: [||], ys: [||]}}, discrete} =>
|
||||
| {continuous: {xyShape: {xs: [||], ys: [||]}}, discrete} =>
|
||||
Some(Discrete(discrete))
|
||||
| shape => Some(Mixed(shape))
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user