Add simple percentiles to distribution shower
This commit is contained in:
parent
c9161d230e
commit
f887af22ea
|
@ -6,6 +6,9 @@ let showAsForm = (distPlus: DistTypes.distPlus) => {
|
|||
</div>;
|
||||
};
|
||||
|
||||
let showFloat = (~precision=3, number) =>
|
||||
<ForetoldComponents.NumberShower number precision />;
|
||||
|
||||
let table = (distPlus, x) => {
|
||||
<div>
|
||||
<table className="table-auto text-sm">
|
||||
|
@ -120,6 +123,60 @@ let table = (distPlus, x) => {
|
|||
</table>
|
||||
</div>;
|
||||
};
|
||||
let percentiles = distPlus => {
|
||||
<table className="table-auto text-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<td className="px-4 py-2"> {"1" |> ReasonReact.string} </td>
|
||||
<td className="px-4 py-2"> {"5" |> ReasonReact.string} </td>
|
||||
<td className="px-4 py-2"> {"25" |> ReasonReact.string} </td>
|
||||
<td className="px-4 py-2"> {"50" |> ReasonReact.string} </td>
|
||||
<td className="px-4 py-2"> {"75" |> ReasonReact.string} </td>
|
||||
<td className="px-4 py-2"> {"95" |> ReasonReact.string} </td>
|
||||
<td className="px-4 py-2"> {"99" |> ReasonReact.string} </td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="px-4 py-2 border">
|
||||
{distPlus
|
||||
|> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.01)
|
||||
|> showFloat}
|
||||
</td>
|
||||
<td className="px-4 py-2 border">
|
||||
{distPlus
|
||||
|> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.05)
|
||||
|> showFloat}
|
||||
</td>
|
||||
<td className="px-4 py-2 border">
|
||||
{distPlus
|
||||
|> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.25)
|
||||
|> showFloat}
|
||||
</td>
|
||||
<td className="px-4 py-2 border">
|
||||
{distPlus
|
||||
|> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.5)
|
||||
|> showFloat}
|
||||
</td>
|
||||
<td className="px-4 py-2 border">
|
||||
{distPlus
|
||||
|> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.75)
|
||||
|> showFloat}
|
||||
</td>
|
||||
<td className="px-4 py-2 border">
|
||||
{distPlus
|
||||
|> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.95)
|
||||
|> showFloat}
|
||||
</td>
|
||||
<td className="px-4 py-2 border">
|
||||
{distPlus
|
||||
|> Distributions.DistPlus.T.Integral.yToX(~cache=None, 0.99)
|
||||
|> showFloat}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>;
|
||||
};
|
||||
|
||||
let adjustBoth = discreteProbabilityMass => {
|
||||
let yMaxDiscreteDomainFactor = discreteProbabilityMass;
|
||||
|
@ -287,8 +344,12 @@ let make = (~distPlus: DistTypes.distPlus) => {
|
|||
|> E.L.toArray
|
||||
|> ReasonReact.array}
|
||||
<div className="inline-flex opacity-50 hover:opacity-100">
|
||||
<button
|
||||
className=button onClick={_ => dispatch(CHANGE_SHOW_PERCENTILES)}>
|
||||
{"Percentiles" |> ReasonReact.string}
|
||||
</button>
|
||||
<button className=button onClick={_ => dispatch(CHANGE_SHOW_STATS)}>
|
||||
{"Stats" |> ReasonReact.string}
|
||||
{"Debug Stats" |> ReasonReact.string}
|
||||
</button>
|
||||
<button className=button onClick={_ => dispatch(CHANGE_SHOW_PARAMS)}>
|
||||
{"Params" |> ReasonReact.string}
|
||||
|
@ -299,5 +360,6 @@ let make = (~distPlus: DistTypes.distPlus) => {
|
|||
</div>
|
||||
{state.showParams ? showAsForm(distPlus) : ReasonReact.null}
|
||||
{state.showStats ? table(distPlus, x) : ReasonReact.null}
|
||||
{state.showPercentiles ? percentiles(distPlus) : ReasonReact.null}
|
||||
</div>;
|
||||
};
|
|
@ -7,6 +7,7 @@ type chartConfig = {
|
|||
|
||||
type state = {
|
||||
showStats: bool,
|
||||
showPercentiles: bool,
|
||||
showParams: bool,
|
||||
distributions: list(chartConfig),
|
||||
};
|
||||
|
@ -14,6 +15,7 @@ type state = {
|
|||
type action =
|
||||
| CHANGE_SHOW_STATS
|
||||
| CHANGE_SHOW_PARAMS
|
||||
| CHANGE_SHOW_PERCENTILES
|
||||
| REMOVE_DIST(int)
|
||||
| ADD_DIST
|
||||
| CHANGE_X_LOG(int)
|
||||
|
@ -90,11 +92,16 @@ let reducer = (state: state, action: action) =>
|
|||
}
|
||||
| CHANGE_SHOW_STATS => {...state, showStats: !state.showStats}
|
||||
| CHANGE_SHOW_PARAMS => {...state, showParams: !state.showParams}
|
||||
| CHANGE_SHOW_PERCENTILES => {
|
||||
...state,
|
||||
showPercentiles: !state.showPercentiles,
|
||||
}
|
||||
};
|
||||
|
||||
let init = {
|
||||
showStats: false,
|
||||
showParams: false,
|
||||
showPercentiles: true,
|
||||
distributions: [
|
||||
{yLog: false, xLog: false, isCumulative: false, height: 2},
|
||||
{yLog: false, xLog: false, isCumulative: true, height: 1},
|
||||
|
|
|
@ -31,6 +31,7 @@ module type dist = {
|
|||
let integral: (~cache: option(integral), t) => integral;
|
||||
let integralEndY: (~cache: option(integral), t) => float;
|
||||
let integralXtoY: (~cache: option(integral), float, t) => float;
|
||||
let integralYtoX: (~cache: option(integral), float, t) => float;
|
||||
};
|
||||
|
||||
module Dist = (T: dist) => {
|
||||
|
@ -58,6 +59,7 @@ module Dist = (T: dist) => {
|
|||
type t = T.integral;
|
||||
let get = T.integral;
|
||||
let xToY = T.integralXtoY;
|
||||
let yToX = T.integralYtoX;
|
||||
let sum = T.integralEndY;
|
||||
};
|
||||
|
||||
|
@ -105,7 +107,7 @@ module Continuous = {
|
|||
type integral = DistTypes.continuousShape;
|
||||
let minX = shapeFn(XYShape.minX);
|
||||
let maxX = shapeFn(XYShape.maxX);
|
||||
let toDiscreteProbabilityMass = t => 0.0;
|
||||
let toDiscreteProbabilityMass = _ => 0.0;
|
||||
let pointwiseFmap = (fn, t: t) =>
|
||||
t |> xyShape |> XYShape.pointwiseMap(fn) |> fromShape;
|
||||
let toShape = (t: t): DistTypes.shape => Continuous(t);
|
||||
|
@ -142,6 +144,8 @@ module Continuous = {
|
|||
let integralEndY = (~cache, t) => t |> integral(~cache) |> lastY;
|
||||
let integralXtoY = (~cache, f, t) =>
|
||||
t |> integral(~cache) |> shapeFn(CdfLibrary.Distribution.findY(f));
|
||||
let integralYtoX = (~cache, f, t) =>
|
||||
t |> integral(~cache) |> shapeFn(CdfLibrary.Distribution.findX(f));
|
||||
let toContinuous = t => Some(t);
|
||||
let toDiscrete = _ => None;
|
||||
let toScaledContinuous = t => Some(t);
|
||||
|
@ -176,12 +180,19 @@ module Discrete = {
|
|||
|> E.O.default(0.0)
|
||||
|> DistTypes.MixedPoint.makeDiscrete;
|
||||
};
|
||||
|
||||
// todo: This should use cache and/or same code as above. FindingY is more complex, should use interpolationType.
|
||||
let integralXtoY = (~cache, f, t) =>
|
||||
t
|
||||
|> integral(~cache)
|
||||
|> Continuous.getShape
|
||||
|> CdfLibrary.Distribution.findY(f);
|
||||
|
||||
let integralYtoX = (~cache, f, t) =>
|
||||
t
|
||||
|> integral(~cache)
|
||||
|> Continuous.getShape
|
||||
|> CdfLibrary.Distribution.findX(f);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -297,10 +308,18 @@ module Mixed = {
|
|||
integral(~cache, t) |> Continuous.lastY;
|
||||
};
|
||||
|
||||
let integralXtoY = (~cache, f, {discrete, continuous} as t: t) => {
|
||||
let cont = Continuous.T.Integral.xToY(~cache, f, continuous);
|
||||
let discrete = Discrete.T.Integral.xToY(~cache, f, discrete);
|
||||
scaleDiscreteFn(t, discrete) +. scaleContinuousFn(t, cont);
|
||||
let integralXtoY = (~cache, f, t) => {
|
||||
t
|
||||
|> integral(~cache)
|
||||
|> Continuous.getShape
|
||||
|> CdfLibrary.Distribution.findX(f);
|
||||
};
|
||||
|
||||
let integralYtoX = (~cache, f, t) => {
|
||||
t
|
||||
|> integral(~cache)
|
||||
|> Continuous.getShape
|
||||
|> CdfLibrary.Distribution.findY(f);
|
||||
};
|
||||
|
||||
// TODO: This functionality is kinda weird, because it seems to assume the cdf adds to 1.0 elsewhere, which wouldn't happen here.
|
||||
|
@ -421,6 +440,16 @@ module Shape = {
|
|||
),
|
||||
);
|
||||
};
|
||||
let integralYtoX = (~cache, f, t) => {
|
||||
mapToAll(
|
||||
t,
|
||||
(
|
||||
Mixed.T.Integral.yToX(~cache, f),
|
||||
Discrete.T.Integral.yToX(~cache, f),
|
||||
Continuous.T.Integral.yToX(~cache, f),
|
||||
),
|
||||
);
|
||||
};
|
||||
let maxX = (t: t) =>
|
||||
mapToAll(t, (Mixed.T.maxX, Discrete.T.maxX, Continuous.T.maxX));
|
||||
let pointwiseFmap = (fn, t: t) =>
|
||||
|
@ -543,6 +572,11 @@ module DistPlus = {
|
|||
Shape.T.Integral.xToY(~cache=Some(t.integralCache), f, toShape(t))
|
||||
|> domainIncludedProbabilityMassAdjustment(t);
|
||||
};
|
||||
|
||||
// TODO: This part is broken when there is a limit, if this is supposed to be taken into account.
|
||||
let integralYtoX = (~cache as _, f, t: t) => {
|
||||
Shape.T.Integral.yToX(~cache=Some(t.integralCache), f, toShape(t));
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user