First step for GenericDistribution
This commit is contained in:
parent
ab9c8726d6
commit
626b4f65c3
|
@ -1,62 +1,4 @@
|
||||||
type timeUnit = [
|
open TimeTypes;
|
||||||
| `days
|
|
||||||
| `hours
|
|
||||||
| `milliseconds
|
|
||||||
| `minutes
|
|
||||||
| `months
|
|
||||||
| `quarters
|
|
||||||
| `seconds
|
|
||||||
| `weeks
|
|
||||||
| `years
|
|
||||||
];
|
|
||||||
|
|
||||||
type timeVector = {
|
|
||||||
zero: MomentRe.Moment.t,
|
|
||||||
unit: timeUnit,
|
|
||||||
};
|
|
||||||
|
|
||||||
type timePoint = {
|
|
||||||
timeVector,
|
|
||||||
value: float,
|
|
||||||
};
|
|
||||||
|
|
||||||
module TimePoint = {
|
|
||||||
let fromTimeVector = (timeVector, value): timePoint => {timeVector, value};
|
|
||||||
|
|
||||||
let toMoment = (timePoint: timePoint) => {
|
|
||||||
timePoint.timeVector.zero
|
|
||||||
|> MomentRe.Moment.add(
|
|
||||||
~duration=
|
|
||||||
MomentRe.duration(timePoint.value, timePoint.timeVector.unit),
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
let fromMoment = (timeVector: timeVector, moment: MomentRe.Moment.t) =>
|
|
||||||
MomentRe.diff(timeVector.zero, moment, timeVector.unit);
|
|
||||||
};
|
|
||||||
|
|
||||||
module RelativeTimePoint = {
|
|
||||||
type timeInVector =
|
|
||||||
| Time(MomentRe.Moment.t)
|
|
||||||
| XValue(float);
|
|
||||||
|
|
||||||
let toTime = (timeVector: timeVector, timeInVector: timeInVector) =>
|
|
||||||
switch (timeInVector) {
|
|
||||||
| Time(r) => r
|
|
||||||
| XValue(r) =>
|
|
||||||
timeVector.zero
|
|
||||||
|> MomentRe.Moment.add(~duration=MomentRe.duration(r, timeVector.unit))
|
|
||||||
};
|
|
||||||
|
|
||||||
let _timeToX = (time, timeStart, timeUnit) =>
|
|
||||||
MomentRe.diff(timeStart, time, timeUnit);
|
|
||||||
|
|
||||||
let toXValue = (timeVector: timeVector, timeInVector: timeInVector) =>
|
|
||||||
switch (timeInVector) {
|
|
||||||
| Time(r) => _timeToX(r, timeVector.zero, timeVector.unit)
|
|
||||||
| XValue(r) => r
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
type t = {
|
type t = {
|
||||||
timeVector,
|
timeVector,
|
||||||
|
|
136
src/lib/DistributionTypes.re
Normal file
136
src/lib/DistributionTypes.re
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
type domainLimit = {
|
||||||
|
xPoint: float,
|
||||||
|
excludingProbabilityMass: float,
|
||||||
|
};
|
||||||
|
|
||||||
|
type domain =
|
||||||
|
| Complete
|
||||||
|
| LeftLimited(domainLimit)
|
||||||
|
| RightLimited(domainLimit)
|
||||||
|
| LeftAndRightLimited(domainLimit, domainLimit);
|
||||||
|
|
||||||
|
type continuousShape = {
|
||||||
|
xs: array(float),
|
||||||
|
ys: array(float),
|
||||||
|
};
|
||||||
|
|
||||||
|
type discreteShape = {
|
||||||
|
xs: array(float),
|
||||||
|
ys: array(float),
|
||||||
|
};
|
||||||
|
|
||||||
|
type mixedShape = {
|
||||||
|
continuous: continuousShape,
|
||||||
|
discrete: discreteShape,
|
||||||
|
discreteProbabilityMassFraction: float,
|
||||||
|
};
|
||||||
|
|
||||||
|
type pointsType =
|
||||||
|
| Mixed(mixedShape)
|
||||||
|
| Discrete(discreteShape)
|
||||||
|
| Continuous(continuousShape);
|
||||||
|
|
||||||
|
type generationSource =
|
||||||
|
| GuesstimatorString(string)
|
||||||
|
| Shape(pointsType);
|
||||||
|
|
||||||
|
type distributionUnit =
|
||||||
|
| Unspecified
|
||||||
|
| Time(TimeTypes.timeVector);
|
||||||
|
|
||||||
|
type probabilityType =
|
||||||
|
| Cdf
|
||||||
|
| Pdf
|
||||||
|
| Arbitrary;
|
||||||
|
|
||||||
|
type genericDistribution = {
|
||||||
|
generationSource,
|
||||||
|
probabilityType,
|
||||||
|
domain,
|
||||||
|
unit: distributionUnit,
|
||||||
|
};
|
||||||
|
|
||||||
|
module Shape = {
|
||||||
|
module Continuous = {
|
||||||
|
let fromArrays = (xs, ys): continuousShape => {xs, ys};
|
||||||
|
};
|
||||||
|
|
||||||
|
module Discrete = {
|
||||||
|
let fromArrays = (xs, ys): continuousShape => {xs, ys};
|
||||||
|
};
|
||||||
|
|
||||||
|
module Mixed = {
|
||||||
|
let make = (~continuous, ~discrete, ~discreteProbabilityMassFraction) => {
|
||||||
|
continuous,
|
||||||
|
discrete,
|
||||||
|
discreteProbabilityMassFraction,
|
||||||
|
};
|
||||||
|
|
||||||
|
module Builder = {
|
||||||
|
type assumption =
|
||||||
|
| ADDS_TO_1
|
||||||
|
| ADDS_TO_CORRECT_PROBABILITY;
|
||||||
|
type assumptions = {
|
||||||
|
continuous: assumption,
|
||||||
|
discrete: assumption,
|
||||||
|
discreteProbabilityMass: option(float),
|
||||||
|
};
|
||||||
|
let build = (~continuous, ~discrete, ~assumptions) =>
|
||||||
|
switch (assumptions) {
|
||||||
|
| {
|
||||||
|
continuous: ADDS_TO_CORRECT_PROBABILITY,
|
||||||
|
discrete: ADDS_TO_CORRECT_PROBABILITY,
|
||||||
|
discreteProbabilityMass: Some(r),
|
||||||
|
} =>
|
||||||
|
// TODO: Fix this, it's wrong :(
|
||||||
|
Some(
|
||||||
|
make(~continuous, ~discrete, ~discreteProbabilityMassFraction=r),
|
||||||
|
)
|
||||||
|
| {
|
||||||
|
continuous: ADDS_TO_1,
|
||||||
|
discrete: ADDS_TO_1,
|
||||||
|
discreteProbabilityMass: Some(r),
|
||||||
|
} =>
|
||||||
|
Some(
|
||||||
|
make(~continuous, ~discrete, ~discreteProbabilityMassFraction=r),
|
||||||
|
)
|
||||||
|
| {
|
||||||
|
continuous: ADDS_TO_1,
|
||||||
|
discrete: ADDS_TO_1,
|
||||||
|
discreteProbabilityMass: None,
|
||||||
|
} =>
|
||||||
|
None
|
||||||
|
| {
|
||||||
|
continuous: ADDS_TO_CORRECT_PROBABILITY,
|
||||||
|
discrete: ADDS_TO_1,
|
||||||
|
discreteProbabilityMass: None,
|
||||||
|
} =>
|
||||||
|
None
|
||||||
|
| {
|
||||||
|
continuous: ADDS_TO_1,
|
||||||
|
discrete: ADDS_TO_CORRECT_PROBABILITY,
|
||||||
|
discreteProbabilityMass: None,
|
||||||
|
} =>
|
||||||
|
None
|
||||||
|
| _ => None
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
module GenericDistribution = {
|
||||||
|
let make =
|
||||||
|
(
|
||||||
|
~generationSource,
|
||||||
|
~probabilityType=Pdf,
|
||||||
|
~domain=Complete,
|
||||||
|
~unit=Unspecified,
|
||||||
|
(),
|
||||||
|
)
|
||||||
|
: genericDistribution => {
|
||||||
|
generationSource,
|
||||||
|
probabilityType,
|
||||||
|
domain,
|
||||||
|
unit,
|
||||||
|
};
|
||||||
|
};
|
|
@ -55,41 +55,41 @@ module Value = {
|
||||||
| SelectSingle(r) => r |> ReasonReact.string
|
| SelectSingle(r) => r |> ReasonReact.string
|
||||||
| ConditionalArray(r) => "Array" |> ReasonReact.string
|
| ConditionalArray(r) => "Array" |> ReasonReact.string
|
||||||
| Conditional(r) => r.name |> ReasonReact.string
|
| Conditional(r) => r.name |> ReasonReact.string
|
||||||
| TimeLimitedDomainCdfLazy(r) =>
|
| TimeLimitedDomainCdfLazy(r) => <div />
|
||||||
let timeLimited = r(CdfLibrary.Distribution.fromString(_, 1000));
|
// let timeLimited = r(CdfLibrary.Distribution.fromString(_, 1000));
|
||||||
let cdf = timeLimited.limitedDomainCdf.distribution;
|
// let cdf = timeLimited.limitedDomainCdf.distribution;
|
||||||
<>
|
// <>
|
||||||
<Chart height=100 data={cdf |> Types.ContinuousDistribution.toJs} />
|
// <Chart height=100 data={cdf |> Types.ContinuousDistribution.toJs} />
|
||||||
<Chart
|
// <Chart
|
||||||
height=100
|
// height=100
|
||||||
data={
|
// data={
|
||||||
cdf
|
// cdf
|
||||||
|> CdfLibrary.Distribution.toPdf
|
// |> CdfLibrary.Distribution.toPdf
|
||||||
|> Types.ContinuousDistribution.toJs
|
// |> Types.ContinuousDistribution.toJs
|
||||||
}
|
// }
|
||||||
/>
|
// />
|
||||||
{FloatCdf.logNormal(50., 20.) |> ReasonReact.string}
|
// {FloatCdf.logNormal(50., 20.) |> ReasonReact.string}
|
||||||
</>;
|
// </>;
|
||||||
| TimeLimitedDomainCdf(r) =>
|
| TimeLimitedDomainCdf(r) =>
|
||||||
let cdf: Types.ContinuousDistribution.t =
|
let cdf: Types.ContinuousDistribution.t =
|
||||||
r.limitedDomainCdf.distribution;
|
r.limitedDomainCdf.distribution;
|
||||||
<>
|
<>
|
||||||
<Chart height=100 data={cdf |> Types.ContinuousDistribution.toJs} />
|
<Chart height=100 data={cdf |> Types.ContinuousDistribution.toJs} />
|
||||||
</>;
|
</>;
|
||||||
| FloatCdf(r) =>
|
| FloatCdf(r) => <div />
|
||||||
let cdf: Types.ContinuousDistribution.t =
|
// let cdf: Types.MixedDistribution.t =
|
||||||
CdfLibrary.Distribution.fromString(r, 2000);
|
// CdfLibrary.Distribution.fromString(r, 2000);
|
||||||
<>
|
// <>
|
||||||
<Chart
|
// <Chart
|
||||||
height=100
|
// height=100
|
||||||
data={
|
// data={
|
||||||
cdf
|
// cdf
|
||||||
|> CdfLibrary.Distribution.toPdf
|
// |> CdfLibrary.Distribution.toPdf
|
||||||
|> Types.ContinuousDistribution.toJs
|
// |> Types.ContinuousDistribution.toJs
|
||||||
}
|
// }
|
||||||
/>
|
// />
|
||||||
{r |> ReasonReact.string}
|
// {r |> ReasonReact.string}
|
||||||
</>;
|
// </>;
|
||||||
| Probability(r) =>
|
| Probability(r) =>
|
||||||
(r *. 100. |> Js.Float.toFixed) ++ "%" |> ReasonReact.string
|
(r *. 100. |> Js.Float.toFixed) ++ "%" |> ReasonReact.string
|
||||||
| DateTime(r) => r |> MomentRe.Moment.defaultFormat |> ReasonReact.string
|
| DateTime(r) => r |> MomentRe.Moment.defaultFormat |> ReasonReact.string
|
||||||
|
|
59
src/lib/TimeTypes.re
Normal file
59
src/lib/TimeTypes.re
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
type timeUnit = [
|
||||||
|
| `days
|
||||||
|
| `hours
|
||||||
|
| `milliseconds
|
||||||
|
| `minutes
|
||||||
|
| `months
|
||||||
|
| `quarters
|
||||||
|
| `seconds
|
||||||
|
| `weeks
|
||||||
|
| `years
|
||||||
|
];
|
||||||
|
|
||||||
|
type timeVector = {
|
||||||
|
zero: MomentRe.Moment.t,
|
||||||
|
unit: timeUnit,
|
||||||
|
};
|
||||||
|
|
||||||
|
type timePoint = {
|
||||||
|
timeVector,
|
||||||
|
value: float,
|
||||||
|
};
|
||||||
|
|
||||||
|
module TimePoint = {
|
||||||
|
let fromTimeVector = (timeVector, value): timePoint => {timeVector, value};
|
||||||
|
|
||||||
|
let toMoment = (timePoint: timePoint) => {
|
||||||
|
timePoint.timeVector.zero
|
||||||
|
|> MomentRe.Moment.add(
|
||||||
|
~duration=
|
||||||
|
MomentRe.duration(timePoint.value, timePoint.timeVector.unit),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
let fromMoment = (timeVector: timeVector, moment: MomentRe.Moment.t) =>
|
||||||
|
MomentRe.diff(timeVector.zero, moment, timeVector.unit);
|
||||||
|
};
|
||||||
|
|
||||||
|
module RelativeTimePoint = {
|
||||||
|
type timeInVector =
|
||||||
|
| Time(MomentRe.Moment.t)
|
||||||
|
| XValue(float);
|
||||||
|
|
||||||
|
let toTime = (timeVector: timeVector, timeInVector: timeInVector) =>
|
||||||
|
switch (timeInVector) {
|
||||||
|
| Time(r) => r
|
||||||
|
| XValue(r) =>
|
||||||
|
timeVector.zero
|
||||||
|
|> MomentRe.Moment.add(~duration=MomentRe.duration(r, timeVector.unit))
|
||||||
|
};
|
||||||
|
|
||||||
|
let _timeToX = (time, timeStart, timeUnit) =>
|
||||||
|
MomentRe.diff(timeStart, time, timeUnit);
|
||||||
|
|
||||||
|
let toXValue = (timeVector: timeVector, timeInVector: timeInVector) =>
|
||||||
|
switch (timeInVector) {
|
||||||
|
| Time(r) => _timeToX(r, timeVector.zero, timeVector.unit)
|
||||||
|
| XValue(r) => r
|
||||||
|
};
|
||||||
|
};
|
|
@ -59,7 +59,7 @@ module DiscreteDistribution = {
|
||||||
};
|
};
|
||||||
|
|
||||||
module MixedDistribution = {
|
module MixedDistribution = {
|
||||||
type distribution = {
|
type t = {
|
||||||
discrete: DiscreteDistribution.t,
|
discrete: DiscreteDistribution.t,
|
||||||
continuous: ContinuousDistribution.t,
|
continuous: ContinuousDistribution.t,
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,8 +39,35 @@ module JS = {
|
||||||
external scoreNonMarketCdfCdf: (int, distJs, distJs, float) => distJs =
|
external scoreNonMarketCdfCdf: (int, distJs, distJs, float) => distJs =
|
||||||
"scoreNonMarketCdfCdf";
|
"scoreNonMarketCdfCdf";
|
||||||
|
|
||||||
|
module Guesstimator = {
|
||||||
|
[@bs.deriving abstract]
|
||||||
|
type discrete = {
|
||||||
|
xs: array(float),
|
||||||
|
ys: array(float),
|
||||||
|
};
|
||||||
|
|
||||||
|
let jsToDistDiscrete = (d: discrete): Types.DiscreteDistribution.t => {
|
||||||
|
xs: xsGet(d),
|
||||||
|
ys: ysGet(d),
|
||||||
|
};
|
||||||
|
|
||||||
|
[@bs.deriving abstract]
|
||||||
|
type combined = {
|
||||||
|
continuous: distJs,
|
||||||
|
discrete,
|
||||||
|
};
|
||||||
|
|
||||||
|
let toContinous = (r: combined) => continuousGet(r) |> jsToDist;
|
||||||
|
let toDiscrete = (r: combined): Types.DiscreteDistribution.t =>
|
||||||
|
discreteGet(r) |> jsToDistDiscrete;
|
||||||
|
let toMixed = (r: combined): Types.MixedDistribution.t => {
|
||||||
|
discrete: toDiscrete(r),
|
||||||
|
continuous: toContinous(r),
|
||||||
|
};
|
||||||
|
|
||||||
[@bs.module "./GuesstimatorLibrary.js"]
|
[@bs.module "./GuesstimatorLibrary.js"]
|
||||||
external toGuesstimator: (string, int) => distJs = "run";
|
external toGuesstimator: (string, int) => combined = "run";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
module Distribution = {
|
module Distribution = {
|
||||||
|
@ -49,7 +76,8 @@ module Distribution = {
|
||||||
let findX = (y, dist) => dist |> JS.distToJs |> JS.findX(y);
|
let findX = (y, dist) => dist |> JS.distToJs |> JS.findX(y);
|
||||||
let findY = (x, dist) => dist |> JS.distToJs |> JS.findY(x);
|
let findY = (x, dist) => dist |> JS.distToJs |> JS.findY(x);
|
||||||
let fromString = (str: string, sampleCount: int) =>
|
let fromString = (str: string, sampleCount: int) =>
|
||||||
JS.toGuesstimator(str, sampleCount) |> JS.jsToDist;
|
JS.Guesstimator.toGuesstimator(str, sampleCount)
|
||||||
|
|> JS.Guesstimator.toMixed;
|
||||||
let integral = dist => dist |> JS.distToJs |> JS.integral;
|
let integral = dist => dist |> JS.distToJs |> JS.integral;
|
||||||
let differentialEntropy = (maxCalculationLength, dist) =>
|
let differentialEntropy = (maxCalculationLength, dist) =>
|
||||||
dist
|
dist
|
||||||
|
|
|
@ -33,14 +33,19 @@ const ratioSize = samples => {
|
||||||
return minMaxRatio(minValue, maxValue);
|
return minMaxRatio(minValue, maxValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const toPdf = (values, sampleCount, min, max) => {
|
const toPdf = (values, sampleCount, min, max) => {
|
||||||
const samples = new Samples(values);
|
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 continuousSamples = _.difference(values, frequencies.map(f => f.value));
|
||||||
|
const samples = new Samples(continuousSamples);
|
||||||
|
|
||||||
const ratioSize$ = ratioSize(samples);
|
const ratioSize$ = ratioSize(samples);
|
||||||
const width = ratioSize$ === 'SMALL' ? 20 : 1;
|
const width = ratioSize$ === 'SMALL' ? 20 : 1;
|
||||||
|
|
||||||
const cdf = samples.toCdf({ size: sampleCount, width, min, max });
|
const cdf = samples.toCdf({ size: sampleCount, width, min, max });
|
||||||
return {ys:cdf.ys, xs:cdf.xs};
|
return {continuous:{ys:cdf.ys, xs:cdf.xs}, discrete: {xs: frequencies.map(f => f.value), ys: frequencies.map(f => f.percentage)}};
|
||||||
};
|
};
|
||||||
|
|
||||||
let run = (text, sampleCount, inputs=[], min=false, max=false) => {
|
let run = (text, sampleCount, inputs=[], min=false, max=false) => {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user