From 9430653b7a14cbd86c2ae9535f6f34f3ffba8029 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 9 Apr 2022 12:37:26 -0400 Subject: [PATCH 01/10] Namechange: Exponential -> Power --- packages/squiggle-lang/src/js/index.ts | 12 +++++------ .../DistributionOperation.res | 8 ++++---- .../DistributionOperation.resi | 4 ++-- .../Distributions/DistributionTypes.res | 4 ++-- .../Distributions/GenericDist/GenericDist.res | 2 +- .../GenericDist/GenericDist_Types.res | 12 +++++------ .../AlgebraicShapeCombination.res | 6 +++--- .../rescript/OldInterpreter/ASTEvaluator.res | 2 +- .../typeSystem/HardcodedFunctions.res | 2 +- .../src/rescript/OldParser/Parser.res | 4 ++-- .../ReducerInterface_GenericDistribution.res | 4 ++-- .../src/rescript/Utility/Operation.res | 20 +++++++++---------- 12 files changed, 40 insertions(+), 40 deletions(-) diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 25515db6..1f67e369 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -32,13 +32,13 @@ import { Constructors_algebraicDivide, Constructors_algebraicSubtract, Constructors_algebraicLogarithm, - Constructors_algebraicExponentiate, + Constructors_algebraicPower, Constructors_pointwiseAdd, Constructors_pointwiseMultiply, Constructors_pointwiseDivide, Constructors_pointwiseSubtract, Constructors_pointwiseLogarithm, - Constructors_pointwiseExponentiate, + Constructors_pointwisePower, } from "../rescript/Distributions/DistributionOperation/DistributionOperation.gen"; export let defaultSamplingInputs: SamplingInputs = { @@ -179,9 +179,9 @@ export class GenericDist { ); } - algebraicExponentiate(d2: GenericDist) { + algebraicPower(d2: GenericDist) { return this.mapResultDist( - Constructors_algebraicExponentiate({ env: this.env }, this.t, d2.t) + Constructors_algebraicPower({ env: this.env }, this.t, d2.t) ); } @@ -215,9 +215,9 @@ export class GenericDist { ); } - pointwiseExponentiate(d2: GenericDist) { + pointwisePower(d2: GenericDist) { return this.mapResultDist( - Constructors_pointwiseExponentiate({ env: this.env }, this.t, d2.t) + Constructors_pointwisePower({ env: this.env }, this.t, d2.t) ); } } diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res index a36674db..69a9a4ed 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res @@ -213,8 +213,8 @@ module Constructors = { C.algebraicSubtract(dist1, dist2)->run(~env)->toDistR let algebraicLogarithm = (~env, dist1, dist2) => C.algebraicLogarithm(dist1, dist2)->run(~env)->toDistR - let algebraicExponentiate = (~env, dist1, dist2) => - C.algebraicExponentiate(dist1, dist2)->run(~env)->toDistR + let algebraicPower = (~env, dist1, dist2) => + C.algebraicPower(dist1, dist2)->run(~env)->toDistR let pointwiseAdd = (~env, dist1, dist2) => C.pointwiseAdd(dist1, dist2)->run(~env)->toDistR let pointwiseMultiply = (~env, dist1, dist2) => C.pointwiseMultiply(dist1, dist2)->run(~env)->toDistR @@ -223,6 +223,6 @@ module Constructors = { C.pointwiseSubtract(dist1, dist2)->run(~env)->toDistR let pointwiseLogarithm = (~env, dist1, dist2) => C.pointwiseLogarithm(dist1, dist2)->run(~env)->toDistR - let pointwiseExponentiate = (~env, dist1, dist2) => - C.pointwiseExponentiate(dist1, dist2)->run(~env)->toDistR + let pointwisePower = (~env, dist1, dist2) => + C.pointwisePower(dist1, dist2)->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 ce0fca72..bfe45013 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi @@ -79,7 +79,7 @@ module Constructors: { @genType let algebraicLogarithm: (~env: env, genericDist, genericDist) => result @genType - let algebraicExponentiate: (~env: env, genericDist, genericDist) => result + let algebraicPower: (~env: env, genericDist, genericDist) => result @genType let pointwiseAdd: (~env: env, genericDist, genericDist) => result @genType @@ -91,5 +91,5 @@ module Constructors: { @genType let pointwiseLogarithm: (~env: env, genericDist, genericDist) => result @genType - let pointwiseExponentiate: (~env: env, genericDist, genericDist) => result + let pointwisePower: (~env: env, genericDist, genericDist) => result } diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res index a3e249d3..cab58839 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res @@ -19,7 +19,7 @@ module Operation = { | #Multiply | #Subtract | #Divide - | #Exponentiate + | #Power | #Logarithm ] @@ -28,7 +28,7 @@ module Operation = { | #Add => \"+." | #Multiply => \"*." | #Subtract => \"-." - | #Exponentiate => \"**" + | #Power => \"**" | #Divide => \"/." | #Logarithm => (a, b) => log(a) /. log(b) } diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res index 6bcbb221..ba19e60b 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res @@ -247,7 +247,7 @@ let pointwiseCombinationFloat = ( ): result => { let m = switch arithmeticOperation { | #Add | #Subtract => Error(GenericDist_Types.DistributionVerticalShiftIsInvalid) - | (#Multiply | #Divide | #Exponentiate | #Logarithm) as arithmeticOperation => + | (#Multiply | #Divide | #Power | #Logarithm) as arithmeticOperation => toPointSetFn(t)->E.R2.fmap(t => { //TODO: Move to PointSet codebase let fn = (secondary, main) => Operation.Scale.toFn(arithmeticOperation, main, secondary) diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res index b3aeddac..70754807 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res @@ -20,7 +20,7 @@ module Operation = { | #Multiply | #Subtract | #Divide - | #Exponentiate + | #Power | #Logarithm ] @@ -29,7 +29,7 @@ module Operation = { | #Add => \"+." | #Multiply => \"*." | #Subtract => \"-." - | #Exponentiate => \"**" + | #Power => \"**" | #Divide => \"/." | #Logarithm => (a, b) => log(a) /. log(b) } @@ -143,8 +143,8 @@ module Constructors = { ToDistCombination(Algebraic, #Logarithm, #Dist(dist2)), dist1, ) - let algebraicExponentiate = (dist1, dist2): t => FromDist( - ToDistCombination(Algebraic, #Exponentiate, #Dist(dist2)), + let algebraicPower = (dist1, dist2): t => FromDist( + ToDistCombination(Algebraic, #Power, #Dist(dist2)), dist1, ) let pointwiseAdd = (dist1, dist2): t => FromDist( @@ -167,8 +167,8 @@ module Constructors = { ToDistCombination(Pointwise, #Logarithm, #Dist(dist2)), dist1, ) - let pointwiseExponentiate = (dist1, dist2): t => FromDist( - ToDistCombination(Pointwise, #Exponentiate, #Dist(dist2)), + let pointwisePower = (dist1, dist2): t => FromDist( + ToDistCombination(Pointwise, #Power, #Dist(dist2)), dist1, ) } diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/AlgebraicShapeCombination.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/AlgebraicShapeCombination.res index c0d85e60..70440878 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/AlgebraicShapeCombination.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/AlgebraicShapeCombination.res @@ -114,7 +114,7 @@ let combineShapesContinuousContinuous = ( | #Subtract => (m1, m2) => m1 -. m2 | #Multiply => (m1, m2) => m1 *. m2 | #Divide => (m1, mInv2) => m1 *. mInv2 - | #Exponentiate => (m1, mInv2) => m1 ** mInv2 + | #Power => (m1, mInv2) => m1 ** mInv2 | #Logarithm => (m1, m2) => log(m1) /. log(m2) } // note: here, mInv2 = mean(1 / t2) ~= 1 / mean(t2) @@ -124,7 +124,7 @@ let combineShapesContinuousContinuous = ( | #Add => (v1, v2, _, _) => v1 +. v2 | #Subtract => (v1, v2, _, _) => v1 +. v2 | #Multiply => (v1, v2, m1, m2) => v1 *. v2 +. v1 *. m2 ** 2. +. v2 *. m1 ** 2. - | #Exponentiate => (v1, v2, m1, m2) => v1 *. v2 +. v1 *. m2 ** 2. +. v2 *. m1 ** 2. + | #Power => (v1, v2, m1, m2) => v1 *. v2 +. v1 *. m2 ** 2. +. v2 *. m1 ** 2. | #Logarithm => (v1, v2, m1, m2) => v1 *. v2 +. v1 *. m2 ** 2. +. v2 *. m1 ** 2. | #Divide => (v1, vInv2, m1, mInv2) => v1 *. vInv2 +. v1 *. mInv2 ** 2. +. vInv2 *. m1 ** 2. } @@ -233,7 +233,7 @@ let combineShapesContinuousDiscrete = ( () } | #Multiply - | #Exponentiate + | #Power | #Logarithm | #Divide => for j in 0 to t2n - 1 { diff --git a/packages/squiggle-lang/src/rescript/OldInterpreter/ASTEvaluator.res b/packages/squiggle-lang/src/rescript/OldInterpreter/ASTEvaluator.res index 44c5565e..cd4c241d 100644 --- a/packages/squiggle-lang/src/rescript/OldInterpreter/ASTEvaluator.res +++ b/packages/squiggle-lang/src/rescript/OldInterpreter/ASTEvaluator.res @@ -118,7 +118,7 @@ module PointwiseCombination = { switch pointwiseOp { | #Add => pointwiseAdd(evaluationParams, t1, t2) | #Multiply => pointwiseCombine(\"*.", evaluationParams, t1, t2) - | #Exponentiate => pointwiseCombine(\"**", evaluationParams, t1, t2) + | #Power => pointwiseCombine(\"**", evaluationParams, t1, t2) } } diff --git a/packages/squiggle-lang/src/rescript/OldInterpreter/typeSystem/HardcodedFunctions.res b/packages/squiggle-lang/src/rescript/OldInterpreter/typeSystem/HardcodedFunctions.res index cf8fe470..8302b532 100644 --- a/packages/squiggle-lang/src/rescript/OldInterpreter/typeSystem/HardcodedFunctions.res +++ b/packages/squiggle-lang/src/rescript/OldInterpreter/typeSystem/HardcodedFunctions.res @@ -227,7 +227,7 @@ let all = [ }, (), ), - makeRenderedDistFloat("scaleExp", (dist, float) => verticalScaling(#Exponentiate, dist, float)), + makeRenderedDistFloat("scaleExp", (dist, float) => verticalScaling(#Power, dist, float)), makeRenderedDistFloat("scaleMultiply", (dist, float) => verticalScaling(#Multiply, dist, float)), makeRenderedDistFloat("scaleLog", (dist, float) => verticalScaling(#Logarithm, dist, float)), Multimodal._function, diff --git a/packages/squiggle-lang/src/rescript/OldParser/Parser.res b/packages/squiggle-lang/src/rescript/OldParser/Parser.res index 0a837823..6f5fd9ef 100644 --- a/packages/squiggle-lang/src/rescript/OldParser/Parser.res +++ b/packages/squiggle-lang/src/rescript/OldParser/Parser.res @@ -144,11 +144,11 @@ module MathAdtToDistDst = { | ("subtract", _) => Error("Subtraction needs two operands") | ("multiply", [l, r]) => toOkAlgebraic((#Multiply, l, r)) | ("multiply", _) => Error("Multiplication needs two operands") - | ("pow", [l, r]) => toOkAlgebraic((#Exponentiate, l, r)) + | ("pow", [l, r]) => toOkAlgebraic((#Power, l, r)) | ("pow", _) => Error("Exponentiation needs two operands") | ("dotMultiply", [l, r]) => toOkPointwise((#Multiply, l, r)) | ("dotMultiply", _) => Error("Dotwise multiplication needs two operands") - | ("dotPow", [l, r]) => toOkPointwise((#Exponentiate, l, r)) + | ("dotPow", [l, r]) => toOkPointwise((#Power, l, r)) | ("dotPow", _) => Error("Dotwise exponentiation needs two operands") | ("rightLogShift", [l, r]) => toOkPointwise((#Add, l, r)) | ("rightLogShift", _) => Error("Dotwise addition needs two operands") diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index 89be2d46..ea65b963 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -18,8 +18,8 @@ module Helpers = { | "divide" => #Divide | "log" => #Logarithm | "dotDivide" => #Divide - | "pow" => #Exponentiate - | "dotPow" => #Exponentiate + | "pow" => #Power + | "dotPow" => #Power | "multiply" => #Multiply | "dotMultiply" => #Multiply | "dotLog" => #Logarithm diff --git a/packages/squiggle-lang/src/rescript/Utility/Operation.res b/packages/squiggle-lang/src/rescript/Utility/Operation.res index 55e0b42f..5145955c 100644 --- a/packages/squiggle-lang/src/rescript/Utility/Operation.res +++ b/packages/squiggle-lang/src/rescript/Utility/Operation.res @@ -6,12 +6,12 @@ type algebraicOperation = [ | #Multiply | #Subtract | #Divide - | #Exponentiate + | #Power | #Logarithm ] @genType -type pointwiseOperation = [#Add | #Multiply | #Exponentiate] -type scaleOperation = [#Multiply | #Exponentiate | #Logarithm | #Divide] +type pointwiseOperation = [#Add | #Multiply | #Power] +type scaleOperation = [#Multiply | #Power | #Logarithm | #Divide] type distToFloatOperation = [ | #Pdf(float) | #Cdf(float) @@ -27,7 +27,7 @@ module Algebraic = { | #Add => \"+." | #Subtract => \"-." | #Multiply => \"*." - | #Exponentiate => \"**" + | #Power => \"**" | #Divide => \"/." | #Logarithm => (a, b) => log(a) /. log(b) } @@ -43,7 +43,7 @@ module Algebraic = { | #Add => "+" | #Subtract => "-" | #Multiply => "*" - | #Exponentiate => "**" + | #Power => "**" | #Divide => "/" | #Logarithm => "log" } @@ -56,7 +56,7 @@ module Pointwise = { let toString = x => switch x { | #Add => "+" - | #Exponentiate => "^" + | #Power => "^" | #Multiply => "*" } @@ -83,7 +83,7 @@ module Scale = { switch x { | #Multiply => \"*." | #Divide => \"/." - | #Exponentiate => \"**" + | #Power => \"**" | #Logarithm => (a, b) => log(a) /. log(b) } @@ -91,7 +91,7 @@ module Scale = { switch operation { | #Multiply => j`verticalMultiply($value, $scaleBy) ` | #Divide => j`verticalDivide($value, $scaleBy) ` - | #Exponentiate => j`verticalExponentiate($value, $scaleBy) ` + | #Power => j`verticalPower($value, $scaleBy) ` | #Logarithm => j`verticalLog($value, $scaleBy) ` } @@ -99,7 +99,7 @@ module Scale = { switch x { | #Multiply => (a, b) => Some(a *. b) | #Divide => (a, b) => Some(a /. b) - | #Exponentiate => (_, _) => None + | #Power => (_, _) => None | #Logarithm => (_, _) => None } @@ -107,7 +107,7 @@ module Scale = { switch x { | #Multiply => (_, _) => None // TODO: this could probably just be multiplied out (using Continuous.scaleBy) | #Divide => (_, _) => None - | #Exponentiate => (_, _) => None + | #Power => (_, _) => None | #Logarithm => (_, _) => None } } From 61aaca3e2ff86a1e80e22b8c2654f72eea388490 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 9 Apr 2022 18:10:06 -0400 Subject: [PATCH 02/10] Gave SampleSetDist a private type --- .../DistributionOperation_test.res | 3 +- .../__tests__/Distributions/Samples_test.res | 8 ++-- .../DistributionOperation.res | 2 +- .../Distributions/GenericDist/GenericDist.res | 31 +++++++----- .../GenericDist/GenericDist.resi | 3 +- .../GenericDist/GenericDist_Types.res | 2 +- .../SampleSetDist/SampleSetDist.res | 48 +++++++++++++++++++ ...leSet.res => SampleSetDist_ToPointSet.res} | 27 ----------- .../src/rescript/OldInterpreter/ASTTypes.res | 14 +++--- 9 files changed, 83 insertions(+), 55 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res rename packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/{SampleSet.res => SampleSetDist_ToPointSet.res} (85%) diff --git a/packages/squiggle-lang/__tests__/Distributions/DistributionOperation_test.res b/packages/squiggle-lang/__tests__/Distributions/DistributionOperation_test.res index cd22d512..f206b31d 100644 --- a/packages/squiggle-lang/__tests__/Distributions/DistributionOperation_test.res +++ b/packages/squiggle-lang/__tests__/Distributions/DistributionOperation_test.res @@ -91,8 +91,9 @@ describe("toPointSet", () => { }) test("on sample set distribution with under 4 points", () => { + let sampleSet = SampleSetDist.make([0.0, 1.0, 2.0, 3.0]) -> E.R.toExn; let result = - run(FromDist(ToDist(ToPointSet), SampleSet([0.0, 1.0, 2.0, 3.0])))->outputMap( + run(FromDist(ToDist(ToPointSet), SampleSet(sampleSet)))->outputMap( FromDist(ToFloat(#Mean)), ) expect(result)->toEqual(GenDistError(Other("Converting sampleSet to pointSet failed"))) diff --git a/packages/squiggle-lang/__tests__/Distributions/Samples_test.res b/packages/squiggle-lang/__tests__/Distributions/Samples_test.res index db80f9f7..5a48dd80 100644 --- a/packages/squiggle-lang/__tests__/Distributions/Samples_test.res +++ b/packages/squiggle-lang/__tests__/Distributions/Samples_test.res @@ -4,12 +4,12 @@ open TestHelpers describe("Continuous and discrete splits", () => { makeTest( "splits (1)", - SampleSet.Internals.T.splitContinuousAndDiscrete([1.432, 1.33455, 2.0]), + SampleSetDist_ToPointSet.Internals.T.splitContinuousAndDiscrete([1.432, 1.33455, 2.0]), ([1.432, 1.33455, 2.0], E.FloatFloatMap.empty()), ) makeTest( "splits (2)", - SampleSet.Internals.T.splitContinuousAndDiscrete([ + SampleSetDist_ToPointSet.Internals.T.splitContinuousAndDiscrete([ 1.432, 1.33455, 2.0, @@ -26,13 +26,13 @@ describe("Continuous and discrete splits", () => { E.A.concatMany([sorted, sorted, sorted, sorted]) |> Belt.SortArray.stableSortBy(_, compare) } - let (_, discrete1) = SampleSet.Internals.T.splitContinuousAndDiscrete( + let (_, discrete1) = SampleSetDist_ToPointSet.Internals.T.splitContinuousAndDiscrete( makeDuplicatedArray(10), ) let toArr1 = discrete1 |> E.FloatFloatMap.toArray makeTest("splitMedium at count=10", toArr1 |> Belt.Array.length, 10) - let (_c, discrete2) = SampleSet.Internals.T.splitContinuousAndDiscrete( + let (_c, discrete2) = SampleSetDist_ToPointSet.Internals.T.splitContinuousAndDiscrete( makeDuplicatedArray(500), ) let toArr2 = discrete2 |> E.FloatFloatMap.toArray diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res index 69a9a4ed..bb5f4f1a 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res @@ -128,7 +128,7 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => { ->E.R2.fmap(r => Dist(r)) ->OutputLocal.fromResult | ToDist(ToSampleSet(n)) => - dist->GenericDist.sampleN(n)->E.R2.fmap(r => Dist(SampleSet(r)))->OutputLocal.fromResult + dist->GenericDist.toSampleSetDist(n)->E.R2.fmap(r => Dist(SampleSet(r)))->OutputLocal.fromResult | ToDist(ToPointSet) => dist ->GenericDist.toPointSet(~xyPointLength, ~sampleCount, ()) diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res index ba19e60b..90381fba 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res @@ -2,16 +2,18 @@ type t = GenericDist_Types.genericDist type error = GenericDist_Types.error type toPointSetFn = t => result -type toSampleSetFn = t => result, error> +type toSampleSetFn = t => result type scaleMultiplyFn = (t, float) => result type pointwiseAddFn = (t, t) => result - +let mapStringErrors = n => n->E.R2.errMap(r => Error(GenericDist_Types.Other(r))) let sampleN = (t: t, n) => switch t { | PointSet(r) => Ok(PointSetDist.sampleNRendered(n, r)) | Symbolic(r) => Ok(SymbolicDist.T.sampleN(n, r)) - | SampleSet(r) => Ok(SampleSet.sampleN(r, n)) + | SampleSet(r) => Ok(SampleSetDist.sampleN(r, n)) } +let toSampleSetDist = (t: t, n) => sampleN(t, n)->E.R.bind(SampleSetDist.make)->mapStringErrors +let mapStringErrors = n => n->E.R2.errMap(r => Error(GenericDist_Types.Other(r))) let fromFloat = (f: float): t => Symbolic(SymbolicDist.Float.make(f)) @@ -63,7 +65,7 @@ let toPointSet = ( | PointSet(pointSet) => Ok(pointSet) | Symbolic(r) => Ok(SymbolicDist.T.toPointSetDist(~xSelection, xyPointLength, r)) | SampleSet(r) => { - let response = SampleSet.toPointSetDist( + let response = SampleSetDist.toPointSetDist( ~samples=r, ~samplingInputs={ sampleCount: sampleCount, @@ -167,8 +169,9 @@ module AlgebraicCombination = { t2: t, ) => { let arithmeticOperation = Operation.Algebraic.toFn(arithmeticOperation) - E.R.merge(toSampleSet(t1), toSampleSet(t2))->E.R2.fmap(((a, b)) => { - Belt.Array.zip(a, b)->E.A2.fmap(((a, b)) => arithmeticOperation(a, b)) + E.R.merge(toSampleSet(t1), toSampleSet(t2))->E.R.bind(((a, b)) => { + SampleSetDist.runMonteCarlo(arithmeticOperation, a, b) + ->mapStringErrors }) } @@ -200,13 +203,15 @@ module AlgebraicCombination = { | Some(Error(e)) => Error(Other(e)) | None => switch chooseConvolutionOrMonteCarlo(t1, t2) { - | #CalculateWithMonteCarlo => - runMonteCarlo( - toSampleSetFn, - arithmeticOperation, - t1, - t2, - )->E.R2.fmap(r => GenericDist_Types.SampleSet(r)) + | #CalculateWithMonteCarlo => { + let sampleSetDist: result = runMonteCarlo( + toSampleSetFn, + arithmeticOperation, + t1, + t2, + ) + sampleSetDist->E.R2.fmap(r => GenericDist_Types.SampleSet(r)) + } | #CalculateWithConvolution => runConvolution( toPointSetFn, diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi index adf3b9d4..b65489e3 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi @@ -1,11 +1,12 @@ type t = GenericDist_Types.genericDist type error = GenericDist_Types.error type toPointSetFn = t => result -type toSampleSetFn = t => result, error> +type toSampleSetFn = t => result type scaleMultiplyFn = (t, float) => result type pointwiseAddFn = (t, t) => result let sampleN: (t, int) => result, error> +let toSampleSetDist: (t, int) => Belt.Result.t let fromFloat: float => t diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res index 70754807..c3c923a4 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res @@ -1,6 +1,6 @@ type genericDist = | PointSet(PointSetTypes.pointSetDist) - | SampleSet(SampleSet.t) + | SampleSet(SampleSetDist.t) | Symbolic(SymbolicDistTypes.symbolicDist) @genType diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res new file mode 100644 index 00000000..cea650f8 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res @@ -0,0 +1,48 @@ +module T: { + type t + let make: array => result + let get: t => array +} = { + type t = array + let make = (a: array) => + if E.A.length(a) > 5 { + Ok(a) + } else { + Error("too small") + } + let get = (a: t) => a +} + +include T + +// TODO: Refactor to raise correct error when not enough samples + +let toPointSetDist = (~samples: t, ~samplingInputs: SamplingInputs.samplingInputs, ()) => + SampleSetDist_ToPointSet.toPointSetDist(~samples=get(samples), ~samplingInputs, ()) + +//Randomly get one sample from the distribution +let sample = (t: t): float => { + let i = E.Int.random(~min=0, ~max=E.A.length(get(t)) - 1) + E.A.unsafe_get(get(t), i) +} + +/* +If asked for a length of samples shorter or equal the length of the distribution, +return this first n samples of this distribution. +Else, return n random samples of the distribution. +The former helps in cases where multiple distributions are correlated. +However, if n > length(t), then there's no clear right answer, so we just randomly +sample everything. +*/ +let sampleN = (t: t, n) => { + if n <= E.A.length(get(t)) { + E.A.slice(get(t), ~offset=0, ~len=n) + } else { + Belt.Array.makeBy(n, _ => sample(t)) + } +} + +let runMonteCarlo = (fn: (float, float) => float, t1: t, t2: t) => { + let samples = Belt.Array.zip(get(t1), get(t2))->E.A2.fmap(((a, b)) => fn(a, b)) + make(samples) +} diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSet.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res similarity index 85% rename from packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSet.res rename to packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res index f8bce6f6..c8880f7a 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSet.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res @@ -1,8 +1,3 @@ -@genType -type t = array - -// TODO: Refactor to raise correct error when not enough samples - module Internals = { module Types = { type samplingStats = { @@ -145,25 +140,3 @@ let toPointSetDist = ( samplesParse } - -//Randomly get one sample from the distribution -let sample = (t: t): float => { - let i = E.Int.random(~min=0, ~max=E.A.length(t) - 1) - E.A.unsafe_get(t, i) -} - -/* -If asked for a length of samples shorter or equal the length of the distribution, -return this first n samples of this distribution. -Else, return n random samples of the distribution. -The former helps in cases where multiple distributions are correlated. -However, if n > length(t), then there's no clear right answer, so we just randomly -sample everything. -*/ -let sampleN = (t: t, n) => { - if n <= E.A.length(t) { - E.A.slice(t, ~offset=0, ~len=n) - } else { - Belt.Array.makeBy(n, _ => sample(t)) - } -} diff --git a/packages/squiggle-lang/src/rescript/OldInterpreter/ASTTypes.res b/packages/squiggle-lang/src/rescript/OldInterpreter/ASTTypes.res index 31217374..57b4577c 100644 --- a/packages/squiggle-lang/src/rescript/OldInterpreter/ASTTypes.res +++ b/packages/squiggle-lang/src/rescript/OldInterpreter/ASTTypes.res @@ -218,15 +218,15 @@ module SamplingDistribution = { algebraicOp, a, b, - ) + ) |> E.O.toResult("Could not get samples") + + let sampleSetDist = samples -> E.R.bind(SampleSetDist.make) let pointSetDist = - samples - |> E.O.fmap(r => - SampleSet.toPointSetDist(~samplingInputs=evaluationParams.samplingInputs, ~samples=r, ()) - ) - |> E.O.bind(_, r => r.pointSetDist) - |> E.O.toResult("No response") + sampleSetDist + -> E.R2.fmap(r => + SampleSetDist.toPointSetDist(~samplingInputs=evaluationParams.samplingInputs, ~samples=r, ())) + -> E.R.bind(r => r.pointSetDist |> E.O.toResult("combineShapesUsingSampling Error")) pointSetDist |> E.R.fmap(r => #Normalize(#RenderedDist(r))) }) } From fa3d874a4e263354c621b5fceb147c9b0e7aecd7 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 9 Apr 2022 20:21:02 -0400 Subject: [PATCH 03/10] Start of refactor for toPointSetDist --- .../Distributions/GenericDist/GenericDist.res | 30 ++++++++----------- .../SampleSetDist/SampleSetDist.res | 9 ++++-- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res index 90381fba..f87b3a22 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res @@ -64,22 +64,17 @@ let toPointSet = ( switch (t: t) { | PointSet(pointSet) => Ok(pointSet) | Symbolic(r) => Ok(SymbolicDist.T.toPointSetDist(~xSelection, xyPointLength, r)) - | SampleSet(r) => { - let response = SampleSetDist.toPointSetDist( - ~samples=r, - ~samplingInputs={ - sampleCount: sampleCount, - outputXYPoints: xyPointLength, - pointSetDistLength: xyPointLength, - kernelWidth: None, - }, - (), - ).pointSetDist - switch response { - | Some(r) => Ok(r) - | None => Error(Other("Converting sampleSet to pointSet failed")) - } - } + | SampleSet(r) => + SampleSetDist.toPointSetDist2( + ~samples=r, + ~samplingInputs={ + sampleCount: sampleCount, + outputXYPoints: xyPointLength, + pointSetDistLength: xyPointLength, + kernelWidth: None, + }, + (), + )->mapStringErrors } } @@ -170,8 +165,7 @@ module AlgebraicCombination = { ) => { let arithmeticOperation = Operation.Algebraic.toFn(arithmeticOperation) E.R.merge(toSampleSet(t1), toSampleSet(t2))->E.R.bind(((a, b)) => { - SampleSetDist.runMonteCarlo(arithmeticOperation, a, b) - ->mapStringErrors + SampleSetDist.map2(~fn=arithmeticOperation, ~t1=a, ~t2=b)->mapStringErrors }) } diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res index cea650f8..264b32ea 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res @@ -15,11 +15,15 @@ module T: { include T -// TODO: Refactor to raise correct error when not enough samples +let length = (t:t) => get(t) |> E.A.length; +// TODO: Refactor to raise correct error when not enough samples let toPointSetDist = (~samples: t, ~samplingInputs: SamplingInputs.samplingInputs, ()) => SampleSetDist_ToPointSet.toPointSetDist(~samples=get(samples), ~samplingInputs, ()) +let toPointSetDist2 = (~samples: t, ~samplingInputs: SamplingInputs.samplingInputs, ()) => + SampleSetDist_ToPointSet.toPointSetDist(~samples=get(samples), ~samplingInputs, ()).pointSetDist |> E.O.toResult("Failed to convert to PointSetDist") + //Randomly get one sample from the distribution let sample = (t: t): float => { let i = E.Int.random(~min=0, ~max=E.A.length(get(t)) - 1) @@ -42,7 +46,8 @@ let sampleN = (t: t, n) => { } } -let runMonteCarlo = (fn: (float, float) => float, t1: t, t2: t) => { +//TODO: Figure out what to do if distributions are different lengths. ``zip`` is kind of inelegant for this. +let map2 = (~fn: (float, float) => float, ~t1: t, ~t2: t) => { let samples = Belt.Array.zip(get(t1), get(t2))->E.A2.fmap(((a, b)) => fn(a, b)) make(samples) } From f17a842c526bf80ec56c96035478086aa89e0932 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 9 Apr 2022 20:27:03 -0400 Subject: [PATCH 04/10] Cleanup from previous refactor --- .../DistributionOperation_test.res | 9 --------- .../Distributions/GenericDist/GenericDist.res | 2 +- .../SampleSetDist/SampleSetDist.res | 18 +++++++++++------- .../src/rescript/OldInterpreter/ASTTypes.res | 7 +++---- 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Distributions/DistributionOperation_test.res b/packages/squiggle-lang/__tests__/Distributions/DistributionOperation_test.res index f206b31d..34a8dd6e 100644 --- a/packages/squiggle-lang/__tests__/Distributions/DistributionOperation_test.res +++ b/packages/squiggle-lang/__tests__/Distributions/DistributionOperation_test.res @@ -90,15 +90,6 @@ describe("toPointSet", () => { expect(result)->toBeSoCloseTo(5.0, ~digits=0) }) - test("on sample set distribution with under 4 points", () => { - let sampleSet = SampleSetDist.make([0.0, 1.0, 2.0, 3.0]) -> E.R.toExn; - let result = - run(FromDist(ToDist(ToPointSet), SampleSet(sampleSet)))->outputMap( - FromDist(ToFloat(#Mean)), - ) - expect(result)->toEqual(GenDistError(Other("Converting sampleSet to pointSet failed"))) - }) - test("on sample set", () => { let result = run(FromDist(ToDist(ToPointSet), normalDist5)) diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res index f87b3a22..a69d7f5d 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res @@ -65,7 +65,7 @@ let toPointSet = ( | PointSet(pointSet) => Ok(pointSet) | Symbolic(r) => Ok(SymbolicDist.T.toPointSetDist(~xSelection, xyPointLength, r)) | SampleSet(r) => - SampleSetDist.toPointSetDist2( + SampleSetDist.toPointSetDist( ~samples=r, ~samplingInputs={ sampleCount: sampleCount, diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res index 264b32ea..ccf1b775 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res @@ -15,14 +15,18 @@ module T: { include T -let length = (t:t) => get(t) |> E.A.length; +let length = (t: t) => get(t) |> E.A.length -// TODO: Refactor to raise correct error when not enough samples -let toPointSetDist = (~samples: t, ~samplingInputs: SamplingInputs.samplingInputs, ()) => - SampleSetDist_ToPointSet.toPointSetDist(~samples=get(samples), ~samplingInputs, ()) - -let toPointSetDist2 = (~samples: t, ~samplingInputs: SamplingInputs.samplingInputs, ()) => - SampleSetDist_ToPointSet.toPointSetDist(~samples=get(samples), ~samplingInputs, ()).pointSetDist |> E.O.toResult("Failed to convert to PointSetDist") +// TODO: Refactor to get error in the toPointSetDist function, instead of adding at very end. +let toPointSetDist = (~samples: t, ~samplingInputs: SamplingInputs.samplingInputs, ()): result< + PointSetTypes.pointSetDist, + string, +> => + SampleSetDist_ToPointSet.toPointSetDist( + ~samples=get(samples), + ~samplingInputs, + (), + ).pointSetDist |> E.O.toResult("Failed to convert to PointSetDist") //Randomly get one sample from the distribution let sample = (t: t): float => { diff --git a/packages/squiggle-lang/src/rescript/OldInterpreter/ASTTypes.res b/packages/squiggle-lang/src/rescript/OldInterpreter/ASTTypes.res index 57b4577c..3c14343a 100644 --- a/packages/squiggle-lang/src/rescript/OldInterpreter/ASTTypes.res +++ b/packages/squiggle-lang/src/rescript/OldInterpreter/ASTTypes.res @@ -222,11 +222,10 @@ module SamplingDistribution = { let sampleSetDist = samples -> E.R.bind(SampleSetDist.make) - let pointSetDist = + let pointSetDist = sampleSetDist - -> E.R2.fmap(r => - SampleSetDist.toPointSetDist(~samplingInputs=evaluationParams.samplingInputs, ~samples=r, ())) - -> E.R.bind(r => r.pointSetDist |> E.O.toResult("combineShapesUsingSampling Error")) + -> E.R.bind(r => + SampleSetDist.toPointSetDist(~samplingInputs=evaluationParams.samplingInputs, ~samples=r, ())); pointSetDist |> E.R.fmap(r => #Normalize(#RenderedDist(r))) }) } From db104694fd79d21288a388a9070f33380770c8be Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 9 Apr 2022 20:34:21 -0400 Subject: [PATCH 05/10] Cleaned up resultStringToResultError --- .../Distributions/GenericDist/GenericDist.res | 15 +++++++++------ .../GenericDist/GenericDist_Types.res | 9 +++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res index a69d7f5d..772e83f7 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res @@ -5,15 +5,14 @@ type toPointSetFn = t => result type toSampleSetFn = t => result type scaleMultiplyFn = (t, float) => result type pointwiseAddFn = (t, t) => result -let mapStringErrors = n => n->E.R2.errMap(r => Error(GenericDist_Types.Other(r))) let sampleN = (t: t, n) => switch t { | PointSet(r) => Ok(PointSetDist.sampleNRendered(n, r)) | Symbolic(r) => Ok(SymbolicDist.T.sampleN(n, r)) | SampleSet(r) => Ok(SampleSetDist.sampleN(r, n)) } -let toSampleSetDist = (t: t, n) => sampleN(t, n)->E.R.bind(SampleSetDist.make)->mapStringErrors -let mapStringErrors = n => n->E.R2.errMap(r => Error(GenericDist_Types.Other(r))) +let toSampleSetDist = (t: t, n) => + sampleN(t, n)->E.R.bind(SampleSetDist.make)->GenericDist_Types.Error.resultStringToResultError let fromFloat = (f: float): t => Symbolic(SymbolicDist.Float.make(f)) @@ -74,7 +73,7 @@ let toPointSet = ( kernelWidth: None, }, (), - )->mapStringErrors + )->GenericDist_Types.Error.resultStringToResultError } } @@ -88,7 +87,7 @@ let toSparkline = (t: t, ~sampleCount: int, ~bucketCount: int=20, unit): result< t ->toPointSet(~xSelection=#Linear, ~xyPointLength=bucketCount * 3, ~sampleCount, ()) ->E.R.bind(r => - r->PointSetDist.toSparkline(bucketCount)->E.R2.errMap(r => Error(GenericDist_Types.Other(r))) + r->PointSetDist.toSparkline(bucketCount)->GenericDist_Types.Error.resultStringToResultError ) module Truncate = { @@ -165,7 +164,11 @@ module AlgebraicCombination = { ) => { let arithmeticOperation = Operation.Algebraic.toFn(arithmeticOperation) E.R.merge(toSampleSet(t1), toSampleSet(t2))->E.R.bind(((a, b)) => { - SampleSetDist.map2(~fn=arithmeticOperation, ~t1=a, ~t2=b)->mapStringErrors + SampleSetDist.map2( + ~fn=arithmeticOperation, + ~t1=a, + ~t2=b, + )->GenericDist_Types.Error.resultStringToResultError }) } diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res index c3c923a4..96e7d3f8 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res @@ -10,6 +10,15 @@ type error = | DistributionVerticalShiftIsInvalid | Other(string) +module Error = { + type t = error + + let fromString = (s: string): t => Other(s) + + let resultStringToResultError: result<'a, string> => result<'a, error> = n => + n->E.R2.errMap(r => r->fromString->Error) +} + module Operation = { type direction = | Algebraic From 9ad73fe69b84671d6ff5f417c442149796913dcb Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 9 Apr 2022 20:36:33 -0400 Subject: [PATCH 06/10] Power should be ** to be consistent --- packages/squiggle-lang/src/rescript/Utility/Operation.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/Utility/Operation.res b/packages/squiggle-lang/src/rescript/Utility/Operation.res index 5145955c..6fb3b24b 100644 --- a/packages/squiggle-lang/src/rescript/Utility/Operation.res +++ b/packages/squiggle-lang/src/rescript/Utility/Operation.res @@ -56,7 +56,7 @@ module Pointwise = { let toString = x => switch x { | #Add => "+" - | #Power => "^" + | #Power => "**" | #Multiply => "*" } From 4338f482ef37d9d5e0017c3a7e44c74e9c79723e Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 9 Apr 2022 21:24:44 -0400 Subject: [PATCH 07/10] Added genType to SampleSetDist to make pass tests, other minor fixes --- .../DistributionOperation.res | 14 ++++---- .../Distributions/GenericDist/GenericDist.res | 35 +++++++------------ .../GenericDist/GenericDist.resi | 3 +- .../SampleSetDist/SampleSetDist.res | 3 +- .../src/rescript/OldInterpreter/ASTTypes.res | 2 +- 5 files changed, 26 insertions(+), 31 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res index bb5f4f1a..71776f61 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res @@ -128,7 +128,10 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => { ->E.R2.fmap(r => Dist(r)) ->OutputLocal.fromResult | ToDist(ToSampleSet(n)) => - dist->GenericDist.toSampleSetDist(n)->E.R2.fmap(r => Dist(SampleSet(r)))->OutputLocal.fromResult + dist + ->GenericDist.toSampleSetDist(n) + ->E.R2.fmap(r => Dist(SampleSet(r))) + ->OutputLocal.fromResult | ToDist(ToPointSet) => dist ->GenericDist.toPointSet(~xyPointLength, ~sampleCount, ()) @@ -204,7 +207,8 @@ module Constructors = { C.truncate(dist, leftCutoff, rightCutoff)->run(~env)->toDistR let inspect = (~env, dist) => C.inspect(dist)->run(~env)->toDistR let toString = (~env, dist) => C.toString(dist)->run(~env)->toStringR - let toSparkline = (~env, dist, bucketCount) => C.toSparkline(dist, bucketCount)->run(~env)->toStringR + let toSparkline = (~env, dist, bucketCount) => + C.toSparkline(dist, bucketCount)->run(~env)->toStringR let algebraicAdd = (~env, dist1, dist2) => C.algebraicAdd(dist1, dist2)->run(~env)->toDistR let algebraicMultiply = (~env, dist1, dist2) => C.algebraicMultiply(dist1, dist2)->run(~env)->toDistR @@ -213,8 +217,7 @@ module Constructors = { C.algebraicSubtract(dist1, dist2)->run(~env)->toDistR let algebraicLogarithm = (~env, dist1, dist2) => C.algebraicLogarithm(dist1, dist2)->run(~env)->toDistR - let algebraicPower = (~env, dist1, dist2) => - C.algebraicPower(dist1, dist2)->run(~env)->toDistR + let algebraicPower = (~env, dist1, dist2) => C.algebraicPower(dist1, dist2)->run(~env)->toDistR let pointwiseAdd = (~env, dist1, dist2) => C.pointwiseAdd(dist1, dist2)->run(~env)->toDistR let pointwiseMultiply = (~env, dist1, dist2) => C.pointwiseMultiply(dist1, dist2)->run(~env)->toDistR @@ -223,6 +226,5 @@ module Constructors = { C.pointwiseSubtract(dist1, dist2)->run(~env)->toDistR let pointwiseLogarithm = (~env, dist1, dist2) => C.pointwiseLogarithm(dist1, dist2)->run(~env)->toDistR - let pointwisePower = (~env, dist1, dist2) => - C.pointwisePower(dist1, dist2)->run(~env)->toDistR + let pointwisePower = (~env, dist1, dist2) => C.pointwisePower(dist1, dist2)->run(~env)->toDistR } diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res index 772e83f7..b14ea27f 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res @@ -5,14 +5,16 @@ type toPointSetFn = t => result type toSampleSetFn = t => result type scaleMultiplyFn = (t, float) => result type pointwiseAddFn = (t, t) => result + let sampleN = (t: t, n) => switch t { - | PointSet(r) => Ok(PointSetDist.sampleNRendered(n, r)) - | Symbolic(r) => Ok(SymbolicDist.T.sampleN(n, r)) - | SampleSet(r) => Ok(SampleSetDist.sampleN(r, n)) + | PointSet(r) => PointSetDist.sampleNRendered(n, r) + | Symbolic(r) => SymbolicDist.T.sampleN(n, r) + | SampleSet(r) => SampleSetDist.sampleN(r, n) } + let toSampleSetDist = (t: t, n) => - sampleN(t, n)->E.R.bind(SampleSetDist.make)->GenericDist_Types.Error.resultStringToResultError + SampleSetDist.make(sampleN(t, n))->GenericDist_Types.Error.resultStringToResultError let fromFloat = (f: float): t => Symbolic(SymbolicDist.Float.make(f)) @@ -72,7 +74,6 @@ let toPointSet = ( pointSetDistLength: xyPointLength, kernelWidth: None, }, - (), )->GenericDist_Types.Error.resultStringToResultError } } @@ -162,14 +163,12 @@ module AlgebraicCombination = { t1: t, t2: t, ) => { - let arithmeticOperation = Operation.Algebraic.toFn(arithmeticOperation) - E.R.merge(toSampleSet(t1), toSampleSet(t2))->E.R.bind(((a, b)) => { - SampleSetDist.map2( - ~fn=arithmeticOperation, - ~t1=a, - ~t2=b, - )->GenericDist_Types.Error.resultStringToResultError + let fn = Operation.Algebraic.toFn(arithmeticOperation) + E.R.merge(toSampleSet(t1), toSampleSet(t2)) + ->E.R.bind(((t1, t2)) => { + SampleSetDist.map2(~fn, ~t1, ~t2)->GenericDist_Types.Error.resultStringToResultError }) + ->E.R2.fmap(r => GenericDist_Types.SampleSet(r)) } //I'm (Ozzie) really just guessing here, very little idea what's best @@ -200,15 +199,7 @@ module AlgebraicCombination = { | Some(Error(e)) => Error(Other(e)) | None => switch chooseConvolutionOrMonteCarlo(t1, t2) { - | #CalculateWithMonteCarlo => { - let sampleSetDist: result = runMonteCarlo( - toSampleSetFn, - arithmeticOperation, - t1, - t2, - ) - sampleSetDist->E.R2.fmap(r => GenericDist_Types.SampleSet(r)) - } + | #CalculateWithMonteCarlo => runMonteCarlo(toSampleSetFn, arithmeticOperation, t1, t2) | #CalculateWithConvolution => runConvolution( toPointSetFn, @@ -274,7 +265,7 @@ let mixture = ( ~pointwiseAddFn: pointwiseAddFn, ) => { if E.A.length(values) == 0 { - Error(GenericDist_Types.Other("mixture must have at least 1 element")) + Error(GenericDist_Types.Other("Mixture error: mixture must have at least 1 element")) } else { let totalWeight = values->E.A2.fmap(E.Tuple2.second)->E.A.Floats.sum let properlyWeightedValues = diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi index b65489e3..4565ec14 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi @@ -5,7 +5,8 @@ type toSampleSetFn = t => result type scaleMultiplyFn = (t, float) => result type pointwiseAddFn = (t, t) => result -let sampleN: (t, int) => result, error> +let sampleN: (t, int) => array + let toSampleSetDist: (t, int) => Belt.Result.t let fromFloat: float => t diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res index ccf1b775..7a63332f 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res @@ -1,4 +1,5 @@ module T: { + @genType type t let make: array => result let get: t => array @@ -18,7 +19,7 @@ include T let length = (t: t) => get(t) |> E.A.length // TODO: Refactor to get error in the toPointSetDist function, instead of adding at very end. -let toPointSetDist = (~samples: t, ~samplingInputs: SamplingInputs.samplingInputs, ()): result< +let toPointSetDist = (~samples: t, ~samplingInputs: SamplingInputs.samplingInputs): result< PointSetTypes.pointSetDist, string, > => diff --git a/packages/squiggle-lang/src/rescript/OldInterpreter/ASTTypes.res b/packages/squiggle-lang/src/rescript/OldInterpreter/ASTTypes.res index 3c14343a..17477f8f 100644 --- a/packages/squiggle-lang/src/rescript/OldInterpreter/ASTTypes.res +++ b/packages/squiggle-lang/src/rescript/OldInterpreter/ASTTypes.res @@ -225,7 +225,7 @@ module SamplingDistribution = { let pointSetDist = sampleSetDist -> E.R.bind(r => - SampleSetDist.toPointSetDist(~samplingInputs=evaluationParams.samplingInputs, ~samples=r, ())); + SampleSetDist.toPointSetDist(~samplingInputs=evaluationParams.samplingInputs, ~samples=r)); pointSetDist |> E.R.fmap(r => #Normalize(#RenderedDist(r))) }) } From 5b0efbb3a85b796acea70f091d74c49d0c725bce Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 9 Apr 2022 21:31:34 -0400 Subject: [PATCH 08/10] Bandwidth -> SampleSetDist_Bandwidth --- .../squiggle-lang/__tests__/Bandwidth_test.res | 4 ++-- .../Distributions/SampleSetDist/SampleSetDist.res | 14 +++++++++++--- .../{Bandwidth.res => SampleSetDist_Bandwidth.res} | 2 +- .../SampleSetDist/SampleSetDist_ToPointSet.res | 4 ++-- 4 files changed, 16 insertions(+), 8 deletions(-) rename packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/{Bandwidth.res => SampleSetDist_Bandwidth.res} (94%) diff --git a/packages/squiggle-lang/__tests__/Bandwidth_test.res b/packages/squiggle-lang/__tests__/Bandwidth_test.res index d37e5bb8..4e5c630a 100644 --- a/packages/squiggle-lang/__tests__/Bandwidth_test.res +++ b/packages/squiggle-lang/__tests__/Bandwidth_test.res @@ -4,10 +4,10 @@ open Expect describe("Bandwidth", () => { test("nrd0()", () => { let data = [1., 4., 3., 2.] - expect(Bandwidth.nrd0(data)) -> toEqual(0.7625801874014622) + expect(SampleSetDist_Bandwidth.nrd0(data)) -> toEqual(0.7625801874014622) }) test("nrd()", () => { let data = [1., 4., 3., 2.] - expect(Bandwidth.nrd(data)) -> toEqual(0.8981499984950554) + expect(SampleSetDist_Bandwidth.nrd(data)) -> toEqual(0.8981499984950554) }) }) diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res index 7a63332f..f8dfd84a 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res @@ -1,3 +1,8 @@ +/* +This is used as a smart constructor. The only way to create a SampleSetDist.t is to call +this constructor. +https://stackoverflow.com/questions/66909578/how-to-make-a-type-constructor-private-in-rescript-except-in-current-module +*/ module T: { @genType type t @@ -16,9 +21,12 @@ module T: { include T -let length = (t: t) => get(t) |> E.A.length +let length = (t: t) => get(t)->E.A.length -// TODO: Refactor to get error in the toPointSetDist function, instead of adding at very end. +/* +TODO: Refactor to get a more precise estimate. Also, this code is just fairly messy, could use +some refactoring. +*/ let toPointSetDist = (~samples: t, ~samplingInputs: SamplingInputs.samplingInputs): result< PointSetTypes.pointSetDist, string, @@ -27,7 +35,7 @@ let toPointSetDist = (~samples: t, ~samplingInputs: SamplingInputs.samplingInput ~samples=get(samples), ~samplingInputs, (), - ).pointSetDist |> E.O.toResult("Failed to convert to PointSetDist") + ).pointSetDist->E.O2.toResult("Failed to convert to PointSetDist") //Randomly get one sample from the distribution let sample = (t: t): float => { diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/Bandwidth.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res similarity index 94% rename from packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/Bandwidth.res rename to packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res index 6650b862..aef659d1 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/Bandwidth.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res @@ -1,4 +1,4 @@ -//The math here was taken from https://github.com/jasondavies/science.js/blob/master/src/stats/bandwidth.js +//The math here was taken from https://github.com/jasondavies/science.js/blob/master/src/stats/SampleSetDist_Bandwidth.js let len = x => E.A.length(x) |> float_of_int diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res index c8880f7a..59b4fa46 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res @@ -70,7 +70,7 @@ module Internals = { let formatUnitWidth = w => Jstat.max([w, 1.0]) |> int_of_float let suggestedUnitWidth = (samples, outputXYPoints) => { - let suggestedXWidth = Bandwidth.nrd0(samples) + let suggestedXWidth = SampleSetDist_Bandwidth.nrd0(samples) xWidthToUnitWidth(samples, outputXYPoints, suggestedXWidth) } @@ -97,7 +97,7 @@ let toPointSetDist = ( let pdf = continuousPart |> E.A.length > 5 ? { - let _suggestedXWidth = Bandwidth.nrd0(continuousPart) + let _suggestedXWidth = SampleSetDist_Bandwidth.nrd0(continuousPart) // todo: This does some recalculating from the last step. let _suggestedUnitWidth = Internals.T.suggestedUnitWidth( continuousPart, From ec5dc4667f5dc85fadfa30c80d6cc5052312a034 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 9 Apr 2022 21:39:10 -0400 Subject: [PATCH 09/10] Samples_test -> SampleSetDist_test --- .../Distributions/{Samples_test.res => SampleSetDist_test.res} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/squiggle-lang/__tests__/Distributions/{Samples_test.res => SampleSetDist_test.res} (100%) diff --git a/packages/squiggle-lang/__tests__/Distributions/Samples_test.res b/packages/squiggle-lang/__tests__/Distributions/SampleSetDist_test.res similarity index 100% rename from packages/squiggle-lang/__tests__/Distributions/Samples_test.res rename to packages/squiggle-lang/__tests__/Distributions/SampleSetDist_test.res From c94a70b93ac98f9ad05245c51d69b8d160aa2ea0 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 9 Apr 2022 21:56:05 -0400 Subject: [PATCH 10/10] Fixed tests --- packages/squiggle-lang/__tests__/JS__Test.ts | 3 ++- packages/squiggle-lang/src/js/index.ts | 5 +++++ .../rescript/Distributions/SampleSetDist/SampleSetDist.res | 4 +++- packages/squiggle-lang/src/rescript/TypescriptInterface.res | 3 +++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/__tests__/JS__Test.ts b/packages/squiggle-lang/__tests__/JS__Test.ts index ba2f91f4..8e5961a3 100644 --- a/packages/squiggle-lang/__tests__/JS__Test.ts +++ b/packages/squiggle-lang/__tests__/JS__Test.ts @@ -1,4 +1,4 @@ -import { run, GenericDist, resultMap } from "../src/js/index"; +import { run, GenericDist, resultMap, makeSampleSetDist } from "../src/js/index"; let testRun = (x: string) => { let result = run(x); @@ -41,6 +41,7 @@ describe("Multimodal too many weights error", () => { describe("GenericDist", () => { //It's important that sampleCount is less than 9. If it's more, than that will create randomness + //Also, note, the value should be created using makeSampleSetDist() later on. let env = { sampleCount: 8, xyPointLength: 100 }; let dist = new GenericDist( { tag: "SampleSet", value: [3, 4, 5, 6, 6, 7, 10, 15, 30] }, diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 1f67e369..4892c2f3 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -14,6 +14,7 @@ import { resultFloat, resultString, } from "../rescript/TypescriptInterface.gen"; +export {makeSampleSetDist} from "../rescript/TypescriptInterface.gen"; import { Constructors_mean, Constructors_sample, @@ -79,6 +80,10 @@ export function resultMap(r: result, mapFn: any): result { } } +export function resultExn(r: result): any { + r.value +} + export class GenericDist { t: genericDist; env: env; diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res index f8dfd84a..fcd4055d 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res @@ -4,8 +4,10 @@ this constructor. https://stackoverflow.com/questions/66909578/how-to-make-a-type-constructor-private-in-rescript-except-in-current-module */ module T: { + //This really should be hidden (remove the array). The reason it isn't is to act as an escape hatch in JS__Test.ts. + //When we get a good functional library in TS, we could refactor that out. @genType - type t + type t = array let make: array => result let get: t => array } = { diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index fb30ea24..6fe6f3d4 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -22,3 +22,6 @@ type resultDist = result type resultFloat = result @genType type resultString = result + +@genType +let makeSampleSetDist = SampleSetDist.make \ No newline at end of file