From b2b51c8f462d2b2a2407ac9aadc9e4055afdac1b Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 15 May 2022 10:52:35 -0400 Subject: [PATCH 01/15] Added sampleN to interface --- .../src/rescript/Distributions/DistributionOperation.res | 1 + .../src/rescript/Distributions/DistributionOperation.resi | 1 + .../ReducerInterface/ReducerInterface_GenericDistribution.res | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.res index 80a53eb8..da4c010a 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.res @@ -18,6 +18,7 @@ type outputType = | Dist(genericDist) | Float(float) | String(string) + | FloatArray(array) | Bool(bool) | GenDistError(error) diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.resi b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.resi index 200be7d7..a8d61a9a 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.resi @@ -14,6 +14,7 @@ type outputType = | Dist(genericDist) | Float(float) | String(string) + | FloatArray(array) | Bool(bool) | GenDistError(error) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index 8dae2586..37bffeef 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -216,6 +216,9 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall, _environment) ->E.R.bind(r => r(f1, f2, f3)) ->SymbolicConstructors.symbolicResultToOutput | ("sample", [EvDistribution(dist)]) => Helpers.toFloatFn(#Sample, dist) + | ("sampleN", [EvDistribution(dist), EvNumber(n)]) => Some( + FloatArray(GenericDist.sampleN(dist, Belt.Int.fromFloat(n))), + ) | ("mean", [EvDistribution(dist)]) => Helpers.toFloatFn(#Mean, dist) | ("integralSum", [EvDistribution(dist)]) => Helpers.toFloatFn(#IntegralSum, dist) | ("toString", [EvDistribution(dist)]) => Helpers.toStringFn(ToString, dist) @@ -315,6 +318,7 @@ let genericOutputToReducerValue = (o: DistributionOperation.outputType): result< | Float(d) => Ok(EvNumber(d)) | String(d) => Ok(EvString(d)) | Bool(d) => Ok(EvBool(d)) + | FloatArray(d) => Ok(EvArray(d |> E.A.fmap(r =>ReducerInterface_ExpressionValue.EvNumber(r)))) | GenDistError(err) => Error(REDistributionError(err)) } From 4676026aa0e26670ef23860f7cef977591de9bb7 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 15 May 2022 10:58:29 -0400 Subject: [PATCH 02/15] Ran formatter --- packages/squiggle-lang/package.json | 1 - .../ReducerInterface_GenericDistribution.res | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index d21f2eb6..c1705471 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -33,7 +33,6 @@ "Rescript" ], "author": "Quantified Uncertainty Research Institute", - "license": "MIT", "dependencies": { "rescript": "^9.1.4", "jstat": "^1.9.5", diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index 448d7f1b..f36c21bf 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -222,9 +222,8 @@ let dispatchToGenericOutput = ( ->E.R.bind(r => r(f1, f2, f3)) ->SymbolicConstructors.symbolicResultToOutput | ("sample", [EvDistribution(dist)]) => Helpers.toFloatFn(#Sample, dist, ~env) - | ("sampleN", [EvDistribution(dist), EvNumber(n)]) => Some( - FloatArray(GenericDist.sampleN(dist, Belt.Int.fromFloat(n))), - ) + | ("sampleN", [EvDistribution(dist), EvNumber(n)]) => + Some(FloatArray(GenericDist.sampleN(dist, Belt.Int.fromFloat(n)))) | ("mean", [EvDistribution(dist)]) => Helpers.toFloatFn(#Mean, dist, ~env) | ("integralSum", [EvDistribution(dist)]) => Helpers.toFloatFn(#IntegralSum, dist, ~env) | ("toString", [EvDistribution(dist)]) => Helpers.toStringFn(ToString, dist, ~env) @@ -339,7 +338,7 @@ let genericOutputToReducerValue = (o: DistributionOperation.outputType): result< | Float(d) => Ok(EvNumber(d)) | String(d) => Ok(EvString(d)) | Bool(d) => Ok(EvBool(d)) - | FloatArray(d) => Ok(EvArray(d |> E.A.fmap(r =>ReducerInterface_ExpressionValue.EvNumber(r)))) + | FloatArray(d) => Ok(EvArray(d |> E.A.fmap(r => ReducerInterface_ExpressionValue.EvNumber(r)))) | GenDistError(err) => Error(REDistributionError(err)) } From b015c20fa4b36aa557d97ffa184762d45fd4cb14 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 15 May 2022 14:39:50 -0400 Subject: [PATCH 03/15] Cached FunctionChart percentiles calculation --- .../src/components/FunctionChart.tsx | 142 ++++++++++-------- .../src/components/SquiggleChart.tsx | 6 +- .../src/components/SquiggleEditor.tsx | 2 +- .../src/stories/SquiggleChart.stories.mdx | 13 ++ 4 files changed, 93 insertions(+), 70 deletions(-) diff --git a/packages/components/src/components/FunctionChart.tsx b/packages/components/src/components/FunctionChart.tsx index 2fd4587d..26a13c78 100644 --- a/packages/components/src/components/FunctionChart.tsx +++ b/packages/components/src/components/FunctionChart.tsx @@ -7,6 +7,8 @@ import { lambdaValue, environment, runForeign, + squiggleExpression, + errorValue, errorValueToString, } from "@quri/squiggle-lang"; import { createClassFromSpec } from "react-vega"; @@ -45,6 +47,23 @@ interface FunctionChartProps { environment: environment; } +type percentiles = { + x: number; + p1: number; + p5: number; + p10: number; + p20: number; + p30: number; + p40: number; + p50: number; + p60: number; + p70: number; + p80: number; + p90: number; + p95: number; + p99: number; +}[]; + export const FunctionChart: React.FC = ({ fn, chartSettings, @@ -58,7 +77,9 @@ export const FunctionChart: React.FC = ({ setMouseOverlay(NaN); } const signalListeners = { mousemove: handleHover, mouseout: handleOut }; - let mouseItem = runForeign(fn, [mouseOverlay], environment); + let mouseItem: result = !!mouseOverlay + ? runForeign(fn, [mouseOverlay], { sampleCount: 10000, xyPointLength: 1000 }) + : { tag: "Error", value: { tag: "REExpectedType", value: "Expected float, got NaN" } }; let showChart = mouseItem.tag === "Ok" && mouseItem.value.tag == "distribution" ? ( = ({ chartSettings.count ); type point = { x: number; value: result }; - let valueData: point[] = React.useMemo( - () => - data1.map((x) => { - let result = runForeign(fn, [x], environment); - if (result.tag === "Ok") { - if (result.value.tag == "distribution") { - return { x, value: { tag: "Ok", value: result.value.value } }; - } else { - return { - x, - value: { - tag: "Error", - value: - "Cannot currently render functions that don't return distributions", - }, - }; - } + + let getPercentiles: () => percentiles = () => { + let valueData:any = data1.map((x) => { + let result = runForeign(fn, [x], environment); + if (result.tag === "Ok") { + if (result.value.tag == "distribution") { + return { x, value: { tag: "Ok", value: result.value.value } }; } else { return { x, - value: { tag: "Error", value: errorValueToString(result.value) }, + value: { + tag: "Error", + value: + "Cannot currently render functions that don't return distributions", + }, }; } - }), - [environment, fn] - ); + } else { + return { + x, + value: { tag: "Error", value: errorValueToString(result.value) }, + }; + } + }); + let initialPartition: [ + { x: number; value: Distribution }[], + { x: number; value: string }[] + ] = [[], []]; + let [functionImage, errors] = valueData.reduce((acc, current) => { + if (current.value.tag === "Ok") { + acc[0].push({ x: current.x, value: current.value.value }); + } else { + acc[1].push({ x: current.x, value: current.value.value }); + } + return acc; + }, initialPartition); - let initialPartition: [ - { x: number; value: Distribution }[], - { x: number; value: string }[] - ] = [[], []]; - let [functionImage, errors] = valueData.reduce((acc, current) => { - if (current.value.tag === "Ok") { - acc[0].push({ x: current.x, value: current.value.value }); - } else { - acc[1].push({ x: current.x, value: current.value.value }); - } - return acc; - }, initialPartition); + let percentiles:percentiles = functionImage.map(({ x, value }) => { + let toPointSet: Distribution = unwrap(value.toPointSet()); + return { + x: x, + p1: unwrap(toPointSet.inv(0.01)), + p5: unwrap(toPointSet.inv(0.05)), + p10: unwrap(toPointSet.inv(0.12)), + p20: unwrap(toPointSet.inv(0.2)), + p30: unwrap(toPointSet.inv(0.3)), + p40: unwrap(toPointSet.inv(0.4)), + p50: unwrap(toPointSet.inv(0.5)), + p60: unwrap(toPointSet.inv(0.6)), + p70: unwrap(toPointSet.inv(0.7)), + p80: unwrap(toPointSet.inv(0.8)), + p90: unwrap(toPointSet.inv(0.9)), + p95: unwrap(toPointSet.inv(0.95)), + p99: unwrap(toPointSet.inv(0.99)), + }; + }); + return percentiles; + }; - let percentiles = functionImage.map(({ x, value }) => { - return { - x: x, - p1: unwrap(value.inv(0.01)), - p5: unwrap(value.inv(0.05)), - p10: unwrap(value.inv(0.12)), - p20: unwrap(value.inv(0.2)), - p30: unwrap(value.inv(0.3)), - p40: unwrap(value.inv(0.4)), - p50: unwrap(value.inv(0.5)), - p60: unwrap(value.inv(0.6)), - p70: unwrap(value.inv(0.7)), - p80: unwrap(value.inv(0.8)), - p90: unwrap(value.inv(0.9)), - p95: unwrap(value.inv(0.95)), - p99: unwrap(value.inv(0.99)), - }; - }); + let _getPercentiles = React.useMemo(getPercentiles, [environment, fn]) - let groupedErrors = _.groupBy(errors, (x) => x.value); return ( <> {showChart} - {_.entries(groupedErrors).map(([errorName, errorPoints]) => ( - - Values:{" "} - {errorPoints - .map((r, i) => ) - .reduce((a, b) => ( - <> - {a}, {b} - - ))} - - ))} ); }; diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index a54ac64d..b3b71e68 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -194,7 +194,7 @@ const SquiggleItem: React.FC = ({ ); } @@ -232,7 +232,7 @@ const ChartWrapper = styled.div` "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; `; -let defaultChartSettings = { start: 0, stop: 10, count: 100 }; +let defaultChartSettings = { start: 0, stop: 10, count: 20 }; export const SquiggleChart: React.FC = ({ squiggleString = "", environment, @@ -247,7 +247,7 @@ export const SquiggleChart: React.FC = ({ chartSettings = defaultChartSettings, }: SquiggleChartProps) => { let expressionResult = run(squiggleString, bindings, environment, jsImports); - let e = environment ? environment : defaultEnvironment; + let e = environment ? environment : { sampleCount: 100000, xyPointLength: 1000 }; let internal: JSX.Element; if (expressionResult.tag === "Ok") { let expression = expressionResult.value; diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index c4ac1876..a69f6ce2 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -56,7 +56,7 @@ export let SquiggleEditor: React.FC = ({ environment, diagramStart = 0, diagramStop = 10, - diagramCount = 100, + diagramCount = 20, onChange, bindings = defaultBindings, jsImports = defaultImports, diff --git a/packages/components/src/stories/SquiggleChart.stories.mdx b/packages/components/src/stories/SquiggleChart.stories.mdx index 54ed634d..9b4d3c83 100644 --- a/packages/components/src/stories/SquiggleChart.stories.mdx +++ b/packages/components/src/stories/SquiggleChart.stories.mdx @@ -153,6 +153,19 @@ to allow large and small numbers being printed cleanly. +## Functions + + + {Template.bind({})} + + + ## Records From 91ccd333e0fe19ef7ae933a5754bc5ccd9f0f469 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 15 May 2022 15:21:00 -0400 Subject: [PATCH 04/15] Minor refactors --- .../src/components/FunctionChart.tsx | 128 ++++++++++++++++-- .../src/components/SquiggleChart.tsx | 7 +- 2 files changed, 117 insertions(+), 18 deletions(-) diff --git a/packages/components/src/components/FunctionChart.tsx b/packages/components/src/components/FunctionChart.tsx index 26a13c78..32919d67 100644 --- a/packages/components/src/components/FunctionChart.tsx +++ b/packages/components/src/components/FunctionChart.tsx @@ -64,6 +64,81 @@ type percentiles = { p99: number; }[]; +type errors = _.Dictionary< + { + x: number; + value: string; + }[] +>; + +type point = { x: number; value: result }; + +let getPercentiles = ({ chartSettings, fn, environment }) => { + let data1 = _rangeByCount( + chartSettings.start, + chartSettings.stop, + chartSettings.count + ); + let valueData: point[] = data1.map((x) => { + let result = runForeign(fn, [x], environment); + if (result.tag === "Ok") { + if (result.value.tag == "distribution") { + return { x, value: { tag: "Ok", value: result.value.value } }; + } else { + return { + x, + value: { + tag: "Error", + value: + "Cannot currently render functions that don't return distributions", + }, + }; + } + } else { + return { + x, + value: { tag: "Error", value: errorValueToString(result.value) }, + }; + } + }); + let initialPartition: [ + { x: number; value: Distribution }[], + { x: number; value: string }[] + ] = [[], []]; + let [functionImage, errors] = valueData.reduce((acc, current) => { + if (current.value.tag === "Ok") { + acc[0].push({ x: current.x, value: current.value.value }); + } else { + acc[1].push({ x: current.x, value: current.value.value }); + } + return acc; + }, initialPartition); + let groupedErrors: errors = _.groupBy(errors, (x) => x.value); + let percentiles: percentiles = functionImage.map(({ x, value }) => { + // We convert it to to a pointSet distribution first, so that in case its a sample set + // distribution, it doesn't internally convert it to a pointSet distribution for every + // single inv() call. + let toPointSet: Distribution = unwrap(value.toPointSet()); + return { + x: x, + p1: unwrap(toPointSet.inv(0.01)), + p5: unwrap(toPointSet.inv(0.05)), + p10: unwrap(toPointSet.inv(0.12)), + p20: unwrap(toPointSet.inv(0.2)), + p30: unwrap(toPointSet.inv(0.3)), + p40: unwrap(toPointSet.inv(0.4)), + p50: unwrap(toPointSet.inv(0.5)), + p60: unwrap(toPointSet.inv(0.6)), + p70: unwrap(toPointSet.inv(0.7)), + p80: unwrap(toPointSet.inv(0.8)), + p90: unwrap(toPointSet.inv(0.9)), + p95: unwrap(toPointSet.inv(0.95)), + p99: unwrap(toPointSet.inv(0.99)), + }; + }); + return { percentiles, errors: groupedErrors }; +}; + export const FunctionChart: React.FC = ({ fn, chartSettings, @@ -78,8 +153,14 @@ export const FunctionChart: React.FC = ({ } const signalListeners = { mousemove: handleHover, mouseout: handleOut }; let mouseItem: result = !!mouseOverlay - ? runForeign(fn, [mouseOverlay], { sampleCount: 10000, xyPointLength: 1000 }) - : { tag: "Error", value: { tag: "REExpectedType", value: "Expected float, got NaN" } }; + ? runForeign(fn, [mouseOverlay], { + sampleCount: 10000, + xyPointLength: 1000, + }) + : { + tag: "Error", + value: { tag: "REExpectedType", value: "Expected float, got NaN" }, + }; let showChart = mouseItem.tag === "Ok" && mouseItem.value.tag == "distribution" ? ( = ({ ) : ( <> ); - let data1 = _rangeByCount( - chartSettings.start, - chartSettings.stop, - chartSettings.count - ); - type point = { x: number; value: result }; - let getPercentiles: () => percentiles = () => { - let valueData:any = data1.map((x) => { + let getPercentiles2: () => { + percentiles: percentiles; + errors: errors; + } = () => { + let data1 = _rangeByCount( + chartSettings.start, + chartSettings.stop, + chartSettings.count + ); + let valueData: point[] = data1.map((x) => { let result = runForeign(fn, [x], environment); if (result.tag === "Ok") { if (result.value.tag == "distribution") { @@ -133,8 +216,11 @@ export const FunctionChart: React.FC = ({ } return acc; }, initialPartition); - - let percentiles:percentiles = functionImage.map(({ x, value }) => { + let groupedErrors: errors = _.groupBy(errors, (x) => x.value); + let percentiles: percentiles = functionImage.map(({ x, value }) => { + // We convert it to to a pointSet distribution first, so that in case its a sample set + // distribution, it doesn't internally convert it to a pointSet distribution for every + // single inv() call. let toPointSet: Distribution = unwrap(value.toPointSet()); return { x: x, @@ -153,19 +239,31 @@ export const FunctionChart: React.FC = ({ p99: unwrap(toPointSet.inv(0.99)), }; }); - return percentiles; + return { percentiles, errors: groupedErrors }; }; - let _getPercentiles = React.useMemo(getPercentiles, [environment, fn]) + let _getPercentiles = React.useMemo(getPercentiles2, [environment, fn]); return ( <> {showChart} + {_.entries(_getPercentiles.errors).map(([errorName, errorPoints]) => ( + + Values:{" "} + {errorPoints + .map((r, i) => ) + .reduce((a, b) => ( + <> + {a}, {b} + + ))} + + ))} ); }; diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index b3b71e68..f3f1d9c6 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -10,7 +10,6 @@ import { jsImports, defaultImports, defaultBindings, - defaultEnvironment, } from "@quri/squiggle-lang"; import { NumberShower } from "./NumberShower"; import { DistributionChart } from "./DistributionChart"; @@ -194,7 +193,7 @@ const SquiggleItem: React.FC = ({ ); } @@ -233,6 +232,8 @@ const ChartWrapper = styled.div` `; let defaultChartSettings = { start: 0, stop: 10, count: 20 }; +let defaultEnvironment = { sampleCount: 10000, xyPointLength: 1000 }; + export const SquiggleChart: React.FC = ({ squiggleString = "", environment, @@ -247,7 +248,7 @@ export const SquiggleChart: React.FC = ({ chartSettings = defaultChartSettings, }: SquiggleChartProps) => { let expressionResult = run(squiggleString, bindings, environment, jsImports); - let e = environment ? environment : { sampleCount: 100000, xyPointLength: 1000 }; + let e = environment ? environment : defaultEnvironment; let internal: JSX.Element; if (expressionResult.tag === "Ok") { let expression = expressionResult.value; From 56728c7ea5bc8aed9fc25482b19764676cdffade Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 15 May 2022 15:23:58 -0400 Subject: [PATCH 05/15] Removed unneeded code --- .../src/components/FunctionChart.tsx | 74 +------------------ 1 file changed, 4 insertions(+), 70 deletions(-) diff --git a/packages/components/src/components/FunctionChart.tsx b/packages/components/src/components/FunctionChart.tsx index 32919d67..10f97b7d 100644 --- a/packages/components/src/components/FunctionChart.tsx +++ b/packages/components/src/components/FunctionChart.tsx @@ -173,76 +173,10 @@ export const FunctionChart: React.FC = ({ <> ); - let getPercentiles2: () => { - percentiles: percentiles; - errors: errors; - } = () => { - let data1 = _rangeByCount( - chartSettings.start, - chartSettings.stop, - chartSettings.count - ); - let valueData: point[] = data1.map((x) => { - let result = runForeign(fn, [x], environment); - if (result.tag === "Ok") { - if (result.value.tag == "distribution") { - return { x, value: { tag: "Ok", value: result.value.value } }; - } else { - return { - x, - value: { - tag: "Error", - value: - "Cannot currently render functions that don't return distributions", - }, - }; - } - } else { - return { - x, - value: { tag: "Error", value: errorValueToString(result.value) }, - }; - } - }); - let initialPartition: [ - { x: number; value: Distribution }[], - { x: number; value: string }[] - ] = [[], []]; - let [functionImage, errors] = valueData.reduce((acc, current) => { - if (current.value.tag === "Ok") { - acc[0].push({ x: current.x, value: current.value.value }); - } else { - acc[1].push({ x: current.x, value: current.value.value }); - } - return acc; - }, initialPartition); - let groupedErrors: errors = _.groupBy(errors, (x) => x.value); - let percentiles: percentiles = functionImage.map(({ x, value }) => { - // We convert it to to a pointSet distribution first, so that in case its a sample set - // distribution, it doesn't internally convert it to a pointSet distribution for every - // single inv() call. - let toPointSet: Distribution = unwrap(value.toPointSet()); - return { - x: x, - p1: unwrap(toPointSet.inv(0.01)), - p5: unwrap(toPointSet.inv(0.05)), - p10: unwrap(toPointSet.inv(0.12)), - p20: unwrap(toPointSet.inv(0.2)), - p30: unwrap(toPointSet.inv(0.3)), - p40: unwrap(toPointSet.inv(0.4)), - p50: unwrap(toPointSet.inv(0.5)), - p60: unwrap(toPointSet.inv(0.6)), - p70: unwrap(toPointSet.inv(0.7)), - p80: unwrap(toPointSet.inv(0.8)), - p90: unwrap(toPointSet.inv(0.9)), - p95: unwrap(toPointSet.inv(0.95)), - p99: unwrap(toPointSet.inv(0.99)), - }; - }); - return { percentiles, errors: groupedErrors }; - }; - - let _getPercentiles = React.useMemo(getPercentiles2, [environment, fn]); + let _getPercentiles = React.useMemo( + () => getPercentiles({ chartSettings, fn, environment }), + [environment, fn] + ); return ( <> From b63136080be2ebf0e8097b8bad19eb28e7d15153 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 15 May 2022 15:29:54 -0400 Subject: [PATCH 06/15] Formatting --- packages/components/src/components/SquiggleChart.tsx | 5 ++++- packages/components/src/stories/SquiggleChart.stories.mdx | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index f3f1d9c6..eb6214e2 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -193,7 +193,10 @@ const SquiggleItem: React.FC = ({ ); } diff --git a/packages/components/src/stories/SquiggleChart.stories.mdx b/packages/components/src/stories/SquiggleChart.stories.mdx index 9b4d3c83..9ad98ef0 100644 --- a/packages/components/src/stories/SquiggleChart.stories.mdx +++ b/packages/components/src/stories/SquiggleChart.stories.mdx @@ -154,6 +154,7 @@ to allow large and small numbers being printed cleanly. ## Functions + Date: Sun, 15 May 2022 15:58:37 -0400 Subject: [PATCH 07/15] Responded to CR --- .../src/components/FunctionChart.tsx | 54 +++++++++++-------- .../src/components/SquiggleChart.tsx | 2 +- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/packages/components/src/components/FunctionChart.tsx b/packages/components/src/components/FunctionChart.tsx index 10f97b7d..242bf719 100644 --- a/packages/components/src/components/FunctionChart.tsx +++ b/packages/components/src/components/FunctionChart.tsx @@ -74,12 +74,13 @@ type errors = _.Dictionary< type point = { x: number; value: result }; let getPercentiles = ({ chartSettings, fn, environment }) => { - let data1 = _rangeByCount( + let chartPointsToRender = _rangeByCount( chartSettings.start, chartSettings.stop, chartSettings.count ); - let valueData: point[] = data1.map((x) => { + + let chartPointsData: point[] = chartPointsToRender.map((x) => { let result = runForeign(fn, [x], environment); if (result.tag === "Ok") { if (result.value.tag == "distribution") { @@ -101,11 +102,13 @@ let getPercentiles = ({ chartSettings, fn, environment }) => { }; } }); + let initialPartition: [ { x: number; value: Distribution }[], { x: number; value: string }[] ] = [[], []]; - let [functionImage, errors] = valueData.reduce((acc, current) => { + + let [functionImage, errors] = chartPointsData.reduce((acc, current) => { if (current.value.tag === "Ok") { acc[0].push({ x: current.x, value: current.value.value }); } else { @@ -113,7 +116,9 @@ let getPercentiles = ({ chartSettings, fn, environment }) => { } return acc; }, initialPartition); + let groupedErrors: errors = _.groupBy(errors, (x) => x.value); + let percentiles: percentiles = functionImage.map(({ x, value }) => { // We convert it to to a pointSet distribution first, so that in case its a sample set // distribution, it doesn't internally convert it to a pointSet distribution for every @@ -123,7 +128,7 @@ let getPercentiles = ({ chartSettings, fn, environment }) => { x: x, p1: unwrap(toPointSet.inv(0.01)), p5: unwrap(toPointSet.inv(0.05)), - p10: unwrap(toPointSet.inv(0.12)), + p10: unwrap(toPointSet.inv(0.1)), p20: unwrap(toPointSet.inv(0.2)), p30: unwrap(toPointSet.inv(0.3)), p40: unwrap(toPointSet.inv(0.4)), @@ -136,6 +141,7 @@ let getPercentiles = ({ chartSettings, fn, environment }) => { p99: unwrap(toPointSet.inv(0.99)), }; }); + return { percentiles, errors: groupedErrors }; }; @@ -153,13 +159,13 @@ export const FunctionChart: React.FC = ({ } const signalListeners = { mousemove: handleHover, mouseout: handleOut }; let mouseItem: result = !!mouseOverlay - ? runForeign(fn, [mouseOverlay], { - sampleCount: 10000, - xyPointLength: 1000, - }) + ? runForeign(fn, [mouseOverlay], environment) : { tag: "Error", - value: { tag: "REExpectedType", value: "Expected float, got NaN" }, + value: { + tag: "REExpectedType", + value: "Hover x-coordinate returned NaN. Expected a number.", + }, }; let showChart = mouseItem.tag === "Ok" && mouseItem.value.tag == "distribution" ? ( @@ -173,7 +179,7 @@ export const FunctionChart: React.FC = ({ <> ); - let _getPercentiles = React.useMemo( + let getPercentilesMemoized = React.useMemo( () => getPercentiles({ chartSettings, fn, environment }), [environment, fn] ); @@ -181,23 +187,25 @@ export const FunctionChart: React.FC = ({ return ( <> {showChart} - {_.entries(_getPercentiles.errors).map(([errorName, errorPoints]) => ( - - Values:{" "} - {errorPoints - .map((r, i) => ) - .reduce((a, b) => ( - <> - {a}, {b} - - ))} - - ))} + {_.entries(getPercentilesMemoized.errors).map( + ([errorName, errorPoints]) => ( + + Values:{" "} + {errorPoints + .map((r, i) => ) + .reduce((a, b) => ( + <> + {a}, {b} + + ))} + + ) + )} ); }; diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index eb6214e2..ce562368 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -10,6 +10,7 @@ import { jsImports, defaultImports, defaultBindings, + defaultEnvironment, } from "@quri/squiggle-lang"; import { NumberShower } from "./NumberShower"; import { DistributionChart } from "./DistributionChart"; @@ -235,7 +236,6 @@ const ChartWrapper = styled.div` `; let defaultChartSettings = { start: 0, stop: 10, count: 20 }; -let defaultEnvironment = { sampleCount: 10000, xyPointLength: 1000 }; export const SquiggleChart: React.FC = ({ squiggleString = "", From 7216f8079f5a0154f2a29a387b254a1612409495 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 15 May 2022 18:27:25 -0400 Subject: [PATCH 08/15] First attempt at adding bernoulli --- packages/squiggle-lang/package.json | 11 +- .../SymbolicDist/SymbolicDist.res | 29 ++ .../SymbolicDist/SymbolicDistTypes.res | 3 + .../ReducerInterface_GenericDistribution.res | 3 +- .../src/rescript/Utility/Stdlib.res | 14 + .../src/rescript/Utility/stdlib.ts | 4 + yarn.lock | 335 +++++++++++++++++- 7 files changed, 390 insertions(+), 9 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/Utility/Stdlib.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/stdlib.ts diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index c1705471..579a5f31 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -34,27 +34,28 @@ ], "author": "Quantified Uncertainty Research Institute", "dependencies": { - "rescript": "^9.1.4", + "@stdlib/stats": "^0.0.13", "jstat": "^1.9.5", + "mathjs": "^10.5.2", "pdfast": "^0.2.0", - "mathjs": "^10.5.2" + "rescript": "^9.1.4" }, "devDependencies": { - "bisect_ppx": "^2.7.1", - "lodash": "^4.17.21", - "rescript-fast-check": "^1.1.1", "@glennsl/rescript-jest": "^0.9.0", "@istanbuljs/nyc-config-typescript": "^1.0.2", "@types/jest": "^27.5.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", + "bisect_ppx": "^2.7.1", "chalk": "^5.0.1", "codecov": "^3.8.3", "fast-check": "^2.25.0", "gentype": "^4.3.0", "jest": "^27.5.1", + "lodash": "^4.17.21", "moduleserve": "^0.9.1", "nyc": "^15.1.0", "reanalyze": "^2.19.0", + "rescript-fast-check": "^1.1.1", "ts-jest": "^27.1.4", "ts-loader": "^9.3.0", "ts-node": "^10.7.0", diff --git a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res index c925e39e..6c57430c 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res @@ -216,6 +216,25 @@ module Uniform = { } } +module Bernoulli = { + type t = bernoulli + let make = p => + p >= 0.0 && p <= 1.0 + ? Ok(#Bernoulli({p: p})) + : Error("Beta distribution parameters must be positive") + let pmf = (x, t: t) => Stdlib.Bernoulli.pmf(x, t.p) + let pdf = (x, t: t) => Stdlib.Bernoulli.pmf(x, t.p) + let cdf = (x, t: t) => Stdlib.Bernoulli.cdf(x, t.p) + let inv = (p, t: t) => Stdlib.Bernoulli.quantile(p, t.p) + let mean = (t: t) => Ok(Stdlib.Bernoulli.mean(t.p)) + let sample = (t: t) => { + let s = Uniform.sample(({low: 0.0, high: 1.0})); + inv(s,t) + } + let toString = ({p}: t) => j`Bernoulli($p)` +} + + module Gamma = { type t = gamma let make = (shape: float, scale: float) => { @@ -278,6 +297,7 @@ module T = { | #Uniform(n) => Uniform.pdf(x, n) | #Beta(n) => Beta.pdf(x, n) | #Float(n) => Float.pdf(x, n) + | #Bernoulli(n) => Bernoulli.pdf(x, n) } let cdf = (x, dist) => @@ -291,6 +311,7 @@ module T = { | #Uniform(n) => Uniform.cdf(x, n) | #Beta(n) => Beta.cdf(x, n) | #Float(n) => Float.cdf(x, n) + | #Bernoulli(n) => Bernoulli.cdf(x, n) } let inv = (x, dist) => @@ -304,6 +325,7 @@ module T = { | #Uniform(n) => Uniform.inv(x, n) | #Beta(n) => Beta.inv(x, n) | #Float(n) => Float.inv(x, n) + | #Bernoulli(n) => Bernoulli.inv(x, n) } let sample: symbolicDist => float = x => @@ -317,6 +339,7 @@ module T = { | #Uniform(n) => Uniform.sample(n) | #Beta(n) => Beta.sample(n) | #Float(n) => Float.sample(n) + | #Bernoulli(n) => Bernoulli.sample(n) } let doN = (n, fn) => { @@ -340,6 +363,7 @@ module T = { | #Uniform(n) => Uniform.toString(n) | #Beta(n) => Beta.toString(n) | #Float(n) => Float.toString(n) + | #Bernoulli(n) => Bernoulli.toString(n) } let min: symbolicDist => float = x => @@ -351,6 +375,7 @@ module T = { | #Lognormal(n) => Lognormal.inv(minCdfValue, n) | #Gamma(n) => Gamma.inv(minCdfValue, n) | #Uniform({low}) => low + | #Bernoulli(n) => 0.0 | #Beta(n) => Beta.inv(minCdfValue, n) | #Float(n) => n } @@ -364,6 +389,7 @@ module T = { | #Gamma(n) => Gamma.inv(maxCdfValue, n) | #Lognormal(n) => Lognormal.inv(maxCdfValue, n) | #Beta(n) => Beta.inv(maxCdfValue, n) + | #Bernoulli(n) => 1.0 | #Uniform({high}) => high | #Float(n) => n } @@ -379,6 +405,7 @@ module T = { | #Uniform(n) => Uniform.mean(n) | #Gamma(n) => Gamma.mean(n) | #Float(n) => Float.mean(n) + | #Bernoulli(n) => Bernoulli.mean(n) } let operate = (distToFloatOp: Operation.distToFloatOperation, s) => @@ -454,6 +481,8 @@ module T = { ): PointSetTypes.pointSetDist => switch d { | #Float(v) => Discrete(Discrete.make(~integralSumCache=Some(1.0), {xs: [v], ys: [1.0]})) + | #Bernoulli(v) => + Discrete(Discrete.make(~integralSumCache=Some(1.0), {xs: [0.0, 1.0], ys: [1.0 -. v.p, v.p]})) | _ => let xs = interpolateXs(~xSelection, d, sampleCount) let ys = xs |> E.A.fmap(x => pdf(x, d)) diff --git a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res index 7878a3bc..e888fbd2 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res @@ -36,6 +36,8 @@ type gamma = { scale: float, } +type bernoulli = {p: float} + @genType type symbolicDist = [ | #Normal(normal) @@ -47,6 +49,7 @@ type symbolicDist = [ | #Triangular(triangular) | #Gamma(gamma) | #Float(float) + | #Bernoulli(bernoulli) ] type analyticalSimplificationResult = [ diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index f36c21bf..8dffecb4 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -168,6 +168,7 @@ module SymbolicConstructors = { let oneFloat = name => switch name { | "exponential" => Ok(SymbolicDist.Exponential.make) + | "bernoulli" => Ok(SymbolicDist.Bernoulli.make) | _ => Error("Unreachable state") } @@ -204,7 +205,7 @@ let dispatchToGenericOutput = ( ): option => { let (fnName, args) = call switch (fnName, args) { - | ("exponential" as fnName, [EvNumber(f)]) => + | (("exponential" | "bernoulli") as fnName, [EvNumber(f)]) => SymbolicConstructors.oneFloat(fnName) ->E.R.bind(r => r(f)) ->SymbolicConstructors.symbolicResultToOutput diff --git a/packages/squiggle-lang/src/rescript/Utility/Stdlib.res b/packages/squiggle-lang/src/rescript/Utility/Stdlib.res new file mode 100644 index 00000000..e208173e --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/Stdlib.res @@ -0,0 +1,14 @@ +module Bernoulli = { + +@module external cdf: (float, float) => float = "@stdlib/stats/base/dists/bernoulli/cdf" +let cdf = cdf + +@module external pmf: (float, float) => float = "@stdlib/stats/base/dists/bernoulli/pmf" +let pmf = pmf + +@module external quantile: (float, float) => float = "@stdlib/stats/base/dists/bernoulli/quantile" +let quantile = quantile + +@module external mean: (float) => float = "@stdlib/stats/base/dists/bernoulli/mean" +let mean = mean +} \ No newline at end of file diff --git a/packages/squiggle-lang/src/rescript/Utility/stdlib.ts b/packages/squiggle-lang/src/rescript/Utility/stdlib.ts new file mode 100644 index 00000000..5d106084 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/stdlib.ts @@ -0,0 +1,4 @@ +var Bernoulli = require("@stdlib/stats/base/dists/bernoulli").Bernoulli; + +let bernoulliCdf = (p: number, x: number): number => new Bernoulli(p).cdf(x); +let bernoulliPmf = (p: number, x: number): number => new Bernoulli(p).cmf(x); diff --git a/yarn.lock b/yarn.lock index 81c8c21f..c30a22ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2502,6 +2502,335 @@ eval "^0.1.8" webpack-sources "^1.4.3" +"@stdlib/array@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/array/-/array-0.0.12.tgz#12f40ab95bb36d424cdad991f29fc3cb491ee29e" + integrity sha512-nDksiuvRC1dSTHrf5yOGQmlRwAzSKV8MdFQwFSvLbZGGhi5Y4hExqea5HloLgNVouVs8lnAFi2oubSM4Mc7YAg== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/blas" "^0.0.x" + "@stdlib/complex" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/symbol" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/assert@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/assert/-/assert-0.0.12.tgz#1648c9016e5041291f55a6464abcc4069c5103ce" + integrity sha512-38FxFf+ZoQZbdc+m09UsWtaCmzd/2e7im0JOaaFYE7icmRfm+4KiE9BRvBT4tIn7ioLB2f9PsBicKjIsf+tY1w== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/complex" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/ndarray" "^0.0.x" + "@stdlib/number" "^0.0.x" + "@stdlib/os" "^0.0.x" + "@stdlib/process" "^0.0.x" + "@stdlib/regexp" "^0.0.x" + "@stdlib/streams" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/symbol" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/bigint@^0.0.x": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@stdlib/bigint/-/bigint-0.0.11.tgz#c416a1d727001c55f4897e6424124199d638f2fd" + integrity sha512-uz0aYDLABAYyqxaCSHYbUt0yPkXYUCR7TrVvHN+UUD3i8FZ02ZKcLO+faKisDyxKEoSFTNtn3Ro8Ir5ebOlVXQ== + dependencies: + "@stdlib/utils" "^0.0.x" + +"@stdlib/blas@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/blas/-/blas-0.0.12.tgz#7e93e42b4621fc6903bf63264f045047333536c2" + integrity sha512-nWY749bWceuoWQ7gz977blCwR7lyQ/rsIXVO4b600h+NFpeA2i/ea7MYC680utIbeu2cnDWHdglBPoK535VAzA== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/number" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/buffer@^0.0.x": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@stdlib/buffer/-/buffer-0.0.11.tgz#6137b00845e6c905181cc7ebfae9f7e47c01b0ce" + integrity sha512-Jeie5eDDa1tVuRcuU+cBXI/oOXSmMxUUccZpqXzgYe0IO8QSNtNxv9mUTzJk/m5wH+lmLoDvNxzPpOH9TODjJg== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/process" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/cli@^0.0.x": + version "0.0.10" + resolved "https://registry.yarnpkg.com/@stdlib/cli/-/cli-0.0.10.tgz#28e2fbe6865d7f5cd15b7dc5846c99bd3b91674f" + integrity sha512-OITGaxG46kwK799+NuOd/+ccosJ9koVuQBC610DDJv0ZJf8mD7sbjGXrmue9C4EOh8MP7Vm/6HN14BojX8oTCg== + dependencies: + "@stdlib/utils" "^0.0.x" + minimist "^1.2.0" + +"@stdlib/complex@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/complex/-/complex-0.0.12.tgz#3afbc190cd0a9b37fc7c6e508c3aa9fda9106944" + integrity sha512-UbZBdaUxT2G+lsTIrVlRZwx2IRY6GXnVILggeejsIVxHSuK+oTyapfetcAv0FJFLP+Rrr+ZzrN4b9G3hBw6NHA== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/constants@^0.0.x": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@stdlib/constants/-/constants-0.0.11.tgz#78cd56d6c2982b30264843c3d75bde7125e90cd2" + integrity sha512-cWKy0L9hXHUQTvFzdPkTvZnn/5Pjv7H4UwY0WC1rLt+A5CxFDJKjvnIi9ypSzJS3CAiGl1ZaHCdadoqXhNdkUg== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/number" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/fs@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/fs/-/fs-0.0.12.tgz#662365fd5846a51f075724b4f2888ae88441b70d" + integrity sha512-zcDLbt39EEM3M3wJW6luChS53B8T+TMJkjs2526UpKJ71O0/0adR57cI7PfCpkMd33d05uM7GM+leEj4eks4Cw== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/process" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/utils" "^0.0.x" + debug "^2.6.9" + +"@stdlib/math@^0.0.x": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@stdlib/math/-/math-0.0.11.tgz#eb6638bc03a20fbd6727dd5b977ee0170bda4649" + integrity sha512-qI78sR1QqGjHj8k/aAqkZ51Su2fyBvaR/jMKQqcB/ML8bpYpf+QGlGvTty5Qdru/wpqds4kVFOVbWGcNFIV2+Q== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/ndarray" "^0.0.x" + "@stdlib/number" "^0.0.x" + "@stdlib/strided" "^0.0.x" + "@stdlib/symbol" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + debug "^2.6.9" + +"@stdlib/ndarray@^0.0.x": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@stdlib/ndarray/-/ndarray-0.0.13.tgz#2e8fc645e10f56a645a0ab81598808c0e8f43b82" + integrity sha512-Z+U9KJP4U2HWrLtuAXSPvhNetAdqaNLMcliR6S/fz+VPlFDeymRK7omRFMgVQ+1zcAvIgKZGJxpLC3vjiPUYEw== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/bigint" "^0.0.x" + "@stdlib/buffer" "^0.0.x" + "@stdlib/complex" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/number" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/nlp@^0.0.x": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@stdlib/nlp/-/nlp-0.0.11.tgz#532ec0f7267b8d639e4c20c6de864e8de8a09054" + integrity sha512-D9avYWANm0Db2W7RpzdSdi5GxRYALGAqUrNnRnnKIO6sMEfr/DvONoAbWruda4QyvSC+0MJNwcEn7+PHhRwYhw== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/random" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/number@^0.0.x": + version "0.0.10" + resolved "https://registry.yarnpkg.com/@stdlib/number/-/number-0.0.10.tgz#4030ad8fc3fac19a9afb415c443cee6deea0e65c" + integrity sha512-RyfoP9MlnX4kccvg8qv7vYQPbLdzfS1Mnp/prGOoWhvMG3pyBwFAan34kwFb5IS/zHC3W5EmrgXCV2QWyLg/Kg== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/os" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/os@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/os/-/os-0.0.12.tgz#08bbf013c62a7153099fa9cbac086ca1349a4677" + integrity sha512-O7lklZ/9XEzoCmYvzjPh7jrFWkbpOSHGI71ve3dkSvBy5tyiSL3TtivfKsIC+9ZxuEJZ3d3lIjc9e+yz4HVbqQ== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/process" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/process@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/process/-/process-0.0.12.tgz#123325079d89a32f4212f72fb694f8fe3614cf18" + integrity sha512-P0X0TMvkissBE1Wr877Avi2/AxmP7X5Toa6GatHbpJdDg6jQmN4SgPd+NZNp98YtZUyk478c8XSIzMr1krQ20g== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/buffer" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/streams" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/random@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/random/-/random-0.0.12.tgz#e819c3abd602ed5559ba800dba751e49c633ff85" + integrity sha512-c5yND4Ahnm9Jx0I+jsKhn4Yrz10D53ALSrIe3PG1qIz3kNFcIPnmvCuNGd+3V4ch4Mbrez55Y8z/ZC5RJh4vJQ== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/blas" "^0.0.x" + "@stdlib/buffer" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/process" "^0.0.x" + "@stdlib/stats" "^0.0.x" + "@stdlib/streams" "^0.0.x" + "@stdlib/symbol" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + debug "^2.6.9" + readable-stream "^2.1.4" + +"@stdlib/regexp@^0.0.x": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@stdlib/regexp/-/regexp-0.0.13.tgz#80b98361dc7a441b47bc3fa964bb0c826759e971" + integrity sha512-3JT5ZIoq/1nXY+dY+QtkU8/m7oWDeekyItEEXMx9c/AOf0ph8fmvTUGMDNfUq0RetcznFe3b66kFz6Zt4XHviA== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/stats@^0.0.13", "@stdlib/stats@^0.0.x": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@stdlib/stats/-/stats-0.0.13.tgz#87c973f385379d794707c7b5196a173dba8b07e1" + integrity sha512-hm+t32dKbx/L7+7WlQ1o4NDEzV0J4QSnwFBCsIMIAO8+VPxTZ4FxyNERl4oKlS3hZZe4AVKjoOVhBDtgEWrS4g== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/blas" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/ndarray" "^0.0.x" + "@stdlib/random" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/symbol" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/streams@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/streams/-/streams-0.0.12.tgz#07f5ceae5852590afad8e1cb7ce94174becc8739" + integrity sha512-YLUlXwjJNknHp92IkJUdvn5jEQjDckpawKhDLLCoxyh3h5V+w/8+61SH7TMTfKx5lBxKJ8vvtchZh90mIJOAjQ== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/buffer" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + debug "^2.6.9" + readable-stream "^2.1.4" + +"@stdlib/strided@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/strided/-/strided-0.0.12.tgz#86ac48e660cb7f64a45cf07e80cbbfe58be21ae1" + integrity sha512-1NINP+Y7IJht34iri/bYLY7TVxrip51f6Z3qWxGHUCH33kvk5H5QqV+RsmFEGbbyoGtdeHrT2O+xA+7R2e3SNg== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/ndarray" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/string@^0.0.x": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@stdlib/string/-/string-0.0.13.tgz#37457ca49e8d1dff0e523c68f5673c655c79eb2d" + integrity sha512-nGMHi7Qk9LBW0+Y+e3pSePQEBqyWH7+7DjFR1APcbsYccJE0p4aCaQdhPhx9Tp7j3uRGBmqPFek8wpcvIuC+CQ== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/nlp" "^0.0.x" + "@stdlib/process" "^0.0.x" + "@stdlib/regexp" "^0.0.x" + "@stdlib/streams" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/symbol@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/symbol/-/symbol-0.0.12.tgz#b9f396b0bf269c2985bb7fe99810a8e26d7288c3" + integrity sha512-2IDhpzWVGeLHgsvIsX12RXvf78r7xBkc4QLoRUv3k7Cp61BisR1Ym1p0Tq9PbxT8fknlvLToh9n5RpmESi2d4w== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/time@^0.0.x": + version "0.0.14" + resolved "https://registry.yarnpkg.com/@stdlib/time/-/time-0.0.14.tgz#ea6daa438b1d3b019b99f5091117ee4bcef55d60" + integrity sha512-1gMFCQTabMVIgww+k4g8HHHIhyy1tIlvwT8mC0BHW7Q7TzDAgobwL0bvor+lwvCb5LlDAvNQEpaRgVT99QWGeQ== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/types@^0.0.x": + version "0.0.14" + resolved "https://registry.yarnpkg.com/@stdlib/types/-/types-0.0.14.tgz#02d3aab7a9bfaeb86e34ab749772ea22f7b2f7e0" + integrity sha512-AP3EI9/il/xkwUazcoY+SbjtxHRrheXgSbWZdEGD+rWpEgj6n2i63hp6hTOpAB5NipE0tJwinQlDGOuQ1lCaCw== + +"@stdlib/utils@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/utils/-/utils-0.0.12.tgz#670de5a7b253f04f11a4cba38f790e82393bcb46" + integrity sha512-+JhFpl6l7RSq/xGnbWRQ5dAL90h9ONj8MViqlb7teBZFtePZLMwoRA1wssypFcJ8SFMRWQn7lPmpYVUkGwRSOg== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/blas" "^0.0.x" + "@stdlib/buffer" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/os" "^0.0.x" + "@stdlib/process" "^0.0.x" + "@stdlib/random" "^0.0.x" + "@stdlib/regexp" "^0.0.x" + "@stdlib/streams" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/symbol" "^0.0.x" + "@stdlib/time" "^0.0.x" + "@stdlib/types" "^0.0.x" + debug "^2.6.9" + "@storybook/addon-actions@6.4.22", "@storybook/addon-actions@^6.4.22": version "6.4.22" resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-6.4.22.tgz#ec1b4332e76a8021dc0a1375dfd71a0760457588" @@ -4148,7 +4477,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^18.0.1", "@types/react@^18.0.9": +"@types/react@*", "@types/react@^18.0.9": version "18.0.9" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.9.tgz#d6712a38bd6cd83469603e7359511126f122e878" integrity sha512-9bjbg1hJHUm4De19L1cHiW0Jvx3geel6Qczhjd0qY5VKVE2X5+x77YxAepuCwVh4vrgZJdgEJw48zrhRIeF4Nw== @@ -14349,7 +14678,7 @@ react-vega@^7.5.1: prop-types "^15.8.1" vega-embed "^6.5.1" -react@^18.0.0, react@^18.1.0: +react@^18.1.0: version "18.1.0" resolved "https://registry.yarnpkg.com/react/-/react-18.1.0.tgz#6f8620382decb17fdc5cc223a115e2adbf104890" integrity sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ== @@ -14375,7 +14704,7 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== From 6156ae65d14f83a0d81efe4f5bda20b888ecc7de Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 15 May 2022 19:42:10 -0400 Subject: [PATCH 09/15] Cleanup --- .../ReducerInterface_Distribution_test.res | 2 ++ .../SymbolicDist/SymbolicDist.res | 29 ++++++++++++------- .../src/rescript/Utility/stdlib.ts | 4 --- 3 files changed, 21 insertions(+), 14 deletions(-) delete mode 100644 packages/squiggle-lang/src/rescript/Utility/stdlib.ts diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res index 571a838b..253a9cc3 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res @@ -31,6 +31,8 @@ describe("eval on distribution functions", () => { testEval("mean(normal(5,2))", "Ok(5)") testEval("mean(lognormal(1,2))", "Ok(20.085536923187668)") testEval("mean(gamma(5,5))", "Ok(25)") + testEval("mean(bernoulli(0.2))", "Ok(0.2)") + testEval("mean(bernoulli(0.8))", "Ok(0.8)") }) describe("toString", () => { testEval("toString(normal(5,2))", "Ok('Normal(5,2)')") diff --git a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res index 6c57430c..6356f97c 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res @@ -221,20 +221,27 @@ module Bernoulli = { let make = p => p >= 0.0 && p <= 1.0 ? Ok(#Bernoulli({p: p})) - : Error("Beta distribution parameters must be positive") + : Error("Bernoulli parameter must be between 0 and 1") let pmf = (x, t: t) => Stdlib.Bernoulli.pmf(x, t.p) + + //Bernoulli is a discrete distribution, so it doesn't really have a pdf(). + //We fake this for now with the pmf function, but this should be fixed at some point. let pdf = (x, t: t) => Stdlib.Bernoulli.pmf(x, t.p) let cdf = (x, t: t) => Stdlib.Bernoulli.cdf(x, t.p) let inv = (p, t: t) => Stdlib.Bernoulli.quantile(p, t.p) let mean = (t: t) => Ok(Stdlib.Bernoulli.mean(t.p)) + let min = (t: t) => t.p == 1.0 ? 1.0 : 0.0 + let max = (t: t) => t.p == 0.0 ? 0.0 : 1.0 let sample = (t: t) => { - let s = Uniform.sample(({low: 0.0, high: 1.0})); - inv(s,t) + let s = Uniform.sample({low: 0.0, high: 1.0}) + inv(s, t) } let toString = ({p}: t) => j`Bernoulli($p)` + let toPointSetDist = ({p}: t): PointSetTypes.pointSetDist => Discrete( + Discrete.make(~integralSumCache=Some(1.0), {xs: [0.0, 1.0], ys: [1.0 -. p, p]}), + ) } - module Gamma = { type t = gamma let make = (shape: float, scale: float) => { @@ -271,6 +278,9 @@ module Float = { let mean = (t: t) => Ok(t) let sample = (t: t) => t let toString = (t: t) => j`Delta($t)` + let toPointSetDist = (t: t): PointSetTypes.pointSetDist => Discrete( + Discrete.make(~integralSumCache=Some(1.0), {xs: [t], ys: [1.0]}), + ) } module From90thPercentile = { @@ -375,7 +385,7 @@ module T = { | #Lognormal(n) => Lognormal.inv(minCdfValue, n) | #Gamma(n) => Gamma.inv(minCdfValue, n) | #Uniform({low}) => low - | #Bernoulli(n) => 0.0 + | #Bernoulli(n) => Bernoulli.min(n) | #Beta(n) => Beta.inv(minCdfValue, n) | #Float(n) => n } @@ -389,7 +399,7 @@ module T = { | #Gamma(n) => Gamma.inv(maxCdfValue, n) | #Lognormal(n) => Lognormal.inv(maxCdfValue, n) | #Beta(n) => Beta.inv(maxCdfValue, n) - | #Bernoulli(n) => 1.0 + | #Bernoulli(n) => Bernoulli.max(n) | #Uniform({high}) => high | #Float(n) => n } @@ -404,8 +414,8 @@ module T = { | #Beta(n) => Beta.mean(n) | #Uniform(n) => Uniform.mean(n) | #Gamma(n) => Gamma.mean(n) - | #Float(n) => Float.mean(n) | #Bernoulli(n) => Bernoulli.mean(n) + | #Float(n) => Float.mean(n) } let operate = (distToFloatOp: Operation.distToFloatOperation, s) => @@ -480,9 +490,8 @@ module T = { d: symbolicDist, ): PointSetTypes.pointSetDist => switch d { - | #Float(v) => Discrete(Discrete.make(~integralSumCache=Some(1.0), {xs: [v], ys: [1.0]})) - | #Bernoulli(v) => - Discrete(Discrete.make(~integralSumCache=Some(1.0), {xs: [0.0, 1.0], ys: [1.0 -. v.p, v.p]})) + | #Float(v) => Float.toPointSetDist(v) + | #Bernoulli(v) => Bernoulli.toPointSetDist(v) | _ => let xs = interpolateXs(~xSelection, d, sampleCount) let ys = xs |> E.A.fmap(x => pdf(x, d)) diff --git a/packages/squiggle-lang/src/rescript/Utility/stdlib.ts b/packages/squiggle-lang/src/rescript/Utility/stdlib.ts deleted file mode 100644 index 5d106084..00000000 --- a/packages/squiggle-lang/src/rescript/Utility/stdlib.ts +++ /dev/null @@ -1,4 +0,0 @@ -var Bernoulli = require("@stdlib/stats/base/dists/bernoulli").Bernoulli; - -let bernoulliCdf = (p: number, x: number): number => new Bernoulli(p).cdf(x); -let bernoulliPmf = (p: number, x: number): number => new Bernoulli(p).cmf(x); From 432e5b9bca2da03da9e76c2121c5de70b95fb91b Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 15 May 2022 19:42:43 -0400 Subject: [PATCH 10/15] Formatted code --- .../src/rescript/Utility/Stdlib.res | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Utility/Stdlib.res b/packages/squiggle-lang/src/rescript/Utility/Stdlib.res index e208173e..3455e962 100644 --- a/packages/squiggle-lang/src/rescript/Utility/Stdlib.res +++ b/packages/squiggle-lang/src/rescript/Utility/Stdlib.res @@ -1,14 +1,13 @@ module Bernoulli = { + @module external cdf: (float, float) => float = "@stdlib/stats/base/dists/bernoulli/cdf" + let cdf = cdf -@module external cdf: (float, float) => float = "@stdlib/stats/base/dists/bernoulli/cdf" -let cdf = cdf + @module external pmf: (float, float) => float = "@stdlib/stats/base/dists/bernoulli/pmf" + let pmf = pmf -@module external pmf: (float, float) => float = "@stdlib/stats/base/dists/bernoulli/pmf" -let pmf = pmf + @module external quantile: (float, float) => float = "@stdlib/stats/base/dists/bernoulli/quantile" + let quantile = quantile -@module external quantile: (float, float) => float = "@stdlib/stats/base/dists/bernoulli/quantile" -let quantile = quantile - -@module external mean: (float) => float = "@stdlib/stats/base/dists/bernoulli/mean" -let mean = mean -} \ No newline at end of file + @module external mean: float => float = "@stdlib/stats/base/dists/bernoulli/mean" + let mean = mean +} From b4f67f49c4e69c0e508587b3d3b7342d683bbe51 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 15 May 2022 19:49:33 -0400 Subject: [PATCH 11/15] Updated yarn.lock --- yarn.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index c30a22ff..dc874293 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4477,7 +4477,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^18.0.9": +"@types/react@*", "@types/react@^18.0.1", "@types/react@^18.0.9": version "18.0.9" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.9.tgz#d6712a38bd6cd83469603e7359511126f122e878" integrity sha512-9bjbg1hJHUm4De19L1cHiW0Jvx3geel6Qczhjd0qY5VKVE2X5+x77YxAepuCwVh4vrgZJdgEJw48zrhRIeF4Nw== @@ -14678,7 +14678,7 @@ react-vega@^7.5.1: prop-types "^15.8.1" vega-embed "^6.5.1" -react@^18.1.0: +react@^18.0.0, react@^18.1.0: version "18.1.0" resolved "https://registry.yarnpkg.com/react/-/react-18.1.0.tgz#6f8620382decb17fdc5cc223a115e2adbf104890" integrity sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ== From e0f505c8ead40914b987f5195266c3ceabbf792a Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 15 May 2022 21:10:13 -0400 Subject: [PATCH 12/15] Add logistic distribution --- .../ReducerInterface_Distribution_test.res | 1 + .../SymbolicDist/SymbolicDist.res | 26 ++++++++++++++++++ .../SymbolicDist/SymbolicDistTypes.res | 6 +++++ .../ReducerInterface_GenericDistribution.res | 10 ++++++- .../src/rescript/Utility/Stdlib.res | 27 +++++++++++++++++++ 5 files changed, 69 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res index 253a9cc3..48bdcaa5 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res @@ -33,6 +33,7 @@ describe("eval on distribution functions", () => { testEval("mean(gamma(5,5))", "Ok(25)") testEval("mean(bernoulli(0.2))", "Ok(0.2)") testEval("mean(bernoulli(0.8))", "Ok(0.8)") + testEval("mean(logistic(5,1))", "Ok(5)") }) describe("toString", () => { testEval("toString(normal(5,2))", "Ok('Normal(5,2)')") diff --git a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res index 6356f97c..d1fcb9ef 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res @@ -216,6 +216,24 @@ module Uniform = { } } +module Logistic = { + type t = logistic + let make = (location, scale) => + scale > 0.0 + ? Ok(#Logistic({location: location, scale: scale})) + : Error("Scale must be positive") + + let pdf = (x, t: t) => Stdlib.Logistic.pdf(x, t.location, t.scale) + let cdf = (x, t: t) => Stdlib.Logistic.cdf(x, t.location, t.scale) + let inv = (p, t: t) => Stdlib.Logistic.quantile(p, t.location, t.scale) + let sample = (t: t) => { + let s = Uniform.sample({low: 0.0, high: 1.0}) + inv(s, t) + } + let mean = (t: t) => Ok(Stdlib.Logistic.mean(t.location, t.scale)) + let toString = ({location, scale}: t) => j`Logistic($location,$scale)` +} + module Bernoulli = { type t = bernoulli let make = p => @@ -304,6 +322,7 @@ module T = { | #Cauchy(n) => Cauchy.pdf(x, n) | #Gamma(n) => Gamma.pdf(x, n) | #Lognormal(n) => Lognormal.pdf(x, n) + | #Logistic(n) => Logistic.pdf(x, n) | #Uniform(n) => Uniform.pdf(x, n) | #Beta(n) => Beta.pdf(x, n) | #Float(n) => Float.pdf(x, n) @@ -317,6 +336,7 @@ module T = { | #Exponential(n) => Exponential.cdf(x, n) | #Cauchy(n) => Cauchy.cdf(x, n) | #Gamma(n) => Gamma.cdf(x, n) + | #Logistic(n) => Logistic.cdf(x, n) | #Lognormal(n) => Lognormal.cdf(x, n) | #Uniform(n) => Uniform.cdf(x, n) | #Beta(n) => Beta.cdf(x, n) @@ -331,6 +351,7 @@ module T = { | #Exponential(n) => Exponential.inv(x, n) | #Cauchy(n) => Cauchy.inv(x, n) | #Gamma(n) => Gamma.inv(x, n) + | #Logistic(n) => Logistic.inv(x, n) | #Lognormal(n) => Lognormal.inv(x, n) | #Uniform(n) => Uniform.inv(x, n) | #Beta(n) => Beta.inv(x, n) @@ -345,6 +366,7 @@ module T = { | #Exponential(n) => Exponential.sample(n) | #Cauchy(n) => Cauchy.sample(n) | #Gamma(n) => Gamma.sample(n) + | #Logistic(n) => Logistic.sample(n) | #Lognormal(n) => Lognormal.sample(n) | #Uniform(n) => Uniform.sample(n) | #Beta(n) => Beta.sample(n) @@ -369,6 +391,7 @@ module T = { | #Cauchy(n) => Cauchy.toString(n) | #Normal(n) => Normal.toString(n) | #Gamma(n) => Gamma.toString(n) + | #Logistic(n) => Logistic.toString(n) | #Lognormal(n) => Lognormal.toString(n) | #Uniform(n) => Uniform.toString(n) | #Beta(n) => Beta.toString(n) @@ -383,6 +406,7 @@ module T = { | #Cauchy(n) => Cauchy.inv(minCdfValue, n) | #Normal(n) => Normal.inv(minCdfValue, n) | #Lognormal(n) => Lognormal.inv(minCdfValue, n) + | #Logistic(n) => Logistic.inv(minCdfValue, n) | #Gamma(n) => Gamma.inv(minCdfValue, n) | #Uniform({low}) => low | #Bernoulli(n) => Bernoulli.min(n) @@ -398,6 +422,7 @@ module T = { | #Normal(n) => Normal.inv(maxCdfValue, n) | #Gamma(n) => Gamma.inv(maxCdfValue, n) | #Lognormal(n) => Lognormal.inv(maxCdfValue, n) + | #Logistic(n) => Logistic.inv(maxCdfValue, n) | #Beta(n) => Beta.inv(maxCdfValue, n) | #Bernoulli(n) => Bernoulli.max(n) | #Uniform({high}) => high @@ -412,6 +437,7 @@ module T = { | #Normal(n) => Normal.mean(n) | #Lognormal(n) => Lognormal.mean(n) | #Beta(n) => Beta.mean(n) + | #Logistic(n) => Logistic.mean(n) | #Uniform(n) => Uniform.mean(n) | #Gamma(n) => Gamma.mean(n) | #Bernoulli(n) => Bernoulli.mean(n) diff --git a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res index e888fbd2..8a4956c5 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res @@ -36,6 +36,11 @@ type gamma = { scale: float, } +type logistic = { + location: float, + scale: float, +} + type bernoulli = {p: float} @genType @@ -50,6 +55,7 @@ type symbolicDist = [ | #Gamma(gamma) | #Float(float) | #Bernoulli(bernoulli) + | #Logistic(logistic) ] type analyticalSimplificationResult = [ diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index 8dffecb4..1f1291e9 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -178,6 +178,7 @@ module SymbolicConstructors = { | "uniform" => Ok(SymbolicDist.Uniform.make) | "beta" => Ok(SymbolicDist.Beta.make) | "lognormal" => Ok(SymbolicDist.Lognormal.make) + | "logistic" => Ok(SymbolicDist.Logistic.make) | "cauchy" => Ok(SymbolicDist.Cauchy.make) | "gamma" => Ok(SymbolicDist.Gamma.make) | "to" => Ok(SymbolicDist.From90thPercentile.make) @@ -212,7 +213,14 @@ let dispatchToGenericOutput = ( | ("delta", [EvNumber(f)]) => SymbolicDist.Float.makeSafe(f)->SymbolicConstructors.symbolicResultToOutput | ( - ("normal" | "uniform" | "beta" | "lognormal" | "cauchy" | "gamma" | "to") as fnName, + ("normal" + | "uniform" + | "beta" + | "lognormal" + | "cauchy" + | "gamma" + | "to" + | "logistic") as fnName, [EvNumber(f1), EvNumber(f2)], ) => SymbolicConstructors.twoFloat(fnName) diff --git a/packages/squiggle-lang/src/rescript/Utility/Stdlib.res b/packages/squiggle-lang/src/rescript/Utility/Stdlib.res index 3455e962..faa1cb1d 100644 --- a/packages/squiggle-lang/src/rescript/Utility/Stdlib.res +++ b/packages/squiggle-lang/src/rescript/Utility/Stdlib.res @@ -10,4 +10,31 @@ module Bernoulli = { @module external mean: float => float = "@stdlib/stats/base/dists/bernoulli/mean" let mean = mean + + @module external stdev: float => float = "@stdlib/stats/base/dists/bernoulli/stdev" + let stdev = stdev + + @module external variance: float => float = "@stdlib/stats/base/dists/bernoulli/variance" + let variance = variance +} + +module Logistic = { + @module external cdf: (float, float, float) => float = "@stdlib/stats/base/dists/logistic/cdf" + let cdf = cdf + + @module external pdf: (float, float, float) => float = "@stdlib/stats/base/dists/logistic/pdf" + let pdf = pdf + + @module + external quantile: (float, float, float) => float = "@stdlib/stats/base/dists/logistic/quantile" + let quantile = quantile + + @module external mean: (float, float) => float = "@stdlib/stats/base/dists/logistic/mean" + let mean = mean + + @module external stdev: (float, float) => float = "@stdlib/stats/base/dists/logistic/stdev" + let stdev = stdev + + @module external variance: (float, float) => float = "@stdlib/stats/base/dists/logistic/variance" + let variance = variance } From f493bbc0818c8f617f282cd80390ae1a7f2ec70b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 May 2022 14:35:41 +0000 Subject: [PATCH 13/15] :arrow_up: Bump @types/react-dom from 18.0.3 to 18.0.4 Bumps [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) from 18.0.3 to 18.0.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom) --- updated-dependencies: - dependency-name: "@types/react-dom" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index e8513982..c6870767 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -33,7 +33,7 @@ "@types/lodash": "^4.14.182", "@types/node": "^17.0.32", "@types/react": "^18.0.9", - "@types/react-dom": "^18.0.2", + "@types/react-dom": "^18.0.4", "@types/styled-components": "^5.1.24", "@types/webpack": "^5.28.0", "cross-env": "^7.0.3", diff --git a/yarn.lock b/yarn.lock index dc874293..92b2d1d2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4437,10 +4437,10 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== -"@types/react-dom@^18.0.0", "@types/react-dom@^18.0.2": - version "18.0.3" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.3.tgz#a022ea08c75a476fe5e96b675c3e673363853831" - integrity sha512-1RRW9kst+67gveJRYPxGmVy8eVJ05O43hg77G2j5m76/RFJtMbcfAs2viQ2UNsvvDg8F7OfQZx8qQcl6ymygaQ== +"@types/react-dom@^18.0.0", "@types/react-dom@^18.0.4": + version "18.0.4" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.4.tgz#dcbcadb277bcf6c411ceff70069424c57797d375" + integrity sha512-FgTtbqPOCI3dzZPZoC2T/sx3L34qxy99ITWn4eoSA95qPyXDMH0ALoAqUp49ITniiJFsXUVBtalh/KffMpg21Q== dependencies: "@types/react" "*" From 40fe4433c4a1c19da9191dacb6bba3dc61c99dbb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 May 2022 14:37:54 +0000 Subject: [PATCH 14/15] :arrow_up: Bump prism-react-renderer from 1.3.1 to 1.3.3 Bumps [prism-react-renderer](https://github.com/FormidableLabs/prism-react-renderer) from 1.3.1 to 1.3.3. - [Release notes](https://github.com/FormidableLabs/prism-react-renderer/releases) - [Commits](https://github.com/FormidableLabs/prism-react-renderer/compare/v1.3.1...v1.3.3) --- updated-dependencies: - dependency-name: prism-react-renderer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/website/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/website/package.json b/packages/website/package.json index 5f4172f6..e07feb6f 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -16,7 +16,7 @@ "@docusaurus/preset-classic": "2.0.0-beta.20", "@quri/squiggle-components": "^0.2.20", "clsx": "^1.1.1", - "prism-react-renderer": "^1.2.1", + "prism-react-renderer": "^1.3.3", "react": "^18.1.0", "react-dom": "^18.1.0", "remark-math": "^3", diff --git a/yarn.lock b/yarn.lock index dc874293..e50e856f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14007,10 +14007,10 @@ pretty-time@^1.1.0: resolved "https://registry.yarnpkg.com/pretty-time/-/pretty-time-1.1.0.tgz#ffb7429afabb8535c346a34e41873adf3d74dd0e" integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== -prism-react-renderer@^1.2.1, prism-react-renderer@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.3.1.tgz#88fc9d0df6bed06ca2b9097421349f8c2f24e30d" - integrity sha512-xUeDMEz074d0zc5y6rxiMp/dlC7C+5IDDlaEUlcBOFE2wddz7hz5PNupb087mPwTt7T9BrFmewObfCBuf/LKwQ== +prism-react-renderer@^1.3.1, prism-react-renderer@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.3.3.tgz#9b5a4211a6756eee3c96fee9a05733abc0b0805c" + integrity sha512-Viur/7tBTCH2HmYzwCHmt2rEFn+rdIWNIINXyg0StiISbDiIhHKhrFuEK8eMkKgvsIYSjgGqy/hNyucHp6FpoQ== prismjs@^1.21.0, prismjs@^1.28.0: version "1.28.0" From 909c91d7bf900035a6203ffe014e3d9c604955d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 May 2022 14:42:12 +0000 Subject: [PATCH 15/15] :arrow_up: Bump @types/node from 17.0.32 to 17.0.33 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 17.0.32 to 17.0.33. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index c6870767..e40f285f 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -31,7 +31,7 @@ "@testing-library/user-event": "^14.2.0", "@types/jest": "^27.5.0", "@types/lodash": "^4.14.182", - "@types/node": "^17.0.32", + "@types/node": "^17.0.33", "@types/react": "^18.0.9", "@types/react-dom": "^18.0.4", "@types/styled-components": "^5.1.24", diff --git a/yarn.lock b/yarn.lock index 92b2d1d2..1ba81968 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4367,10 +4367,10 @@ "@types/node" "*" form-data "^3.0.0" -"@types/node@*", "@types/node@^17.0.32", "@types/node@^17.0.5": - version "17.0.32" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.32.tgz#51d59d7a90ef2d0ae961791e0900cad2393a0149" - integrity sha512-eAIcfAvhf/BkHcf4pkLJ7ECpBAhh9kcxRBpip9cTiO+hf+aJrsxYxBeS6OXvOd9WqNAJmavXVpZvY1rBjNsXmw== +"@types/node@*", "@types/node@^17.0.33", "@types/node@^17.0.5": + version "17.0.33" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.33.tgz#3c1879b276dc63e73030bb91165e62a4509cd506" + integrity sha512-miWq2m2FiQZmaHfdZNcbpp9PuXg34W5JZ5CrJ/BaS70VuhoJENBEQybeiYSaPBRNq6KQGnjfEnc/F3PN++D+XQ== "@types/node@^14.0.10": version "14.18.16"