Replaced GenericDistributionChart with ComplexPowerChart
This commit is contained in:
parent
cd1b114295
commit
0d32942110
|
@ -8,15 +8,16 @@ let timeDist =
|
|||
~unit=TimeDistribution({zero: MomentRe.momentNow(), unit: `days}),
|
||||
(),
|
||||
)
|
||||
|> GenericDistribution.renderIfNeeded(~sampleCount=1000);
|
||||
|> GenericDistribution.toComplexPower(~sampleCount=1000);
|
||||
|
||||
let distributions = () =>
|
||||
<div>
|
||||
<div>
|
||||
<h2> {"Basic Mixed Distribution" |> ReasonReact.string} </h2>
|
||||
{timeDist
|
||||
|> E.O.bind(_, GenericDistribution.normalize)
|
||||
|> E.O.React.fmapOrNull(dist => <GenericDistributionChart dist />)}
|
||||
|> E.O.React.fmapOrNull(complexPower =>
|
||||
<ComplexPowerChart complexPower />
|
||||
)}
|
||||
<h2> {"Simple Continuous" |> ReasonReact.string} </h2>
|
||||
</div>
|
||||
</div>;
|
||||
|
|
61
src/components/charts/ComplexPowerChart.re
Normal file
61
src/components/charts/ComplexPowerChart.re
Normal file
|
@ -0,0 +1,61 @@
|
|||
module ComplexPowerChart = {
|
||||
[@react.component]
|
||||
let make = (~complexPower: DistributionTypes.complexPower, ~onHover) => {
|
||||
open DistFunctor.ComplexPower;
|
||||
let discrete = complexPower |> T.toDiscrete;
|
||||
let continuous =
|
||||
complexPower
|
||||
|> T.toContinuous
|
||||
|> E.O.fmap(DistFunctor.Continuous.getShape);
|
||||
let minX = T.minX(complexPower);
|
||||
let maxX = T.maxX(complexPower);
|
||||
let timeScale =
|
||||
complexPower.unit |> DistributionTypes.DistributionUnit.toJson;
|
||||
<CdfChart__Plain
|
||||
minX
|
||||
maxX
|
||||
?discrete
|
||||
?continuous
|
||||
color={`hex("333")}
|
||||
onHover
|
||||
timeScale
|
||||
/>;
|
||||
};
|
||||
};
|
||||
|
||||
[@react.component]
|
||||
let make = (~complexPower: DistributionTypes.complexPower) => {
|
||||
let (x, setX) = React.useState(() => 0.);
|
||||
let chart =
|
||||
React.useMemo1(
|
||||
() => {<ComplexPowerChart complexPower onHover={r => {setX(_ => r)}} />},
|
||||
[|complexPower|],
|
||||
);
|
||||
<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 ">
|
||||
{complexPower
|
||||
|> DistFunctor.ComplexPower.T.Integral.xToY(~cache=None, x)
|
||||
|> E.Float.with2DigitsPrecision
|
||||
|> ReasonReact.string}
|
||||
</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div />
|
||||
</div>;
|
||||
};
|
|
@ -1,77 +0,0 @@
|
|||
module Shapee = {
|
||||
[@react.component]
|
||||
let make = (~shape: DistributionTypes.shape, ~timeScale, ~onHover) => {
|
||||
<div
|
||||
// let discrete = Shape.T.scaledDiscreteComponent(shape);
|
||||
// let continuous = Shape.T.scaledContinuousComponent(shape);
|
||||
// <div>
|
||||
// <CdfChart__Plain
|
||||
// minX={Shape.T.minX(shape)}
|
||||
// maxX={Shape.T.maxX(shape)}
|
||||
// ?discrete
|
||||
// ?continuous
|
||||
// color={`hex("333")}
|
||||
// onHover
|
||||
// timeScale
|
||||
// />
|
||||
// {discrete |> E.O.React.fmapOrNull(Shape.Discrete.render)}
|
||||
// </div>;
|
||||
/>;
|
||||
};
|
||||
};
|
||||
|
||||
module GenericDist = {
|
||||
[@react.component]
|
||||
let make = (~genericDistribution: DistributionTypes.genericDistribution) => {
|
||||
let (x, setX) = React.useState(() => 0.);
|
||||
let timeScale =
|
||||
genericDistribution.unit |> DistributionTypes.DistributionUnit.toJson;
|
||||
let chart =
|
||||
React.useMemo1(
|
||||
() => {
|
||||
genericDistribution
|
||||
|> DistributionTypes.shapee
|
||||
|> E.O.React.fmapOrNull(shape => {
|
||||
<Shapee shape timeScale onHover={r => setX(_ => r)} />
|
||||
})
|
||||
},
|
||||
[|genericDistribution|],
|
||||
);
|
||||
<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 ">
|
||||
{genericDistribution->GenericDistribution.yIntegral(x)
|
||||
|> E.O.fmap(E.Float.with2DigitsPrecision)
|
||||
|> E.O.default("")
|
||||
|> ReasonReact.string}
|
||||
</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div />
|
||||
</div>;
|
||||
};
|
||||
};
|
||||
|
||||
[@react.component]
|
||||
let make = (~dist) => {
|
||||
switch ((dist: DistributionTypes.genericDistribution)) {
|
||||
| {generationSource: Shape(_)} =>
|
||||
<div> <GenericDist genericDistribution=dist /> </div>
|
||||
| _ => <div />
|
||||
};
|
||||
};
|
|
@ -324,7 +324,7 @@ module Shape = {
|
|||
);
|
||||
};
|
||||
let maxX = (t: t) =>
|
||||
mapToAll(t, (Mixed.T.minX, Discrete.T.minX, Continuous.T.minX));
|
||||
mapToAll(t, (Mixed.T.maxX, Discrete.T.maxX, Continuous.T.maxX));
|
||||
let pointwiseFmap = (fn, t: t) =>
|
||||
fmap(
|
||||
t,
|
||||
|
@ -337,7 +337,36 @@ module Shape = {
|
|||
});
|
||||
};
|
||||
|
||||
module WithMetadata = {
|
||||
module ComplexPower = {
|
||||
open DistributionTypes;
|
||||
let make =
|
||||
(
|
||||
~shape,
|
||||
~guesstimatorString,
|
||||
~domain=Complete,
|
||||
~unit=UnspecifiedDistribution,
|
||||
(),
|
||||
)
|
||||
: complexPower => {
|
||||
let integral = Shape.T.Integral.get(~cache=None, shape);
|
||||
{shape, domain, integralCache: integral, unit, guesstimatorString};
|
||||
};
|
||||
let update =
|
||||
(
|
||||
~shape=?,
|
||||
~integralCache=?,
|
||||
~domain=?,
|
||||
~unit=?,
|
||||
~guesstimatorString=?,
|
||||
t: complexPower,
|
||||
) => {
|
||||
shape: E.O.default(t.shape, shape),
|
||||
integralCache: E.O.default(t.integralCache, integralCache),
|
||||
domain: E.O.default(t.domain, domain),
|
||||
unit: E.O.default(t.unit, unit),
|
||||
guesstimatorString: E.O.default(t.guesstimatorString, guesstimatorString),
|
||||
};
|
||||
|
||||
module T =
|
||||
Dist({
|
||||
type t = DistributionTypes.complexPower;
|
||||
|
@ -350,7 +379,7 @@ module WithMetadata = {
|
|||
let xToY = f => shapeFn(Shape.T.xToY(f));
|
||||
let minX = shapeFn(Shape.T.minX);
|
||||
let maxX = shapeFn(Shape.T.maxX);
|
||||
let fromShape = (shape, t): t => DistributionTypes.update(~shape, t);
|
||||
let fromShape = (shape, t): t => update(~shape, t);
|
||||
// todo: adjust for limit
|
||||
let pointwiseFmap = (fn, {shape, _} as t: t): t =>
|
||||
fromShape(Shape.T.pointwiseFmap(fn, shape), t);
|
||||
|
|
|
@ -66,29 +66,12 @@ type genericDistribution = {
|
|||
unit: distributionUnit,
|
||||
};
|
||||
|
||||
let shapee = ({generationSource}: genericDistribution) =>
|
||||
switch (generationSource) {
|
||||
| GuesstimatorString(_) => None
|
||||
| Shape(pointsType) => Some(pointsType)
|
||||
};
|
||||
|
||||
type pdfCdfCombo = {
|
||||
pdf: shape,
|
||||
cdf: continuousShape,
|
||||
};
|
||||
|
||||
type complexPower = {
|
||||
shape,
|
||||
domain,
|
||||
integralCache: continuousShape,
|
||||
domain: domainLimit,
|
||||
unit: distributionUnit,
|
||||
};
|
||||
|
||||
let update = (~shape=?, ~integralCache=?, ~domain=?, ~unit=?, t: complexPower) => {
|
||||
shape: E.O.default(t.shape, shape),
|
||||
integralCache: E.O.default(t.integralCache, integralCache),
|
||||
domain: E.O.default(t.domain, domain),
|
||||
unit: E.O.default(t.unit, unit),
|
||||
guesstimatorString: option(string),
|
||||
};
|
||||
|
||||
module DistributionUnit = {
|
||||
|
@ -102,6 +85,34 @@ module DistributionUnit = {
|
|||
};
|
||||
};
|
||||
|
||||
module Domain = {
|
||||
let excludedProbabilityMass = (t: domain) => {
|
||||
switch (t) {
|
||||
| Complete => 1.0
|
||||
| LeftLimited({excludingProbabilityMass}) => excludingProbabilityMass
|
||||
| RightLimited({excludingProbabilityMass}) => excludingProbabilityMass
|
||||
| LeftAndRightLimited(
|
||||
{excludingProbabilityMass: l},
|
||||
{excludingProbabilityMass: r},
|
||||
) =>
|
||||
l +. r
|
||||
};
|
||||
};
|
||||
|
||||
let initialProbabilityMass = (t: domain) => {
|
||||
switch (t) {
|
||||
| Complete
|
||||
| RightLimited(_) => 0.0
|
||||
| LeftLimited({excludingProbabilityMass}) => excludingProbabilityMass
|
||||
| LeftAndRightLimited({excludingProbabilityMass}, _) => excludingProbabilityMass
|
||||
};
|
||||
};
|
||||
|
||||
let normalizeProbabilityMass = (t: domain) => {
|
||||
1. /. excludedProbabilityMass(t);
|
||||
};
|
||||
};
|
||||
|
||||
type mixedPoint = {
|
||||
continuous: float,
|
||||
discrete: float,
|
||||
|
|
|
@ -1,33 +1,5 @@
|
|||
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,
|
||||
|
@ -43,51 +15,23 @@ let make =
|
|||
unit,
|
||||
};
|
||||
|
||||
//TODO: The fact that it is a CDF is really something you find later, this can't be chosen until GuesstimatorToString happens.
|
||||
let renderIfNeeded =
|
||||
(~sampleCount=1000, t: genericDistribution): option(genericDistribution) => {
|
||||
switch (t.generationSource) {
|
||||
| GuesstimatorString(s) =>
|
||||
Guesstimator.stringToMixedShape(~string=s, ~sampleCount, ())
|
||||
|> E.O.bind(_, DistFunctor.Mixed.clean)
|
||||
|> E.O.fmap((shape: DistributionTypes.shape) =>
|
||||
make(
|
||||
~generationSource=Shape(shape),
|
||||
~probabilityType=Pdf,
|
||||
~domain=t.domain,
|
||||
~unit=t.unit,
|
||||
(),
|
||||
)
|
||||
let toComplexPower =
|
||||
(~sampleCount, t: genericDistribution): option(complexPower) => {
|
||||
let shape =
|
||||
switch (t.generationSource) {
|
||||
| GuesstimatorString(s) =>
|
||||
Guesstimator.stringToMixedShape(~string=s, ~sampleCount, ())
|
||||
|> E.O.bind(_, DistFunctor.Mixed.clean)
|
||||
| Shape(shape) => Some(shape)
|
||||
};
|
||||
shape
|
||||
|> E.O.fmap(shape =>
|
||||
DistFunctor.ComplexPower.make(
|
||||
~shape,
|
||||
~domain=t.domain,
|
||||
~unit=t.unit,
|
||||
~guesstimatorString=None,
|
||||
(),
|
||||
)
|
||||
| Shape(_) => Some(t)
|
||||
};
|
||||
};
|
||||
|
||||
let normalize = (t: genericDistribution): option(genericDistribution) => {
|
||||
switch (t.generationSource) {
|
||||
| Shape(shape) => Some({...t, generationSource: Shape(shape)})
|
||||
| GuesstimatorString(_) => Some(t)
|
||||
};
|
||||
};
|
||||
|
||||
let yIntegral = (t: DistributionTypes.genericDistribution, x) => {
|
||||
switch (t) {
|
||||
| {generationSource: Shape(shape)} =>
|
||||
Some(DistFunctor.Shape.T.Integral.xToY(~cache=None, x, shape))
|
||||
| _ => None
|
||||
};
|
||||
};
|
||||
|
||||
// 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: Pdf,
|
||||
domain,
|
||||
unit,
|
||||
})
|
||||
| _ => None
|
||||
};
|
||||
);
|
||||
};
|
|
@ -1,297 +0,0 @@
|
|||
open DistributionTypes;
|
||||
|
||||
type pointInRange =
|
||||
| Unbounded
|
||||
| X(float);
|
||||
|
||||
module Continuous = {
|
||||
type t = continuousShape;
|
||||
let xyShape = (t: t) => t.xyShape;
|
||||
let getShape = (t: t) => t.xyShape;
|
||||
let interpolation = (t: t) => t.interpolation;
|
||||
let make = (xyShape, interpolation): t => {xyShape, interpolation};
|
||||
let fromShape = xyShape => make(xyShape, `Linear);
|
||||
let shapeMap = (fn, {xyShape, interpolation}: t): t => {
|
||||
xyShape: fn(xyShape),
|
||||
interpolation,
|
||||
};
|
||||
let oShapeMap =
|
||||
(fn, {xyShape, interpolation}: t)
|
||||
: option(DistributionTypes.continuousShape) =>
|
||||
fn(xyShape) |> E.O.fmap(xyShape => make(xyShape, interpolation));
|
||||
let shapeFn = (fn, t: t) => t |> xyShape |> fn;
|
||||
let minX = shapeFn(XYShape.minX);
|
||||
let maxX = shapeFn(XYShape.maxX);
|
||||
let findX = y => shapeFn(CdfLibrary.Distribution.findX(y));
|
||||
let findY = x => shapeFn(CdfLibrary.Distribution.findY(x));
|
||||
let toJs = shapeFn(XYShape.toJs);
|
||||
let fromArrays = (a, b) => make(XYShape.fromArrays(a, b), `Linear);
|
||||
let toPdf = (t: t) => t |> oShapeMap(XYShape.Range.derivative);
|
||||
let toCdf = (t: t) => t |> oShapeMap(XYShape.Range.integrateWithTriangles);
|
||||
let findIntegralY = (f, t) => {
|
||||
t
|
||||
|> toCdf
|
||||
|> E.O.fmap(xyShape)
|
||||
|> E.O.fmap(CdfLibrary.Distribution.findY(f));
|
||||
};
|
||||
let normalizeCdf = (continuousShape: continuousShape) =>
|
||||
continuousShape
|
||||
|> xyShape
|
||||
|> XYShape.scaleCdfTo(~scaleTo=1.0)
|
||||
|> fromShape;
|
||||
let scalePdf = (~scaleTo=1.0, continuousShape: continuousShape) => {
|
||||
switch (toCdf(continuousShape)) {
|
||||
| Some({xyShape}) =>
|
||||
XYShape.scaleCdfTo(~scaleTo, xyShape)
|
||||
|> XYShape.Range.derivative
|
||||
|> E.O.fmap(fromShape)
|
||||
| _ => None
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
module Discrete = {
|
||||
let minX = XYShape.minX;
|
||||
let maxX = XYShape.maxX;
|
||||
type t = discreteShape;
|
||||
let fromArrays = XYShape.fromArrays;
|
||||
let toJs = XYShape.toJs;
|
||||
let ySum = XYShape.ySum;
|
||||
let zip = t => Belt.Array.zip(t.xs, t.ys);
|
||||
let pointwiseMap = (t: discreteShape, fn): discreteShape => {
|
||||
xs: t.xs,
|
||||
ys: t.ys |> E.A.fmap(fn),
|
||||
};
|
||||
|
||||
let scaleYToTotal = (totalDesired, t: t): t => {
|
||||
let difference = totalDesired /. ySum(t);
|
||||
XYShape.fmap(t, y => y *. difference);
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
let integrate = t => t |> XYShape.accumulateYs |> Continuous.fromShape;
|
||||
let derivative = XYShape.subtractYs;
|
||||
|
||||
// TODO: This has a clear bug where it returns the Y value of the first item,
|
||||
// even if X is less than the X of the first item.
|
||||
// It has a second bug that it assumes things are triangular, instead of interpolating via steps.
|
||||
let findIntegralY = (f, t: t) => {
|
||||
t |> XYShape.accumulateYs |> CdfLibrary.Distribution.findY(f);
|
||||
};
|
||||
|
||||
let findY = (f, t: t) => {
|
||||
Belt.Array.zip(t.xs, t.ys)
|
||||
|> E.A.getBy(_, ((x, _)) => x == f)
|
||||
|> E.O.fmap(((_, y)) => y)
|
||||
|> E.O.default(0.);
|
||||
};
|
||||
};
|
||||
|
||||
let min = (f1: option(float), f2: option(float)) =>
|
||||
switch (f1, f2) {
|
||||
| (Some(f1), Some(f2)) => Some(f1 < f2 ? f1 : f2)
|
||||
| (Some(f1), None) => Some(f1)
|
||||
| (None, Some(f2)) => Some(f2)
|
||||
| (None, None) => None
|
||||
};
|
||||
|
||||
let max = (f1: option(float), f2: option(float)) =>
|
||||
switch (f1, f2) {
|
||||
| (Some(f1), Some(f2)) => Some(f1 > f2 ? f1 : f2)
|
||||
| (Some(f1), None) => Some(f1)
|
||||
| (None, Some(f2)) => Some(f2)
|
||||
| (None, None) => None
|
||||
};
|
||||
|
||||
module Mixed = {
|
||||
// let make = (~continuous, ~discrete, ~discreteProbabilityMassFraction) => {
|
||||
// continuous,
|
||||
// discrete,
|
||||
// discreteProbabilityMassFraction,
|
||||
// };
|
||||
|
||||
let minX = (t: DistributionTypes.mixedShape) =>
|
||||
min(t.continuous |> Continuous.minX, t.discrete |> Discrete.minX);
|
||||
|
||||
let maxX = (t: DistributionTypes.mixedShape) => {
|
||||
max(t.continuous |> Continuous.maxX, t.discrete |> Discrete.maxX);
|
||||
};
|
||||
|
||||
let mixedMultiply =
|
||||
(
|
||||
t: DistributionTypes.mixedShape,
|
||||
continuousComponent,
|
||||
discreteComponent,
|
||||
) => {
|
||||
let diffFn = t.discreteProbabilityMassFraction;
|
||||
continuousComponent *. (1.0 -. diffFn) +. discreteComponent *. diffFn;
|
||||
};
|
||||
|
||||
type yPdfPoint = {
|
||||
continuous: option(float),
|
||||
discrete: option(float),
|
||||
};
|
||||
|
||||
let findY = (t: DistributionTypes.mixedShape, x: float): yPdfPoint => {
|
||||
continuous:
|
||||
Continuous.findY(x, t.continuous)
|
||||
|> (e => e *. (1. -. t.discreteProbabilityMassFraction))
|
||||
|> E.O.some,
|
||||
discrete:
|
||||
Discrete.findY(x, t.discrete)
|
||||
|> (e => e *. t.discreteProbabilityMassFraction)
|
||||
|> E.O.some,
|
||||
};
|
||||
|
||||
let findYIntegral =
|
||||
(x: float, t: DistributionTypes.mixedShape): option(float) => {
|
||||
let c = t.continuous |> Continuous.findIntegralY(x);
|
||||
let d = Discrete.findIntegralY(x, t.discrete);
|
||||
switch (c, d) {
|
||||
| (Some(c), d) => Some(mixedMultiply(t, c, d))
|
||||
| _ => None
|
||||
};
|
||||
};
|
||||
} /* }*/;
|
||||
|
||||
// module T = {
|
||||
// type t = DistributionTypes.shape;
|
||||
|
||||
// let y = (t: t, x: float) =>
|
||||
// switch (t) {
|
||||
// | Mixed(m) => `mixed(Mixed.findY(m, x))
|
||||
// | Discrete(discreteShape) => `discrete(Discrete.findY(x, discreteShape))
|
||||
// | Continuous(continuousShape) =>
|
||||
// `continuous(Continuous.findY(x, continuousShape))
|
||||
// };
|
||||
|
||||
// let yIntegral = (t: t, x: float) =>
|
||||
// switch (t) {
|
||||
// | Mixed(m) => Mixed.findYIntegral(x, m)
|
||||
// | Discrete(discreteShape) =>
|
||||
// Discrete.findIntegralY(x, discreteShape) |> E.O.some
|
||||
// | Continuous(continuousShape) =>
|
||||
// Continuous.findIntegralY(x, continuousShape)
|
||||
// };
|
||||
|
||||
// let minX = (t: t) =>
|
||||
// switch (t) {
|
||||
// | Mixed(m) => Mixed.minX(m)
|
||||
// | Discrete(discreteShape) => Discrete.minX(discreteShape)
|
||||
// | Continuous(continuousShape) => Continuous.minX(continuousShape)
|
||||
// };
|
||||
|
||||
// let maxX = (t: t) =>
|
||||
// switch (t) {
|
||||
// | Mixed(m) => Mixed.maxX(m)
|
||||
// | Discrete(discreteShape) => Discrete.maxX(discreteShape)
|
||||
// | Continuous(continuousShape) => Continuous.maxX(continuousShape)
|
||||
// };
|
||||
|
||||
// let discreteComponent = (t: t) =>
|
||||
// switch (t) {
|
||||
// | Mixed({discrete}) => Some(discrete)
|
||||
// | Discrete(d) => Some(d)
|
||||
// | Continuous(_) => None
|
||||
// };
|
||||
|
||||
// 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
|
||||
// // };
|
||||
// // };
|
||||
// // let pointwiseFmap = (fn, t: t): shape =>
|
||||
// // switch (t) {
|
||||
// // | Mixed({discrete, continuous, discreteProbabilityMassFraction}) =>
|
||||
// // Mixed({
|
||||
// // continuous: XYShape.pointwiseMap(fn, continuous),
|
||||
// // discrete: XYShape.pointwiseMap(fn, discrete),
|
||||
// // discreteProbabilityMassFraction,
|
||||
// // })
|
||||
// // | Discrete(x) => Discrete(XYShape.pointwiseMap(fn, x))
|
||||
// // | Continuous(x) => Continuous(XYShape.pointwiseMap(fn, x))
|
||||
// // };
|
||||
// // module Cdf = {
|
||||
// // let normalizeCdf = (t: DistributionTypes.shape) => {
|
||||
// // switch (t) {
|
||||
// // | Mixed({continuous, discrete, discreteProbabilityMassFraction}) =>
|
||||
// // Mixed({
|
||||
// // continuous: continuous |> Continuous.normalizeCdf,
|
||||
// // discrete: discrete |> Discrete.scaleYToTotal(1.0),
|
||||
// // discreteProbabilityMassFraction,
|
||||
// // })
|
||||
// // | Discrete(d) => Discrete(d |> Discrete.scaleYToTotal(1.0))
|
||||
// // | Continuous(continuousShape) =>
|
||||
// // Continuous(Continuous.normalizeCdf(continuousShape))
|
||||
// // };
|
||||
// // };
|
||||
// // };
|
||||
// };
|
||||
|
||||
// module PdfCdfShape = {
|
||||
// type t = pdfCdfCombo;
|
||||
// let pdf = (t: t) =>
|
||||
// switch (t.pdf) {
|
||||
// | Mixed(pdf) => Mixed(pdf)
|
||||
// | Discrete(pdf) => Discrete(pdf)
|
||||
// | Continuous(pdf) => Continuous(pdf)
|
||||
// };
|
||||
// let cdf = (t: t) => t.cdf;
|
||||
// };
|
||||
|
||||
// type distributionUnit =
|
||||
// | UnspecifiedDistribution
|
||||
// | TimeDistribution(TimeTypes.timeVector);
|
||||
|
||||
// type withLimitedDomain = {
|
||||
// domain,
|
||||
// dist: pdfCdfCombo,
|
||||
// };
|
||||
|
||||
// module WithLimitedDomain = {
|
||||
// type t = withLimitedDomain;
|
||||
// let dist = (t: t) => t.dist;
|
||||
// let pdf = (t: t) => PdfCdfShape.pdf(t.dist);
|
||||
// let cdf = (t: t) => PdfCdfShape.cdf(t.dist);
|
||||
// // TODO: This is bad, obviously needs to be fixed.
|
||||
// let distScaleFactor = (t: t) => 3.0;
|
||||
// // let scaledPdfShape = (scaleFactor, t: t) =>
|
||||
// // t |> pdf |> T.pointwiseFmap(r => r *. scaleFactor);
|
||||
// // let scaledCdfShape = (scaleFactor, t: t) =>
|
||||
// // t |> cdf |> XYShape.pointwiseMap(r => r *. scaleFactor);
|
||||
// };
|
||||
|
||||
// type withTimeVector = {
|
||||
// timeVector: TimeTypes.timeVector,
|
||||
// dist: withLimitedDomain,
|
|
@ -19,15 +19,11 @@ let propValue = (t: Prop.Value.t) => {
|
|||
| ConditionalArray(r) => "Array" |> ReasonReact.string
|
||||
| GenericDistribution(r) =>
|
||||
let newDistribution =
|
||||
GenericDistribution.renderIfNeeded(~sampleCount=2000, r);
|
||||
GenericDistribution.toComplexPower(~sampleCount=1000, r);
|
||||
switch (newDistribution) {
|
||||
| Some(distribution) =>
|
||||
<div>
|
||||
{GenericDistribution.normalize(distribution)
|
||||
|> E.O.React.fmapOrNull(dist => <GenericDistributionChart dist />)}
|
||||
</div>
|
||||
<div> <ComplexPowerChart complexPower=distribution /> </div>
|
||||
| None => "Something went wrong" |> ReasonReact.string
|
||||
| _ => <div />
|
||||
};
|
||||
| FloatCdf(_) => <div />
|
||||
| Probability(r) =>
|
||||
|
|
|
@ -112,12 +112,11 @@ module Model = {
|
|||
let model = GlobalCatastrophe.Model.make(dateTime);
|
||||
switch (model) {
|
||||
| Prop.Value.GenericDistribution(genericDistribution) =>
|
||||
GenericDistribution.renderIfNeeded(
|
||||
~sampleCount=1000,
|
||||
genericDistribution,
|
||||
)
|
||||
|> E.O.bind(_, GenericDistribution.normalize)
|
||||
|> E.O.bind(_, GenericDistribution.yIntegral(_, 18.0))
|
||||
genericDistribution
|
||||
|> GenericDistribution.toComplexPower(~sampleCount=1000)
|
||||
|> E.O.fmap(
|
||||
DistFunctor.ComplexPower.T.Integral.xToY(~cache=None, 18.0),
|
||||
)
|
||||
| _ => None
|
||||
};
|
||||
};
|
||||
|
|
|
@ -17,7 +17,9 @@ module Internals = {
|
|||
};
|
||||
|
||||
let toContinous = (r: combined) =>
|
||||
continuousGet(r) |> CdfLibrary.JS.jsToDist |> Shape.Continuous.fromShape;
|
||||
continuousGet(r)
|
||||
|> CdfLibrary.JS.jsToDist
|
||||
|> DistFunctor.Continuous.fromShape;
|
||||
|
||||
let toDiscrete = (r: combined): DistributionTypes.xyShape =>
|
||||
discreteGet(r) |> jsToDistDiscrete;
|
||||
|
|
Loading…
Reference in New Issue
Block a user