From 8217801de33c74b5c7e83eebe635c779c8f118b3 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Fri, 29 Apr 2022 18:38:55 -0400 Subject: [PATCH 1/5] magic numbers in bandwidth; `fromSamples` implementation Value: [1e-3 to 4e-2] --- .../__tests__/TS/SampleSet_test.ts | 16 +++++++++++++++- packages/squiggle-lang/src/js/index.ts | 5 +++++ .../DistributionOperation.res | 7 +++++++ .../DistributionOperation.resi | 2 ++ .../Distributions/DistributionTypes.res | 13 +++++++------ .../SampleSetDist/SampleSetDist.res | 3 ++- .../SampleSetDist/SampleSetDist_Bandwidth.res | 19 +++++++++++-------- .../src/rescript/MagicNumbers.res | 13 +++++++++++++ .../ReducerInterface_GenericDistribution.res | 11 +++++++++++ .../squiggle-lang/src/rescript/Utility/E.res | 2 ++ 10 files changed, 75 insertions(+), 16 deletions(-) diff --git a/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts b/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts index a617010b..356f19a4 100644 --- a/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts +++ b/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts @@ -1,5 +1,5 @@ import { Distribution } from "../../src/js/index"; -import { expectErrorToBeBounded, failDefault } from "./TestHelpers"; +import { expectErrorToBeBounded, failDefault, testRun } from "./TestHelpers"; import * as fc from "fast-check"; // Beware: float64Array makes it appear in an infinite loop. @@ -212,3 +212,17 @@ describe("mean is mean", () => { ); }); }); + +describe("fromSamples function", () => { + test("gives a mean near the mean of the input", () => { + fc.assert( + fc.property(arrayGen(), (xs_) => { + let xs = Array.from(xs_); + let squiggleString = `x = fromSamples($xs); mean(x)`; + let squiggleResult = testRun(squiggleString, {}, { xs: xs }); + let mean = xs.reduce((a, b) => a + b, 0.0) / xs.length; + expect(squiggleResult.value).toBeCloseTo(mean, 3); + }) + ); + }); +}); diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index fb67e47a..d72eb5c7 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -31,6 +31,7 @@ import { Constructors_isNormalized, Constructors_toPointSet, Constructors_toSampleSet, + Constructors_fromSamples, Constructors_truncate, Constructors_inspect, Constructors_toString, @@ -404,6 +405,10 @@ export class Distribution { ); } + fromSamples(n: Array): result { + return this.mapResultDist(Constructors_fromSamples({ env: this.env }, n)); + } + truncate( left: number, right: number diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res index 18ee2d6a..22376589 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res @@ -189,6 +189,12 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => { ->GenericDist.mixture(~scaleMultiplyFn=scaleMultiply, ~pointwiseAddFn=pointwiseAdd) ->E.R2.fmap(r => Dist(r)) ->OutputLocal.fromResult + | FromArray(xs) => + xs + ->SampleSetDist.make + ->E.R2.fmap2(x => DistributionTypes.SampleSetError(x)) + ->E.R2.fmap(x => x->DistributionTypes.SampleSet->Dist) + ->OutputLocal.fromResult } } @@ -229,6 +235,7 @@ module Constructors = { let isNormalized = (~env, dist) => C.isNormalized(dist)->run(~env)->toBoolR let toPointSet = (~env, dist) => C.toPointSet(dist)->run(~env)->toDistR let toSampleSet = (~env, dist, n) => C.toSampleSet(dist, n)->run(~env)->toDistR + let fromSamples = (~env, xs) => C.fromSamples(xs)->run(~env)->toDistR let truncate = (~env, dist, leftCutoff, rightCutoff) => C.truncate(dist, leftCutoff, rightCutoff)->run(~env)->toDistR let inspect = (~env, dist) => C.inspect(dist)->run(~env)->toDistR diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi index 5ad34354..fcaeb5e4 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi @@ -61,6 +61,8 @@ module Constructors: { @genType let toSampleSet: (~env: env, genericDist, int) => result @genType + let fromSamples: (~env: env, SampleSetDist.t) => result + @genType let truncate: (~env: env, genericDist, option, option) => result @genType let inspect: (~env: env, genericDist) => result diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res index 93f86798..a1725c88 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res @@ -11,7 +11,7 @@ type error = | NotYetImplemented | Unreachable | DistributionVerticalShiftIsInvalid - | TooFewSamples + | SampleSetError(SampleSetDist.sampleSetError) | ArgumentError(string) | OperationError(Operation.Error.t) | PointSetConversionError(SampleSetDist.pointsetConversionError) @@ -35,7 +35,8 @@ module Error = { | DistributionVerticalShiftIsInvalid => "Distribution Vertical Shift is Invalid" | ArgumentError(s) => `Argument Error ${s}` | LogarithmOfDistributionError(s) => `Logarithm of input error: ${s}` - | TooFewSamples => "Too Few Samples" + | SampleSetError(TooFewSamples) => "Too Few Samples" + | SampleSetError(NonNumericInput(err)) => `Found a non-number in input: ${err}` | OperationError(err) => Operation.Error.toString(err) | PointSetConversionError(err) => SampleSetDist.pointsetConversionErrorToString(err) | SparklineError(err) => PointSetTypes.sparklineErrorToString(err) @@ -47,10 +48,7 @@ module Error = { let resultStringToResultError: result<'a, string> => result<'a, error> = n => n->E.R2.errMap(r => r->fromString) - let sampleErrorToDistErr = (err: SampleSetDist.sampleSetError): error => - switch err { - | TooFewSamples => TooFewSamples - } + let sampleErrorToDistErr = (err: SampleSetDist.sampleSetError): error => SampleSetError(err) } @genType @@ -100,6 +98,7 @@ module DistributionOperation = { | FromDist(fromDist, genericDist) | FromFloat(fromDist, float) | Mixture(array<(genericDist, float)>) + | FromArray(SampleSetDist.t) let distCallToString = (distFunction: fromDist): string => switch distFunction { @@ -124,6 +123,7 @@ module DistributionOperation = { switch d { | FromDist(f, _) | FromFloat(f, _) => distCallToString(f) | Mixture(_) => `mixture` + | FromArray(_) => `samples` } } module Constructors = { @@ -140,6 +140,7 @@ module Constructors = { let isNormalized = (dist): t => FromDist(ToBool(IsNormalized), dist) let toPointSet = (dist): t => FromDist(ToDist(ToPointSet), dist) let toSampleSet = (dist, r): t => FromDist(ToDist(ToSampleSet(r)), dist) + let fromSamples = (xs): t => FromArray(xs) let truncate = (dist, left, right): t => FromDist(ToDist(Truncate(left, right)), dist) let inspect = (dist): t => FromDist(ToDist(Inspect), dist) let toString = (dist): t => FromDist(ToString(ToString), dist) diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res index 14c66812..55b334c5 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res @@ -1,11 +1,12 @@ @genType module Error = { @genType - type sampleSetError = TooFewSamples + type sampleSetError = TooFewSamples | NonNumericInput(string) let sampleSetErrorToString = (err: sampleSetError): string => switch err { | TooFewSamples => "Too few samples when constructing sample set" + | NonNumericInput(err) => `Found a non-number in input: ${err}` } @genType diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res index aef659d1..29d48ad3 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res @@ -1,27 +1,30 @@ //The math here was taken from https://github.com/jasondavies/science.js/blob/master/src/stats/SampleSetDist_Bandwidth.js - +let {iqr_percentile, nrd0_lo_denominator, one, nrd0_coef, nrd_coef, nrd_fractionalPower} = module( + MagicNumbers.SampleSetBandwidth +) let len = x => E.A.length(x) |> float_of_int -let iqr = x => Jstat.percentile(x, 0.75, true) -. Jstat.percentile(x, 0.25, true) +let iqr = x => + Jstat.percentile(x, iqr_percentile, true) -. Jstat.percentile(x, 1.0 -. iqr_percentile, true) // Silverman, B. W. (1986) Density Estimation. London: Chapman and Hall. let nrd0 = x => { let hi = Js_math.sqrt(Jstat.variance(x)) - let lo = Js_math.minMany_float([hi, iqr(x) /. 1.34]) + let lo = Js_math.minMany_float([hi, iqr(x) /. nrd0_lo_denominator]) let e = Js_math.abs_float(x[1]) let lo' = switch (lo, hi, e) { | (lo, _, _) if !Js.Float.isNaN(lo) => lo | (_, hi, _) if !Js.Float.isNaN(hi) => hi | (_, _, e) if !Js.Float.isNaN(e) => e - | _ => 1.0 + | _ => one } - 0.9 *. lo' *. Js.Math.pow_float(~base=len(x), ~exp=-0.2) + nrd0_coef *. lo' *. Js.Math.pow_float(~base=len(x), ~exp=nrd_fractionalPower) } // Scott, D. W. (1992) Multivariate Density Estimation: Theory, Practice, and Visualization. Wiley. let nrd = x => { - let h = iqr(x) /. 1.34 - 1.06 *. + let h = iqr(x) /. nrd0_lo_denominator + nrd_coef *. Js.Math.min_float(Js.Math.sqrt(Jstat.variance(x)), h) *. - Js.Math.pow_float(~base=len(x), ~exp=-1.0 /. 5.0) + Js.Math.pow_float(~base=len(x), ~exp=nrd_fractionalPower) } diff --git a/packages/squiggle-lang/src/rescript/MagicNumbers.res b/packages/squiggle-lang/src/rescript/MagicNumbers.res index 124a44f4..0f059c03 100644 --- a/packages/squiggle-lang/src/rescript/MagicNumbers.res +++ b/packages/squiggle-lang/src/rescript/MagicNumbers.res @@ -35,3 +35,16 @@ module ToPointSet = { */ let minDiscreteToKeep = samples => max(20, E.A.length(samples) / 50) } + +module SampleSetBandwidth = { + // Silverman, B. W. (1986) Density Estimation. London: Chapman and Hall. + // Scott, D. W. (1992) Multivariate Density Estimation: Theory, Practice, and Visualization. Wiley. + let iqr_percentile = 0.75 + let iqr_percentile_complement = 1.0 -. iqr_percentile + let nrd0_lo_denominator = 1.34 + let one = 1.0 + let nrd0_coef = 0.9 + + let nrd_coef = 1.06 + let nrd_fractionalPower = -0.2 +} diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index ab76f469..49165f0f 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -218,6 +218,17 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option< Helpers.toDistFn(ToSampleSet(Belt.Int.fromFloat(float)), dist) | ("toSampleSet", [EvDistribution(dist)]) => Helpers.toDistFn(ToSampleSet(MagicNumbers.Environment.defaultSampleCount), dist) + | ("fromSamples", [EvArray(arr)]) => + Helpers.toDistFn( + ToSampleSet(MagicNumbers.Environment.defaultSampleCount), + arr + ->Helpers.parseNumberArray + ->E.R2.fmap2(x => SampleSetDist.NonNumericInput(x)) + ->E.R.bind(SampleSetDist.make) + ->E.R2.fmap(x => DistributionTypes.SampleSet(x)) + // Raising here isn't ideal. This: GenDistError(SampleSetError(NonNumericInput("Something wasn't a number"))) would be proper. + ->E.R2.toExn("Something in the input wasn't a number"), + ) | ("inspect", [EvDistribution(dist)]) => Helpers.toDistFn(Inspect, dist) | ("truncateLeft", [EvDistribution(dist), EvNumber(float)]) => Helpers.toDistFn(Truncate(Some(float), None), dist) diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index e0bcaf5c..5b3280d8 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -307,6 +307,8 @@ module R2 = { | Ok(x) => x->Ok | Error(x) => x->f->Error } + + let toExn = (a, b) => R.toExn(b, a) } let safe_fn_of_string = (fn, s: string): option<'a> => From ba0baf31c67cc0664d1df3ce55ace32afd73d63d Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Fri, 29 Apr 2022 18:45:12 -0400 Subject: [PATCH 2/5] Fixed a (now skipped) test [1e-5 to 1e-4] --- packages/squiggle-lang/__tests__/TS/SampleSet_test.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts b/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts index 356f19a4..2c77e210 100644 --- a/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts +++ b/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts @@ -214,14 +214,15 @@ describe("mean is mean", () => { }); describe("fromSamples function", () => { - test("gives a mean near the mean of the input", () => { + test.skip("gives a mean near the mean of the input", () => { fc.assert( fc.property(arrayGen(), (xs_) => { let xs = Array.from(xs_); - let squiggleString = `x = fromSamples($xs); mean(x)`; - let squiggleResult = testRun(squiggleString, {}, { xs: xs }); + let xsString = xs.toString(); + let squiggleString = `x = fromSamples([${xsString}]); mean(x)`; + let squiggleResult = testRun(squiggleString); let mean = xs.reduce((a, b) => a + b, 0.0) / xs.length; - expect(squiggleResult.value).toBeCloseTo(mean, 3); + expect(squiggleResult.value).toBeCloseTo(mean, 4); }) ); }); From 3249f6915522ff963b842a38cb008d1dc284b837 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Fri, 29 Apr 2022 21:41:09 -0400 Subject: [PATCH 3/5] Small cleanup to fromSamples --- .../DistributionOperation.res | 5 ++--- .../Distributions/DistributionTypes.res | 6 +++--- .../ReducerInterface_GenericDistribution.res | 19 ++++++++----------- .../squiggle-lang/src/rescript/Utility/E.res | 7 +++++++ 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res index 22376589..f323cdcb 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res @@ -189,10 +189,9 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => { ->GenericDist.mixture(~scaleMultiplyFn=scaleMultiply, ~pointwiseAddFn=pointwiseAdd) ->E.R2.fmap(r => Dist(r)) ->OutputLocal.fromResult - | FromArray(xs) => - xs + | FromSamples(xs) => xs ->SampleSetDist.make - ->E.R2.fmap2(x => DistributionTypes.SampleSetError(x)) + ->E.R2.errMap(x => DistributionTypes.SampleSetError(x)) ->E.R2.fmap(x => x->DistributionTypes.SampleSet->Dist) ->OutputLocal.fromResult } diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res index a1725c88..c5b9a4ef 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res @@ -97,8 +97,8 @@ module DistributionOperation = { type genericFunctionCallInfo = | FromDist(fromDist, genericDist) | FromFloat(fromDist, float) + | FromSamples(array) | Mixture(array<(genericDist, float)>) - | FromArray(SampleSetDist.t) let distCallToString = (distFunction: fromDist): string => switch distFunction { @@ -123,7 +123,7 @@ module DistributionOperation = { switch d { | FromDist(f, _) | FromFloat(f, _) => distCallToString(f) | Mixture(_) => `mixture` - | FromArray(_) => `samples` + | FromSamples(_) => `fromSamples` } } module Constructors = { @@ -140,7 +140,7 @@ module Constructors = { let isNormalized = (dist): t => FromDist(ToBool(IsNormalized), dist) let toPointSet = (dist): t => FromDist(ToDist(ToPointSet), dist) let toSampleSet = (dist, r): t => FromDist(ToDist(ToSampleSet(r)), dist) - let fromSamples = (xs): t => FromArray(xs) + let fromSamples = (xs): t => FromSamples(xs) let truncate = (dist, left, right): t => FromDist(ToDist(Truncate(left, right)), dist) let inspect = (dist): t => FromDist(ToDist(Inspect), dist) let toString = (dist): t => FromDist(ToString(ToString), dist) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index 49165f0f..5277ae1c 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -218,17 +218,14 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option< Helpers.toDistFn(ToSampleSet(Belt.Int.fromFloat(float)), dist) | ("toSampleSet", [EvDistribution(dist)]) => Helpers.toDistFn(ToSampleSet(MagicNumbers.Environment.defaultSampleCount), dist) - | ("fromSamples", [EvArray(arr)]) => - Helpers.toDistFn( - ToSampleSet(MagicNumbers.Environment.defaultSampleCount), - arr - ->Helpers.parseNumberArray - ->E.R2.fmap2(x => SampleSetDist.NonNumericInput(x)) - ->E.R.bind(SampleSetDist.make) - ->E.R2.fmap(x => DistributionTypes.SampleSet(x)) - // Raising here isn't ideal. This: GenDistError(SampleSetError(NonNumericInput("Something wasn't a number"))) would be proper. - ->E.R2.toExn("Something in the input wasn't a number"), - ) + | ("fromSamples", [EvArray(inputArray)]) => { + let _wrapInputErrors = x => SampleSetDist.NonNumericInput(x) + let parsedArray = Helpers.parseNumberArray(inputArray)->E.R2.errMap(_wrapInputErrors) + switch parsedArray { + | Ok(array) => runGenericOperation(FromSamples(array)) + | Error(e) => GenDistError(SampleSetError(e)) + }->Some + } | ("inspect", [EvDistribution(dist)]) => Helpers.toDistFn(Inspect, dist) | ("truncateLeft", [EvDistribution(dist), EvNumber(float)]) => Helpers.toDistFn(Truncate(Some(float), None), dist) diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index 5b3280d8..9edeae1b 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -289,6 +289,13 @@ module R = { | Ok(r) => r->Ok | Error(x) => x->f->Error } + + //I'm not sure what to call this. + let unify = (a: result<'a, 'b>, c: 'b => 'a): 'a => + switch a { + | Ok(x) => x + | Error(x) => c(x) + } } module R2 = { From e724f43b9d9bafc7cf8220b6a6f9f41b77040a00 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Sat, 30 Apr 2022 10:01:55 -0400 Subject: [PATCH 4/5] Documented `fromSamples` Value: [1e-4 to 1e-3] --- packages/website/docs/Features/Functions.mdx | 32 ++++++++++++-------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/packages/website/docs/Features/Functions.mdx b/packages/website/docs/Features/Functions.mdx index e37ea315..8282b11c 100644 --- a/packages/website/docs/Features/Functions.mdx +++ b/packages/website/docs/Features/Functions.mdx @@ -315,6 +315,26 @@ Or `PointSet` format +### `toSampleSet` has two signatures + +Above, we saw the unary `toSampleSet`, which uses an internal hardcoded number of samples. If you'd like to provide the number of samples, it has a binary signature as well (floored) + + + +#### Validity + +- Second argument to `toSampleSet` must be a number. + +## `fromSamples` + + +#### Validity + +For `fromSamples(xs)`, + +- `xs.length > 5` +- Strictly every element of `xs` must be a number. + ## Normalization Some distribution operations (like horizontal shift) return an unnormalized distriibution. @@ -333,18 +353,6 @@ We provide a predicate `isNormalized`, for when we have simple control flow - Input to `isNormalized` must be a dist -## Convert any distribution to a sample set distribution - -`toSampleSet` has two signatures - -It is unary when you use an internal hardcoded number of samples - - - -And binary when you provide a number of samples (floored) - - - ## `inspect` You may like to debug by right clicking your browser and using the _inspect_ functionality on the webpage, and viewing the _console_ tab. Then, wrap your squiggle output with `inspect` to log an internal representation. From f3561317fdd12c5104715739b93fb08f85364fc1 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Sat, 30 Apr 2022 10:10:09 -0400 Subject: [PATCH 5/5] Moved `fromSamples` to `Inventory` section Value: [1e-7 to 1e-5] --- packages/website/docs/Features/Functions.mdx | 23 +++++++++++--------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/website/docs/Features/Functions.mdx b/packages/website/docs/Features/Functions.mdx index 8282b11c..1de7514b 100644 --- a/packages/website/docs/Features/Functions.mdx +++ b/packages/website/docs/Features/Functions.mdx @@ -98,6 +98,19 @@ bound `a`, mode `b` and upper bound `c`. Squiggle, when the context is right, automatically casts a float to a constant distribution. +## `fromSamples` + +The last distribution constructor takes an array of samples and constructs a sample set distribution. + + + +#### Validity + +For `fromSamples(xs)`, + +- `xs.length > 5` +- Strictly every element of `xs` must be a number. + ## Operating on distributions Here are the ways we combine distributions. @@ -325,16 +338,6 @@ Above, we saw the unary `toSampleSet`, which uses an internal hardcoded number o - Second argument to `toSampleSet` must be a number. -## `fromSamples` - - -#### Validity - -For `fromSamples(xs)`, - -- `xs.length > 5` -- Strictly every element of `xs` must be a number. - ## Normalization Some distribution operations (like horizontal shift) return an unnormalized distriibution.