diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 4b8cddab..4ffeb972 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -28,6 +28,7 @@ import { Constructors_cdf, Constructors_inv, Constructors_normalize, + Constructors_isNormalized, Constructors_toPointSet, Constructors_toSampleSet, Constructors_truncate, @@ -189,6 +190,10 @@ export class Distribution { return Constructors_inv({ env: this.env }, this.t, n); } + isNormalized(): result { + return Constructors_isNormalized({ env: this.env }, this.t); + } + normalize(): result { return this.mapResultDist( Constructors_normalize({ env: this.env }, this.t) diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res index 7ae78e08..a2196f4c 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res @@ -13,6 +13,7 @@ type outputType = | Dist(genericDist) | Float(float) | String(string) + | Bool(bool) | GenDistError(error) /* @@ -66,6 +67,18 @@ module OutputLocal = { | e => Error(toErrorOrUnreachable(e)) } + let toBool = (t: t) => + switch t { + | Bool(d) => Some(d) + | _ => None + } + + let toBoolR = (t: t): result => + switch t { + | Bool(r) => Ok(r) + | e => Error(toErrorOrUnreachable(e)) + } + //This is used to catch errors in other switch statements. let fromResult = (r: result): outputType => switch r { @@ -107,8 +120,8 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => { (), )->OutputLocal.toDistR - let fromDistFn = (subFnName: GenericDist_Types.Operation.fromDist, dist: genericDist) => - switch subFnName { + let fromDistFn = (subFnName: GenericDist_Types.Operation.fromDist, dist: genericDist) =>{ + let response = switch subFnName { | ToFloat(distToFloatOperation) => GenericDist.toFloatOperation(dist, ~toPointSetFn, ~distToFloatOperation) ->E.R2.fmap(r => Float(r)) @@ -123,6 +136,7 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => { Dist(dist) } | ToDist(Normalize) => dist->GenericDist.normalize->Dist + | ToBool(IsNormalized) => dist->GenericDist.isNormalized->Bool | ToDist(Truncate(leftCutoff, rightCutoff)) => GenericDist.truncate(~toPointSetFn, ~leftCutoff, ~rightCutoff, dist, ()) ->E.R2.fmap(r => Dist(r)) @@ -154,6 +168,8 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => { ->E.R2.fmap(r => Dist(r)) ->OutputLocal.fromResult } + response + } switch functionCallInfo { | FromDist(subFnName, dist) => fromDistFn(subFnName, dist) @@ -201,6 +217,7 @@ module Constructors = { let inv = (~env, dist, f) => C.inv(dist, f)->run(~env)->toFloatR let pdf = (~env, dist, f) => C.pdf(dist, f)->run(~env)->toFloatR let normalize = (~env, dist) => C.normalize(dist)->run(~env)->toDistR + 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 truncate = (~env, dist, leftCutoff, rightCutoff) => diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi index e4f7759f..9b21a04e 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi @@ -11,6 +11,7 @@ type outputType = | Dist(genericDist) | Float(float) | String(string) + | Bool(bool) | GenDistError(error) @genType @@ -34,6 +35,8 @@ module Output: { let toFloatR: t => result let toString: t => option let toStringR: t => result + let toBool: t => option + let toBoolR: t => result let toError: t => option let fmap: (~env: env, t, GenericDist_Types.Operation.singleParamaterFunction) => t } @@ -52,6 +55,8 @@ module Constructors: { @genType let normalize: (~env: env, genericDist) => result @genType + let isNormalized: (~env: env, genericDist) => result + @genType let toPointSet: (~env: env, genericDist) => result @genType let toSampleSet: (~env: env, genericDist, int) => result diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res index 1f8739c4..1fe0293f 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res @@ -32,6 +32,15 @@ let normalize = (t: t): t => | SampleSet(_) => t } +let integralEndY = (t: t): float => + switch t { + | PointSet(r) => PointSetDist.T.integralEndY(r) + | Symbolic(_) => 1.0 + | SampleSet(_) => 1.0 + } + +let isNormalized = (t: t): bool => integralEndY(t) == 1.0 + let toFloatOperation = ( t, ~toPointSetFn: toPointSetFn, diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi index bd6755fd..c49d18b5 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi @@ -15,6 +15,8 @@ let toString: t => string let normalize: t => t +let isNormalized: t => bool + let toFloatOperation: ( t, ~toPointSetFn: toPointSetFn, 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 a0ddc911..b045a6d5 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist_Types.res @@ -71,11 +71,14 @@ module Operation = { | ToString | ToSparkline(int) + type toBool = IsNormalized + type fromDist = | ToFloat(toFloat) | ToDist(toDist) | ToDistCombination(direction, arithmeticOperation, [#Dist(genericDist) | #Float(float)]) | ToString(toString) + | ToBool(toBool) type singleParamaterFunction = | FromDist(fromDist) @@ -101,6 +104,7 @@ module Operation = { | ToDist(Inspect) => `inspect` | ToString(ToString) => `toString` | ToString(ToSparkline(n)) => `toSparkline(${E.I.toString(n)})` + | ToBool(IsNormalized) => `isNormalized` | ToDistCombination(Algebraic, _, _) => `algebraic` | ToDistCombination(Pointwise, _, _) => `pointwise` } @@ -131,6 +135,7 @@ module Constructors = { let inv = (dist, x): t => FromDist(ToFloat(#Inv(x)), dist) let pdf = (dist, x): t => FromDist(ToFloat(#Pdf(x)), dist) let normalize = (dist): t => FromDist(ToDist(Normalize), dist) + 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 truncate = (dist, left, right): t => FromDist(ToDist(Truncate(left, right)), dist) diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Distributions.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Distributions.res index 28c8104b..0821611c 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Distributions.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Distributions.res @@ -47,6 +47,7 @@ module Dist = (T: dist) => { let truncate = T.truncate let mean = T.mean let variance = T.variance + let integralEndY = T.integralEndY let updateIntegralCache = T.updateIntegralCache diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res index fcd4055d..6b2fbc9f 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res @@ -12,12 +12,14 @@ module T: { let get: t => array } = { type t = array - let make = (a: array) => + let make = (a: array) =>{ + Js.log2("makingFromArray", a); if E.A.length(a) > 5 { Ok(a) } else { Error("too small") } + } let get = (a: t) => a } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index b0ce84e3..3118c8b0 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -1,9 +1,11 @@ module ExpressionValue = ReducerInterface_ExpressionValue type expressionValue = ReducerInterface_ExpressionValue.expressionValue +let defaultSampleCount = 10000 + let runGenericOperation = DistributionOperation.run( ~env={ - sampleCount: 1000, + sampleCount: defaultSampleCount, xyPointLength: 1000, }, ) @@ -52,6 +54,13 @@ module Helpers = { FromDist(GenericDist_Types.Operation.ToString(fnCall), dist)->runGenericOperation->Some } + let toBoolFn = ( + fnCall: GenericDist_Types.Operation.toBool, + dist: GenericDist_Types.genericDist, + ) => { + FromDist(GenericDist_Types.Operation.ToBool(fnCall), dist)->runGenericOperation->Some + } + let toDistFn = (fnCall: GenericDist_Types.Operation.toDist, dist) => { FromDist(GenericDist_Types.Operation.ToDist(fnCall), dist)->runGenericOperation->Some } @@ -193,12 +202,17 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option< // https://mathjs.org/docs/reference/functions/exp.html Helpers.twoDiststoDistFn(Algebraic, "pow", GenericDist.fromFloat(Math.e), a)->Some | ("normalize", [EvDistribution(dist)]) => Helpers.toDistFn(Normalize, dist) + | ("isNormalized", [EvDistribution(dist)]) => Helpers.toBoolFn(IsNormalized, dist) | ("toPointSet", [EvDistribution(dist)]) => Helpers.toDistFn(ToPointSet, dist) | ("cdf", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Cdf(float), dist) | ("pdf", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Pdf(float), dist) | ("inv", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Inv(float), dist) | ("toSampleSet", [EvDistribution(dist), EvNumber(float)]) => Helpers.toDistFn(ToSampleSet(Belt.Int.fromFloat(float)), dist) + | ("toSampleSet", [EvDistribution(dist)]) => + Helpers.toDistFn(ToSampleSet(defaultSampleCount), dist) + | ("inspect", [EvDistribution(dist)]) => + Helpers.toDistFn(Inspect, dist) | ("truncateLeft", [EvDistribution(dist), EvNumber(float)]) => Helpers.toDistFn(Truncate(Some(float), None), dist) | ("truncateRight", [EvDistribution(dist), EvNumber(float)]) => @@ -244,6 +258,7 @@ let genericOutputToReducerValue = (o: DistributionOperation.outputType): result< | Dist(d) => Ok(ReducerInterface_ExpressionValue.EvDistribution(d)) | Float(d) => Ok(EvNumber(d)) | String(d) => Ok(EvString(d)) + | Bool(d) => Ok(EvBool(d)) | GenDistError(NotYetImplemented) => Error(RETodo("Function not yet implemented")) | GenDistError(Unreachable) => Error(RETodo("Unreachable")) | GenDistError(DistributionVerticalShiftIsInvalid) =>