Simple normalizing functions
This commit is contained in:
parent
510519b24a
commit
25f83d5290
|
@ -39,13 +39,13 @@ let domainLimitedDist =
|
|||
let distributions = () =>
|
||||
<div>
|
||||
<div>
|
||||
|
||||
<h2> {"Basic Mixed Distribution" |> ReasonReact.string} </h2>
|
||||
<GenericDistributionChart dist=timeDist />
|
||||
<h2> {"Simple Continuous" |> ReasonReact.string} </h2>
|
||||
</div>
|
||||
// <GenericDistributionChart dist=mixedDist />
|
||||
<h2> {"Basic Mixed Distribution" |> ReasonReact.string} </h2>
|
||||
{timeDist
|
||||
|> E.O.React.fmapOrNull(dist => <GenericDistributionChart dist />)}
|
||||
<h2> {"Simple Continuous" |> ReasonReact.string} </h2>
|
||||
</div>
|
||||
</div>;
|
||||
// <GenericDistributionChart dist=mixedDist />
|
||||
// <div>
|
||||
// <h2> {"Time Distribution" |> ReasonReact.string} </h2>
|
||||
// <GenericDistributionChart dist=timeDist />
|
||||
|
|
|
@ -7,7 +7,11 @@ module Mixed = {
|
|||
React.useMemo1(
|
||||
() =>
|
||||
<CdfChart__Plain
|
||||
data={data.continuous}
|
||||
data={
|
||||
data.continuous
|
||||
|> Shape.Continuous.normalizePdf
|
||||
|> E.O.toExt("")
|
||||
}
|
||||
color={`hex("333")}
|
||||
timeScale
|
||||
onHover={r => setX(_ => r)}
|
||||
|
@ -47,10 +51,96 @@ module Mixed = {
|
|||
};
|
||||
};
|
||||
|
||||
let discreteComponent = (p: DistributionTypes.pointsType) =>
|
||||
switch (p) {
|
||||
| Mixed(mixedShape) => Some(mixedShape.discrete)
|
||||
| Discrete(discreteShape) => Some(discreteShape)
|
||||
| Continuous(_) => None
|
||||
};
|
||||
|
||||
let continuousComponent = (p: DistributionTypes.pointsType) =>
|
||||
switch (p) {
|
||||
| Mixed(mixedShape) => Some(mixedShape.continuous)
|
||||
| Discrete(_) => None
|
||||
| Continuous(c) => Some(c)
|
||||
};
|
||||
|
||||
module Cont = {
|
||||
[@react.component]
|
||||
let make = (~continuous, ~onHover, ~timeScale) => {
|
||||
let chart =
|
||||
React.useMemo1(
|
||||
() => <CdfChart__Plain data=continuous color={`hex("333")} onHover />,
|
||||
[|continuous|],
|
||||
);
|
||||
chart;
|
||||
};
|
||||
};
|
||||
|
||||
module Shapee = {
|
||||
[@react.component]
|
||||
let make = (~shape: DistributionTypes.pointsType, ~timeScale, ~onHover) => {
|
||||
let continuous = continuousComponent(shape);
|
||||
let discrete = discreteComponent(shape);
|
||||
<div>
|
||||
{continuous
|
||||
|> E.O.React.fmapOrNull(continuous =>
|
||||
<Cont continuous onHover timeScale />
|
||||
)}
|
||||
{discrete
|
||||
|> E.O.React.fmapOrNull(r =>
|
||||
r |> Shape.Discrete.scaleYToTotal(0.3) |> Shape.Discrete.render
|
||||
)}
|
||||
</div>;
|
||||
};
|
||||
};
|
||||
|
||||
module GenericDist = {
|
||||
[@react.component]
|
||||
let make = (~genericDistribution: DistributionTypes.genericDistribution) => {
|
||||
let (x, setX) = React.useState(() => 0.);
|
||||
let timeScale =
|
||||
genericDistribution.unit |> DistributionTypes.DistributionUnit.toJson;
|
||||
<div>
|
||||
{genericDistribution
|
||||
|> DistributionTypes.shape
|
||||
|> E.O.React.fmapOrNull(shape => {
|
||||
<Shapee shape timeScale onHover={r => setX(_ => r)} />
|
||||
})}
|
||||
<table className="table-auto">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="px-4 py-2"> {"X Point" |> ReasonReact.string} </th>
|
||||
<th className="px-4 py-2">
|
||||
{"Y Integral to Point" |> ReasonReact.string}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th className="px-4 py-2 border ">
|
||||
{x |> E.Float.toString |> ReasonReact.string}
|
||||
</th>
|
||||
<th className="px-4 py-2 border ">
|
||||
{genericDistribution
|
||||
|> DistributionTypes.shape
|
||||
|> E.O.bind(_, r => Shape.Any.yIntegral(r, x))
|
||||
|> E.O.fmap(E.Float.with2DigitsPrecision)
|
||||
|> E.O.default("")
|
||||
|> ReasonReact.string}
|
||||
</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div />
|
||||
</div>;
|
||||
};
|
||||
};
|
||||
|
||||
[@react.component]
|
||||
let make = (~dist) => {
|
||||
switch ((dist: option(DistributionTypes.genericDistribution))) {
|
||||
| Some({
|
||||
switch ((dist: DistributionTypes.genericDistribution)) {
|
||||
| {
|
||||
unit,
|
||||
generationSource:
|
||||
Shape(
|
||||
|
@ -60,8 +150,9 @@ let make = (~dist) => {
|
|||
discreteProbabilityMassFraction: f,
|
||||
}),
|
||||
),
|
||||
}) =>
|
||||
} =>
|
||||
<div>
|
||||
<GenericDist genericDistribution=dist />
|
||||
<Mixed
|
||||
unit
|
||||
data={
|
||||
|
|
|
@ -48,6 +48,12 @@ type genericDistribution = {
|
|||
unit: distributionUnit,
|
||||
};
|
||||
|
||||
let shape = ({generationSource}: genericDistribution) =>
|
||||
switch (generationSource) {
|
||||
| GuesstimatorString(_) => None
|
||||
| Shape(pointsType) => Some(pointsType)
|
||||
};
|
||||
|
||||
module DistributionUnit = {
|
||||
let toJson = (distributionUnit: distributionUnit) =>
|
||||
switch (distributionUnit) {
|
||||
|
|
|
@ -32,17 +32,97 @@ let renderIfNeeded =
|
|||
);
|
||||
| Shape(_) => Some(t)
|
||||
};
|
||||
} /* }*/;
|
||||
};
|
||||
|
||||
// let getTimeY =
|
||||
// (t: genericDistribution, point: TimeTypes.RelativeTimePoint.timeInVector) => {
|
||||
// switch (t) {
|
||||
// | {
|
||||
// generationSource: Shape(shape),
|
||||
// probabilityType: Pdf,
|
||||
// unit: Time(timeVector),
|
||||
// } =>
|
||||
// TimeTypes.RelativeTimePoint.toXValue(timeVector, point)
|
||||
// |> E.O.fmap(x => Shape.Mixed.getY(t, x))
|
||||
// | _ => 2.0
|
||||
// };
|
||||
let normalizeCdf = (t: DistributionTypes.pointsType) => {
|
||||
switch (t) {
|
||||
| Mixed({continuous, discrete, discreteProbabilityMassFraction}) =>
|
||||
Mixed({
|
||||
continuous: continuous |> Shape.Continuous.normalizeCdf,
|
||||
discrete: discrete |> Shape.Discrete.scaleYToTotal(1.0),
|
||||
discreteProbabilityMassFraction,
|
||||
})
|
||||
| Discrete(d) => Discrete(d |> Shape.Discrete.scaleYToTotal(1.0))
|
||||
| Continuous(continuousShape) =>
|
||||
Continuous(Shape.Continuous.normalizeCdf(continuousShape))
|
||||
};
|
||||
};
|
||||
|
||||
let normalizePdf = (t: DistributionTypes.pointsType) => {
|
||||
switch (t) {
|
||||
| Mixed({continuous, discrete, discreteProbabilityMassFraction}) =>
|
||||
continuous
|
||||
|> Shape.Continuous.normalizePdf
|
||||
|> E.O.fmap(r =>
|
||||
Mixed({
|
||||
continuous: r,
|
||||
discrete: discrete |> Shape.Discrete.scaleYToTotal(1.0),
|
||||
discreteProbabilityMassFraction,
|
||||
})
|
||||
)
|
||||
| Discrete(d) => Some(Discrete(d |> Shape.Discrete.scaleYToTotal(1.0)))
|
||||
| Continuous(continuousShape) =>
|
||||
continuousShape
|
||||
|> Shape.Continuous.normalizePdf
|
||||
|> E.O.fmap(r => Continuous(r))
|
||||
};
|
||||
};
|
||||
|
||||
let normalize = (t: genericDistribution): genericDistribution => {
|
||||
switch (t.generationSource) {
|
||||
| Shape(shape) => t
|
||||
| GuesstimatorString(_) => t
|
||||
};
|
||||
};
|
||||
|
||||
let excludedProbabilityMass = (t: DistributionTypes.domain) => {
|
||||
switch (t) {
|
||||
| Complete => 1.0
|
||||
| LeftLimited({excludingProbabilityMass}) => excludingProbabilityMass
|
||||
| RightLimited({excludingProbabilityMass}) => excludingProbabilityMass
|
||||
| LeftAndRightLimited(
|
||||
{excludingProbabilityMass: l},
|
||||
{excludingProbabilityMass: r},
|
||||
) =>
|
||||
l +. r
|
||||
};
|
||||
};
|
||||
|
||||
let initialProbabilityMass = (t: DistributionTypes.domain) => {
|
||||
switch (t) {
|
||||
| Complete
|
||||
| RightLimited(_) => 0.0
|
||||
| LeftLimited({excludingProbabilityMass}) => excludingProbabilityMass
|
||||
| LeftAndRightLimited({excludingProbabilityMass}, _) => excludingProbabilityMass
|
||||
};
|
||||
};
|
||||
|
||||
let normalizeProbabilityMass = (t: DistributionTypes.domain) => {
|
||||
1. /. excludedProbabilityMass(t);
|
||||
};
|
||||
|
||||
let yIntegral = (t: DistributionTypes.genericDistribution, x) => {
|
||||
let addInitialMass = n => n +. initialProbabilityMass(t.domain);
|
||||
let normalize = n => n *. normalizeProbabilityMass(t.domain);
|
||||
switch (t) {
|
||||
| {generationSource: Shape(shape)} =>
|
||||
Shape.Any.yIntegral(shape, x)
|
||||
|> E.O.fmap(addInitialMass)
|
||||
|> E.O.fmap(normalize)
|
||||
| _ => None
|
||||
};
|
||||
};
|
||||
|
||||
let integrate = (t: DistributionTypes.genericDistribution) => {
|
||||
switch (t) {
|
||||
| {probabilityType: Pdf, generationSource: Shape(shape), domain, unit} =>
|
||||
Some({
|
||||
generationSource: Shape(shape),
|
||||
probabilityType: Cdf,
|
||||
domain,
|
||||
unit,
|
||||
})
|
||||
| {probabilityType: Cdf, generationSource, domain, unit} => None
|
||||
| _ => None
|
||||
};
|
||||
};
|
|
@ -108,6 +108,12 @@ module Continuous = {
|
|||
let findX = CdfLibrary.Distribution.findX;
|
||||
let findY = CdfLibrary.Distribution.findY;
|
||||
let findIntegralY = (f, r) => r |> toCdf |> E.O.fmap(findY(f));
|
||||
|
||||
let normalizeCdf = (continuousShape: continuousShape) =>
|
||||
continuousShape |> XYShape.scaleCdfTo(~scaleTo=1.0);
|
||||
|
||||
let normalizePdf = (continuousShape: continuousShape) =>
|
||||
continuousShape |> toCdf |> E.O.fmap(normalizeCdf) |> E.O.bind(_, toPdf);
|
||||
};
|
||||
|
||||
module Discrete = {
|
||||
|
@ -208,11 +214,11 @@ module Any = {
|
|||
|
||||
let yIntegral = (t: t, x: float) =>
|
||||
switch (t) {
|
||||
| Mixed(m) => `mixed(Mixed.findYIntegral(x, m))
|
||||
| Mixed(m) => Mixed.findYIntegral(x, m)
|
||||
| Discrete(discreteShape) =>
|
||||
`discrete(Discrete.findIntegralY(x, discreteShape))
|
||||
Discrete.findIntegralY(x, discreteShape) |> E.O.some
|
||||
| Continuous(continuousShape) =>
|
||||
`continuous(Continuous.findIntegralY(x, continuousShape))
|
||||
Continuous.findIntegralY(x, continuousShape)
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user