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])",
let timeDist =
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 = {
[@react.component]
let make = (~shape: DistributionTypes.pointsType, ~timeScale, ~onHover) => {
let discreteScaleFactor = shape |> discreteScaleFactor;
let continuous =
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);
};
let discrete = Shape.Any.scaledDiscreteComponent(shape);
let continuous = Shape.Any.scaledContinuousComponent(shape);
<div>
<CdfChart__Plain
minX
maxX
minX={Shape.Any.minX(shape)}
maxX={Shape.Any.maxX(shape)}
?discrete
?continuous
color={`hex("333")}

View File

@ -1,5 +1,33 @@
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 =
(
~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 addInitialMass = n => n +. initialProbabilityMass(t.domain);
let normalize = n => n *. normalizeProbabilityMass(t.domain);
let addInitialMass = n => n +. Domain.initialProbabilityMass(t.domain);
let normalize = n => n *. Domain.normalizeProbabilityMass(t.domain);
switch (t) {
| {generationSource: Shape(shape)} =>
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) => {
switch (t) {
| {probabilityType: Pdf, generationSource: Shape(shape), domain, unit} =>
Some({
generationSource: Shape(shape),
probabilityType: Cdf,
probabilityType: Pdf,
domain,
unit,
})
| {probabilityType: Cdf, generationSource, domain, unit} => None
| _ => None
};
};

View File

@ -283,11 +283,39 @@ module Any = {
| Continuous(continuous) =>
Continuous.toCdf(continuous) |> E.O.fmap(e => Continuous(e))
};
let discreteComponent = (t: t) =>
switch (t) {
| Mixed({discrete}) => Some(discrete)
| Discrete(d) => Some(d)
| Continuous(_) => None
};
module DomainMixed = {
type t = {
mixedShape,
domain,
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
| GenericDistribution(r) =>
let newDistribution =
GenericDistribution.renderIfNeeded(~sampleCount=1000, r);
GenericDistribution.renderIfNeeded(~sampleCount=2000, r);
switch (newDistribution) {
| Some(distribution) =>
<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 = {
let make = (currentDateTime: MomentRe.Moment.t) => {

View File

@ -46,7 +46,7 @@ const toPdf = (values, sampleCount, min, max) => {
const samples = new Samples(continuousSamples);
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 });
continuous = pdf;