Formatting
This commit is contained in:
parent
2f45f92552
commit
a89960a1e7
|
@ -13,16 +13,15 @@ let makeTest = (~only=false, str, item1, item2) =>
|
|||
);
|
||||
|
||||
let makeTestCloseEquality = (~only=false, str, item1, item2, ~digits) =>
|
||||
only
|
||||
? Only.test(str, () =>
|
||||
expect(item1) |> toBeSoCloseTo(item2, ~digits)
|
||||
)
|
||||
: test(str, () =>
|
||||
expect(item1) |> toBeSoCloseTo(item2, ~digits)
|
||||
);
|
||||
only
|
||||
? Only.test(str, () =>
|
||||
expect(item1) |> toBeSoCloseTo(item2, ~digits)
|
||||
)
|
||||
: test(str, () =>
|
||||
expect(item1) |> toBeSoCloseTo(item2, ~digits)
|
||||
);
|
||||
|
||||
describe("Shape", () => {
|
||||
|
||||
describe("Continuous", () => {
|
||||
open Distributions.Continuous;
|
||||
let continuous = make(`Linear, shape);
|
||||
|
@ -129,7 +128,7 @@ describe("Shape", () => {
|
|||
1.0,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
describe("Discrete", () => {
|
||||
open Distributions.Discrete;
|
||||
let shape: DistTypes.xyShape = {
|
||||
|
@ -195,7 +194,13 @@ describe("Shape", () => {
|
|||
0.9,
|
||||
);
|
||||
makeTest("integralEndY", T.Integral.sum(~cache=None, discrete), 1.0);
|
||||
|
||||
makeTest("mean", T.getMean(discrete), 3.9);
|
||||
makeTestCloseEquality(
|
||||
"variance",
|
||||
T.getVariance(discrete),
|
||||
5.89,
|
||||
~digits=7,
|
||||
);
|
||||
});
|
||||
|
||||
describe("Mixed", () => {
|
||||
|
@ -300,7 +305,6 @@ describe("Shape", () => {
|
|||
},
|
||||
),
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
describe("Distplus", () => {
|
||||
|
@ -380,33 +384,36 @@ describe("Shape", () => {
|
|||
let stdev = 4.0;
|
||||
let variance = stdev ** 2.0;
|
||||
let numSamples = 10000;
|
||||
|
||||
open Distributions.Shape;
|
||||
let normal: SymbolicDist.dist = `Normal({ mean, stdev});
|
||||
let normal: SymbolicDist.dist = `Normal({mean, stdev});
|
||||
let normalShape = SymbolicDist.GenericSimple.toShape(normal, numSamples);
|
||||
let lognormal = SymbolicDist.Lognormal.fromMeanAndStdev(mean, stdev);
|
||||
let lognormalShape = SymbolicDist.GenericSimple.toShape(lognormal, numSamples);
|
||||
let lognormalShape =
|
||||
SymbolicDist.GenericSimple.toShape(lognormal, numSamples);
|
||||
|
||||
makeTestCloseEquality(
|
||||
"Mean of a normal",
|
||||
T.getMean(normalShape),
|
||||
mean,
|
||||
~digits=2);
|
||||
T.getMean(normalShape),
|
||||
mean,
|
||||
~digits=2,
|
||||
);
|
||||
makeTestCloseEquality(
|
||||
"Variance of a normal",
|
||||
T.getVariance(normalShape),
|
||||
variance,
|
||||
~digits=1);
|
||||
"Variance of a normal",
|
||||
T.getVariance(normalShape),
|
||||
variance,
|
||||
~digits=1,
|
||||
);
|
||||
makeTestCloseEquality(
|
||||
"Mean of a lognormal",
|
||||
T.getMean(lognormalShape),
|
||||
mean,
|
||||
~digits=2);
|
||||
"Mean of a lognormal",
|
||||
T.getMean(lognormalShape),
|
||||
mean,
|
||||
~digits=2,
|
||||
);
|
||||
makeTestCloseEquality(
|
||||
"Variance of a lognormal",
|
||||
T.getVariance(lognormalShape),
|
||||
variance,
|
||||
~digits=0);
|
||||
"Variance of a lognormal",
|
||||
T.getVariance(lognormalShape),
|
||||
variance,
|
||||
~digits=0,
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
|
@ -104,7 +104,7 @@ module Continuous = {
|
|||
)
|
||||
|> DistTypes.MixedPoint.makeContinuous;
|
||||
};
|
||||
|
||||
|
||||
// let combineWithFn = (t1: t, t2: t, fn: (float, float) => float) => {
|
||||
// switch(t1, t2){
|
||||
// | ({interpolation: `Stepwise}, {interpolation: `Stepwise}) => 3.0
|
||||
|
@ -141,8 +141,22 @@ module Continuous = {
|
|||
let toScaledContinuous = t => Some(t);
|
||||
let toScaledDiscrete = _ => None;
|
||||
|
||||
let getMean = (t: t) => XYShape.Analysis.integrateContinuousShape(t);
|
||||
let getVariance = (t: t): float => XYShape.Analysis.getVarianceDangerously(t, getMean, XYShape.Analysis.getMeanOfSquaresContinuousShape);
|
||||
let getMean = (t: t) => {
|
||||
let indefiniteIntegralStepwise = (p, h1) => h1 *. p ** 2.0 /. 2.0;
|
||||
let indefiniteIntegralLinear = (p, a, b) =>
|
||||
a *. p ** 2.0 /. 2.0 +. b *. p ** 3.0 /. 3.0;
|
||||
XYShape.Analysis.integrateContinuousShape(
|
||||
~indefiniteIntegralStepwise,
|
||||
~indefiniteIntegralLinear,
|
||||
t,
|
||||
);
|
||||
};
|
||||
let getVariance = (t: t): float =>
|
||||
XYShape.Analysis.getVarianceDangerously(
|
||||
t,
|
||||
getMean,
|
||||
XYShape.Analysis.getMeanOfSquaresContinuousShape,
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -215,13 +229,14 @@ module Discrete = {
|
|||
|> Continuous.getShape
|
||||
|> XYShape.YtoX.linear(f);
|
||||
|
||||
let getMean = (t: t): float => E.A.reducei(t.xs, 0.0, (acc, x, i) => acc +. x*. t.ys[i]);
|
||||
let getMean = (t: t): float =>
|
||||
E.A.reducei(t.xs, 0.0, (acc, x, i) => acc +. x *. t.ys[i]);
|
||||
let getVariance = (t: t): float => {
|
||||
let getMeanOfSquares = t => getMean(XYShape.Analysis.squareXYShape(t));
|
||||
let getMeanOfSquares = t =>
|
||||
getMean(XYShape.Analysis.squareXYShape(t));
|
||||
XYShape.Analysis.getVarianceDangerously(t, getMean, getMeanOfSquares);
|
||||
};
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// TODO: I think this shouldn't assume continuous/discrete are normalized to 1.0, and thus should not need the discreteProbabilityMassFraction being separate.
|
||||
|
@ -393,27 +408,38 @@ module Mixed = {
|
|||
};
|
||||
};
|
||||
|
||||
let getMean = (t: t) : float => {
|
||||
let discreteProbabilityMassFraction = t.discreteProbabilityMassFraction;
|
||||
let mean = switch(discreteProbabilityMassFraction){
|
||||
| 1.0 => Discrete.T.getMean(t.discrete);
|
||||
| 0.0 => Continuous.T.getMean(t.continuous);
|
||||
| _ => (Discrete.T.getMean(t.discrete) *. discreteProbabilityMassFraction)
|
||||
+. (Continuous.T.getMean(t.continuous) *. (1.0 -. discreteProbabilityMassFraction))
|
||||
let getMean = (t: t): float => {
|
||||
let discreteProbabilityMassFraction =
|
||||
t.discreteProbabilityMassFraction;
|
||||
switch (discreteProbabilityMassFraction) {
|
||||
| 1.0 => Discrete.T.getMean(t.discrete)
|
||||
| 0.0 => Continuous.T.getMean(t.continuous)
|
||||
| _ =>
|
||||
Discrete.T.getMean(t.discrete)
|
||||
*. discreteProbabilityMassFraction
|
||||
+. Continuous.T.getMean(t.continuous)
|
||||
*. (1.0 -. discreteProbabilityMassFraction)
|
||||
};
|
||||
mean;
|
||||
};
|
||||
|
||||
let getVariance = (t: t) : float => {
|
||||
let discreteProbabilityMassFraction = t.discreteProbabilityMassFraction;
|
||||
let getVariance = (t: t): float => {
|
||||
let discreteProbabilityMassFraction =
|
||||
t.discreteProbabilityMassFraction;
|
||||
let getMeanOfSquares = (t: t) => {
|
||||
Discrete.T.getMean(XYShape.Analysis.squareXYShape(t.discrete))*.t.discreteProbabilityMassFraction
|
||||
+. XYShape.Analysis.getMeanOfSquaresContinuousShape(t.continuous)*.(1.0 -. t.discreteProbabilityMassFraction)
|
||||
Discrete.T.getMean(XYShape.Analysis.squareXYShape(t.discrete))
|
||||
*. t.discreteProbabilityMassFraction
|
||||
+. XYShape.Analysis.getMeanOfSquaresContinuousShape(t.continuous)
|
||||
*. (1.0 -. t.discreteProbabilityMassFraction);
|
||||
};
|
||||
switch(discreteProbabilityMassFraction){
|
||||
| 1.0 => Discrete.T.getVariance(t.discrete);
|
||||
| 0.0 => Continuous.T.getVariance(t.continuous);
|
||||
| _ => XYShape.Analysis.getVarianceDangerously(t, getMean, getMeanOfSquares);
|
||||
switch (discreteProbabilityMassFraction) {
|
||||
| 1.0 => Discrete.T.getVariance(t.discrete)
|
||||
| 0.0 => Continuous.T.getVariance(t.continuous)
|
||||
| _ =>
|
||||
XYShape.Analysis.getVarianceDangerously(
|
||||
t,
|
||||
getMean,
|
||||
getMeanOfSquares,
|
||||
)
|
||||
};
|
||||
};
|
||||
});
|
||||
|
@ -520,18 +546,20 @@ module Shape = {
|
|||
Discrete.T.mapY(fn),
|
||||
Continuous.T.mapY(fn),
|
||||
));
|
||||
|
||||
let getMean = (t: t): float => switch (t) {
|
||||
| Mixed(m) => Mixed.T.getMean(m);
|
||||
| Discrete(m) => Discrete.T.getMean(m);
|
||||
| Continuous(m) => Continuous.T.getMean(m);
|
||||
};
|
||||
|
||||
let getVariance = (t: t): float => switch (t) {
|
||||
| Mixed(m) => Mixed.T.getVariance(m);
|
||||
| Discrete(m) => Discrete.T.getVariance(m);
|
||||
| Continuous(m) => Continuous.T.getVariance(m);
|
||||
};
|
||||
let getMean = (t: t): float =>
|
||||
switch (t) {
|
||||
| Mixed(m) => Mixed.T.getMean(m)
|
||||
| Discrete(m) => Discrete.T.getMean(m)
|
||||
| Continuous(m) => Continuous.T.getMean(m)
|
||||
};
|
||||
|
||||
let getVariance = (t: t): float =>
|
||||
switch (t) {
|
||||
| Mixed(m) => Mixed.T.getVariance(m)
|
||||
| Discrete(m) => Discrete.T.getVariance(m)
|
||||
| Continuous(m) => Continuous.T.getVariance(m)
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ module T = {
|
|||
type ts = array(xyShape);
|
||||
let xs = (t: t) => t.xs;
|
||||
let ys = (t: t) => t.ys;
|
||||
let empty = ({xs: [||], ys: [||]});
|
||||
let empty = {xs: [||], ys: [||]};
|
||||
let minX = (t: t) => t |> xs |> E.A.Sorted.min |> extImp;
|
||||
let maxX = (t: t) => t |> xs |> E.A.Sorted.max |> extImp;
|
||||
let firstY = (t: t) => t |> ys |> E.A.first |> extImp;
|
||||
|
@ -299,55 +299,62 @@ let logScorePoint = (sampleCount, t1, t2) =>
|
|||
|> E.O.fmap(Pairs.last)
|
||||
|> E.O.fmap(Pairs.y);
|
||||
|
||||
|
||||
module Analysis = {
|
||||
let integrateContinuousShape = (
|
||||
~indefiniteIntegralStepwise = (p,h1) => (h1*.(p**2.0)/. 2.0),
|
||||
~indefiniteIntegralLinear = (p, a, b) => (a *. (p ** 2.0) /.2.0) +. (b *. (p**3.0) /. 3.0),
|
||||
t: DistTypes.continuousShape
|
||||
): float => {
|
||||
module Analysis = {
|
||||
let integrateContinuousShape =
|
||||
(
|
||||
~indefiniteIntegralStepwise=(p, h1) => h1 *. p,
|
||||
~indefiniteIntegralLinear=(p, a, b) => a *. p +. b *. p ** 2.0 /. 2.0,
|
||||
t: DistTypes.continuousShape,
|
||||
)
|
||||
: float => {
|
||||
let xs = t.xyShape.xs;
|
||||
let ys = t.xyShape.ys;
|
||||
|
||||
E.A.reducei(xs, 0.0, (acc, _x, i) => {
|
||||
let areaUnderIntegral = switch(t.interpolation, i){
|
||||
| (_, 0) => 0.0;
|
||||
| (`Stepwise, _) => indefiniteIntegralStepwise(xs[i],ys[i-1])
|
||||
-. indefiniteIntegralStepwise(xs[i-1],ys[i-1]);
|
||||
| (`Linear, _) => {
|
||||
let x1 = xs[i-1];
|
||||
let x2 = xs[i];
|
||||
let h1 = ys[i-1];
|
||||
let h2 = ys[i];
|
||||
let b = (h1 -. h2 ) /. (x1 -.x2)
|
||||
let a = h1 -. b *.x1;
|
||||
indefiniteIntegralLinear(x2, a, b) -. indefiniteIntegralLinear(x1, a, b);
|
||||
E.A.reducei(
|
||||
xs,
|
||||
0.0,
|
||||
(acc, _x, i) => {
|
||||
let areaUnderIntegral =
|
||||
switch (t.interpolation, i) {
|
||||
| (_, 0) => 0.0
|
||||
| (`Stepwise, _) =>
|
||||
indefiniteIntegralStepwise(xs[i], ys[i - 1])
|
||||
-. indefiniteIntegralStepwise(xs[i - 1], ys[i - 1])
|
||||
| (`Linear, _) =>
|
||||
let x1 = xs[i - 1];
|
||||
let x2 = xs[i];
|
||||
let h1 = ys[i - 1];
|
||||
let h2 = ys[i];
|
||||
let b = (h1 -. h2) /. (x1 -. x2);
|
||||
let a = h1 -. b *. x1;
|
||||
indefiniteIntegralLinear(x2, a, b)
|
||||
-. indefiniteIntegralLinear(x1, a, b);
|
||||
};
|
||||
};
|
||||
acc +. areaUnderIntegral;
|
||||
});
|
||||
acc +. areaUnderIntegral;
|
||||
},
|
||||
);
|
||||
};
|
||||
let getVarianceDangerously = (
|
||||
t: 't,
|
||||
getMean: ('t => float),
|
||||
getMeanOfSquares: ('t => float),
|
||||
): float => {
|
||||
|
||||
let meanSquared = getMean(t)**2.0;
|
||||
let meanOfSquares = getMeanOfSquares(t);
|
||||
|
||||
meanOfSquares -. meanSquared;
|
||||
};
|
||||
|
||||
let squareXYShape = t: DistTypes.xyShape => {...t, xs: E.A.fmap(x => x**2.0, t.xs)};
|
||||
|
||||
let getMeanOfSquaresContinuousShape = (t: DistTypes.continuousShape) => {
|
||||
let indefiniteIntegralLinear = (p, a, b) => (a *. (p ** 3.0) /.3.0) +. (b *. (p**4.0) /. 4.0);
|
||||
let indefiniteIntegralStepwise = (p,h1) => h1*.(p**3.0)/. 3.0;
|
||||
let indefiniteIntegralLinear = (p, a, b) =>
|
||||
a *. p ** 3.0 /. 3.0 +. b *. p ** 4.0 /. 4.0;
|
||||
let indefiniteIntegralStepwise = (p, h1) => h1 *. p ** 3.0 /. 3.0;
|
||||
integrateContinuousShape(
|
||||
~indefiniteIntegralStepwise,
|
||||
~indefiniteIntegralLinear,
|
||||
t
|
||||
t,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let getVarianceDangerously =
|
||||
(t: 't, getMean: 't => float, getMeanOfSquares: 't => float): float => {
|
||||
let meanSquared = getMean(t) ** 2.0;
|
||||
let meanOfSquares = getMeanOfSquares(t);
|
||||
meanOfSquares -. meanSquared;
|
||||
};
|
||||
|
||||
let squareXYShape = (t): DistTypes.xyShape => {
|
||||
...t,
|
||||
xs: E.A.fmap(x => x ** 2.0, t.xs),
|
||||
};
|
||||
};
|
Loading…
Reference in New Issue
Block a user