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,38 +35,42 @@ export const FunctionChart: React.FC<FunctionChartProps> = ({
}
};
let validResult = getValidResult();
let resultType = validResult.tag === "Ok" ? validResult.value.tag : "Error";
let component = () => {
switch (resultType) {
case "distribution":
switch (validResult.tag) {
case "Ok": {
switch (validResult.value.tag) {
case "distribution":
return (
<FunctionChart1Dist
fn={fn}
chartSettings={chartSettings}
environment={environment}
height={height}
/>
);
case "number":
return (
<FunctionChart1Number
fn={fn}
chartSettings={chartSettings}
environment={environment}
height={height}
/>
);
default:
return (
<ErrorBox heading="No Viewer">
There is no function visualization for this type of function
</ErrorBox>
);
}
}
case "Error": {
return (
<FunctionChart1Dist
fn={fn}
chartSettings={chartSettings}
environment={environment}
height={height}
/>
);
case "number":
return (
<FunctionChart1Number
fn={fn}
chartSettings={chartSettings}
environment={environment}
height={height}
/>
);
case "Error":
return (
<ErrorBox heading="Error">The function failed to be run</ErrorBox>
);
default:
return (
<ErrorBox heading="No Viewer">
There is no function visualization for this type of function
</ErrorBox>
<ErrorBox heading="Error">The function failed to be run {errorValueToString(validResult.value)}</ErrorBox>
);
}
}
};

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);
// 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;
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) };
// 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,8 +57,9 @@ module Internals = {
xWidthToUnitWidth(samples, outputXYPoints, suggestedXWidth)
}
let kde = (~samples, ~outputXYPoints, width) =>
let kde = (~samples, ~outputXYPoints, width) => {
KDE.normalSampling(samples, outputXYPoints, width)
}
}
}
@ -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(
~samples=_,
~outputXYPoints=samplingInputs.outputXYPoints,
Internals.T.formatUnitWidth(usedUnitWidth),
)
|> Continuous.make
|> (r => Some((r, samplingStats)))
let foo =
continuousPart |> Internals.T.kde(
~samples=_,
~outputXYPoints=samplingInputs.outputXYPoints,
Internals.T.formatUnitWidth(usedUnitWidth),
)
foo->E.R2.fmap(r => (Continuous.make(r), samplingStats))
}
: None
: Error("Bad Stuff")
let pointSetDist = MixedShapeBuilder.buildSimple(
~continuous=pdf |> E.O.fmap(fst),
~discrete=Some(discrete),
)
let pointSetDist =
pdf |> E.R2.bind(_pdf =>
MixedShapeBuilder.buildSimple(
~continuous=Some(fst(_pdf)),
~discrete=Some(discrete),
) |> E.O.toResult("BadMan")
)
/*
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 samplesParse: Internals.Types.outputs = {
continuousParseParams: pdf |> E.O.fmap(snd),
pointSetDist: normalizedPointSet,
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 normalized = PointSetDist.T.normalize(pointSetDist)
let samplesParse: Internals.Types.outputs = {
continuousParseParams: snd(pdf)->Some,
pointSetDist: Ok(PointSetDist.T.normalize(pointSetDist)),
}
Ok(samplesParse)
}
| Error(r) => Error(r)
}
}
| Error(r) => Error(r)
}
samplesParse
foo
}