diff --git a/packages/components/src/components/FunctionChart.tsx b/packages/components/src/components/FunctionChart.tsx index bb5a9e24..eeca509c 100644 --- a/packages/components/src/components/FunctionChart.tsx +++ b/packages/components/src/components/FunctionChart.tsx @@ -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 = ({ } }; 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 ( + + ); + case "number": + return ( + + ); + default: + return ( + + There is no function visualization for this type of function + + ); + } + } + case "Error": { return ( - - ); - case "number": - return ( - - ); - case "Error": - return ( - The function failed to be run - ); - default: - return ( - - There is no function visualization for this type of function - + The function failed to be run {errorValueToString(validResult.value)} ); + } } }; diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/KdeLibrary.js b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/KdeLibrary.js index 9cc75b39..ad1b3c40 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/KdeLibrary.js +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/KdeLibrary.js @@ -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 = { diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res index ec2bf0d0..2a72ac4f 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res @@ -11,7 +11,7 @@ module Internals = { type outputs = { continuousParseParams: option, - pointSetDist: option, + pointSetDist: result, } } @@ -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 }