Cleanup of Domain functions

This commit is contained in:
Ozzie Gooen 2020-02-20 15:41:53 +00:00
parent 2e1287e746
commit d48277ce79
7 changed files with 72 additions and 142 deletions

View File

@ -1,8 +1,3 @@
let data: DistributionTypes.xyShape = {
xs: [|1., 10., 10., 200., 250., 292., 330.|],
ys: [|0.0, 0.0, 0.1, 0.3, 0.5, 0.2, 0.1|],
};
// "mm(floor(uniform(30,35)), normal(50,20), [.25,.5])", // "mm(floor(uniform(30,35)), normal(50,20), [.25,.5])",
let timeDist = let timeDist =
GenericDistribution.make( GenericDistribution.make(

View File

@ -1,107 +1,12 @@
module Mixed = {
[@react.component]
let make = (~data: DistributionTypes.mixedShape, ~unit) => {
let (x, setX) = React.useState(() => 0.);
let timeScale = unit |> DistributionTypes.DistributionUnit.toJson;
let chart =
React.useMemo1(
() =>
<CdfChart__Plain
continuous={data.continuous}
discrete={data.discrete}
color={`hex("333")}
timeScale
onHover={r => setX(_ => r)}
showDistributionYAxis=true
/>,
[|data|],
);
<div>
chart
<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 ">
{Shape.Mixed.findYIntegral(x, data)
|> E.O.fmap(E.Float.with2DigitsPrecision)
|> E.O.default("")
|> ReasonReact.string}
</th>
</tr>
</tbody>
</table>
<div />
{data.discrete
|> Shape.Discrete.scaleYToTotal(data.discreteProbabilityMassFraction)
|> Shape.Discrete.render}
</div>;
};
};
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)
};
let discreteScaleFactor = (p: DistributionTypes.pointsType) =>
switch (p) {
| Mixed(mixedShape) => Some(mixedShape.discreteProbabilityMassFraction)
| Discrete(_) => None
| Continuous(_) => None
};
module Shapee = { module Shapee = {
[@react.component] [@react.component]
let make = (~shape: DistributionTypes.pointsType, ~timeScale, ~onHover) => { let make = (~shape: DistributionTypes.pointsType, ~timeScale, ~onHover) => {
let discreteScaleFactor = shape |> discreteScaleFactor; let discrete = Shape.Any.scaledDiscreteComponent(shape);
let continuous = let continuous = Shape.Any.scaledContinuousComponent(shape);
continuousComponent(shape)
|> E.O.bind(
_,
Shape.Continuous.scalePdf(
~scaleTo=
discreteScaleFactor
|> E.O.fmap(r => 1. -. r)
|> E.O.default(1.0),
),
);
let discrete =
discreteComponent(shape)
|> E.O.fmap(
Shape.Discrete.scaleYToTotal(
discreteScaleFactor |> E.O.default(1.0),
),
);
let minX = {
Shape.Any.minX(shape);
};
let maxX = {
Shape.Any.maxX(shape);
};
<div> <div>
<CdfChart__Plain <CdfChart__Plain
minX minX={Shape.Any.minX(shape)}
maxX maxX={Shape.Any.maxX(shape)}
?discrete ?discrete
?continuous ?continuous
color={`hex("333")} color={`hex("333")}

View File

@ -1,5 +1,33 @@
open DistributionTypes; open DistributionTypes;
module Domain = {
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 make = let make =
( (
~generationSource, ~generationSource,
@ -92,35 +120,9 @@ let normalize = (t: genericDistribution): option(genericDistribution) => {
}; };
}; };
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 yIntegral = (t: DistributionTypes.genericDistribution, x) => {
let addInitialMass = n => n +. initialProbabilityMass(t.domain); let addInitialMass = n => n +. Domain.initialProbabilityMass(t.domain);
let normalize = n => n *. normalizeProbabilityMass(t.domain); let normalize = n => n *. Domain.normalizeProbabilityMass(t.domain);
switch (t) { switch (t) {
| {generationSource: Shape(shape)} => | {generationSource: Shape(shape)} =>
Shape.Any.yIntegral(shape, x) Shape.Any.yIntegral(shape, x)
@ -130,16 +132,16 @@ let yIntegral = (t: DistributionTypes.genericDistribution, x) => {
}; };
}; };
// TODO: This obviously needs to be fleshed out a lot.
let integrate = (t: DistributionTypes.genericDistribution) => { let integrate = (t: DistributionTypes.genericDistribution) => {
switch (t) { switch (t) {
| {probabilityType: Pdf, generationSource: Shape(shape), domain, unit} => | {probabilityType: Pdf, generationSource: Shape(shape), domain, unit} =>
Some({ Some({
generationSource: Shape(shape), generationSource: Shape(shape),
probabilityType: Cdf, probabilityType: Pdf,
domain, domain,
unit, unit,
}) })
| {probabilityType: Cdf, generationSource, domain, unit} => None
| _ => None | _ => None
}; };
}; };

View File

@ -283,11 +283,39 @@ module Any = {
| Continuous(continuous) => | Continuous(continuous) =>
Continuous.toCdf(continuous) |> E.O.fmap(e => Continuous(e)) Continuous.toCdf(continuous) |> E.O.fmap(e => Continuous(e))
}; };
};
module DomainMixed = { let discreteComponent = (t: t) =>
type t = { switch (t) {
mixedShape, | Mixed({discrete}) => Some(discrete)
domain, | Discrete(d) => Some(d)
| Continuous(_) => None
};
let continuousComponent = (t: t) =>
switch (t) {
| Mixed({continuous}) => Some(continuous)
| Continuous(c) => Some(c)
| Discrete(_) => None
};
let scaledContinuousComponent = (t: t): option(continuousShape) => {
switch (t) {
| Mixed({continuous, discreteProbabilityMassFraction}) =>
Continuous.scalePdf(
~scaleTo=1.0 -. discreteProbabilityMassFraction,
continuous,
)
| Discrete(_) => None
| Continuous(c) => Some(c)
};
};
let scaledDiscreteComponent = (t: t): option(discreteShape) => {
switch (t) {
| Mixed({discrete, discreteProbabilityMassFraction}) =>
Some(Discrete.scaleYToTotal(discreteProbabilityMassFraction, discrete))
| Discrete(d) => Some(d)
| Continuous(_) => None
};
}; };
}; };

View File

@ -19,7 +19,7 @@ let propValue = (t: Prop.Value.t) => {
| ConditionalArray(r) => "Array" |> ReasonReact.string | ConditionalArray(r) => "Array" |> ReasonReact.string
| GenericDistribution(r) => | GenericDistribution(r) =>
let newDistribution = let newDistribution =
GenericDistribution.renderIfNeeded(~sampleCount=1000, r); GenericDistribution.renderIfNeeded(~sampleCount=2000, r);
switch (newDistribution) { switch (newDistribution) {
| Some(distribution) => | Some(distribution) =>
<div> <div>

View File

@ -1,4 +1,4 @@
let guesstimatorString = GuesstimatorDist.logNormal(20., 3.); let guesstimatorString = "mm(10 to 30, floor(20 to 25), [.5,.5])";
module Model = { module Model = {
let make = (currentDateTime: MomentRe.Moment.t) => { let make = (currentDateTime: MomentRe.Moment.t) => {

View File

@ -46,7 +46,7 @@ const toPdf = (values, sampleCount, min, max) => {
const samples = new Samples(continuousSamples); const samples = new Samples(continuousSamples);
const ratioSize$ = ratioSize(samples); const ratioSize$ = ratioSize(samples);
const width = ratioSize$ === 'SMALL' ? 20 : 1; const width = ratioSize$ === 'SMALL' ? 100 : 1;
const pdf = samples.toPdf({ size: sampleCount, width, min, max }); const pdf = samples.toPdf({ size: sampleCount, width, min, max });
continuous = pdf; continuous = pdf;