From 7e360b290e06345d4684e7e5d47ca01f1bfec6c1 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Mon, 24 Oct 2022 11:39:32 -0400 Subject: [PATCH] Swap argument order for most point-set distribution code --- .../Scoring/KlDivergence_test.res | 3 +- .../rescript/Distributions/GenericDist.res | 2 +- .../Distributions/PointSetDist/Continuous.res | 54 +++++++------ .../Distributions/PointSetDist/Discrete.res | 50 ++++++------ .../PointSetDist/Distributions.res | 6 +- .../Distributions/PointSetDist/Mixed.res | 72 ++++++++--------- .../PointSetDist/PointSetDist.res | 80 +++++++++---------- .../src/rescript/FR/FR_Pointset.res | 2 +- .../src/rescript/FR/FR_Sampleset.res | 5 +- .../src/rescript/Utility/E/E_A.res | 8 +- .../src/rescript/Utility/XYShape.res | 40 +++++----- 11 files changed, 157 insertions(+), 165 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Distributions/Scoring/KlDivergence_test.res b/packages/squiggle-lang/__tests__/Distributions/Scoring/KlDivergence_test.res index d0cdff1464..78564e7fb5 100644 --- a/packages/squiggle-lang/__tests__/Distributions/Scoring/KlDivergence_test.res +++ b/packages/squiggle-lang/__tests__/Distributions/Scoring/KlDivergence_test.res @@ -46,8 +46,7 @@ describe("klDivergence: continuous -> continuous -> float", () => { let stdev1 = 4.0 let stdev2 = 1.0 - let prediction = - normalMakeR(mean1, stdev1)->E.R.errMap(s => DistributionTypes.ArgumentError(s)) + let prediction = normalMakeR(mean1, stdev1)->E.R.errMap(s => DistributionTypes.ArgumentError(s)) let answer = normalMakeR(mean2, stdev2)->E.R.errMap(s => DistributionTypes.ArgumentError(s)) // https://stats.stackexchange.com/questions/7440/kl-divergence-between-two-univariate-gaussians let analyticalKl = diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist.res index fb52ae28b2..49d2f1de9b 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist.res @@ -483,8 +483,8 @@ let pointwiseCombinationFloat = ( PointSetDist.T.mapYResult( ~integralSumCacheFn=integralSumCacheFn(f), ~integralCacheFn=integralCacheFn(f), - ~fn=fn(f), t, + fn(f), )->E.R.errMap(x => DistributionTypes.OperationError(x)) }) let m = switch algebraicCombination { diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Continuous.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Continuous.res index 5575a5a49d..6a5df88a09 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Continuous.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Continuous.res @@ -131,14 +131,14 @@ let toLinear = (t: t): option => xyShape->XYShape.Range.stepsToContinuous->E.O.fmap(make(~integralSumCache, ~integralCache)) | {interpolation: #Linear} => Some(t) } -let shapeFn = (fn, t: t) => t->getShape->fn +let shapeFn = (t: t, fn) => t->getShape->fn -let updateIntegralSumCache = (integralSumCache, t: t): t => { +let updateIntegralSumCache = (t: t, integralSumCache): t => { ...t, integralSumCache, } -let updateIntegralCache = (integralCache, t: t): t => {...t, integralCache} +let updateIntegralCache = (t: t, integralCache): t => {...t, integralCache} let sum = ( ~integralSumCachesFn: (float, float) => option=(_, _) => None, @@ -151,9 +151,9 @@ let sum = ( ) let reduce = ( + continuousShapes, ~integralSumCachesFn: (float, float) => option=(_, _) => None, fn: (float, float) => result, - continuousShapes, ): result => { let merge = combinePointwise(~integralSumCachesFn, fn) continuousShapes->E.A.R.foldM(merge, empty, _) @@ -162,10 +162,12 @@ let reduce = ( let mapYResult = ( ~integralSumCacheFn=_ => None, ~integralCacheFn=_ => None, - ~fn: float => result, t: t, + fn: float => result, ): result => - XYShape.T.mapYResult(fn, getShape(t))->E.R.fmap(x => + getShape(t) + ->XYShape.T.mapYResult(fn) + ->E.R.fmap(x => make( ~interpolation=t.interpolation, ~integralSumCache=t.integralSumCache->E.O.bind(integralSumCacheFn), @@ -177,31 +179,31 @@ let mapYResult = ( let mapY = ( ~integralSumCacheFn=_ => None, ~integralCacheFn=_ => None, - ~fn: float => float, t: t, + fn: float => float, ): t => make( ~interpolation=t.interpolation, ~integralSumCache=t.integralSumCache->E.O.bind(integralSumCacheFn), ~integralCache=t.integralCache->E.O.bind(integralCacheFn), - t->getShape->XYShape.T.mapY(fn, _), + t->getShape->XYShape.T.mapY(fn), ) -let rec scaleBy = (~scale=1.0, t: t): t => { +let rec scaleBy = (t: t, scale): t => { let scaledIntegralSumCache = E.O.bind(t.integralSumCache, v => Some(scale *. v)) - let scaledIntegralCache = E.O.bind(t.integralCache, v => Some(scaleBy(~scale, v))) + let scaledIntegralCache = E.O.bind(t.integralCache, v => Some(scaleBy(v, scale))) t - ->mapY(~fn=(r: float) => r *. scale, _) - ->updateIntegralSumCache(scaledIntegralSumCache, _) - ->updateIntegralCache(scaledIntegralCache, _) + ->mapY((r: float) => r *. scale) + ->updateIntegralSumCache(scaledIntegralSumCache) + ->updateIntegralCache(scaledIntegralCache) } module T = Dist({ type t = PointSetTypes.continuousShape type integral = PointSetTypes.continuousShape - let minX = shapeFn(XYShape.T.minX) - let maxX = shapeFn(XYShape.T.maxX) + let minX = shapeFn(_, XYShape.T.minX) + let maxX = shapeFn(_, XYShape.T.maxX) let mapY = mapY let mapYResult = mapYResult let updateIntegralCache = updateIntegralCache @@ -209,15 +211,15 @@ module T = Dist({ let toPointSetDist = (t: t): PointSetTypes.pointSetDist => Continuous(t) let xToY = (f, {interpolation, xyShape}: t) => switch interpolation { - | #Stepwise => xyShape->XYShape.XtoY.stepwiseIncremental(f, _)->E.O.default(0.0) - | #Linear => xyShape->XYShape.XtoY.linear(f, _) + | #Stepwise => xyShape->XYShape.XtoY.stepwiseIncremental(f)->E.O.default(0.0) + | #Linear => xyShape->XYShape.XtoY.linear(f) }->PointSetTypes.MixedPoint.makeContinuous let truncate = (leftCutoff: option, rightCutoff: option, t: t) => { let lc = E.O.default(leftCutoff, neg_infinity) let rc = E.O.default(rightCutoff, infinity) let truncatedZippedPairs = - t->getShape->XYShape.T.zip->XYShape.Zipped.filterByX(x => x >= lc && x <= rc, _) + t->getShape->XYShape.T.zip->XYShape.Zipped.filterByX(x => x >= lc && x <= rc) let leftNewPoint = leftCutoff->E.O.dimap(lc => [(lc -. epsilon_float, 0.)], _ => []) let rightNewPoint = rightCutoff->E.O.dimap(rc => [(rc +. epsilon_float, 0.)], _ => []) @@ -246,18 +248,18 @@ module T = Dist({ } let downsample = (length, t): t => - t->shapeMap(XYShape.XsConversion.proportionByProbabilityMass(length, integral(t).xyShape)) + t->shapeMap(XYShape.XsConversion.proportionByProbabilityMass(_, length, integral(t).xyShape)) let integralEndY = (t: t) => t.integralSumCache->E.O.defaultFn(() => t->integral->lastY) - let integralXtoY = (f, t: t) => t->integral->shapeFn(XYShape.XtoY.linear(f), _) - let integralYtoX = (f, t: t) => t->integral->shapeFn(XYShape.YtoX.linear(f), _) + let integralXtoY = (f, t: t) => t->integral->shapeFn(XYShape.XtoY.linear(_, f)) + let integralYtoX = (f, t: t) => t->integral->shapeFn(XYShape.YtoX.linear(_, f)) let toContinuous = t => Some(t) let toDiscrete = _ => None let normalize = (t: t): t => t - ->updateIntegralCache(Some(integral(t)), _) - ->scaleBy(~scale=1. /. integralEndY(t), _) - ->updateIntegralSumCache(Some(1.0), _) + ->updateIntegralCache(Some(integral(t))) + ->scaleBy(1. /. integralEndY(t)) + ->updateIntegralSumCache(Some(1.0)) let mean = (t: t) => { let indefiniteIntegralStepwise = (p, h1) => h1 *. p ** 2.0 /. 2.0 @@ -270,13 +272,13 @@ module T = Dist({ }) let isNormalized = (t: t): bool => { - let areaUnderIntegral = t->updateIntegralCache(Some(T.integral(t)), _)->T.integralEndY + let areaUnderIntegral = t->updateIntegralCache(Some(T.integral(t)))->T.integralEndY areaUnderIntegral < 1. +. MagicNumbers.Epsilon.seven && areaUnderIntegral > 1. -. MagicNumbers.Epsilon.seven } let downsampleEquallyOverX = (length, t): t => - t->shapeMap(XYShape.XsConversion.proportionEquallyOverX(length)) + t->shapeMap(XYShape.XsConversion.proportionEquallyOverX(_, length)) /* This simply creates multiple copies of the continuous distribution, scaled and shifted according to each discrete data point, and then adds them all together. */ diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res index bc4d94c316..612da05643 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res @@ -29,7 +29,7 @@ let empty: PointSetTypes.discreteShape = { integralCache: Some(emptyIntegral), } -let shapeFn = (fn, t: t) => t->getShape->fn +let shapeFn = (t: t, fn) => t->getShape->fn let lastY = (t: t) => t->getShape->XYShape.T.lastY @@ -53,20 +53,20 @@ let combinePointwise = ( } let reduce = ( + discreteShapes: array, ~integralSumCachesFn=(_, _) => None, fn: (float, float) => result, - discreteShapes: array, ): result => { let merge = combinePointwise(~integralSumCachesFn, ~fn) discreteShapes->E.A.R.foldM(merge, empty, _) } -let updateIntegralSumCache = (integralSumCache, t: t): t => { +let updateIntegralSumCache = (t: t, integralSumCache): t => { ...t, integralSumCache, } -let updateIntegralCache = (integralCache, t: t): t => { +let updateIntegralCache = (t: t, integralCache): t => { ...t, integralCache, } @@ -107,10 +107,12 @@ let combineAlgebraically = (op: Operation.convolutionOperation, t1: t, t2: t): t let mapYResult = ( ~integralSumCacheFn=_ => None, ~integralCacheFn=_ => None, - ~fn: float => result, t: t, + fn: float => result, ): result => - XYShape.T.mapYResult(fn, getShape(t))->E.R.fmap(x => + getShape(t) + ->XYShape.T.mapYResult(fn) + ->E.R.fmap(x => make( ~integralSumCache=t.integralSumCache->E.O.bind(integralSumCacheFn), ~integralCache=t.integralCache->E.O.bind(integralCacheFn), @@ -121,23 +123,23 @@ let mapYResult = ( let mapY = ( ~integralSumCacheFn=_ => None, ~integralCacheFn=_ => None, - ~fn: float => float, t: t, + fn: float => float, ): t => make( ~integralSumCache=t.integralSumCache->E.O.bind(integralSumCacheFn), ~integralCache=t.integralCache->E.O.bind(integralCacheFn), - t->getShape->XYShape.T.mapY(fn, _), + t->getShape->XYShape.T.mapY(fn), ) -let scaleBy = (~scale=1.0, t: t): t => { +let scaleBy = (t: t, scale): t => { let scaledIntegralSumCache = t.integralSumCache->E.O.fmap(\"*."(scale)) - let scaledIntegralCache = t.integralCache->E.O.fmap(Continuous.scaleBy(~scale)) + let scaledIntegralCache = t.integralCache->E.O.fmap(Continuous.scaleBy(_, scale)) t - ->mapY(~fn=(r: float) => r *. scale, _) - ->updateIntegralSumCache(scaledIntegralSumCache, _) - ->updateIntegralCache(scaledIntegralCache, _) + ->mapY((r: float) => r *. scale) + ->updateIntegralSumCache(scaledIntegralSumCache) + ->updateIntegralCache(scaledIntegralCache) } module T = Dist({ @@ -152,16 +154,15 @@ module T = Dist({ // The first xy of this integral should always be the zero, to ensure nice plotting let firstX = ts->XYShape.T.minX let prependedZeroPoint: XYShape.T.t = {xs: [firstX -. epsilon_float], ys: [0.]} - let integralShape = - ts->XYShape.T.concat(prependedZeroPoint, _)->XYShape.T.accumulateYs(\"+.", _) + let integralShape = ts->XYShape.T.concat(prependedZeroPoint, _)->XYShape.T.accumulateYs(\"+.") Continuous.make(~interpolation=#Stepwise, integralShape) } let integralEndY = (t: t) => t.integralSumCache->E.O.defaultFn(() => t->integral->Continuous.lastY) - let minX = shapeFn(XYShape.T.minX) - let maxX = shapeFn(XYShape.T.maxX) + let minX = shapeFn(_, XYShape.T.minX) + let maxX = shapeFn(_, XYShape.T.maxX) let toDiscreteProbabilityMassFraction = _ => 1.0 let mapY = mapY let mapYResult = mapYResult @@ -170,8 +171,7 @@ module T = Dist({ let toContinuous = _ => None let toDiscrete = t => Some(t) - let normalize = (t: t): t => - t->scaleBy(~scale=1. /. integralEndY(t), _)->updateIntegralSumCache(Some(1.0), _) + let normalize = (t: t): t => t->scaleBy(1. /. integralEndY(t))->updateIntegralSumCache(Some(1.0)) let downsample = (i, t: t): t => { // It's not clear how to downsample a set of discrete points in a meaningful way. @@ -197,9 +197,8 @@ module T = Dist({ t ->getShape ->XYShape.T.zip - ->XYShape.Zipped.filterByX( - x => x >= E.O.default(leftCutoff, neg_infinity) && x <= E.O.default(rightCutoff, infinity), - _, + ->XYShape.Zipped.filterByX(x => + x >= E.O.default(leftCutoff, neg_infinity) && x <= E.O.default(rightCutoff, infinity) ) ->XYShape.T.fromZippedArray ->make @@ -207,13 +206,12 @@ module T = Dist({ let xToY = (f, t) => t ->getShape - ->XYShape.XtoY.stepwiseIfAtX(f, _) + ->XYShape.XtoY.stepwiseIfAtX(f) ->E.O.default(0.0) ->PointSetTypes.MixedPoint.makeDiscrete - let integralXtoY = (f, t) => t->integral->Continuous.getShape->XYShape.XtoY.linear(f, _) - - let integralYtoX = (f, t) => t->integral->Continuous.getShape->XYShape.YtoX.linear(f, _) + let integralXtoY = (f, t) => t->integral->Continuous.getShape->XYShape.XtoY.linear(f) + let integralYtoX = (f, t) => t->integral->Continuous.getShape->XYShape.YtoX.linear(f) let mean = (t: t): float => { let s = getShape(t) diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Distributions.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Distributions.res index 3a35d57bf2..097b7194f3 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Distributions.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Distributions.res @@ -6,14 +6,14 @@ module type dist = { let mapY: ( ~integralSumCacheFn: float => option=?, ~integralCacheFn: PointSetTypes.continuousShape => option=?, - ~fn: float => float, t, + float => float, ) => t let mapYResult: ( ~integralSumCacheFn: float => option=?, ~integralCacheFn: PointSetTypes.continuousShape => option=?, - ~fn: float => result, t, + float => result, ) => result let xToY: (float, t) => PointSetTypes.mixedPoint let toPointSetDist: t => PointSetTypes.pointSetDist @@ -24,7 +24,7 @@ module type dist = { let downsample: (int, t) => t let truncate: (option, option, t) => t - let updateIntegralCache: (option, t) => t + let updateIntegralCache: (t, option) => t let integral: t => integral let integralEndY: t => float diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Mixed.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Mixed.res index 65b6d236e0..92923da37c 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Mixed.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Mixed.res @@ -11,16 +11,16 @@ let make = (~integralSumCache=None, ~integralCache=None, ~continuous, ~discrete) } let totalLength = (t: t): int => { - let continuousLength = t.continuous |> Continuous.getShape |> XYShape.T.length - let discreteLength = t.discrete |> Discrete.getShape |> XYShape.T.length + let continuousLength = t.continuous->Continuous.getShape->XYShape.T.length + let discreteLength = t.discrete->Discrete.getShape->XYShape.T.length continuousLength + discreteLength } -let scaleBy = (~scale=1.0, t: t): t => { - let scaledDiscrete = Discrete.scaleBy(~scale, t.discrete) - let scaledContinuous = Continuous.scaleBy(~scale, t.continuous) - let scaledIntegralCache = E.O.bind(t.integralCache, v => Some(Continuous.scaleBy(~scale, v))) +let scaleBy = (t: t, scale): t => { + let scaledDiscrete = Discrete.scaleBy(t.discrete, scale) + let scaledContinuous = Continuous.scaleBy(t.continuous, scale) + let scaledIntegralCache = E.O.bind(t.integralCache, v => Some(Continuous.scaleBy(v, scale))) let scaledIntegralSumCache = E.O.bind(t.integralSumCache, s => Some(s *. scale)) make( ~discrete=scaledDiscrete, @@ -33,7 +33,7 @@ let scaleBy = (~scale=1.0, t: t): t => { let toContinuous = ({continuous}: t) => Some(continuous) let toDiscrete = ({discrete}: t) => Some(discrete) -let updateIntegralCache = (integralCache, t: t): t => { +let updateIntegralCache = (t: t, integralCache): t => { ...t, integralCache, } @@ -48,15 +48,12 @@ let combinePointwise = ( let reducedDiscrete = [t1, t2] ->E.A.fmap(toDiscrete) - -> E.A.O.concatSomes - -> Discrete.reduce(~integralSumCachesFn, fn, _) - -> E.R.toExn("Theoretically unreachable state") + ->E.A.O.concatSomes + ->Discrete.reduce(~integralSumCachesFn, fn) + ->E.R.toExn("Theoretically unreachable state") let reducedContinuous = - [t1, t2] - ->E.A.fmap(toContinuous) - -> E.A.O.concatSomes - -> Continuous.reduce(~integralSumCachesFn, fn, _) + [t1, t2]->E.A.fmap(toContinuous)->E.A.O.concatSomes->Continuous.reduce(~integralSumCachesFn, fn) let combinedIntegralSum = Common.combineIntegralSums( integralSumCachesFn, @@ -113,8 +110,8 @@ module T = Dist({ let continuousIntegral = Continuous.T.Integral.get(t.continuous) let discreteIntegral = Discrete.T.Integral.get(t.discrete) - let continuous = t.continuous |> Continuous.updateIntegralCache(Some(continuousIntegral)) - let discrete = t.discrete |> Discrete.updateIntegralCache(Some(discreteIntegral)) + let continuous = t.continuous->Continuous.updateIntegralCache(Some(continuousIntegral)) + let discrete = t.discrete->Discrete.updateIntegralCache(Some(discreteIntegral)) let continuousIntegralSum = Continuous.T.Integral.sum(continuous) let discreteIntegralSum = Discrete.T.Integral.sum(discrete) @@ -125,12 +122,12 @@ module T = Dist({ let normalizedContinuous = continuous - |> Continuous.scaleBy(~scale=newContinuousSum /. continuousIntegralSum) - |> Continuous.updateIntegralSumCache(Some(newContinuousSum)) + ->Continuous.scaleBy(newContinuousSum /. continuousIntegralSum) + ->Continuous.updateIntegralSumCache(Some(newContinuousSum)) let normalizedDiscrete = discrete - |> Discrete.scaleBy(~scale=newDiscreteSum /. discreteIntegralSum) - |> Discrete.updateIntegralSumCache(Some(newDiscreteSum)) + ->Discrete.scaleBy(newDiscreteSum /. discreteIntegralSum) + ->Discrete.updateIntegralSumCache(Some(newDiscreteSum)) make( ~integralSumCache=Some(1.0), @@ -197,11 +194,10 @@ module T = Dist({ ) } - let integralEndY = (t: t) => t |> integral |> Continuous.lastY - - let integralXtoY = (f, t) => t |> integral |> Continuous.getShape |> XYShape.XtoY.linear(f) + let integralEndY = (t: t) => t->integral->Continuous.lastY - let integralYtoX = (f, t) => t |> integral |> Continuous.getShape |> XYShape.YtoX.linear(f) + let integralXtoY = (f, t) => t->integral->Continuous.getShape->XYShape.XtoY.linear(f) + let integralYtoX = (f, t) => t->integral->Continuous.getShape->XYShape.YtoX.linear(f) let createMixedFromContinuousDiscrete = ( ~integralSumCacheFn=_ => None, @@ -212,15 +208,15 @@ module T = Dist({ ): t => { let yMappedDiscrete: PointSetTypes.discreteShape = discrete - |> Discrete.updateIntegralSumCache(E.O.bind(t.discrete.integralSumCache, integralSumCacheFn)) - |> Discrete.updateIntegralCache(E.O.bind(t.discrete.integralCache, integralCacheFn)) + ->Discrete.updateIntegralSumCache(E.O.bind(t.discrete.integralSumCache, integralSumCacheFn)) + ->Discrete.updateIntegralCache(E.O.bind(t.discrete.integralCache, integralCacheFn)) let yMappedContinuous: PointSetTypes.continuousShape = continuous - |> Continuous.updateIntegralSumCache( + ->Continuous.updateIntegralSumCache( E.O.bind(t.continuous.integralSumCache, integralSumCacheFn), ) - |> Continuous.updateIntegralCache(E.O.bind(t.continuous.integralCache, integralCacheFn)) + ->Continuous.updateIntegralCache(E.O.bind(t.continuous.integralCache, integralCacheFn)) { discrete: yMappedDiscrete, @@ -236,11 +232,11 @@ module T = Dist({ let mapY = ( ~integralSumCacheFn=_ => None, ~integralCacheFn=_ => None, - ~fn: float => float, t: t, + fn: float => float, ): t => { - let discrete = t.discrete |> Discrete.T.mapY(~fn) - let continuous = t.continuous |> Continuous.T.mapY(~fn) + let discrete = t.discrete->Discrete.T.mapY(fn) + let continuous = t.continuous->Continuous.T.mapY(fn) createMixedFromContinuousDiscrete( ~integralCacheFn, ~integralSumCacheFn, @@ -253,12 +249,12 @@ module T = Dist({ let mapYResult = ( ~integralSumCacheFn=_ => None, ~integralCacheFn=_ => None, - ~fn: float => result, t: t, + fn: float => result, ): result => { E.R.merge( - Discrete.T.mapYResult(~fn, t.discrete), - Continuous.T.mapYResult(~fn, t.continuous), + Discrete.T.mapYResult(t.discrete, fn), + Continuous.T.mapYResult(t.continuous, fn), )->E.R.fmap(((discreteMapped, continuousMapped)) => { createMixedFromContinuousDiscrete( ~integralCacheFn, @@ -291,7 +287,7 @@ module T = Dist({ let getMeanOfSquares = ({discrete, continuous}: t) => { let discreteMean = discrete->Discrete.shapeMap(XYShape.T.square)->Discrete.T.mean - let continuousMean = continuous |> Continuous.Analysis.getMeanOfSquares + let continuousMean = continuous->Continuous.Analysis.getMeanOfSquares (discreteMean *. discreteIntegralSum +. continuousMean *. continuousIntegralSum) /. totalIntegralSum } @@ -359,12 +355,10 @@ let combinePointwise = ( t2: t, ): result => { let reducedDiscrete = - [t1, t2]->E.A.fmap(toDiscrete) |> E.A.O.concatSomes |> Discrete.reduce(~integralSumCachesFn, fn) + [t1, t2]->E.A.fmap(toDiscrete)->E.A.O.concatSomes->Discrete.reduce(~integralSumCachesFn, fn) let reducedContinuous = - [t1, t2]->E.A.fmap(toContinuous) - |> E.A.O.concatSomes - |> Continuous.reduce(~integralSumCachesFn, fn) + [t1, t2]->E.A.fmap(toContinuous)->E.A.O.concatSomes->Continuous.reduce(~integralSumCachesFn, fn) let combinedIntegralSum = Common.combineIntegralSums( integralSumCachesFn, diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res index 36c5ea750b..67a4c2f366 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res @@ -9,14 +9,14 @@ let mapToAll = ((fn1, fn2, fn3), t: t) => | Continuous(m) => fn3(m) } -let fmap = ((fn1, fn2, fn3), t: t): t => +let fmap = (t: t, (fn1, fn2, fn3)): t => switch t { | Mixed(m) => Mixed(fn1(m)) | Discrete(m) => Discrete(fn2(m)) | Continuous(m) => Continuous(fn3(m)) } -let fmapResult = ((fn1, fn2, fn3), t: t): result => +let fmapResult = (t: t, (fn1, fn2, fn3)): result => switch t { | Mixed(m) => fn1(m)->E.R.fmap(x => PointSetTypes.Mixed(x)) | Discrete(m) => fn2(m)->E.R.fmap(x => PointSetTypes.Discrete(x)) @@ -45,24 +45,24 @@ let toMixed = mapToAll(( let combineAlgebraically = (op: Operation.convolutionOperation, t1: t, t2: t): t => switch (t1, t2) { | (Continuous(m1), Continuous(m2)) => - Continuous.combineAlgebraically(op, m1, m2) |> Continuous.T.toPointSetDist + Continuous.combineAlgebraically(op, m1, m2)->Continuous.T.toPointSetDist | (Discrete(m1), Continuous(m2)) => Continuous.combineAlgebraicallyWithDiscrete( op, m2, m1, ~discretePosition=First, - ) |> Continuous.T.toPointSetDist + )->Continuous.T.toPointSetDist | (Continuous(m1), Discrete(m2)) => Continuous.combineAlgebraicallyWithDiscrete( op, m1, m2, ~discretePosition=Second, - ) |> Continuous.T.toPointSetDist + )->Continuous.T.toPointSetDist | (Discrete(m1), Discrete(m2)) => - Discrete.combineAlgebraically(op, m1, m2) |> Discrete.T.toPointSetDist - | (m1, m2) => Mixed.combineAlgebraically(op, toMixed(m1), toMixed(m2)) |> Mixed.T.toPointSetDist + Discrete.combineAlgebraically(op, m1, m2)->Discrete.T.toPointSetDist + | (m1, m2) => Mixed.combineAlgebraically(op, toMixed(m1), toMixed(m2))->Mixed.T.toPointSetDist } let combinePointwise = ( @@ -112,29 +112,23 @@ module T = Dist({ let toPointSetDist = (t: t) => t let downsample = (i, t) => - fmap((Mixed.T.downsample(i), Discrete.T.downsample(i), Continuous.T.downsample(i)), t) + t->fmap((Mixed.T.downsample(i), Discrete.T.downsample(i), Continuous.T.downsample(i))) let truncate = (leftCutoff, rightCutoff, t): t => - fmap( - ( - Mixed.T.truncate(leftCutoff, rightCutoff), - Discrete.T.truncate(leftCutoff, rightCutoff), - Continuous.T.truncate(leftCutoff, rightCutoff), - ), - t, - ) + t->fmap(( + Mixed.T.truncate(leftCutoff, rightCutoff), + Discrete.T.truncate(leftCutoff, rightCutoff), + Continuous.T.truncate(leftCutoff, rightCutoff), + )) - let normalize = fmap((Mixed.T.normalize, Discrete.T.normalize, Continuous.T.normalize)) + let normalize = fmap(_, (Mixed.T.normalize, Discrete.T.normalize, Continuous.T.normalize)) - let updateIntegralCache = (integralCache, t: t): t => - fmap( - ( - Mixed.T.updateIntegralCache(integralCache), - Discrete.T.updateIntegralCache(integralCache), - Continuous.T.updateIntegralCache(integralCache), - ), - t, - ) + let updateIntegralCache = (t: t, integralCache): t => + t->fmap(( + Mixed.T.updateIntegralCache(_, integralCache), + Discrete.T.updateIntegralCache(_, integralCache), + Continuous.T.updateIntegralCache(_, integralCache), + )) let toContinuous = mapToAll(( Mixed.T.toContinuous, @@ -165,24 +159,28 @@ module T = Dist({ let integralYtoX = f => mapToAll((Mixed.T.Integral.yToX(f), Discrete.T.Integral.yToX(f), Continuous.T.Integral.yToX(f))) let maxX = mapToAll((Mixed.T.maxX, Discrete.T.maxX, Continuous.T.maxX)) - let mapY = (~integralSumCacheFn=_ => None, ~integralCacheFn=_ => None, ~fn: float => float): ( - t => t - ) => - fmap(( - Mixed.T.mapY(~integralSumCacheFn, ~integralCacheFn, ~fn), - Discrete.T.mapY(~integralSumCacheFn, ~integralCacheFn, ~fn), - Continuous.T.mapY(~integralSumCacheFn, ~integralCacheFn, ~fn), + let mapY = ( + ~integralSumCacheFn=_ => None, + ~integralCacheFn=_ => None, + t: t, + fn: float => float, + ): t => + t->fmap(( + Mixed.T.mapY(~integralSumCacheFn, ~integralCacheFn, _, fn), + Discrete.T.mapY(~integralSumCacheFn, ~integralCacheFn, _, fn), + Continuous.T.mapY(~integralSumCacheFn, ~integralCacheFn, _, fn), )) let mapYResult = ( ~integralSumCacheFn=_ => None, ~integralCacheFn=_ => None, - ~fn: float => result, - ): (t => result) => - fmapResult(( - Mixed.T.mapYResult(~integralSumCacheFn, ~integralCacheFn, ~fn), - Discrete.T.mapYResult(~integralSumCacheFn, ~integralCacheFn, ~fn), - Continuous.T.mapYResult(~integralSumCacheFn, ~integralCacheFn, ~fn), + t: t, + fn: float => result, + ): result => + t->fmapResult(( + Mixed.T.mapYResult(~integralSumCacheFn, ~integralCacheFn, _, fn), + Discrete.T.mapYResult(~integralSumCacheFn, ~integralCacheFn, _, fn), + Continuous.T.mapYResult(~integralSumCacheFn, ~integralCacheFn, _, fn), )) let mean = (t: t): float => @@ -226,7 +224,7 @@ let doN = (n, fn) => { let sample = (t: t): float => { let randomItem = Random.float(1.0) - t |> T.Integral.yToX(randomItem) + t->T.Integral.yToX(randomItem, _) } let isFloat = (t: t) => @@ -237,7 +235,7 @@ let isFloat = (t: t) => let sampleNRendered = (n, dist) => { let integralCache = T.Integral.get(dist) - let distWithUpdatedIntegralCache = T.updateIntegralCache(Some(integralCache), dist) + let distWithUpdatedIntegralCache = T.updateIntegralCache(dist, Some(integralCache)) doN(n, () => sample(distWithUpdatedIntegralCache)) } diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res index f1b09d397d..7bb8d3a69d 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res @@ -47,7 +47,7 @@ module Internal = { let mapY = (pointSetDist: t, aLambdaValue, env, reducer) => { let fn = r => doLambdaCall(aLambdaValue, [IEvNumber(r)], env, reducer) - PointSetDist.T.mapYResult(~fn, pointSetDist)->toType + pointSetDist->PointSetDist.T.mapYResult(fn)->toType } } diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res index 72d0ea4b43..ef29de4e0d 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res @@ -114,8 +114,9 @@ let libaryBase = [ ~inputs=[FRTypeArray(FRTypeNumber)], ~run=(inputs, _, _) => { let sampleSet = - inputs->Prepare.ToTypedArray.numbers - -> E.R.bind(r => SampleSetDist.make(r)->E.R.errMap(SampleSetDist.Error.toString)) + inputs + ->Prepare.ToTypedArray.numbers + ->E.R.bind(r => SampleSetDist.make(r)->E.R.errMap(SampleSetDist.Error.toString)) sampleSet ->E.R.fmap(Wrappers.sampleSet) ->E.R.fmap(Wrappers.evDistribution) diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_A.res b/packages/squiggle-lang/src/rescript/Utility/E/E_A.res index 2cdb4efedf..7f0a04ea25 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E/E_A.res +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_A.res @@ -56,8 +56,8 @@ let intersperse = (a: array<'a>, b: array<'a>) => { } // This is like map, but -//accumulate((a,b) => a + b, [1,2,3]) => [1, 3, 6] -let accumulate = (fn: ('a, 'a) => 'a, items: array<'a>) => { +//[1,2,3]->accumulate((a,b) => a + b) => [1, 3, 6] +let accumulate = (items: array<'a>, fn: ('a, 'a) => 'a) => { let length = items->length let empty = Belt.Array.make(length, items->unsafe_get(0)) forEachI(items, (index, element) => { @@ -204,8 +204,8 @@ module Floats = { // diff([1,5,3,7]) = [4,-2,4] let diff = (t: t): array => t->pairwise((left, right) => right -. left) - let cumSum = (t: t): array => accumulate((a, b) => a +. b, t) - let cumProd = (t: t): array => accumulate((a, b) => a *. b, t) + let cumSum = (t: t): array => t->accumulate((a, b) => a +. b) + let cumProd = (t: t): array => t->accumulate((a, b) => a *. b) exception RangeError(string) let range = (min: float, max: float, n: int): array => diff --git a/packages/squiggle-lang/src/rescript/Utility/XYShape.res b/packages/squiggle-lang/src/rescript/Utility/XYShape.res index bf2a2129bb..e0785a090a 100644 --- a/packages/squiggle-lang/src/rescript/Utility/XYShape.res +++ b/packages/squiggle-lang/src/rescript/Utility/XYShape.res @@ -76,17 +76,17 @@ module T = { let firstY = (t: t) => t->ys->E.A.first->extImp let lastY = (t: t) => t->ys->E.A.last->extImp let xTotalRange = (t: t) => maxX(t) -. minX(t) - let mapX = (fn, t: t): t => {xs: E.A.fmap(t.xs, fn), ys: t.ys} - let mapY = (fn, t: t): t => {xs: t.xs, ys: E.A.fmap(t.ys, fn)} - let mapYResult = (fn: float => result, t: t): result => { + let mapX = (t: t, fn): t => {xs: E.A.fmap(t.xs, fn), ys: t.ys} + let mapY = (t: t, fn): t => {xs: t.xs, ys: E.A.fmap(t.ys, fn)} + let mapYResult = (t: t, fn: float => result): result => { let mappedYs = E.A.fmap(t.ys, fn) E.A.R.firstErrorOrOpen(mappedYs)->E.R.fmap(y => {xs: t.xs, ys: y}) } - let square = mapX(x => x ** 2.0) + let square = mapX(_, x => x ** 2.0) let zip = ({xs, ys}: t) => E.A.zip(xs, ys) let fromArray = ((xs, ys)): t => {xs, ys} let fromArrays = (xs, ys): t => {xs, ys} - let accumulateYs = (fn, p: t) => fromArray((p.xs, E.A.accumulate(fn, p.ys))) + let accumulateYs = (p: t, fn) => (p.xs, p.ys->E.A.accumulate(fn))->fromArray let concat = (t1: t, t2: t) => { let cxs = E.A.concat(t1.xs, t2.xs) let cys = E.A.concat(t1.ys, t2.ys) @@ -95,7 +95,7 @@ module T = { let fromZippedArray = (pairs: array<(float, float)>): t => pairs->E.A.unzip->fromArray let equallyDividedXs = (t: t, newLength) => E.A.Floats.range(minX(t), maxX(t), newLength) let toJs = (t: t) => {"xs": t.xs, "ys": t.ys} - let filterYValues = (fn, t: t): t => t->zip->E.A.filter(((_, y)) => fn(y))->fromZippedArray + let filterYValues = (t: t, fn): t => t->zip->E.A.filter(((_, y)) => fn(y))->fromZippedArray let filterOkYs = (xs: array, ys: array>): t => { let n = E.A.length(xs) // Assume length(xs) == length(ys) let newXs = [] @@ -170,7 +170,7 @@ module Pairs = { let getBy = (t: T.t, fn) => t->T.zip->E.A.getBy(fn) - let firstAtOrBeforeXValue = (xValue, t: T.t) => { + let firstAtOrBeforeXValue = (t: T.t, xValue) => { let zipped = T.zip(t) let firstIndex = zipped->E.A.getIndexBy(((x, _)) => x > xValue) let previousIndex = switch firstIndex { @@ -183,7 +183,7 @@ module Pairs = { } module YtoX = { - let linear = (y: float, t: T.t): float => { + let linear = (t: T.t, y: float): float => { let firstHigherIndex = E.A.Sorted.binarySearchFirstElementGreaterIndex(T.ys(t), y) let foundX = switch firstHigherIndex { | #overMax => T.maxX(t) @@ -209,12 +209,12 @@ module YtoX = { } module XtoY = { - let stepwiseIncremental = (f, t: T.t) => Pairs.firstAtOrBeforeXValue(f, t)->E.O.fmap(Pairs.y) + let stepwiseIncremental = (t: T.t, f) => Pairs.firstAtOrBeforeXValue(t, f)->E.O.fmap(Pairs.y) - let stepwiseIfAtX = (f: float, t: T.t) => + let stepwiseIfAtX = (t: T.t, f: float) => Pairs.getBy(t, ((x: float, _)) => x == f)->E.O.fmap(Pairs.y) - let linear = (x: float, t: T.t): float => { + let linear = (t: T.t, x: float): float => { let firstHigherIndex = E.A.Sorted.binarySearchFirstElementGreaterIndex(T.xs(t), x) let n = switch firstHigherIndex { | #overMax => T.lastY(t) @@ -300,17 +300,17 @@ module XtoY = { module XsConversion = { let _replaceWithXs = (newXs: array, t: T.t): T.t => { - let newYs = E.A.fmap(newXs, XtoY.linear(_, t)) + let newYs = E.A.fmap(newXs, XtoY.linear(t)) {xs: newXs, ys: newYs} } let equallyDivideXByMass = (integral: T.t, newLength: int) => - E.A.Floats.range(0.0, 1.0, newLength)->E.A.fmap(YtoX.linear(_, integral)) + E.A.Floats.range(0.0, 1.0, newLength)->E.A.fmap(YtoX.linear(integral)) - let proportionEquallyOverX = (newLength: int, t: T.t): T.t => + let proportionEquallyOverX = (t: T.t, newLength: int): T.t => T.equallyDividedXs(t, newLength)->_replaceWithXs(t) - let proportionByProbabilityMass = (newLength: int, integral: T.t, t: T.t): T.t => + let proportionByProbabilityMass = (t: T.t, newLength: int, integral: T.t): T.t => integral->equallyDivideXByMass(newLength)->_replaceWithXs(t) // creates a new set of xs at evenly spaced percentiles // linearly interpolates new ys for the new xs } @@ -320,7 +320,7 @@ module Zipped = { let compareXs = ((x1, _): (float, float), (x2, _): (float, float)) => x1 > x2 ? 1 : 0 let sortByY = (t: zipped) => t->E.A.stableSortBy(compareYs) let sortByX = (t: zipped) => t->E.A.stableSortBy(compareXs) - let filterByX = (testFn: float => bool, t: zipped) => t->E.A.filter(((x, _)) => testFn(x)) + let filterByX = (t: zipped, testFn: float => bool) => t->E.A.filter(((x, _)) => testFn(x)) } module PointwiseCombination = { @@ -493,7 +493,7 @@ module PointwiseCombination = { t.xs, ) let newXs = E.A.concatMany(newXsUnflattened) - let newYs = E.A.fmap(newXs, x => XtoY.linear(x, t)) + let newYs = E.A.fmap(newXs, x => XtoY.linear(t, x)) {xs: newXs, ys: newYs} } @@ -539,7 +539,7 @@ module Range = { let delta_y_over_delta_x = (((lastX, lastY), (nextX, nextY)): zippedRange) => (nextY -. lastY) /. (nextX -. lastX) - let mapYsBasedOnRanges = (fn, t) => + let mapYsBasedOnRanges = (t, fn) => E.A.zip(t.xs, t.ys) ->E.A.toRanges ->E.R.toOption @@ -560,7 +560,7 @@ module Range = { Some({xs, ys: cumulativeY}) } - let derivative = mapYsBasedOnRanges(delta_y_over_delta_x) + let derivative = mapYsBasedOnRanges(_, delta_y_over_delta_x) let stepwiseToLinear = ({xs, ys}: T.t): T.t => { // adds points at the bottom of each step. @@ -594,7 +594,7 @@ module Range = { items ->E.A.fmap(rangePointAssumingSteps) ->T.fromZippedArray - ->PointwiseCombination.intersperse(T.mapX(e => e +. diff, t), _), + ->PointwiseCombination.intersperse(t->T.mapX(e => e +. diff), _), ) | _ => Some(t) }