WIP for pdf fix
This commit is contained in:
parent
ba34c1abf1
commit
33487afba8
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user