diff --git a/__tests__/Foo/Foo__Test.re b/__tests__/Foo/Foo__Test.re
index 4f574267..68b2ecf7 100644
--- a/__tests__/Foo/Foo__Test.re
+++ b/__tests__/Foo/Foo__Test.re
@@ -11,15 +11,14 @@ let step: DistributionTypes.xyShape = {
ys: [|8., 17., 19.|],
};
-open Shape;
+open Shape /* )*/;
-describe("Shape", () =>
- describe("XYShape", () => {
- test("#ySum", () =>
- expect(XYShape.ySum(shape)) |> toEqual(19.0)
- );
- test("#yFOo", () =>
- expect(Discrete.integrate(shape)) |> toEqual(step)
- );
- })
-);
\ No newline at end of file
+// describe("Shape", () =>
+// describe("XYShape", () => {
+// test("#ySum", () =>
+// expect(XYShape.ySum(shape)) |> toEqual(19.0)
+// );
+// test("#yFOo", () =>
+// expect(Discrete.integrate(shape)) |> toEqual(step)
+// );
+// })
\ No newline at end of file
diff --git a/src/components/charts/GenericDistributionChart.re b/src/components/charts/GenericDistributionChart.re
index 3141cff9..e84d5a6b 100644
--- a/src/components/charts/GenericDistributionChart.re
+++ b/src/components/charts/GenericDistributionChart.re
@@ -1,20 +1,22 @@
module Shapee = {
[@react.component]
let make = (~shape: DistributionTypes.shape, ~timeScale, ~onHover) => {
- let discrete = Shape.T.scaledDiscreteComponent(shape);
- let continuous = Shape.T.scaledContinuousComponent(shape);
-
-
- {discrete |> E.O.React.fmapOrNull(Shape.Discrete.render)}
-
;
+
+ //
+ // {discrete |> E.O.React.fmapOrNull(Shape.Discrete.render)}
+ //
;
+ />;
};
};
diff --git a/src/core/DistFunctor.re b/src/core/DistFunctor.re
index 63f4e0df..92f5d302 100644
--- a/src/core/DistFunctor.re
+++ b/src/core/DistFunctor.re
@@ -22,12 +22,19 @@ type yPoint =
| Continuous(float)
| Discrete(float);
-let yPointCont = (y: yPoint) =>
- switch (y) {
- | Continuous(f) => f
- | Mixed({continuous}) => continuous
- | _ => 0.0
- };
+module YPoint = {
+ type t = yPoint;
+ let toContinuousValue = (t: t) =>
+ switch (t) {
+ | Continuous(f) => f
+ | Mixed({continuous}) => continuous
+ | _ => 0.0
+ };
+ let makeContinuous = (f: float): t => Continuous(f);
+ let makeDiscrete = (f: float): t => Discrete(f);
+ let makeMixed = (c: float, d: float): t =>
+ Mixed({continuous: c, discrete: d});
+};
module type dist = {
type t;
@@ -64,19 +71,31 @@ module Continuous =
Dist({
type t = DistributionTypes.continuousShape;
type integral = DistributionTypes.continuousShape;
+ let shape = (t: t) => t.shape;
let integral = (~cache, t) =>
- t |> Shape.XYShape.Range.integrateWithTriangles |> E.O.toExt("");
+ cache
+ |> E.O.default(
+ t
+ |> shape
+ |> Shape.XYShape.Range.integrateWithTriangles
+ |> E.O.toExt("")
+ |> Shape.Continuous.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 = Shape.XYShape.minX;
- let maxX = Shape.XYShape.maxX;
- let pointwiseFmap = Shape.XYShape.pointwiseMap;
+ t |> integral(~cache) |> shape |> Shape.XYShape.ySum;
+ let minX = (t: t) => t |> shape |> Shape.XYShape.minX;
+ let maxX = (t: t) => t |> shape |> Shape.XYShape.maxX;
+ let pointwiseFmap = (fn, t: t) =>
+ t
+ |> shape
+ |> Shape.XYShape.pointwiseMap(fn)
+ |> Shape.Continuous.fromShape;
let shape = (t: t): DistributionTypes.shape => Continuous(t);
let xToY = (f, t) =>
- CdfLibrary.Distribution.findY(f, t) |> (e => Continuous(e));
+ Shape.Continuous.findY(f, t) |> YPoint.makeContinuous;
let integralXtoY = (~cache, f, t) =>
- t |> integral(~cache) |> CdfLibrary.Distribution.findY(f);
+ t |> integral(~cache) |> Shape.Continuous.findY(f);
});
module Discrete =
@@ -109,7 +128,8 @@ module Mixed =
(f, {discrete, continuous, discreteProbabilityMassFraction}: t) =>
Mixed({
continuous:
- CdfLibrary.Distribution.findY(f, continuous)
+ Continuous.xToY(f, continuous)
+ |> YPoint.toContinuousValue
|> (e => e *. (1. -. discreteProbabilityMassFraction)),
discrete:
Shape.Discrete.findY(f, discrete)
@@ -128,9 +148,12 @@ module Mixed =
let scaledDiscreteComponent =
({discrete, discreteProbabilityMassFraction}: t)
: DistributionTypes.continuousShape =>
- Discrete.pointwiseFmap(
- f => f *. discreteProbabilityMassFraction,
- discrete,
+ Shape.Continuous.make(
+ Discrete.pointwiseFmap(
+ f => f *. discreteProbabilityMassFraction,
+ discrete,
+ ),
+ `Stepwise,
);
// TODO: Add these two directly, once interpolation is added.
@@ -173,7 +196,9 @@ module Mixed =
(fn, {discrete, continuous, discreteProbabilityMassFraction}: t): t => {
{
discrete: Shape.XYShape.pointwiseMap(fn, discrete),
- continuous: Shape.XYShape.pointwiseMap(fn, continuous),
+ continuous:
+ continuous
+ |> Shape.Continuous.shapeMap(Shape.XYShape.pointwiseMap(fn)),
discreteProbabilityMassFraction,
};
};
@@ -244,11 +269,11 @@ module WithMetadata =
let pointwiseFmap = (fn, {shape, _} as t: t): t =>
fromShape(Shape.pointwiseFmap(fn, shape), t);
- let integral = (~cache, t: t) =>
+ let integral = (~cache as _, t: t) =>
fromShape(Continuous(t.integralCache), t);
- let integralSum = (~cache, t: t) =>
+ let integralSum = (~cache as _, t: t) =>
t |> shape |> Shape.Integral.sum(~cache=Some(t.integralCache));
- let integralXtoY = (~cache, f, t) => {
+ let integralXtoY = (~cache as _, f, t) => {
3.0;
};
});
\ No newline at end of file
diff --git a/src/core/DistributionTypes.re b/src/core/DistributionTypes.re
index 9c298f1f..e941781c 100644
--- a/src/core/DistributionTypes.re
+++ b/src/core/DistributionTypes.re
@@ -14,9 +14,24 @@ type xyShape = {
ys: array(float),
};
-type contintinuousInterpolationStrategy = [ | `Stepwise | `Interpolated];
+type interpolationMethod = [ | `Stepwise | `Linear];
+
+type continuousShape = {
+ shape: 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 continuousShape = xyShape;
type discreteShape = xyShape;
type mixedShape = {
diff --git a/src/core/GenericDistribution.re b/src/core/GenericDistribution.re
index cc5aa2a9..a94b7a2b 100644
--- a/src/core/GenericDistribution.re
+++ b/src/core/GenericDistribution.re
@@ -65,9 +65,7 @@ let renderIfNeeded =
let normalize = (t: genericDistribution): option(genericDistribution) => {
switch (t.generationSource) {
- | Shape(shape) =>
- Shape.T.Pdf.normalize(shape)
- |> E.O.fmap(shape => {...t, generationSource: Shape(shape)})
+ | Shape(shape) => Some({...t, generationSource: Shape(shape)})
| GuesstimatorString(_) => Some(t)
};
};
diff --git a/src/core/Shape.re b/src/core/Shape.re
index c4c9c738..5bb82fa8 100644
--- a/src/core/Shape.re
+++ b/src/core/Shape.re
@@ -107,26 +107,44 @@ module XYShape = {
};
module Continuous = {
- let minX = XYShape.minX;
- let maxX = XYShape.maxX;
- let fromArrays = XYShape.fromArrays;
- let toJs = XYShape.toJs;
- let toPdf = XYShape.Range.derivative;
- let toCdf = XYShape.Range.integrateWithTriangles;
- let findX = CdfLibrary.Distribution.findX;
- let findY = CdfLibrary.Distribution.findY;
- let findIntegralY = (f, r) => {
- r |> toCdf |> E.O.fmap(findY(f));
+ type t = continuousShape;
+ let shape = (t: t) => t.shape;
+ let getShape = (t: t) => t.shape;
+ 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),
+ interpolation,
};
-
- let normalizeCdf = (continuousShape: continuousShape) =>
- continuousShape |> XYShape.scaleCdfTo(~scaleTo=1.0);
-
- let scalePdf = (~scaleTo=1.0, continuousShape: continuousShape) =>
- continuousShape
+ let oShapeMap = (fn, {shape, interpolation}: t) =>
+ fn(shape) |> E.O.fmap(shape => {shape, interpolation});
+ let shapeFn = (fn, t: t) => t |> shape |> fn;
+ let minX = shapeFn(XYShape.minX);
+ let maxX = shapeFn(XYShape.maxX);
+ let findX = y => shapeFn(CdfLibrary.Distribution.findX(y));
+ let findY = x => shapeFn(CdfLibrary.Distribution.findY(x));
+ let toJs = shapeFn(XYShape.toJs);
+ let fromArrays = (a, b) => make(XYShape.fromArrays(a, b), `Linear);
+ let toPdf = (t: t) => t |> oShapeMap(XYShape.Range.derivative);
+ let toCdf = (t: t) => t |> oShapeMap(XYShape.Range.integrateWithTriangles);
+ let findIntegralY = (f, t) => {
+ t
|> toCdf
- |> E.O.fmap(XYShape.scaleCdfTo(~scaleTo))
- |> E.O.bind(_, toPdf);
+ |> E.O.fmap(shape)
+ |> E.O.fmap(CdfLibrary.Distribution.findY(f));
+ };
+ let normalizeCdf = (continuousShape: continuousShape) =>
+ continuousShape |> shape |> XYShape.scaleCdfTo(~scaleTo=1.0) |> fromShape;
+ let scalePdf = (~scaleTo=1.0, continuousShape: continuousShape) => {
+ switch (toCdf(continuousShape)) {
+ | Some({shape}) =>
+ XYShape.scaleCdfTo(~scaleTo, shape)
+ |> XYShape.Range.derivative
+ |> E.O.fmap(fromShape)
+ | _ => None
+ };
+ };
};
module Discrete = {
@@ -159,7 +177,7 @@ module Discrete = {
)
|> ReasonReact.array;
- let integrate = XYShape.accumulateYs;
+ let integrate = t => t |> XYShape.accumulateYs |> Continuous.fromShape;
let derivative = XYShape.subtractYs;
// TODO: This has a clear bug where it returns the Y value of the first item,
@@ -245,12 +263,15 @@ module Mixed = {
let clean = (t: DistributionTypes.mixedShape) =>
switch (t) {
- | {continuous: {xs: [||], ys: [||]}, discrete: {xs: [||], ys: [||]}} =>
+ | {
+ continuous: {shape: {xs: [||], ys: [||]}},
+ discrete: {xs: [||], ys: [||]},
+ } =>
None
| {discrete: {xs: [|_|], ys: [|_|]}} => None
| {continuous, discrete: {xs: [||], ys: [||]}} =>
Some(Continuous(continuous))
- | {continuous: {xs: [||], ys: [||]}, discrete} =>
+ | {continuous: {shape: {xs: [||], ys: [||]}}, discrete} =>
Some(Discrete(discrete))
| shape => Some(Mixed(shape))
};
@@ -318,108 +339,92 @@ module T = {
| 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 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 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))
- };
+ // 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 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))
- };
-
- 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))
- };
- };
+ // 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))
+ // };
+ // 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))
+ // };
+ // };
};
-
- let toPdfCdfCombo = (t: t): option(pdfCdfCombo) =>
- switch (t) {
- | Mixed({continuous, discrete, discreteProbabilityMassFraction} as tt) =>
- Some({
- cdf: continuous |> Continuous.toCdf |> E.O.toExt(""),
- pdf: Mixed(tt),
- })
- | Discrete(d) => Some({cdf: d |> Discrete.integrate, pdf: Discrete(d)})
- | Continuous(c) =>
- Some({
- cdf: c |> Continuous.toCdf |> E.O.toExt(""),
- pdf: Continuous(c),
- })
- };
};
module PdfCdfShape = {
@@ -449,10 +454,10 @@ module WithLimitedDomain = {
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);
+ // 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 = {
diff --git a/src/utility/CdfLibrary.re b/src/utility/CdfLibrary.re
index 2354331c..aabbc092 100644
--- a/src/utility/CdfLibrary.re
+++ b/src/utility/CdfLibrary.re
@@ -5,15 +5,15 @@ module JS = {
ys: array(float),
};
- let distToJs = (d: DistributionTypes.continuousShape) =>
+ let distToJs = (d: DistributionTypes.xyShape) =>
distJs(~xs=d.xs, ~ys=d.ys);
- let jsToDist = (d: distJs): DistributionTypes.continuousShape => {
+ let jsToDist = (d: distJs): DistributionTypes.xyShape => {
xs: xsGet(d),
ys: ysGet(d),
};
- let doAsDist = (f, d: DistributionTypes.continuousShape) =>
+ let doAsDist = (f, d: DistributionTypes.xyShape) =>
d |> distToJs |> f |> jsToDist;
[@bs.module "./CdfLibrary.js"]
diff --git a/src/utility/Guesstimator.re b/src/utility/Guesstimator.re
index 7407c36f..5729fb2b 100644
--- a/src/utility/Guesstimator.re
+++ b/src/utility/Guesstimator.re
@@ -16,10 +16,10 @@ module Internals = {
discrete,
};
- let toContinous = (r: combined): DistributionTypes.continuousShape =>
- continuousGet(r) |> CdfLibrary.JS.jsToDist;
+ let toContinous = (r: combined) =>
+ continuousGet(r) |> CdfLibrary.JS.jsToDist |> Shape.Continuous.fromShape;
- let toDiscrete = (r: combined): DistributionTypes.discreteShape =>
+ let toDiscrete = (r: combined): DistributionTypes.xyShape =>
discreteGet(r) |> jsToDistDiscrete;
[@bs.module "./GuesstimatorLibrary.js"]