The slow replacement of Shape.re begins
This commit is contained in:
parent
0d2c53eca4
commit
cd1b114295
|
@ -45,7 +45,7 @@ let make =
|
|||
?minX
|
||||
?scale
|
||||
?timeScale
|
||||
discrete={discrete |> E.O.fmap(Shape.Discrete.toJs)}
|
||||
discrete={discrete |> E.O.fmap(XYShape.toJs)}
|
||||
height
|
||||
marginBottom=50
|
||||
marginTop=0
|
||||
|
|
|
@ -49,6 +49,12 @@ module Dist = (T: dist) => {
|
|||
let xToY = T.integralXtoY;
|
||||
let sum = T.integralSum;
|
||||
};
|
||||
|
||||
// This is suboptimal because it could get the cache but doesn't here.
|
||||
let scaleToIntegralSum = (~intendedSum=1.0, t: t) => {
|
||||
let scale = intendedSum /. Integral.sum(~cache=None, t);
|
||||
scaleBy(~scale, t);
|
||||
};
|
||||
};
|
||||
|
||||
module Continuous = {
|
||||
|
@ -123,6 +129,31 @@ module Discrete = {
|
|||
};
|
||||
|
||||
module Mixed = {
|
||||
let make =
|
||||
(~continuous, ~discrete, ~discreteProbabilityMassFraction)
|
||||
: DistributionTypes.mixedShape => {
|
||||
continuous,
|
||||
discrete,
|
||||
discreteProbabilityMassFraction,
|
||||
};
|
||||
|
||||
let clean =
|
||||
(t: DistributionTypes.mixedShape): option(DistributionTypes.shape) => {
|
||||
switch (t) {
|
||||
| {
|
||||
continuous: {xyShape: {xs: [||], ys: [||]}},
|
||||
discrete: {xs: [||], ys: [||]},
|
||||
} =>
|
||||
None
|
||||
| {discrete: {xs: [|_|], ys: [|_|]}} => None
|
||||
| {continuous, discrete: {xs: [||], ys: [||]}} =>
|
||||
Some(Continuous(continuous))
|
||||
| {continuous: {xyShape: {xs: [||], ys: [||]}}, discrete} =>
|
||||
Some(Discrete(discrete))
|
||||
| shape => Some(Mixed(shape))
|
||||
};
|
||||
};
|
||||
|
||||
module T =
|
||||
Dist({
|
||||
type t = DistributionTypes.mixedShape;
|
||||
|
@ -312,24 +343,24 @@ module WithMetadata = {
|
|||
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;
|
||||
let shapeFn = (fn, t: t) => t |> toShape |> fn;
|
||||
let toContinuous = shapeFn(Shape.T.toContinuous);
|
||||
let toDiscrete = shapeFn(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 xToY = f => shapeFn(Shape.T.xToY(f));
|
||||
let minX = shapeFn(Shape.T.minX);
|
||||
let maxX = shapeFn(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));
|
||||
Shape.T.Integral.sum(~cache=Some(t.integralCache), toShape(t));
|
||||
// TODO: Fix this below, obviously. Adjust for limit.
|
||||
let integralXtoY = (~cache as _, f, t) => {
|
||||
1337.0;
|
||||
let integralXtoY = (~cache as _, f, t: t) => {
|
||||
Shape.T.Integral.xToY(~cache=Some(t.integralCache), f, toShape(t));
|
||||
};
|
||||
});
|
||||
};
|
|
@ -49,7 +49,7 @@ let renderIfNeeded =
|
|||
switch (t.generationSource) {
|
||||
| GuesstimatorString(s) =>
|
||||
Guesstimator.stringToMixedShape(~string=s, ~sampleCount, ())
|
||||
|> E.O.bind(_, Shape.Mixed.clean)
|
||||
|> E.O.bind(_, DistFunctor.Mixed.clean)
|
||||
|> E.O.fmap((shape: DistributionTypes.shape) =>
|
||||
make(
|
||||
~generationSource=Shape(shape),
|
||||
|
@ -71,13 +71,9 @@ let normalize = (t: genericDistribution): option(genericDistribution) => {
|
|||
};
|
||||
|
||||
let yIntegral = (t: DistributionTypes.genericDistribution, x) => {
|
||||
let addInitialMass = n => n +. Domain.initialProbabilityMass(t.domain);
|
||||
let normalize = n => n *. Domain.normalizeProbabilityMass(t.domain);
|
||||
switch (t) {
|
||||
| {generationSource: Shape(shape)} =>
|
||||
Shape.T.yIntegral(shape, x)
|
||||
|> E.O.fmap(addInitialMass)
|
||||
|> E.O.fmap(normalize)
|
||||
Some(DistFunctor.Shape.T.Integral.xToY(~cache=None, x, shape))
|
||||
| _ => None
|
||||
};
|
||||
};
|
||||
|
|
|
@ -17,7 +17,7 @@ let build = (~continuous, ~discrete, ~assumptions) =>
|
|||
} =>
|
||||
// TODO: Fix this, it's wrong :(
|
||||
Some(
|
||||
Shape.Mixed.make(
|
||||
DistFunctor.Mixed.make(
|
||||
~continuous,
|
||||
~discrete,
|
||||
~discreteProbabilityMassFraction=r,
|
||||
|
@ -30,7 +30,7 @@ let build = (~continuous, ~discrete, ~assumptions) =>
|
|||
discreteProbabilityMass: Some(r),
|
||||
} =>
|
||||
Some(
|
||||
Shape.Mixed.make(
|
||||
DistFunctor.Mixed.make(
|
||||
~continuous,
|
||||
~discrete,
|
||||
~discreteProbabilityMassFraction=r,
|
||||
|
@ -56,10 +56,12 @@ let build = (~continuous, ~discrete, ~assumptions) =>
|
|||
discrete: ADDS_TO_CORRECT_PROBABILITY,
|
||||
discreteProbabilityMass: None,
|
||||
} =>
|
||||
let discreteProbabilityMassFraction = Shape.Discrete.ySum(discrete);
|
||||
let discrete = Shape.Discrete.scaleYToTotal(1.0, discrete);
|
||||
let discreteProbabilityMassFraction =
|
||||
DistFunctor.Discrete.T.Integral.sum(~cache=None, discrete);
|
||||
let discrete =
|
||||
DistFunctor.Discrete.T.scaleToIntegralSum(~intendedSum=1.0, discrete);
|
||||
Some(
|
||||
Shape.Mixed.make(
|
||||
DistFunctor.Mixed.make(
|
||||
~continuous,
|
||||
~discrete,
|
||||
~discreteProbabilityMassFraction,
|
||||
|
|
|
@ -115,11 +115,11 @@ let max = (f1: option(float), f2: option(float)) =>
|
|||
};
|
||||
|
||||
module Mixed = {
|
||||
let make = (~continuous, ~discrete, ~discreteProbabilityMassFraction) => {
|
||||
continuous,
|
||||
discrete,
|
||||
discreteProbabilityMassFraction,
|
||||
};
|
||||
// let make = (~continuous, ~discrete, ~discreteProbabilityMassFraction) => {
|
||||
// continuous,
|
||||
// discrete,
|
||||
// discreteProbabilityMassFraction,
|
||||
// };
|
||||
|
||||
let minX = (t: DistributionTypes.mixedShape) =>
|
||||
min(t.continuous |> Continuous.minX, t.discrete |> Discrete.minX);
|
||||
|
@ -163,193 +163,135 @@ module Mixed = {
|
|||
| _ => None
|
||||
};
|
||||
};
|
||||
} /* }*/;
|
||||
|
||||
let clean = (t: DistributionTypes.mixedShape) =>
|
||||
switch (t) {
|
||||
| {
|
||||
continuous: {xyShape: {xs: [||], ys: [||]}},
|
||||
discrete: {xs: [||], ys: [||]},
|
||||
} =>
|
||||
None
|
||||
| {discrete: {xs: [|_|], ys: [|_|]}} => None
|
||||
| {continuous, discrete: {xs: [||], ys: [||]}} =>
|
||||
Some(Continuous(continuous))
|
||||
| {continuous: {xyShape: {xs: [||], ys: [||]}}, discrete} =>
|
||||
Some(Discrete(discrete))
|
||||
| shape => Some(Mixed(shape))
|
||||
};
|
||||
};
|
||||
// module T = {
|
||||
// type t = DistributionTypes.shape;
|
||||
|
||||
module T = {
|
||||
type t = DistributionTypes.shape;
|
||||
|
||||
let y = (t: t, x: float) =>
|
||||
switch (t) {
|
||||
| Mixed(m) => `mixed(Mixed.findY(m, x))
|
||||
| Discrete(discreteShape) => `discrete(Discrete.findY(x, discreteShape))
|
||||
| Continuous(continuousShape) =>
|
||||
`continuous(Continuous.findY(x, continuousShape))
|
||||
};
|
||||
|
||||
let yIntegral = (t: t, x: float) =>
|
||||
switch (t) {
|
||||
| Mixed(m) => Mixed.findYIntegral(x, m)
|
||||
| Discrete(discreteShape) =>
|
||||
Discrete.findIntegralY(x, discreteShape) |> E.O.some
|
||||
| Continuous(continuousShape) =>
|
||||
Continuous.findIntegralY(x, continuousShape)
|
||||
};
|
||||
|
||||
let minX = (t: t) =>
|
||||
switch (t) {
|
||||
| Mixed(m) => Mixed.minX(m)
|
||||
| Discrete(discreteShape) => Discrete.minX(discreteShape)
|
||||
| Continuous(continuousShape) => Continuous.minX(continuousShape)
|
||||
};
|
||||
|
||||
let maxX = (t: t) =>
|
||||
switch (t) {
|
||||
| Mixed(m) => Mixed.maxX(m)
|
||||
| Discrete(discreteShape) => Discrete.maxX(discreteShape)
|
||||
| Continuous(continuousShape) => Continuous.maxX(continuousShape)
|
||||
};
|
||||
|
||||
let discreteComponent = (t: t) =>
|
||||
switch (t) {
|
||||
| Mixed({discrete}) => Some(discrete)
|
||||
| Discrete(d) => Some(d)
|
||||
| Continuous(_) => None
|
||||
};
|
||||
|
||||
let continuousComponent = (t: t) =>
|
||||
switch (t) {
|
||||
| Mixed({continuous}) => Some(continuous)
|
||||
| Continuous(c) => Some(c)
|
||||
| Discrete(_) => None
|
||||
};
|
||||
|
||||
// let scaledContinuousComponent = (t: t): option(continuousShape) => {
|
||||
// let y = (t: t, x: float) =>
|
||||
// switch (t) {
|
||||
// | Mixed({continuous, discreteProbabilityMassFraction}) =>
|
||||
// Continuous.scalePdf(
|
||||
// ~scaleTo=1.0 -. discreteProbabilityMassFraction,
|
||||
// continuous,
|
||||
// )
|
||||
// | Discrete(_) => None
|
||||
// | Continuous(c) => Some(c)
|
||||
// };
|
||||
// | Mixed(m) => `mixed(Mixed.findY(m, x))
|
||||
// | Discrete(discreteShape) => `discrete(Discrete.findY(x, discreteShape))
|
||||
// | Continuous(continuousShape) =>
|
||||
// `continuous(Continuous.findY(x, continuousShape))
|
||||
// };
|
||||
|
||||
// let scaledDiscreteComponent = (t: t): option(discreteShape) => {
|
||||
// let yIntegral = (t: t, x: float) =>
|
||||
// switch (t) {
|
||||
// | Mixed({discrete, discreteProbabilityMassFraction}) =>
|
||||
// Some(Discrete.scaleYToTotal(discreteProbabilityMassFraction, discrete))
|
||||
// | Mixed(m) => Mixed.findYIntegral(x, m)
|
||||
// | Discrete(discreteShape) =>
|
||||
// Discrete.findIntegralY(x, discreteShape) |> E.O.some
|
||||
// | Continuous(continuousShape) =>
|
||||
// Continuous.findIntegralY(x, continuousShape)
|
||||
// };
|
||||
|
||||
// let minX = (t: t) =>
|
||||
// switch (t) {
|
||||
// | Mixed(m) => Mixed.minX(m)
|
||||
// | Discrete(discreteShape) => Discrete.minX(discreteShape)
|
||||
// | Continuous(continuousShape) => Continuous.minX(continuousShape)
|
||||
// };
|
||||
|
||||
// let maxX = (t: t) =>
|
||||
// switch (t) {
|
||||
// | Mixed(m) => Mixed.maxX(m)
|
||||
// | Discrete(discreteShape) => Discrete.maxX(discreteShape)
|
||||
// | Continuous(continuousShape) => Continuous.maxX(continuousShape)
|
||||
// };
|
||||
|
||||
// let discreteComponent = (t: t) =>
|
||||
// switch (t) {
|
||||
// | Mixed({discrete}) => Some(discrete)
|
||||
// | Discrete(d) => Some(d)
|
||||
// | Continuous(_) => None
|
||||
// };
|
||||
// };
|
||||
|
||||
// let pointwiseFmap = (fn, t: t): shape =>
|
||||
// let continuousComponent = (t: t) =>
|
||||
// switch (t) {
|
||||
// | Mixed({discrete, continuous, discreteProbabilityMassFraction}) =>
|
||||
// Mixed({
|
||||
// continuous: XYShape.pointwiseMap(fn, continuous),
|
||||
// discrete: XYShape.pointwiseMap(fn, discrete),
|
||||
// discreteProbabilityMassFraction,
|
||||
// })
|
||||
// | Discrete(x) => Discrete(XYShape.pointwiseMap(fn, x))
|
||||
// | Continuous(x) => Continuous(XYShape.pointwiseMap(fn, x))
|
||||
// | Mixed({continuous}) => Some(continuous)
|
||||
// | Continuous(c) => Some(c)
|
||||
// | Discrete(_) => None
|
||||
// };
|
||||
// // let scaledContinuousComponent = (t: t): option(continuousShape) => {
|
||||
// // switch (t) {
|
||||
// // | Mixed({continuous, discreteProbabilityMassFraction}) =>
|
||||
// // Continuous.scalePdf(
|
||||
// // ~scaleTo=1.0 -. discreteProbabilityMassFraction,
|
||||
// // continuous,
|
||||
// // )
|
||||
// // | Discrete(_) => None
|
||||
// // | Continuous(c) => Some(c)
|
||||
// // };
|
||||
// // };
|
||||
// // let scaledDiscreteComponent = (t: t): option(discreteShape) => {
|
||||
// // switch (t) {
|
||||
// // | Mixed({discrete, discreteProbabilityMassFraction}) =>
|
||||
// // Some(Discrete.scaleYToTotal(discreteProbabilityMassFraction, discrete))
|
||||
// // | Discrete(d) => Some(d)
|
||||
// // | Continuous(_) => None
|
||||
// // };
|
||||
// // };
|
||||
// // let pointwiseFmap = (fn, t: t): shape =>
|
||||
// // switch (t) {
|
||||
// // | Mixed({discrete, continuous, discreteProbabilityMassFraction}) =>
|
||||
// // Mixed({
|
||||
// // continuous: XYShape.pointwiseMap(fn, continuous),
|
||||
// // discrete: XYShape.pointwiseMap(fn, discrete),
|
||||
// // discreteProbabilityMassFraction,
|
||||
// // })
|
||||
// // | Discrete(x) => Discrete(XYShape.pointwiseMap(fn, x))
|
||||
// // | Continuous(x) => Continuous(XYShape.pointwiseMap(fn, x))
|
||||
// // };
|
||||
// // module Cdf = {
|
||||
// // let normalizeCdf = (t: DistributionTypes.shape) => {
|
||||
// // switch (t) {
|
||||
// // | Mixed({continuous, discrete, discreteProbabilityMassFraction}) =>
|
||||
// // Mixed({
|
||||
// // continuous: continuous |> Continuous.normalizeCdf,
|
||||
// // discrete: discrete |> Discrete.scaleYToTotal(1.0),
|
||||
// // discreteProbabilityMassFraction,
|
||||
// // })
|
||||
// // | Discrete(d) => Discrete(d |> Discrete.scaleYToTotal(1.0))
|
||||
// // | Continuous(continuousShape) =>
|
||||
// // Continuous(Continuous.normalizeCdf(continuousShape))
|
||||
// // };
|
||||
// // };
|
||||
// // };
|
||||
// };
|
||||
|
||||
// module Cdf = {
|
||||
// let normalizeCdf = (t: DistributionTypes.shape) => {
|
||||
// switch (t) {
|
||||
// | Mixed({continuous, discrete, discreteProbabilityMassFraction}) =>
|
||||
// Mixed({
|
||||
// continuous: continuous |> Continuous.normalizeCdf,
|
||||
// discrete: discrete |> Discrete.scaleYToTotal(1.0),
|
||||
// discreteProbabilityMassFraction,
|
||||
// })
|
||||
// | Discrete(d) => Discrete(d |> Discrete.scaleYToTotal(1.0))
|
||||
// | Continuous(continuousShape) =>
|
||||
// Continuous(Continuous.normalizeCdf(continuousShape))
|
||||
// };
|
||||
// module PdfCdfShape = {
|
||||
// type t = pdfCdfCombo;
|
||||
// let pdf = (t: t) =>
|
||||
// switch (t.pdf) {
|
||||
// | Mixed(pdf) => Mixed(pdf)
|
||||
// | Discrete(pdf) => Discrete(pdf)
|
||||
// | Continuous(pdf) => Continuous(pdf)
|
||||
// };
|
||||
// let cdf = (t: t) => t.cdf;
|
||||
// };
|
||||
|
||||
module Pdf = {
|
||||
// TODO: This is wrong. The discrete component should be made continuous when integrating.
|
||||
// let toCdf = (t: t) =>
|
||||
// switch (t) {
|
||||
// | Mixed({continuous, discrete, discreteProbabilityMassFraction}) =>
|
||||
// Some(
|
||||
// Mixed({
|
||||
// continuous: Continuous.toCdf(continuous) |> E.O.toExt(""),
|
||||
// discrete: discrete |> Discrete.integrate,
|
||||
// discreteProbabilityMassFraction,
|
||||
// }),
|
||||
// )
|
||||
// | Discrete(discrete) =>
|
||||
// Some(Continuous(discrete |> Discrete.integrate))
|
||||
// | Continuous(continuous) =>
|
||||
// Continuous.toCdf(continuous) |> E.O.fmap(e => Continuous(e))
|
||||
// type distributionUnit =
|
||||
// | UnspecifiedDistribution
|
||||
// | TimeDistribution(TimeTypes.timeVector);
|
||||
|
||||
// type withLimitedDomain = {
|
||||
// domain,
|
||||
// dist: pdfCdfCombo,
|
||||
// };
|
||||
// let normalize = (t: DistributionTypes.shape): option(shape) => {
|
||||
// switch (t) {
|
||||
// | Mixed({continuous, discrete, discreteProbabilityMassFraction}) =>
|
||||
// continuous
|
||||
// |> Continuous.scalePdf(~scaleTo=1.0)
|
||||
// |> E.O.fmap(r =>
|
||||
// Mixed({
|
||||
// continuous: r,
|
||||
// discrete: discrete |> Discrete.scaleYToTotal(1.0),
|
||||
// discreteProbabilityMassFraction,
|
||||
// })
|
||||
// )
|
||||
// | Discrete(d) => Some(Discrete(d |> Discrete.scaleYToTotal(1.0)))
|
||||
// | Continuous(continuousShape) =>
|
||||
// continuousShape
|
||||
// |> Continuous.scalePdf(~scaleTo=1.0)
|
||||
// |> E.O.fmap(r => Continuous(r))
|
||||
|
||||
// module WithLimitedDomain = {
|
||||
// type t = withLimitedDomain;
|
||||
// let dist = (t: t) => t.dist;
|
||||
// let pdf = (t: t) => PdfCdfShape.pdf(t.dist);
|
||||
// let cdf = (t: t) => PdfCdfShape.cdf(t.dist);
|
||||
// // TODO: This is bad, obviously needs to be fixed.
|
||||
// let distScaleFactor = (t: t) => 3.0;
|
||||
// // let scaledPdfShape = (scaleFactor, t: t) =>
|
||||
// // t |> pdf |> T.pointwiseFmap(r => r *. scaleFactor);
|
||||
// // let scaledCdfShape = (scaleFactor, t: t) =>
|
||||
// // t |> cdf |> XYShape.pointwiseMap(r => r *. scaleFactor);
|
||||
// };
|
||||
// };
|
||||
};
|
||||
};
|
||||
|
||||
module PdfCdfShape = {
|
||||
type t = pdfCdfCombo;
|
||||
let pdf = (t: t) =>
|
||||
switch (t.pdf) {
|
||||
| Mixed(pdf) => Mixed(pdf)
|
||||
| Discrete(pdf) => Discrete(pdf)
|
||||
| Continuous(pdf) => Continuous(pdf)
|
||||
};
|
||||
let cdf = (t: t) => t.cdf;
|
||||
};
|
||||
|
||||
type distributionUnit =
|
||||
| UnspecifiedDistribution
|
||||
| TimeDistribution(TimeTypes.timeVector);
|
||||
|
||||
type withLimitedDomain = {
|
||||
domain,
|
||||
dist: pdfCdfCombo,
|
||||
};
|
||||
|
||||
module WithLimitedDomain = {
|
||||
type t = withLimitedDomain;
|
||||
let dist = (t: t) => t.dist;
|
||||
let pdf = (t: t) => PdfCdfShape.pdf(t.dist);
|
||||
let cdf = (t: t) => PdfCdfShape.cdf(t.dist);
|
||||
// TODO: This is bad, obviously needs to be fixed.
|
||||
let distScaleFactor = (t: t) => 3.0;
|
||||
// let scaledPdfShape = (scaleFactor, t: t) =>
|
||||
// t |> pdf |> T.pointwiseFmap(r => r *. scaleFactor);
|
||||
// let scaledCdfShape = (scaleFactor, t: t) =>
|
||||
// t |> cdf |> XYShape.pointwiseMap(r => r *. scaleFactor);
|
||||
};
|
||||
|
||||
type withTimeVector = {
|
||||
timeVector: TimeTypes.timeVector,
|
||||
dist: withLimitedDomain,
|
||||
};
|
||||
// type withTimeVector = {
|
||||
// timeVector: TimeTypes.timeVector,
|
||||
// dist: withLimitedDomain,
|
Loading…
Reference in New Issue
Block a user