Implemented step function transformation

This commit is contained in:
Ozzie Gooen 2020-02-22 23:55:43 +00:00
parent 3e04d3390d
commit 0328b86833
6 changed files with 131 additions and 26 deletions

View File

@ -2,7 +2,7 @@
let timeDist =
GenericDistribution.make(
~generationSource=
GuesstimatorString("mm(floor(normal(30,3)), normal(39,1), [.5,.5])"),
GuesstimatorString("mm(floor(normal(30,2)), normal(39,1), [.5,.5])"),
~probabilityType=Pdf,
~domain=Complete,
~unit=TimeDistribution({zero: MomentRe.momentNow(), unit: `days}),

View File

@ -23,6 +23,37 @@ module ComplexPowerChart = {
};
};
let bar: DistributionTypes.xyShape = {
ys: [|0.5, 0.8, 0.4, 1.0, 2.0|],
xs: [|0.0, 1., 2., 5., 8.|],
};
module IntegralChart = {
[@react.component]
let make = (~complexPower: DistributionTypes.complexPower, ~onHover) => {
open DistFunctor.ComplexPower;
let integral =
DistFunctor.ComplexPower.T.Integral.get(~cache=None, complexPower);
let continuous =
integral
|> T.toContinuous
|> E.O.fmap(DistFunctor.Continuous.toLinear)
|> E.O.fmap(DistFunctor.Continuous.getShape);
let minX = T.minX(integral);
let maxX = T.maxX(integral);
let timeScale =
complexPower.unit |> DistributionTypes.DistributionUnit.toJson;
<CdfChart__Plain
minX
maxX
?continuous
color={`hex("333")}
timeScale
onHover
/>;
};
};
[@react.component]
let make = (~complexPower: DistributionTypes.complexPower) => {
let (x, setX) = React.useState(() => 0.);
@ -31,8 +62,14 @@ let make = (~complexPower: DistributionTypes.complexPower) => {
() => {<ComplexPowerChart complexPower onHover={r => {setX(_ => r)}} />},
[|complexPower|],
);
let chart2 =
React.useMemo1(
() => {<IntegralChart complexPower onHover={r => {setX(_ => r)}} />},
[|complexPower|],
);
<div>
chart
chart2
<table className="table-auto">
<thead>
<tr>

View File

@ -77,18 +77,28 @@ module Continuous = {
: option(DistributionTypes.continuousShape) =>
fn(xyShape) |> E.O.fmap(xyShape => make(xyShape, interpolation));
let toLinear = (t: t): t =>
switch (t) {
| {interpolation: `Stepwise, xyShape} => {
interpolation: `Linear,
xyShape: xyShape |> XYShape.Range.stepsToContinuous |> E.O.toExt(""),
}
| {interpolation: `Linear, _} => t
};
module T =
Dist({
type t = DistributionTypes.continuousShape;
type integral = DistributionTypes.continuousShape;
let shapeFn = (fn, t: t) => t |> xyShape |> fn;
// TODO: Obviously fix this, it's terrible
let integral = (~cache, t) =>
cache
|> E.O.default(
t
|> xyShape
|> XYShape.Range.integrateWithTriangles
|> E.O.toExt("")
|> E.O.toExt("Error1")
|> fromShape,
);
// This seems wrong, we really want the ending bit, I'd assume
@ -118,7 +128,16 @@ module Discrete = {
type integral = DistributionTypes.continuousShape;
let integral = (~cache, t) =>
cache
|> E.O.default(t |> XYShape.accumulateYs |> Continuous.fromShape);
|> E.O.default(
{
Continuous.make(
XYShape.accumulateYs(t)
|> XYShape.Range.stepsToContinuous
|> E.O.toExt("ERROR"),
`Stepwise,
);
},
);
let integralSum = (~cache, t) => t |> XYShape.ySum;
let minX = XYShape.minX;
let maxX = XYShape.maxX;
@ -197,26 +216,42 @@ module Mixed = {
DistributionTypes.MixedPoint.add(c, d);
};
let toScaledContinuous =
({continuous, discreteProbabilityMassFraction}: t) =>
Some(
continuous
|> Continuous.T.scaleBy(
~scale=1.0 -. discreteProbabilityMassFraction,
),
);
let scaleContinuous =
({discreteProbabilityMassFraction}: t, continuous) =>
continuous
|> Continuous.T.scaleBy(~scale=1.0 -. discreteProbabilityMassFraction);
let toScaledDiscrete = ({discrete, discreteProbabilityMassFraction}: t) =>
Some(
discrete
|> Discrete.T.scaleBy(~scale=discreteProbabilityMassFraction),
);
let scaleDiscrete = ({discreteProbabilityMassFraction}: t, disrete) =>
disrete |> Discrete.T.scaleBy(~scale=discreteProbabilityMassFraction);
let toScaledContinuous = ({continuous} as t: t) =>
Some(scaleContinuous(t, continuous));
let toScaledDiscrete = ({discrete} as t: t) =>
Some(scaleDiscrete(t, discrete));
// TODO: Add these two directly, once interpolation is added.
let integral = (~cache, t) => {
// let cont = scaledContinuousComponent(t);
// let discrete = scaledDiscreteComponent(t);
cache |> E.O.toExt("");
let integral =
(
~cache,
{continuous, discrete, discreteProbabilityMassFraction} as t: t,
) => {
cache
|> E.O.default(
{
let cont =
continuous
|> Continuous.T.Integral.get(~cache=None)
|> scaleContinuous(t);
let dist =
discrete
|> Discrete.T.Integral.get(~cache=None)
|> Continuous.T.scaleBy(
~scale=discreteProbabilityMassFraction,
);
dist;
},
);
};
let integralSum =
@ -323,7 +358,7 @@ module Shape = {
);
let minX = (t: t) =>
mapToAll(t, (Mixed.T.minX, Discrete.T.minX, Continuous.T.minX));
let integral = (~cache, t: t) =>
let integral = (~cache, t: t) => {
mapToAll(
t,
(
@ -332,6 +367,7 @@ module Shape = {
Continuous.T.Integral.get(~cache),
),
);
};
let integralSum = (~cache, t: t) =>
mapToAll(
t,

View File

@ -14,6 +14,11 @@ type xyShape = {
ys: array(float),
};
let foo = {xs: [|1., 2., 5.|], ys: [|1., 2., 3.|]};
let answer = {xs: [|1., 2., 2., 5., 5.|], ys: [|1., 1., 2., 2., 3.|]};
let toStepwise = (xyShape: xyShape) => {};
type interpolationMethod = [ | `Stepwise | `Linear];
type continuousShape = {

View File

@ -15,8 +15,7 @@ let make =
unit,
};
let toComplexPower =
(~sampleCount, t: genericDistribution): option(complexPower) => {
let toComplexPower = (~sampleCount, t: genericDistribution) => {
let shape =
switch (t.generationSource) {
| GuesstimatorString(s) =>

View File

@ -19,8 +19,24 @@ let zip = t => Belt.Array.zip(t.xs, t.ys);
let fmap = (t: t, y): t => {xs: t.xs, ys: t.ys |> E.A.fmap(y)};
let fromArray = ((xs, ys)): t => {xs, ys};
let fromArrays = (xs, ys): t => {xs, ys};
let pointwiseMap = (fn, t: t): t => {xs: t.xs, ys: t.ys |> E.A.fmap(fn)};
let intersperce = (t1: t, t2: t) => {
let foo: ref(array((float, float))) = ref([||]);
let t1 = zip(t1);
let t2 = zip(t2);
Belt.Array.forEachWithIndex(t1, (i, item) => {
switch (Belt.Array.get(t2, i)) {
| Some(r) => foo := E.A.append(foo^, [|item, r|])
| None => foo := E.A.append(foo^, [|item|])
}
});
foo^ |> Belt.Array.unzip |> fromArray;
};
let scaleCdfTo = (~scaleTo=1., t: t) =>
switch (_lastElement(t.ys)) {
| Some(n) =>
@ -35,9 +51,6 @@ let yFold = (fn, t: t) => {
let ySum = yFold((a, b) => a +. b);
let fromArray = ((xs, ys)): t => {xs, ys};
let fromArrays = (xs, ys): t => {xs, ys};
let _transverse = fn =>
Belt.Array.reduce(_, [||], (items, (x, y)) =>
switch (_lastElement(items)) {
@ -68,6 +81,12 @@ module Range = {
let rangeAreaAssumingSteps = (((lastX, lastY), (nextX, _)): zippedRange) =>
(nextX -. lastX) *. lastY;
let rangePointAssumingSteps =
(((lastX, lastY), (nextX, nextY)): zippedRange) => (
nextX,
lastY,
);
let rangeAreaAssumingTriangles =
(((lastX, lastY), (nextX, nextY)): zippedRange) =>
(nextX -. lastX) *. (lastY +. nextY) /. 2.;
@ -93,6 +112,15 @@ module Range = {
|> E.O.fmap(accumulateYs);
let derivative = mapYsBasedOnRanges(delta_y_over_delta_x);
let stepsToContinuous = t =>
Belt.Array.zip(t.xs, t.ys)
|> E.A.toRanges
|> E.R.toOption
|> E.O.fmap(r => r |> Belt.Array.map(_, rangePointAssumingSteps))
|> E.O.fmap(Belt.Array.unzip)
|> E.O.fmap(fromArray)
|> E.O.fmap(intersperce(t));
};
let findY = CdfLibrary.Distribution.findY;