Minor improvement of integrals for mixed distributions

This commit is contained in:
Ozzie Gooen 2020-02-19 17:47:25 +00:00
parent 7389fda068
commit e5fb663c5d
4 changed files with 46 additions and 37 deletions

View File

@ -6,21 +6,20 @@ let shape: DistributionTypes.xyShape = {
ys: [|8., 9., 2.|], ys: [|8., 9., 2.|],
}; };
let step: DistributionTypes.xyShape = {
xs: [|1., 4., 8.|],
ys: [|8., 17., 19.|],
};
open Shape; open Shape;
describe("Shape", () => describe("Shape", () =>
describe("XYShape", () => describe("XYShape", () => {
test("#ySum", () test("#ySum", () =>
=> expect(XYShape.ySum(shape)) |> toEqual(19.0)
expect(XYShape.ySum(shape)) |> toEqual(19.0) );
) test("#yFOo", () =>
// test("#both", () => { expect(Discrete.integrate(shape)) |> toEqual(step)
// let expected: DistributionTypes.xyShape = { );
// xs: [|1., 4., 8.|], })
// ys: [|8., 1., 1.|],
// };
// expect(shape |> XYShape.derivative |> XYShape.integral)
// |> toEqual(shape);
// });
)
); );

View File

@ -39,11 +39,12 @@ let domainLimitedDist =
let distributions = () => let distributions = () =>
<div> <div>
<div> <div>
<h2> {"Basic Mixed Distribution" |> ReasonReact.string} </h2>
<GenericDistributionChart dist=timeDist /> <h2> {"Basic Mixed Distribution" |> ReasonReact.string} </h2>
<h2> {"Simple Continuous" |> ReasonReact.string} </h2> <GenericDistributionChart dist=timeDist />
<GenericDistributionChart dist=mixedDist /> <h2> {"Simple Continuous" |> ReasonReact.string} </h2>
</div> </div>
// <GenericDistributionChart dist=mixedDist />
</div>; </div>;
// <div> // <div>
// <h2> {"Time Distribution" |> ReasonReact.string} </h2> // <h2> {"Time Distribution" |> ReasonReact.string} </h2>

View File

@ -20,7 +20,6 @@ module Mixed = {
<thead> <thead>
<tr> <tr>
<th className="px-4 py-2"> {"X Point" |> ReasonReact.string} </th> <th className="px-4 py-2"> {"X Point" |> ReasonReact.string} </th>
<th className="px-4 py-2"> {"Y Pount" |> ReasonReact.string} </th>
<th className="px-4 py-2"> <th className="px-4 py-2">
{"Y Integral to Point" |> ReasonReact.string} {"Y Integral to Point" |> ReasonReact.string}
</th> </th>
@ -41,6 +40,9 @@ module Mixed = {
</tbody> </tbody>
</table> </table>
<div /> <div />
{data.discrete
|> Shape.Discrete.scaleYToTotal(data.discreteProbabilityMassFraction)
|> Shape.Discrete.render}
</div>; </div>;
}; };
}; };

View File

@ -17,6 +17,8 @@ module XYShape = {
{"xs": t.xs, "ys": t.ys}; {"xs": t.xs, "ys": t.ys};
}; };
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 fmap = (t: t, y): t => {xs: t.xs, ys: t.ys |> E.A.fmap(y)};
let scaleCdfTo = (~scaleTo=1., t: t) => let scaleCdfTo = (~scaleTo=1., t: t) =>
@ -84,8 +86,6 @@ module XYShape = {
let mapYsBasedOnRanges = fn => inRanges(r => (nextX(r), fn(r)), toT); let mapYsBasedOnRanges = fn => inRanges(r => (nextX(r), fn(r)), toT);
let toStepFn = z => mapYsBasedOnRanges(rangeAreaAssumingSteps, z);
let integrateWithSteps = z => let integrateWithSteps = z =>
mapYsBasedOnRanges(rangeAreaAssumingSteps, z) |> E.O.fmap(accumulateYs); mapYsBasedOnRanges(rangeAreaAssumingSteps, z) |> E.O.fmap(accumulateYs);
@ -142,23 +142,21 @@ module Discrete = {
) )
|> ReasonReact.array; |> ReasonReact.array;
let findY = (x: float, t: t) =>
switch (E.A.getBy(zip(t), ((ix, _)) => ix == x)) {
| Some((_, y)) => y
| None => 0.
};
let integrate = XYShape.accumulateYs; let integrate = XYShape.accumulateYs;
let derivative = XYShape.subtractYs; let derivative = XYShape.subtractYs;
let findIntegralY = (f, t: t) => // TODO: This has a clear bug where it returns the Y value of the first item,
t // even if X is less than the X of the first item.
|> XYShape.Range.toStepFn let findIntegralY = (f, t: t) => {
|> E.O.fmap(XYShape.accumulateYs) t |> XYShape.accumulateYs |> CdfLibrary.Distribution.findY(f);
|> E.O.fmap(CdfLibrary.Distribution.findY(f)); };
let findX = (f, t: t) => let findY = (f, t: t) => {
t |> XYShape.Range.toStepFn |> E.O.fmap(CdfLibrary.Distribution.findX(f)); Belt.Array.zip(t.xs, t.ys)
|> E.A.getBy(_, ((x, _)) => x == f)
|> E.O.fmap(((_, y)) => y)
|> E.O.default(0.);
};
}; };
module Mixed = { module Mixed = {
@ -195,7 +193,7 @@ module Mixed = {
let c = t.continuous |> Continuous.findIntegralY(x); let c = t.continuous |> Continuous.findIntegralY(x);
let d = Discrete.findIntegralY(x, t.discrete); let d = Discrete.findIntegralY(x, t.discrete);
switch (c, d) { switch (c, d) {
| (Some(c), Some(d)) => Some(mixedMultiply(t, c, d)) | (Some(c), d) => Some(mixedMultiply(t, c, d))
| _ => None | _ => None
}; };
}; };
@ -208,13 +206,22 @@ module Mixed = {
module Any = { module Any = {
type t = DistributionTypes.pointsType; type t = DistributionTypes.pointsType;
let x = (t: t, x: float) => let y = (t: t, x: float) =>
switch (t) { switch (t) {
| Mixed(m) => `mixed(Mixed.getY(m, x)) | Mixed(m) => `mixed(Mixed.getY(m, x))
| Discrete(discreteShape) => `discrete(Discrete.findY(x, discreteShape)) | Discrete(discreteShape) => `discrete(Discrete.findY(x, discreteShape))
| Continuous(continuousShape) => | Continuous(continuousShape) =>
`continuous(Continuous.findY(x, continuousShape)) `continuous(Continuous.findY(x, continuousShape))
}; };
let yIntegral = (t: t, x: float) =>
switch (t) {
| Mixed(m) => `mixed(Mixed.getYIntegral(x, m))
| Discrete(discreteShape) =>
`discrete(Discrete.findIntegralY(x, discreteShape))
| Continuous(continuousShape) =>
`continuous(Continuous.findIntegralY(x, continuousShape))
};
}; };
module DomainMixed = { module DomainMixed = {