Basic mixed discrete-continuous distributions
This commit is contained in:
parent
beda0b61ed
commit
03cc7293a4
|
@ -61,13 +61,10 @@ module Value = {
|
||||||
let newDistribution =
|
let newDistribution =
|
||||||
GenericDistribution.renderIfNeeded(~sampleCount=1000, r);
|
GenericDistribution.renderIfNeeded(~sampleCount=1000, r);
|
||||||
switch (newDistribution) {
|
switch (newDistribution) {
|
||||||
| Some({generationSource: Shape(Mixed({continuous: n}))}) =>
|
| Some({generationSource: Shape(Mixed({continuous: n, discrete: d}))}) =>
|
||||||
<div>
|
<div>
|
||||||
<Chart height=100 data={n |> Shape.Continuous.toJs} />
|
<Chart height=100 data={n |> Shape.Continuous.toJs} />
|
||||||
<Chart
|
{Shape.Discrete.render(d)}
|
||||||
height=100
|
|
||||||
data={n |> Shape.Continuous.toCdf |> Shape.Continuous.toJs}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
| None => "Something went wrong" |> ReasonReact.string
|
| None => "Something went wrong" |> ReasonReact.string
|
||||||
| _ => <div />
|
| _ => <div />
|
||||||
|
|
|
@ -45,6 +45,18 @@ module Discrete = {
|
||||||
|> Belt.Array.unzip;
|
|> Belt.Array.unzip;
|
||||||
fromArrays(xs, ys);
|
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 = {
|
module Mixed = {
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
// ~generationSource=GuesstimatorString(FloatCdf.logNormal(20., 3.)),
|
||||||
module Model = {
|
module Model = {
|
||||||
let make = (currentDateTime: MomentRe.Moment.t) => {
|
let make = (currentDateTime: MomentRe.Moment.t) => {
|
||||||
let genericDistribution =
|
let genericDistribution =
|
||||||
GenericDistribution.make(
|
GenericDistribution.make(
|
||||||
~generationSource=GuesstimatorString(FloatCdf.logNormal(20., 3.)),
|
~generationSource=
|
||||||
|
GuesstimatorString("mm(floor(10 to 15), 20 to 30, [.5,.5])"),
|
||||||
~probabilityType=Cdf,
|
~probabilityType=Cdf,
|
||||||
~domain=RightLimited({xPoint: 200., excludingProbabilityMass: 0.3}),
|
~domain=RightLimited({xPoint: 200., excludingProbabilityMass: 0.3}),
|
||||||
~unit=Time({zero: currentDateTime, unit: `years}),
|
~unit=Time({zero: currentDateTime, unit: `years}),
|
||||||
|
|
|
@ -37,15 +37,21 @@ const ratioSize = samples => {
|
||||||
const toPdf = (values, sampleCount, min, max) => {
|
const toPdf = (values, sampleCount, min, max) => {
|
||||||
let duplicateSamples = _(values).groupBy().pickBy(x => x.length > 1).keys().value();
|
let duplicateSamples = _(values).groupBy().pickBy(x => x.length > 1).keys().value();
|
||||||
let totalLength = _.size(values);
|
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));
|
let continuousSamples = _.difference(values, frequencies.map(f => f.value));
|
||||||
const samples = new Samples(continuousSamples);
|
|
||||||
|
|
||||||
const ratioSize$ = ratioSize(samples);
|
let discrete = {xs: frequencies.map(f => f.value), ys: frequencies.map(f => f.percentage)};
|
||||||
const width = ratioSize$ === 'SMALL' ? 20 : 1;
|
let continuous = {ys: [], xs: []};
|
||||||
|
if (continuousSamples.length > 1){
|
||||||
|
const samples = new Samples(continuousSamples);
|
||||||
|
|
||||||
const cdf = samples.toCdf({ size: sampleCount, width, min, max });
|
const ratioSize$ = ratioSize(samples);
|
||||||
return {continuous:{ys:cdf.ys, xs:cdf.xs}, discrete: {xs: frequencies.map(f => f.value), ys: frequencies.map(f => f.percentage)}};
|
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) => {
|
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);
|
const values = _.filter(value.values, _.isFinite);
|
||||||
|
|
||||||
let update;
|
let update;
|
||||||
|
let blankResponse = {
|
||||||
|
continuous: {ys: [], xs: []},
|
||||||
|
discrete: {ys: [], xs: []}
|
||||||
|
};
|
||||||
if (values.length === 0) {
|
if (values.length === 0) {
|
||||||
update = {xs: [], ys: []};
|
update = blankResponse;
|
||||||
} else if (values.length === 1) {
|
} else if (values.length === 1) {
|
||||||
update = {xs: [], ys: []};
|
update = blankResponse;
|
||||||
} else {
|
} else {
|
||||||
update = toPdf(values, sampleCount, min, max);
|
update = toPdf(values, sampleCount, min, max);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user