diff --git a/showcase/entries/Continuous.re b/showcase/entries/Continuous.re
index 741d1ddc..16a377b3 100644
--- a/showcase/entries/Continuous.re
+++ b/showcase/entries/Continuous.re
@@ -2,7 +2,7 @@
let timeDist =
GenericDistribution.make(
~generationSource=
- GuesstimatorString("mm(floor(normal(30,3)), normal(39,1), [.5,.5])"),
+ GuesstimatorString("mm(floor(normal(30,2)), normal(39,1), [.5,.5])"),
~probabilityType=Pdf,
~domain=Complete,
~unit=TimeDistribution({zero: MomentRe.momentNow(), unit: `days}),
diff --git a/src/components/charts/ComplexPowerChart.re b/src/components/charts/ComplexPowerChart.re
index 9f80d8eb..191847ff 100644
--- a/src/components/charts/ComplexPowerChart.re
+++ b/src/components/charts/ComplexPowerChart.re
@@ -23,6 +23,37 @@ module ComplexPowerChart = {
};
};
+let bar: DistributionTypes.xyShape = {
+ ys: [|0.5, 0.8, 0.4, 1.0, 2.0|],
+ xs: [|0.0, 1., 2., 5., 8.|],
+};
+
+module IntegralChart = {
+ [@react.component]
+ let make = (~complexPower: DistributionTypes.complexPower, ~onHover) => {
+ open DistFunctor.ComplexPower;
+ let integral =
+ DistFunctor.ComplexPower.T.Integral.get(~cache=None, complexPower);
+ let continuous =
+ integral
+ |> T.toContinuous
+ |> E.O.fmap(DistFunctor.Continuous.toLinear)
+ |> E.O.fmap(DistFunctor.Continuous.getShape);
+ let minX = T.minX(integral);
+ let maxX = T.maxX(integral);
+ let timeScale =
+ complexPower.unit |> DistributionTypes.DistributionUnit.toJson;
+ ;
+ };
+};
+
[@react.component]
let make = (~complexPower: DistributionTypes.complexPower) => {
let (x, setX) = React.useState(() => 0.);
@@ -31,8 +62,14 @@ let make = (~complexPower: DistributionTypes.complexPower) => {
() => { {setX(_ => r)}} />},
[|complexPower|],
);
+ let chart2 =
+ React.useMemo1(
+ () => { {setX(_ => r)}} />},
+ [|complexPower|],
+ );
chart
+ chart2
diff --git a/src/core/DistFunctor.re b/src/core/DistFunctor.re
index 4fc802cb..7a1fe17a 100644
--- a/src/core/DistFunctor.re
+++ b/src/core/DistFunctor.re
@@ -77,18 +77,28 @@ module Continuous = {
: option(DistributionTypes.continuousShape) =>
fn(xyShape) |> E.O.fmap(xyShape => make(xyShape, interpolation));
+ let toLinear = (t: t): t =>
+ switch (t) {
+ | {interpolation: `Stepwise, xyShape} => {
+ interpolation: `Linear,
+ xyShape: xyShape |> XYShape.Range.stepsToContinuous |> E.O.toExt(""),
+ }
+ | {interpolation: `Linear, _} => t
+ };
+
module T =
Dist({
type t = DistributionTypes.continuousShape;
type integral = DistributionTypes.continuousShape;
let shapeFn = (fn, t: t) => t |> xyShape |> fn;
+ // TODO: Obviously fix this, it's terrible
let integral = (~cache, t) =>
cache
|> E.O.default(
t
|> xyShape
|> XYShape.Range.integrateWithTriangles
- |> E.O.toExt("")
+ |> E.O.toExt("Error1")
|> fromShape,
);
// This seems wrong, we really want the ending bit, I'd assume
@@ -118,7 +128,16 @@ module Discrete = {
type integral = DistributionTypes.continuousShape;
let integral = (~cache, t) =>
cache
- |> E.O.default(t |> XYShape.accumulateYs |> Continuous.fromShape);
+ |> E.O.default(
+ {
+ Continuous.make(
+ XYShape.accumulateYs(t)
+ |> XYShape.Range.stepsToContinuous
+ |> E.O.toExt("ERROR"),
+ `Stepwise,
+ );
+ },
+ );
let integralSum = (~cache, t) => t |> XYShape.ySum;
let minX = XYShape.minX;
let maxX = XYShape.maxX;
@@ -197,26 +216,42 @@ module Mixed = {
DistributionTypes.MixedPoint.add(c, d);
};
- let toScaledContinuous =
- ({continuous, discreteProbabilityMassFraction}: t) =>
- Some(
- continuous
- |> Continuous.T.scaleBy(
- ~scale=1.0 -. discreteProbabilityMassFraction,
- ),
- );
+ let scaleContinuous =
+ ({discreteProbabilityMassFraction}: t, continuous) =>
+ continuous
+ |> Continuous.T.scaleBy(~scale=1.0 -. discreteProbabilityMassFraction);
- let toScaledDiscrete = ({discrete, discreteProbabilityMassFraction}: t) =>
- Some(
- discrete
- |> Discrete.T.scaleBy(~scale=discreteProbabilityMassFraction),
- );
+ let scaleDiscrete = ({discreteProbabilityMassFraction}: t, disrete) =>
+ disrete |> Discrete.T.scaleBy(~scale=discreteProbabilityMassFraction);
+
+ let toScaledContinuous = ({continuous} as t: t) =>
+ Some(scaleContinuous(t, continuous));
+
+ let toScaledDiscrete = ({discrete} as t: t) =>
+ Some(scaleDiscrete(t, discrete));
// TODO: Add these two directly, once interpolation is added.
- let integral = (~cache, t) => {
- // let cont = scaledContinuousComponent(t);
- // let discrete = scaledDiscreteComponent(t);
- cache |> E.O.toExt("");
+ let integral =
+ (
+ ~cache,
+ {continuous, discrete, discreteProbabilityMassFraction} as t: t,
+ ) => {
+ cache
+ |> E.O.default(
+ {
+ let cont =
+ continuous
+ |> Continuous.T.Integral.get(~cache=None)
+ |> scaleContinuous(t);
+ let dist =
+ discrete
+ |> Discrete.T.Integral.get(~cache=None)
+ |> Continuous.T.scaleBy(
+ ~scale=discreteProbabilityMassFraction,
+ );
+ dist;
+ },
+ );
};
let integralSum =
@@ -323,7 +358,7 @@ module Shape = {
);
let minX = (t: t) =>
mapToAll(t, (Mixed.T.minX, Discrete.T.minX, Continuous.T.minX));
- let integral = (~cache, t: t) =>
+ let integral = (~cache, t: t) => {
mapToAll(
t,
(
@@ -332,6 +367,7 @@ module Shape = {
Continuous.T.Integral.get(~cache),
),
);
+ };
let integralSum = (~cache, t: t) =>
mapToAll(
t,
diff --git a/src/core/DistributionTypes.re b/src/core/DistributionTypes.re
index 0cf2a0da..6eda94ee 100644
--- a/src/core/DistributionTypes.re
+++ b/src/core/DistributionTypes.re
@@ -14,6 +14,11 @@ type xyShape = {
ys: array(float),
};
+let foo = {xs: [|1., 2., 5.|], ys: [|1., 2., 3.|]};
+let answer = {xs: [|1., 2., 2., 5., 5.|], ys: [|1., 1., 2., 2., 3.|]};
+
+let toStepwise = (xyShape: xyShape) => {};
+
type interpolationMethod = [ | `Stepwise | `Linear];
type continuousShape = {
diff --git a/src/core/GenericDistribution.re b/src/core/GenericDistribution.re
index f2c734a6..2603a1cf 100644
--- a/src/core/GenericDistribution.re
+++ b/src/core/GenericDistribution.re
@@ -15,8 +15,7 @@ let make =
unit,
};
-let toComplexPower =
- (~sampleCount, t: genericDistribution): option(complexPower) => {
+let toComplexPower = (~sampleCount, t: genericDistribution) => {
let shape =
switch (t.generationSource) {
| GuesstimatorString(s) =>
diff --git a/src/core/XYShape.re b/src/core/XYShape.re
index 3b6196f9..8da043ca 100644
--- a/src/core/XYShape.re
+++ b/src/core/XYShape.re
@@ -19,8 +19,24 @@ let zip = t => Belt.Array.zip(t.xs, t.ys);
let fmap = (t: t, y): t => {xs: t.xs, ys: t.ys |> E.A.fmap(y)};
+let fromArray = ((xs, ys)): t => {xs, ys};
+let fromArrays = (xs, ys): t => {xs, ys};
let pointwiseMap = (fn, t: t): t => {xs: t.xs, ys: t.ys |> E.A.fmap(fn)};
+let intersperce = (t1: t, t2: t) => {
+ let foo: ref(array((float, float))) = ref([||]);
+ let t1 = zip(t1);
+ let t2 = zip(t2);
+
+ Belt.Array.forEachWithIndex(t1, (i, item) => {
+ switch (Belt.Array.get(t2, i)) {
+ | Some(r) => foo := E.A.append(foo^, [|item, r|])
+ | None => foo := E.A.append(foo^, [|item|])
+ }
+ });
+ foo^ |> Belt.Array.unzip |> fromArray;
+};
+
let scaleCdfTo = (~scaleTo=1., t: t) =>
switch (_lastElement(t.ys)) {
| Some(n) =>
@@ -35,9 +51,6 @@ let yFold = (fn, t: t) => {
let ySum = yFold((a, b) => a +. b);
-let fromArray = ((xs, ys)): t => {xs, ys};
-let fromArrays = (xs, ys): t => {xs, ys};
-
let _transverse = fn =>
Belt.Array.reduce(_, [||], (items, (x, y)) =>
switch (_lastElement(items)) {
@@ -68,6 +81,12 @@ module Range = {
let rangeAreaAssumingSteps = (((lastX, lastY), (nextX, _)): zippedRange) =>
(nextX -. lastX) *. lastY;
+ let rangePointAssumingSteps =
+ (((lastX, lastY), (nextX, nextY)): zippedRange) => (
+ nextX,
+ lastY,
+ );
+
let rangeAreaAssumingTriangles =
(((lastX, lastY), (nextX, nextY)): zippedRange) =>
(nextX -. lastX) *. (lastY +. nextY) /. 2.;
@@ -93,6 +112,15 @@ module Range = {
|> E.O.fmap(accumulateYs);
let derivative = mapYsBasedOnRanges(delta_y_over_delta_x);
+
+ let stepsToContinuous = t =>
+ Belt.Array.zip(t.xs, t.ys)
+ |> E.A.toRanges
+ |> E.R.toOption
+ |> E.O.fmap(r => r |> Belt.Array.map(_, rangePointAssumingSteps))
+ |> E.O.fmap(Belt.Array.unzip)
+ |> E.O.fmap(fromArray)
+ |> E.O.fmap(intersperce(t));
};
let findY = CdfLibrary.Distribution.findY;