Basic mixed discrete-continuous distributions

This commit is contained in:
Ozzie Gooen 2020-02-15 23:27:25 +00:00
parent beda0b61ed
commit 03cc7293a4
4 changed files with 35 additions and 14 deletions

View File

@ -61,13 +61,10 @@ module Value = {
let newDistribution =
GenericDistribution.renderIfNeeded(~sampleCount=1000, r);
switch (newDistribution) {
| Some({generationSource: Shape(Mixed({continuous: n}))}) =>
| Some({generationSource: Shape(Mixed({continuous: n, discrete: d}))}) =>
<div>
<Chart height=100 data={n |> Shape.Continuous.toJs} />
<Chart
height=100
data={n |> Shape.Continuous.toCdf |> Shape.Continuous.toJs}
/>
{Shape.Discrete.render(d)}
</div>
| None => "Something went wrong" |> ReasonReact.string
| _ => <div />

View File

@ -45,6 +45,18 @@ module Discrete = {
|> Belt.Array.unzip;
fromArrays(xs, ys);
};
let render = (t: t) =>
Belt.Array.zip(t.xs, t.ys)
|> E.A.fmap(((x, y)) =>
<div>
{E.Float.toFixed(x)
++ "---"
++ E.Float.with3DigitsPrecision(y *. 100.)
|> ReasonReact.string}
</div>
)
|> ReasonReact.array;
};
module Mixed = {

View File

@ -1,8 +1,10 @@
// ~generationSource=GuesstimatorString(FloatCdf.logNormal(20., 3.)),
module Model = {
let make = (currentDateTime: MomentRe.Moment.t) => {
let genericDistribution =
GenericDistribution.make(
~generationSource=GuesstimatorString(FloatCdf.logNormal(20., 3.)),
~generationSource=
GuesstimatorString("mm(floor(10 to 15), 20 to 30, [.5,.5])"),
~probabilityType=Cdf,
~domain=RightLimited({xPoint: 200., excludingProbabilityMass: 0.3}),
~unit=Time({zero: currentDateTime, unit: `years}),

View File

@ -37,15 +37,21 @@ const ratioSize = samples => {
const toPdf = (values, sampleCount, min, max) => {
let duplicateSamples = _(values).groupBy().pickBy(x => x.length > 1).keys().value();
let totalLength = _.size(values);
let frequencies = duplicateSamples.map(s => ({value: parseFloat(s), percentage: totalLength/_(values).filter(x => x ==s).size()}));
let frequencies = duplicateSamples.map(s => ({value: parseFloat(s), percentage: _(values).filter(x => x ==s).size()/totalLength}));
let continuousSamples = _.difference(values, frequencies.map(f => f.value));
const samples = new Samples(continuousSamples);
const ratioSize$ = ratioSize(samples);
const width = ratioSize$ === 'SMALL' ? 20 : 1;
let discrete = {xs: frequencies.map(f => f.value), ys: frequencies.map(f => f.percentage)};
let continuous = {ys: [], xs: []};
if (continuousSamples.length > 1){
const samples = new Samples(continuousSamples);
const cdf = samples.toCdf({ size: sampleCount, width, min, max });
return {continuous:{ys:cdf.ys, xs:cdf.xs}, discrete: {xs: frequencies.map(f => f.value), ys: frequencies.map(f => f.percentage)}};
const ratioSize$ = ratioSize(samples);
const width = ratioSize$ === 'SMALL' ? 20 : 1;
const cdf = samples.toCdf({ size: sampleCount, width, min, max });
continuous = cdf;
}
return {continuous, discrete};
};
let run = (text, sampleCount, inputs=[], min=false, max=false) => {
@ -63,10 +69,14 @@ let run = (text, sampleCount, inputs=[], min=false, max=false) => {
const values = _.filter(value.values, _.isFinite);
let update;
let blankResponse = {
continuous: {ys: [], xs: []},
discrete: {ys: [], xs: []}
};
if (values.length === 0) {
update = {xs: [], ys: []};
update = blankResponse;
} else if (values.length === 1) {
update = {xs: [], ys: []};
update = blankResponse;
} else {
update = toPdf(values, sampleCount, min, max);
}