WIP for pdf fix

This commit is contained in:
Ozzie Gooen 2022-05-28 22:01:46 -04:00
parent ba34c1abf1
commit 33487afba8
3 changed files with 96 additions and 64 deletions

View File

@ -1,5 +1,5 @@
import * as React from "react";
import { lambdaValue, environment, runForeign } from "@quri/squiggle-lang";
import { lambdaValue, environment, runForeign, errorValueToString } from "@quri/squiggle-lang";
import { FunctionChart1Dist } from "./FunctionChart1Dist";
import { FunctionChart1Number } from "./FunctionChart1Number";
import { ErrorBox } from "./ErrorBox";
@ -35,10 +35,11 @@ export const FunctionChart: React.FC<FunctionChartProps> = ({
}
};
let validResult = getValidResult();
let resultType = validResult.tag === "Ok" ? validResult.value.tag : "Error";
let component = () => {
switch (resultType) {
switch (validResult.tag) {
case "Ok": {
switch (validResult.value.tag) {
case "distribution":
return (
<FunctionChart1Dist
@ -57,10 +58,6 @@ export const FunctionChart: React.FC<FunctionChartProps> = ({
height={height}
/>
);
case "Error":
return (
<ErrorBox heading="Error">The function failed to be run</ErrorBox>
);
default:
return (
<ErrorBox heading="No Viewer">
@ -68,6 +65,13 @@ export const FunctionChart: React.FC<FunctionChartProps> = ({
</ErrorBox>
);
}
}
case "Error": {
return (
<ErrorBox heading="Error">The function failed to be run {errorValueToString(validResult.value)}</ErrorBox>
);
}
}
};
return component();

View File

@ -16,17 +16,23 @@ const samplesToContinuousPdf = (
_samples = _.filter(_samples, (r) => r < max);
}
console.log("19 line", _samples);
// The pdf that's created from this function is not a pdf but a pmf. y values
// being probability mass and not density.
// This is awkward, because our code assumes later that y is a density
let pdf = pdfast.create(_samples, { size, width });
console.log("24 line", pdf);
if (pdf.length < 2) {
return { xs: [], ys: [] };
} else {
// To convert this to a density, we need to find the step size. This is kept
// constant for all y values
let stepSize = pdf[1].x - pdf[0].x;
// We then adjust the y values to density
return { xs: pdf.map((r) => r.x), ys: pdf.map((r) => r.y / stepSize) };
}
};
module.exports = {

View File

@ -11,7 +11,7 @@ module Internals = {
type outputs = {
continuousParseParams: option<samplingStats>,
pointSetDist: option<PointSetTypes.pointSetDist>,
pointSetDist: result<PointSetTypes.pointSetDist, string>,
}
}
@ -32,8 +32,13 @@ module Internals = {
}
module KDE = {
let normalSampling = (samples, outputXYPoints, kernelWidth) =>
samples |> JS.samplesToContinuousPdf(_, outputXYPoints, kernelWidth) |> JS.jsToDist
let normalSampling = (samples, outputXYPoints, kernelWidth): result<
PointSetTypes.xyShape,
string,
> => {
let foo = samples |> JS.samplesToContinuousPdf(_, outputXYPoints, kernelWidth) |> JS.jsToDist
Ok(foo)
}
}
module T = {
@ -52,10 +57,11 @@ module Internals = {
xWidthToUnitWidth(samples, outputXYPoints, suggestedXWidth)
}
let kde = (~samples, ~outputXYPoints, width) =>
let kde = (~samples, ~outputXYPoints, width) => {
KDE.normalSampling(samples, outputXYPoints, width)
}
}
}
let toPointSetDist = (
~samples: Internals.T.t,
@ -68,6 +74,7 @@ let toPointSetDist = (
samples,
~minDiscreteWeight=minDiscreteToKeep,
)
Js.log3("Split", continuousPart, discretePart)
let length = samples |> E.A.length |> float_of_int
let discrete: PointSetTypes.discreteShape =
discretePart
@ -99,34 +106,49 @@ let toPointSetDist = (
bandwidthXImplemented: usedWidth,
bandwidthUnitImplemented: usedUnitWidth,
}
continuousPart
|> Internals.T.kde(
let foo =
continuousPart |> Internals.T.kde(
~samples=_,
~outputXYPoints=samplingInputs.outputXYPoints,
Internals.T.formatUnitWidth(usedUnitWidth),
)
|> Continuous.make
|> (r => Some((r, samplingStats)))
foo->E.R2.fmap(r => (Continuous.make(r), samplingStats))
}
: None
: Error("Bad Stuff")
let pointSetDist = MixedShapeBuilder.buildSimple(
~continuous=pdf |> E.O.fmap(fst),
let pointSetDist =
pdf |> E.R2.bind(_pdf =>
MixedShapeBuilder.buildSimple(
~continuous=Some(fst(_pdf)),
~discrete=Some(discrete),
) |> E.O.toResult("BadMan")
)
let foo = switch pdf {
| Ok(pdf) => {
let pointSetDist =
MixedShapeBuilder.buildSimple(
~continuous=Some(fst(pdf)),
~discrete=Some(discrete),
) |> E.O.toResult("BadMan")
switch pointSetDist {
| Ok(pointSetDist) => {
/*
I'm surprised that this doesn't come out normalized. My guess is that the KDE library
we're using is standardizing on something else. If we ever change that library, we should
check to see if we still need to do this.
*/
let normalizedPointSet = pointSetDist->E.O2.fmap(PointSetDist.T.normalize)
let normalized = PointSetDist.T.normalize(pointSetDist)
let samplesParse: Internals.Types.outputs = {
continuousParseParams: pdf |> E.O.fmap(snd),
pointSetDist: normalizedPointSet,
continuousParseParams: snd(pdf)->Some,
pointSetDist: Ok(PointSetDist.T.normalize(pointSetDist)),
}
samplesParse
Ok(samplesParse)
}
| Error(r) => Error(r)
}
}
| Error(r) => Error(r)
}
foo
}