First step for GenericDistribution
This commit is contained in:
parent
ab9c8726d6
commit
626b4f65c3
|
@ -1,62 +1,4 @@
|
|||
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
|
||||
};
|
||||
};
|
||||
open TimeTypes;
|
||||
|
||||
type t = {
|
||||
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
|
||||
| ConditionalArray(r) => "Array" |> ReasonReact.string
|
||||
| Conditional(r) => r.name |> ReasonReact.string
|
||||
| TimeLimitedDomainCdfLazy(r) =>
|
||||
let timeLimited = r(CdfLibrary.Distribution.fromString(_, 1000));
|
||||
let cdf = timeLimited.limitedDomainCdf.distribution;
|
||||
<>
|
||||
<Chart height=100 data={cdf |> Types.ContinuousDistribution.toJs} />
|
||||
<Chart
|
||||
height=100
|
||||
data={
|
||||
cdf
|
||||
|> CdfLibrary.Distribution.toPdf
|
||||
|> Types.ContinuousDistribution.toJs
|
||||
}
|
||||
/>
|
||||
{FloatCdf.logNormal(50., 20.) |> ReasonReact.string}
|
||||
</>;
|
||||
| TimeLimitedDomainCdfLazy(r) => <div />
|
||||
// let timeLimited = r(CdfLibrary.Distribution.fromString(_, 1000));
|
||||
// let cdf = timeLimited.limitedDomainCdf.distribution;
|
||||
// <>
|
||||
// <Chart height=100 data={cdf |> Types.ContinuousDistribution.toJs} />
|
||||
// <Chart
|
||||
// height=100
|
||||
// data={
|
||||
// cdf
|
||||
// |> CdfLibrary.Distribution.toPdf
|
||||
// |> Types.ContinuousDistribution.toJs
|
||||
// }
|
||||
// />
|
||||
// {FloatCdf.logNormal(50., 20.) |> ReasonReact.string}
|
||||
// </>;
|
||||
| TimeLimitedDomainCdf(r) =>
|
||||
let cdf: Types.ContinuousDistribution.t =
|
||||
r.limitedDomainCdf.distribution;
|
||||
<>
|
||||
<Chart height=100 data={cdf |> Types.ContinuousDistribution.toJs} />
|
||||
</>;
|
||||
| FloatCdf(r) =>
|
||||
let cdf: Types.ContinuousDistribution.t =
|
||||
CdfLibrary.Distribution.fromString(r, 2000);
|
||||
<>
|
||||
<Chart
|
||||
height=100
|
||||
data={
|
||||
cdf
|
||||
|> CdfLibrary.Distribution.toPdf
|
||||
|> Types.ContinuousDistribution.toJs
|
||||
}
|
||||
/>
|
||||
{r |> ReasonReact.string}
|
||||
</>;
|
||||
| FloatCdf(r) => <div />
|
||||
// let cdf: Types.MixedDistribution.t =
|
||||
// CdfLibrary.Distribution.fromString(r, 2000);
|
||||
// <>
|
||||
// <Chart
|
||||
// height=100
|
||||
// data={
|
||||
// cdf
|
||||
// |> CdfLibrary.Distribution.toPdf
|
||||
// |> Types.ContinuousDistribution.toJs
|
||||
// }
|
||||
// />
|
||||
// {r |> ReasonReact.string}
|
||||
// </>;
|
||||
| Probability(r) =>
|
||||
(r *. 100. |> Js.Float.toFixed) ++ "%" |> 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 = {
|
||||
type distribution = {
|
||||
type t = {
|
||||
discrete: DiscreteDistribution.t,
|
||||
continuous: ContinuousDistribution.t,
|
||||
};
|
||||
|
|
|
@ -39,8 +39,35 @@ module JS = {
|
|||
external scoreNonMarketCdfCdf: (int, distJs, distJs, float) => distJs =
|
||||
"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"]
|
||||
external toGuesstimator: (string, int) => distJs = "run";
|
||||
external toGuesstimator: (string, int) => combined = "run";
|
||||
};
|
||||
};
|
||||
|
||||
module Distribution = {
|
||||
|
@ -49,7 +76,8 @@ module Distribution = {
|
|||
let findX = (y, dist) => dist |> JS.distToJs |> JS.findX(y);
|
||||
let findY = (x, dist) => dist |> JS.distToJs |> JS.findY(x);
|
||||
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 differentialEntropy = (maxCalculationLength, dist) =>
|
||||
dist
|
||||
|
|
|
@ -33,14 +33,19 @@ const ratioSize = samples => {
|
|||
return minMaxRatio(minValue, maxValue);
|
||||
};
|
||||
|
||||
|
||||
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 width = ratioSize$ === 'SMALL' ? 20 : 1;
|
||||
|
||||
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) => {
|
||||
|
|
Loading…
Reference in New Issue
Block a user