Fix rendering of uniforms; add normalization constant in convolution code
This commit is contained in:
parent
89e07dad86
commit
8d09cf9beb
|
@ -146,7 +146,6 @@ module DemoDist = {
|
||||||
(),
|
(),
|
||||||
);
|
);
|
||||||
let response = DistPlusRenderer.run(inputs);
|
let response = DistPlusRenderer.run(inputs);
|
||||||
Js.log(response);
|
|
||||||
switch (RenderTypes.DistPlusRenderer.Outputs.distplus(response)) {
|
switch (RenderTypes.DistPlusRenderer.Outputs.distplus(response)) {
|
||||||
| Some(distPlus) => <DistPlusPlot distPlus />
|
| Some(distPlus) => <DistPlusPlot distPlus />
|
||||||
| _ =>
|
| _ =>
|
||||||
|
@ -172,7 +171,7 @@ let make = () => {
|
||||||
~onSubmit=({state}) => {None},
|
~onSubmit=({state}) => {None},
|
||||||
~initialState={
|
~initialState={
|
||||||
//guesstimatorString: "mm(normal(-10, 2), uniform(18, 25), lognormal({mean: 10, stdev: 8}), triangular(31,40,50))",
|
//guesstimatorString: "mm(normal(-10, 2), uniform(18, 25), lognormal({mean: 10, stdev: 8}), triangular(31,40,50))",
|
||||||
guesstimatorString: "truncate(normal(100, 60), 50, 100)",
|
guesstimatorString: "uniform(1,2) * uniform(2, 3)", // , triangular(30, 40, 60)
|
||||||
domainType: "Complete",
|
domainType: "Complete",
|
||||||
xPoint: "50.0",
|
xPoint: "50.0",
|
||||||
xPoint2: "60.0",
|
xPoint2: "60.0",
|
||||||
|
|
|
@ -139,8 +139,8 @@ let combineShapesContinuousContinuous =
|
||||||
// converts the variances and means of the two inputs into the variance of the output
|
// converts the variances and means of the two inputs into the variance of the output
|
||||||
let combineVariancesFn =
|
let combineVariancesFn =
|
||||||
switch (op) {
|
switch (op) {
|
||||||
| `Add => ((v1, v2, m1, m2) => v1 +. v2)
|
| `Add => ((v1, v2, _, _) => v1 +. v2)
|
||||||
| `Subtract => ((v1, v2, m1, m2) => v1 +. v2)
|
| `Subtract => ((v1, v2, _, _) => v1 +. v2)
|
||||||
| `Multiply => (
|
| `Multiply => (
|
||||||
(v1, v2, m1, m2) => v1 *. v2 +. v1 *. m2 ** 2. +. v2 *. m1 ** 2.
|
(v1, v2, m1, m2) => v1 *. v2 +. v1 *. m2 ** 2. +. v2 *. m1 ** 2.
|
||||||
)
|
)
|
||||||
|
@ -176,8 +176,8 @@ let combineShapesContinuousContinuous =
|
||||||
let _ = Belt.Array.set(means, k, mean);
|
let _ = Belt.Array.set(means, k, mean);
|
||||||
let _ = Belt.Array.set(variances, k, variance);
|
let _ = Belt.Array.set(variances, k, variance);
|
||||||
// update bounds
|
// update bounds
|
||||||
let minX = mean -. variance *. 1.644854;
|
let minX = mean -. 2. *. sqrt(variance) *. 1.644854;
|
||||||
let maxX = mean +. variance *. 1.644854;
|
let maxX = mean +. 2. *. sqrt(variance) *. 1.644854;
|
||||||
if (minX < outputMinX^) {
|
if (minX < outputMinX^) {
|
||||||
outputMinX := minX;
|
outputMinX := minX;
|
||||||
};
|
};
|
||||||
|
@ -193,11 +193,11 @@ let combineShapesContinuousContinuous =
|
||||||
let outputXs: array(float) = E.A.Floats.range(outputMinX^, outputMaxX^, nOut);
|
let outputXs: array(float) = E.A.Floats.range(outputMinX^, outputMaxX^, nOut);
|
||||||
let outputYs: array(float) = Belt.Array.make(nOut, 0.0);
|
let outputYs: array(float) = Belt.Array.make(nOut, 0.0);
|
||||||
// now, for each of the outputYs, accumulate from a Gaussian kernel over each input point.
|
// now, for each of the outputYs, accumulate from a Gaussian kernel over each input point.
|
||||||
for (j in 0 to E.A.length(masses) - 1) {
|
for (j in 0 to E.A.length(masses) - 1) { // go through all of the result points
|
||||||
let _ = if (variances[j] > 0.) {
|
let _ = if (variances[j] > 0. && masses[j] > 0.) {
|
||||||
for (i in 0 to E.A.length(outputXs) - 1) {
|
for (i in 0 to E.A.length(outputXs) - 1) { // go through all of the target points
|
||||||
let dx = outputXs[i] -. means[j];
|
let dx = outputXs[i] -. means[j];
|
||||||
let contribution = masses[j] *. exp(-. (dx ** 2.) /. (2. *. variances[j]));
|
let contribution = masses[j] *. exp(-. (dx ** 2.) /. (2. *. variances[j])) /. (sqrt(2. *. 3.14159276 *. variances[j]));
|
||||||
let _ = Belt.Array.set(outputYs, i, outputYs[i] +. contribution);
|
let _ = Belt.Array.set(outputYs, i, outputYs[i] +. contribution);
|
||||||
();
|
();
|
||||||
};
|
};
|
||||||
|
|
|
@ -112,7 +112,7 @@ module Continuous = {
|
||||||
t2.knownIntegralSum,
|
t2.knownIntegralSum,
|
||||||
);
|
);
|
||||||
|
|
||||||
make(
|
let res = make(
|
||||||
`Linear,
|
`Linear,
|
||||||
XYShape.PointwiseCombination.combine(
|
XYShape.PointwiseCombination.combine(
|
||||||
~xsSelection=ALL_XS,
|
~xsSelection=ALL_XS,
|
||||||
|
@ -123,6 +123,7 @@ module Continuous = {
|
||||||
),
|
),
|
||||||
combinedIntegralSum,
|
combinedIntegralSum,
|
||||||
);
|
);
|
||||||
|
res
|
||||||
};
|
};
|
||||||
|
|
||||||
let toLinear = (t: t): option(t) => {
|
let toLinear = (t: t): option(t) => {
|
||||||
|
@ -219,7 +220,9 @@ module Continuous = {
|
||||||
let integral = (~cache, t) =>
|
let integral = (~cache, t) =>
|
||||||
if (t |> getShape |> XYShape.T.length > 0) {
|
if (t |> getShape |> XYShape.T.length > 0) {
|
||||||
switch (cache) {
|
switch (cache) {
|
||||||
| Some(cache) => cache
|
| Some(cache) => {
|
||||||
|
cache;
|
||||||
|
}
|
||||||
| None =>
|
| None =>
|
||||||
t
|
t
|
||||||
|> getShape
|
|> getShape
|
||||||
|
@ -254,7 +257,7 @@ module Continuous = {
|
||||||
|> updateKnownIntegralSum(Some(1.0));
|
|> updateKnownIntegralSum(Some(1.0));
|
||||||
};
|
};
|
||||||
|
|
||||||
let normalizedToContinuous = t => Some(t); // TODO: this should be normalized
|
let normalizedToContinuous = t => Some(t |> normalize);
|
||||||
let normalizedToDiscrete = _ => None;
|
let normalizedToDiscrete = _ => None;
|
||||||
|
|
||||||
let mean = (t: t) => {
|
let mean = (t: t) => {
|
||||||
|
@ -1059,18 +1062,17 @@ module Shape = {
|
||||||
Continuous.T.normalizedToContinuous,
|
Continuous.T.normalizedToContinuous,
|
||||||
));
|
));
|
||||||
let minX = mapToAll((Mixed.T.minX, Discrete.T.minX, Continuous.T.minX));
|
let minX = mapToAll((Mixed.T.minX, Discrete.T.minX, Continuous.T.minX));
|
||||||
let integral = (~cache) => {
|
let integral = (~cache) =>
|
||||||
mapToAll((
|
mapToAll((
|
||||||
Mixed.T.Integral.get(~cache),
|
Mixed.T.Integral.get(~cache=None),
|
||||||
Discrete.T.Integral.get(~cache),
|
Discrete.T.Integral.get(~cache=None),
|
||||||
Continuous.T.Integral.get(~cache),
|
Continuous.T.Integral.get(~cache=None),
|
||||||
));
|
));
|
||||||
};
|
|
||||||
let integralEndY = (~cache) =>
|
let integralEndY = (~cache) =>
|
||||||
mapToAll((
|
mapToAll((
|
||||||
Mixed.T.Integral.sum(~cache),
|
Mixed.T.Integral.sum(~cache=None),
|
||||||
Discrete.T.Integral.sum(~cache),
|
Discrete.T.Integral.sum(~cache),
|
||||||
Continuous.T.Integral.sum(~cache),
|
Continuous.T.Integral.sum(~cache=None),
|
||||||
));
|
));
|
||||||
let integralXtoY = (~cache, f) => {
|
let integralXtoY = (~cache, f) => {
|
||||||
mapToAll((
|
mapToAll((
|
||||||
|
@ -1178,7 +1180,6 @@ module DistPlus = {
|
||||||
|
|
||||||
let normalize = (t: t): t => {
|
let normalize = (t: t): t => {
|
||||||
let normalizedShape = t |> toShape |> Shape.T.normalize;
|
let normalizedShape = t |> toShape |> Shape.T.normalize;
|
||||||
|
|
||||||
t |> updateShape(normalizedShape);
|
t |> updateShape(normalizedShape);
|
||||||
// TODO: also adjust for domainIncludedProbabilityMass here.
|
// TODO: also adjust for domainIncludedProbabilityMass here.
|
||||||
};
|
};
|
||||||
|
@ -1190,7 +1191,6 @@ module DistPlus = {
|
||||||
t |> updateShape(truncatedShape);
|
t |> updateShape(truncatedShape);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: replace this with
|
|
||||||
let normalizedToContinuous = (t: t) => {
|
let normalizedToContinuous = (t: t) => {
|
||||||
t
|
t
|
||||||
|> toShape
|
|> toShape
|
||||||
|
@ -1236,8 +1236,10 @@ module DistPlus = {
|
||||||
: t =>
|
: t =>
|
||||||
Shape.T.mapY(~knownIntegralSumFn, fn, shape) |> updateShape(_, t);
|
Shape.T.mapY(~knownIntegralSumFn, fn, shape) |> updateShape(_, t);
|
||||||
|
|
||||||
let integralEndY = (~cache as _, t: t) =>
|
// get the total of everything
|
||||||
|
let integralEndY = (~cache as _, t: t) => {
|
||||||
Shape.T.Integral.sum(~cache=Some(t.integralCache), toShape(t));
|
Shape.T.Integral.sum(~cache=Some(t.integralCache), toShape(t));
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Fix this below, obviously. Adjust for limits
|
// TODO: Fix this below, obviously. Adjust for limits
|
||||||
let integralXtoY = (~cache as _, f, t: t) => {
|
let integralXtoY = (~cache as _, f, t: t) => {
|
||||||
|
@ -1247,8 +1249,9 @@ module DistPlus = {
|
||||||
|
|
||||||
// TODO: This part is broken when there is a limit, if this is supposed to be taken into account.
|
// TODO: This part is broken when there is a limit, if this is supposed to be taken into account.
|
||||||
let integralYtoX = (~cache as _, f, t: t) => {
|
let integralYtoX = (~cache as _, f, t: t) => {
|
||||||
Shape.T.Integral.yToX(~cache=Some(t.integralCache), f, toShape(t));
|
Shape.T.Integral.yToX(~cache=None, f, toShape(t));
|
||||||
};
|
};
|
||||||
|
|
||||||
let mean = (t: t) => {
|
let mean = (t: t) => {
|
||||||
Shape.T.mean(t.shape);
|
Shape.T.mean(t.shape);
|
||||||
};
|
};
|
||||||
|
|
|
@ -168,8 +168,11 @@ module Normalize = {
|
||||||
let rec operationToLeaf =
|
let rec operationToLeaf =
|
||||||
(toLeaf, renderParams, t: node): result(node, string) => {
|
(toLeaf, renderParams, t: node): result(node, string) => {
|
||||||
switch (t) {
|
switch (t) {
|
||||||
| `RenderedDist(s) =>
|
| `RenderedDist(s) => {
|
||||||
Ok(`RenderedDist(Distributions.Shape.T.normalize(s)))
|
Js.log2("normed", Distributions.Shape.T.normalize(s));
|
||||||
|
//Js.log2("normed integral", Distributions.Shape.T.normalize(s)));
|
||||||
|
Ok(`RenderedDist(Distributions.Shape.T.normalize(s)));
|
||||||
|
}
|
||||||
| `SymbolicDist(_) => Ok(t)
|
| `SymbolicDist(_) => Ok(t)
|
||||||
| _ =>
|
| _ =>
|
||||||
t
|
t
|
||||||
|
|
|
@ -258,11 +258,11 @@ module T = {
|
||||||
(~xSelection: [ | `Linear | `ByWeight]=`Linear, dist: symbolicDist, n) => {
|
(~xSelection: [ | `Linear | `ByWeight]=`Linear, dist: symbolicDist, n) => {
|
||||||
switch (xSelection, dist) {
|
switch (xSelection, dist) {
|
||||||
| (`Linear, _) => E.A.Floats.range(min(dist), max(dist), n)
|
| (`Linear, _) => E.A.Floats.range(min(dist), max(dist), n)
|
||||||
/* | (`ByWeight, `Uniform(n)) =>
|
| (`ByWeight, `Uniform(n)) =>
|
||||||
// In `ByWeight mode, uniform distributions get special treatment because we need two x's
|
// In `ByWeight mode, uniform distributions get special treatment because we need two x's
|
||||||
// on either side for proper rendering (just left and right of the discontinuities).
|
// on either side for proper rendering (just left and right of the discontinuities).
|
||||||
let dx = 0.00001 *. (n.high -. n.low);
|
let dx = 0.00001 *. (n.high -. n.low);
|
||||||
[|n.low -. dx, n.low +. dx, n.high -. dx, n.high +. dx|]; */
|
[|n.low -. dx, n.low +. dx, n.high -. dx, n.high +. dx|];
|
||||||
| (`ByWeight, _) =>
|
| (`ByWeight, _) =>
|
||||||
let ys = E.A.Floats.range(minCdfValue, maxCdfValue, n);
|
let ys = E.A.Floats.range(minCdfValue, maxCdfValue, n);
|
||||||
ys |> E.A.fmap(y => inv(y, dist));
|
ys |> E.A.fmap(y => inv(y, dist));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user