From 2d84805f8814510c5d06d620dd9319b9250d2200 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Mon, 2 May 2022 17:15:23 -0400 Subject: [PATCH] Added infinity error; fixed infinities in logs Value: [1e-3 to 3e-2] --- .../__tests__/Distributions/Scale_test.res | 19 +++++++++++++++++++ .../__tests__/Distributions/Score_test.res | 3 --- .../squiggle-lang/__tests__/TestHelpers.res | 16 ++++++++++++++++ .../DistributionOperation.res | 2 ++ .../DistributionOperation.resi | 4 ++++ .../Distributions/DistributionTypes.res | 1 + .../Distributions/PointSetDist/Discrete.res | 10 +++++----- .../src/rescript/Utility/Operation.res | 11 ++++++++++- 8 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 packages/squiggle-lang/__tests__/Distributions/Scale_test.res delete mode 100644 packages/squiggle-lang/__tests__/Distributions/Score_test.res diff --git a/packages/squiggle-lang/__tests__/Distributions/Scale_test.res b/packages/squiggle-lang/__tests__/Distributions/Scale_test.res new file mode 100644 index 00000000..c9d52d0c --- /dev/null +++ b/packages/squiggle-lang/__tests__/Distributions/Scale_test.res @@ -0,0 +1,19 @@ +/* +This test case comes via Nuño https://github.com/quantified-uncertainty/squiggle/issues/433 + + +*/ + +open Jest +open Expect +open TestHelpers + +describe("", () => { + test("", () => { + let scalelog = DistributionOperation.Constructors.scaleLogarithm(~env, mkExponential(10.0), 2.0) + + E.R2.bind(DistributionOperation.Constructors.mean(~env), scalelog) + ->expect + ->toEqual(Ok(-2.348336572091017)) + }) +}) diff --git a/packages/squiggle-lang/__tests__/Distributions/Score_test.res b/packages/squiggle-lang/__tests__/Distributions/Score_test.res deleted file mode 100644 index eb096950..00000000 --- a/packages/squiggle-lang/__tests__/Distributions/Score_test.res +++ /dev/null @@ -1,3 +0,0 @@ -open Jest -open Expect -open TestHelpers diff --git a/packages/squiggle-lang/__tests__/TestHelpers.res b/packages/squiggle-lang/__tests__/TestHelpers.res index cbb3258d..4502c68a 100644 --- a/packages/squiggle-lang/__tests__/TestHelpers.res +++ b/packages/squiggle-lang/__tests__/TestHelpers.res @@ -60,3 +60,19 @@ let cauchyMake = SymbolicDist.Cauchy.make let lognormalMake = SymbolicDist.Lognormal.make let triangularMake = SymbolicDist.Triangular.make let floatMake = SymbolicDist.Float.make + +let normalMakeR = (mean, stdev) => + E.R.fmap(s => DistributionTypes.Symbolic(s), SymbolicDist.Normal.make(mean, stdev)) +let betaMakeR = (alpha, beta) => + E.R.fmap(s => DistributionTypes.Symbolic(s), SymbolicDist.Beta.make(alpha, beta)) +let exponentialMakeR = rate => + E.R.fmap(s => DistributionTypes.Symbolic(s), SymbolicDist.Exponential.make(rate)) +let uniformMakeR = (low, high) => + E.R.fmap(s => DistributionTypes.Symbolic(s), SymbolicDist.Uniform.make(low, high)) +let cauchyMakeR = (local, rate) => + E.R.fmap(s => DistributionTypes.Symbolic(s), SymbolicDist.Cauchy.make(local, rate)) +let lognormalMakeR = (mu, sigma) => + E.R.fmap(s => DistributionTypes.Symbolic(s), SymbolicDist.Lognormal.make(mu, sigma)) +let triangularMakeR = (low, mode, high) => + E.R.fmap(s => DistributionTypes.Symbolic(s), SymbolicDist.Triangular.make(low, mode, high)) +// let floatMakeR = x =>E.R.fmap(s => DistributionTypes.Symbolic(s), SymbolicDist.Float.make(x)) diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res index 8d65ca66..4d2f190e 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res @@ -266,6 +266,8 @@ module Constructors = { 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 scalePower = (~env, dist, n) => C.scalePower(dist, n)->run(~env)->toDistR + let scaleLogarithm = (~env, dist, n) => C.scaleLogarithm(dist, n)->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 diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi index 738f0e89..4a54099c 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi @@ -85,6 +85,10 @@ module Constructors: { @genType let algebraicPower: (~env: env, genericDist, genericDist) => result @genType + let scaleLogarithm: (~env: env, genericDist, float) => result + @genType + let scalePower: (~env: env, genericDist, float) => result + @genType let pointwiseAdd: (~env: env, genericDist, genericDist) => result @genType let pointwiseMultiply: (~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 2cc7df49..d5b38855 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res @@ -117,6 +117,7 @@ module DistributionOperation = { | ToFloat(#Mean) => `mean` | ToFloat(#Pdf(r)) => `pdf(${E.Float.toFixed(r)})` | ToFloat(#Sample) => `sample` + | ToFloat(#IntegralSum) => `integralSum` | ToScore(LogScore(_)) => `logScore` | ToDist(Normalize) => `normalize` | ToDist(ToPointSet) => `toPointSet` diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res index 59858420..4eef1f91 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res @@ -38,11 +38,11 @@ let combinePointwise = ( t1: PointSetTypes.discreteShape, t2: PointSetTypes.discreteShape, ): result => { - let combinedIntegralSum = Common.combineIntegralSums( - integralSumCachesFn, - t1.integralSumCache, - t2.integralSumCache, - ) + // let combinedIntegralSum = Common.combineIntegralSums( + // integralSumCachesFn, + // t1.integralSumCache, + // t2.integralSumCache, + // ) // TODO: does it ever make sense to pointwise combine the integrals here? // It could be done for pointwise additions, but is that ever needed? diff --git a/packages/squiggle-lang/src/rescript/Utility/Operation.res b/packages/squiggle-lang/src/rescript/Utility/Operation.res index 4a1ef91a..8f67c340 100644 --- a/packages/squiggle-lang/src/rescript/Utility/Operation.res +++ b/packages/squiggle-lang/src/rescript/Utility/Operation.res @@ -52,6 +52,7 @@ module Convolution = { type operationError = | DivisionByZeroError | ComplexNumberError + | InfinityError @genType module Error = { @@ -62,6 +63,7 @@ module Error = { switch err { | DivisionByZeroError => "Cannot divide by zero" | ComplexNumberError => "Operation returned complex result" + | InfinityError => "Operation returned + or - infinity" } } @@ -86,6 +88,8 @@ let logarithm = (a: float, b: float): result => Ok(0.) } else if a > 0.0 && b > 0.0 { Ok(log(a) /. log(b)) + } else if a == 0.0 { + Error(InfinityError) } else { Error(ComplexNumberError) } @@ -150,7 +154,12 @@ module Scale = { | #Multiply => Ok(a *. b) | #Divide => divide(a, b) | #Power => power(a, b) - | #Logarithm => logarithm(a, b) + | #Logarithm => + if a < MagicNumbers.Epsilon.seven { + Ok(0.0) + } else { + logarithm(a, b) + } } let format = (operation: t, value, scaleBy) =>