Finish converting shape -> pointSetDist

This commit is contained in:
Ozzie Gooen 2022-02-15 17:43:31 -05:00
parent 336a5fb57f
commit 1daeb81441
18 changed files with 85 additions and 85 deletions

View File

@ -10,12 +10,12 @@ describe("Lodash", () =>
describe("Lodash", () => { describe("Lodash", () => {
makeTest( makeTest(
"split", "split",
SamplesToShape.Internals.T.splitContinuousAndDiscrete([1.432, 1.33455, 2.0]), SampleSet.Internals.T.splitContinuousAndDiscrete([1.432, 1.33455, 2.0]),
([1.432, 1.33455, 2.0], E.FloatFloatMap.empty()), ([1.432, 1.33455, 2.0], E.FloatFloatMap.empty()),
) )
makeTest( makeTest(
"split", "split",
SamplesToShape.Internals.T.splitContinuousAndDiscrete([ SampleSet.Internals.T.splitContinuousAndDiscrete([
1.432, 1.432,
1.33455, 1.33455,
2.0, 2.0,
@ -32,13 +32,13 @@ describe("Lodash", () =>
E.A.concatMany([sorted, sorted, sorted, sorted]) |> Belt.SortArray.stableSortBy(_, compare) E.A.concatMany([sorted, sorted, sorted, sorted]) |> Belt.SortArray.stableSortBy(_, compare)
} }
let (_, discrete) = SamplesToShape.Internals.T.splitContinuousAndDiscrete( let (_, discrete) = SampleSet.Internals.T.splitContinuousAndDiscrete(
makeDuplicatedArray(10), makeDuplicatedArray(10),
) )
let toArr = discrete |> E.FloatFloatMap.toArray let toArr = discrete |> E.FloatFloatMap.toArray
makeTest("splitMedium", toArr |> Belt.Array.length, 10) makeTest("splitMedium", toArr |> Belt.Array.length, 10)
let (c, discrete) = SamplesToShape.Internals.T.splitContinuousAndDiscrete( let (c, discrete) = SampleSet.Internals.T.splitContinuousAndDiscrete(
makeDuplicatedArray(500), makeDuplicatedArray(500),
) )
let toArr = discrete |> E.FloatFloatMap.toArray let toArr = discrete |> E.FloatFloatMap.toArray

View File

@ -5,7 +5,7 @@ module Inputs = {
sampleCount: option<int>, sampleCount: option<int>,
outputXYPoints: option<int>, outputXYPoints: option<int>,
kernelWidth: option<float>, kernelWidth: option<float>,
shapeLength: option<int>, pointSetDistLength: option<int>,
} }
} }
let defaultRecommendedLength = 100 let defaultRecommendedLength = 100
@ -21,7 +21,7 @@ module Inputs = {
sampleCount: None, sampleCount: None,
outputXYPoints: None, outputXYPoints: None,
kernelWidth: None, kernelWidth: None,
shapeLength: None, pointSetDistLength: None,
} }
let make = ( let make = (
@ -60,15 +60,15 @@ module Internals = {
type outputs = { type outputs = {
graph: ASTTypes.AST.node, graph: ASTTypes.AST.node,
shape: PointSetTypes.shape, pointSetDist: PointSetTypes.pointSetDist,
} }
let makeOutputs = (graph, shape): outputs => {graph: graph, shape: shape} let makeOutputs = (graph, pointSetDist): outputs => {graph: graph, pointSetDist: pointSetDist}
let makeInputs = (inputs: Inputs.inputs): ASTTypes.AST.samplingInputs => { let makeInputs = (inputs: Inputs.inputs): ASTTypes.AST.samplingInputs => {
sampleCount: inputs.samplingInputs.sampleCount |> E.O.default(10000), sampleCount: inputs.samplingInputs.sampleCount |> E.O.default(10000),
outputXYPoints: inputs.samplingInputs.outputXYPoints |> E.O.default(10000), outputXYPoints: inputs.samplingInputs.outputXYPoints |> E.O.default(10000),
kernelWidth: inputs.samplingInputs.kernelWidth, kernelWidth: inputs.samplingInputs.kernelWidth,
shapeLength: inputs.samplingInputs.shapeLength |> E.O.default(10000), pointSetDistLength: inputs.samplingInputs.pointSetDistLength |> E.O.default(10000),
} }
let runNode = (inputs, node) => let runNode = (inputs, node) =>
@ -93,8 +93,8 @@ module Internals = {
let inputsToLeaf = (inputs: Inputs.inputs) => let inputsToLeaf = (inputs: Inputs.inputs) =>
Parser.fromString(inputs.squiggleString) |> E.R.bind(_, g => runProgram(inputs, g)) Parser.fromString(inputs.squiggleString) |> E.R.bind(_, g => runProgram(inputs, g))
let outputToDistPlus = (inputs: Inputs.inputs, shape: PointSetTypes.shape) => let outputToDistPlus = (inputs: Inputs.inputs, pointSetDist: PointSetTypes.pointSetDist) =>
DistPlus.make(~shape, ~squiggleString=Some(inputs.squiggleString), ()) DistPlus.make(~pointSetDist, ~squiggleString=Some(inputs.squiggleString), ())
} }
let renderIfNeeded = (inputs: Inputs.inputs, node: ASTTypes.AST.node): result< let renderIfNeeded = (inputs: Inputs.inputs, node: ASTTypes.AST.node): result<
@ -179,7 +179,7 @@ let runAll = (squiggleString: string) => {
sampleCount: Some(10000), sampleCount: Some(10000),
outputXYPoints: Some(10000), outputXYPoints: Some(10000),
kernelWidth: None, kernelWidth: None,
shapeLength: Some(1000), pointSetDistLength: Some(1000),
}, },
~squiggleString, ~squiggleString,
~environment=[]->Belt.Map.String.fromArray, ~environment=[]->Belt.Map.String.fromArray,

View File

@ -1,6 +1,7 @@
open ASTTypes.AST open ASTTypes.AST
let toString = ASTBasic.toString let toString = ASTBasic.toString
let envs = (samplingInputs, environment) => { let envs = (samplingInputs, environment) => {
samplingInputs: samplingInputs, samplingInputs: samplingInputs,
environment: environment, environment: environment,
@ -9,9 +10,10 @@ let envs = (samplingInputs, environment) => {
let toLeaf = (samplingInputs, environment, node: node) => let toLeaf = (samplingInputs, environment, node: node) =>
ASTEvaluator.toLeaf(envs(samplingInputs, environment), node) ASTEvaluator.toLeaf(envs(samplingInputs, environment), node)
let toShape = (samplingInputs, environment, node: node) =>
let toPointSetDist = (samplingInputs, environment, node: node) =>
switch toLeaf(samplingInputs, environment, node) { switch toLeaf(samplingInputs, environment, node) {
| Ok(#RenderedDist(shape)) => Ok(shape) | Ok(#RenderedDist(pointSetDist)) => Ok(pointSetDist)
| Ok(_) => Error("Rendering failed.") | Ok(_) => Error("Rendering failed.")
| Error(e) => Error(e) | Error(e) => Error(e)
} }

View File

@ -94,7 +94,7 @@ module PointwiseCombination = {
let pointwiseCombine = (fn, evaluationParams: evaluationParams, t1: t, t2: t) => let pointwiseCombine = (fn, evaluationParams: evaluationParams, t1: t, t2: t) =>
switch // TODO: construct a function that we can easily sample from, to construct switch // TODO: construct a function that we can easily sample from, to construct
// a RenderedDist. Use the xMin and xMax of the rendered shapes to tell the sampling function where to look. // a RenderedDist. Use the xMin and xMax of the rendered pointSetDists to tell the sampling function where to look.
// TODO: This should work for symbolic distributions too! // TODO: This should work for symbolic distributions too!
(Render.render(evaluationParams, t1), Render.render(evaluationParams, t2)) { (Render.render(evaluationParams, t1), Render.render(evaluationParams, t2)) {
| (Ok(#RenderedDist(rs1)), Ok(#RenderedDist(rs2))) => | (Ok(#RenderedDist(rs1)), Ok(#RenderedDist(rs2))) =>
@ -195,8 +195,8 @@ module Render = {
switch t { switch t {
| #Function(_) => Error("Cannot render a function") | #Function(_) => Error("Cannot render a function")
| #SymbolicDist(d) => | #SymbolicDist(d) =>
Ok(#RenderedDist(SymbolicDist.T.toShape(evaluationParams.samplingInputs.shapeLength, d))) Ok(#RenderedDist(SymbolicDist.T.toPointSetDist(evaluationParams.samplingInputs.pointSetDistLength, d)))
| #RenderedDist(_) as t => Ok(t) // already a rendered shape, we're done here | #RenderedDist(_) as t => Ok(t) // already a rendered pointSetDist, we're done here
| _ => evaluateAndRetry(evaluationParams, operationToLeaf, t) | _ => evaluateAndRetry(evaluationParams, operationToLeaf, t)
} }
} }

View File

@ -19,7 +19,7 @@ module AST = {
type rec hash = array<(string, node)> type rec hash = array<(string, node)>
and node = [ and node = [
| #SymbolicDist(SymbolicDistTypes.symbolicDist) | #SymbolicDist(SymbolicDistTypes.symbolicDist)
| #RenderedDist(PointSetTypes.shape) | #RenderedDist(PointSetTypes.pointSetDist)
| #Symbol(string) | #Symbol(string)
| #Hash(hash) | #Hash(hash)
| #Array(array<node>) | #Array(array<node>)
@ -64,7 +64,7 @@ module AST = {
sampleCount: int, sampleCount: int,
outputXYPoints: int, outputXYPoints: int,
kernelWidth: option<float>, kernelWidth: option<float>,
shapeLength: int, pointSetDistLength: int,
} }
module SamplingInputs = { module SamplingInputs = {
@ -72,13 +72,13 @@ module AST = {
sampleCount: option<int>, sampleCount: option<int>,
outputXYPoints: option<int>, outputXYPoints: option<int>,
kernelWidth: option<float>, kernelWidth: option<float>,
shapeLength: option<int>, pointSetDistLength: option<int>,
} }
let withDefaults = (t: t): samplingInputs => { let withDefaults = (t: t): samplingInputs => {
sampleCount: t.sampleCount |> E.O.default(10000), sampleCount: t.sampleCount |> E.O.default(10000),
outputXYPoints: t.outputXYPoints |> E.O.default(10000), outputXYPoints: t.outputXYPoints |> E.O.default(10000),
kernelWidth: t.kernelWidth, kernelWidth: t.kernelWidth,
shapeLength: t.shapeLength |> E.O.default(10000), pointSetDistLength: t.pointSetDistLength |> E.O.default(10000),
} }
} }
@ -148,7 +148,7 @@ module AST = {
| _ => None | _ => None
} }
let _toFloat = (t: PointSetTypes.shape) => let _toFloat = (t: PointSetTypes.pointSetDist) =>
switch t { switch t {
| Discrete({xyShape: {xs: [x], ys: [1.0]}}) => Some(#SymbolicDist(#Float(x))) | Discrete({xyShape: {xs: [x], ys: [1.0]}}) => Some(#SymbolicDist(#Float(x)))
| _ => None | _ => None

View File

@ -37,7 +37,7 @@ module Function = {
module Primative = { module Primative = {
type t = [ type t = [
| #SymbolicDist(SymbolicDistTypes.symbolicDist) | #SymbolicDist(SymbolicDistTypes.symbolicDist)
| #RenderedDist(PointSetTypes.shape) | #RenderedDist(PointSetTypes.pointSetDist)
| #Function(array<string>, node) | #Function(array<string>, node)
] ]
@ -62,7 +62,7 @@ module Primative = {
module SamplingDistribution = { module SamplingDistribution = {
type t = [ type t = [
| #SymbolicDist(SymbolicDistTypes.symbolicDist) | #SymbolicDist(SymbolicDistTypes.symbolicDist)
| #RenderedDist(PointSetTypes.shape) | #RenderedDist(PointSetTypes.pointSetDist)
] ]
let isSamplingDistribution: node => bool = x => let isSamplingDistribution: node => bool = x =>
@ -126,12 +126,13 @@ module SamplingDistribution = {
) )
// todo: This bottom part should probably be somewhere else. // todo: This bottom part should probably be somewhere else.
let shape = // todo: REFACTOR: I'm not sure about the SampleSet line.
let pointSetDist =
samples samples
|> E.O.fmap(SamplesToShape.fromSamples(~samplingInputs=evaluationParams.samplingInputs)) |> E.O.fmap(r => SampleSet.toPointSetDist(~samplingInputs=evaluationParams.samplingInputs, ~samples=r, ()))
|> E.O.bind(_, r => r.shape) |> E.O.bind(_, r => r.pointSetDist)
|> E.O.toResult("No response") |> E.O.toResult("No response")
shape |> E.R.fmap(r => #Normalize(#RenderedDist(r))) pointSetDist |> E.R.fmap(r => #Normalize(#RenderedDist(r)))
}) })
} }
} }

View File

@ -3,7 +3,7 @@ let getFloat = ASTTypes.AST.getFloat
type samplingDist = [ type samplingDist = [
| #SymbolicDist(SymbolicDistTypes.symbolicDist) | #SymbolicDist(SymbolicDistTypes.symbolicDist)
| #RenderedDist(PointSetTypes.shape) | #RenderedDist(PointSetTypes.pointSetDist)
] ]
type rec hashType = array<(string, _type)> type rec hashType = array<(string, _type)>
@ -18,7 +18,7 @@ and _type = [
type rec hashTypedValue = array<(string, typedValue)> type rec hashTypedValue = array<(string, typedValue)>
and typedValue = [ and typedValue = [
| #Float(float) | #Float(float)
| #RenderedDist(PointSetTypes.shape) | #RenderedDist(PointSetTypes.pointSetDist)
| #SamplingDist(samplingDist) | #SamplingDist(samplingDist)
| #Array(array<typedValue>) | #Array(array<typedValue>)
| #Hash(hashTypedValue) | #Hash(hashTypedValue)

View File

@ -137,7 +137,7 @@ module T = Dist({
let mapY = mapY let mapY = mapY
let updateIntegralCache = updateIntegralCache let updateIntegralCache = updateIntegralCache
let toDiscreteProbabilityMassFraction = _ => 0.0 let toDiscreteProbabilityMassFraction = _ => 0.0
let toShape = (t: t): PointSetTypes.shape => Continuous(t) let toPointSetDist = (t: t): PointSetTypes.pointSetDist => Continuous(t)
let xToY = (f, {interpolation, xyShape}: t) => let xToY = (f, {interpolation, xyShape}: t) =>
switch interpolation { switch interpolation {
| #Stepwise => xyShape |> XYShape.XtoY.stepwiseIncremental(f) |> E.O.default(0.0) | #Stepwise => xyShape |> XYShape.XtoY.stepwiseIncremental(f) |> E.O.default(0.0)

View File

@ -157,7 +157,7 @@ module T = Dist({
let toDiscreteProbabilityMassFraction = _ => 1.0 let toDiscreteProbabilityMassFraction = _ => 1.0
let mapY = mapY let mapY = mapY
let updateIntegralCache = updateIntegralCache let updateIntegralCache = updateIntegralCache
let toShape = (t: t): PointSetTypes.shape => Discrete(t) let toPointSetDist = (t: t): PointSetTypes.pointSetDist => Discrete(t)
let toContinuous = _ => None let toContinuous = _ => None
let toDiscrete = t => Some(t) let toDiscrete = t => Some(t)

View File

@ -2,39 +2,39 @@ open PointSetTypes;
type t = PointSetTypes.distPlus; type t = PointSetTypes.distPlus;
let shapeIntegral = shape => PointSetDist.T.Integral.get(shape); let pointSetDistIntegral = pointSetDist => PointSetDist.T.Integral.get(pointSetDist);
let make = let make =
( (
~shape, ~pointSetDist,
~squiggleString, ~squiggleString,
~domain=Complete, ~domain=Complete,
~unit=UnspecifiedDistribution, ~unit=UnspecifiedDistribution,
(), (),
) )
: t => { : t => {
let integral = shapeIntegral(shape); let integral = pointSetDistIntegral(pointSetDist);
{shape, domain, integralCache: integral, unit, squiggleString}; {pointSetDist, domain, integralCache: integral, unit, squiggleString};
}; };
let update = let update =
( (
~shape=?, ~pointSetDist=?,
~integralCache=?, ~integralCache=?,
~domain=?, ~domain=?,
~unit=?, ~unit=?,
~squiggleString=?, ~squiggleString=?,
t: t, t: t,
) => { ) => {
shape: E.O.default(t.shape, shape), pointSetDist: E.O.default(t.pointSetDist, pointSetDist),
integralCache: E.O.default(t.integralCache, integralCache), integralCache: E.O.default(t.integralCache, integralCache),
domain: E.O.default(t.domain, domain), domain: E.O.default(t.domain, domain),
unit: E.O.default(t.unit, unit), unit: E.O.default(t.unit, unit),
squiggleString: E.O.default(t.squiggleString, squiggleString), squiggleString: E.O.default(t.squiggleString, squiggleString),
}; };
let updateShape = (shape, t) => { let updateShape = (pointSetDist, t) => {
let integralCache = shapeIntegral(shape); let integralCache = pointSetDistIntegral(pointSetDist);
update(~shape, ~integralCache, t); update(~pointSetDist, ~integralCache, t);
}; };
let domainIncludedProbabilityMass = (t: t) => let domainIncludedProbabilityMass = (t: t) =>
@ -43,27 +43,27 @@ let domainIncludedProbabilityMass = (t: t) =>
let domainIncludedProbabilityMassAdjustment = (t: t, f) => let domainIncludedProbabilityMassAdjustment = (t: t, f) =>
f *. Domain.includedProbabilityMass(t.domain); f *. Domain.includedProbabilityMass(t.domain);
let toShape = ({shape, _}: t) => shape; let toPointSetDist = ({pointSetDist, _}: t) => pointSetDist;
let shapeFn = (fn, {shape}: t) => fn(shape); let pointSetDistFn = (fn, {pointSetDist}: t) => fn(pointSetDist);
module T = module T =
Distributions.Dist({ Distributions.Dist({
type t = PointSetTypes.distPlus; type t = PointSetTypes.distPlus;
type integral = PointSetTypes.distPlus; type integral = PointSetTypes.distPlus;
let toShape = toShape; let toPointSetDist = toPointSetDist;
let toContinuous = shapeFn(PointSetDist.T.toContinuous); let toContinuous = pointSetDistFn(PointSetDist.T.toContinuous);
let toDiscrete = shapeFn(PointSetDist.T.toDiscrete); let toDiscrete = pointSetDistFn(PointSetDist.T.toDiscrete);
let normalize = (t: t): t => { let normalize = (t: t): t => {
let normalizedShape = t |> toShape |> PointSetDist.T.normalize; let normalizedShape = t |> toPointSetDist |> PointSetDist.T.normalize;
t |> updateShape(normalizedShape); t |> updateShape(normalizedShape);
}; };
let truncate = (leftCutoff, rightCutoff, t: t): t => { let truncate = (leftCutoff, rightCutoff, t: t): t => {
let truncatedShape = let truncatedShape =
t t
|> toShape |> toPointSetDist
|> PointSetDist.T.truncate(leftCutoff, rightCutoff); |> PointSetDist.T.truncate(leftCutoff, rightCutoff);
t |> updateShape(truncatedShape); t |> updateShape(truncatedShape);
@ -71,14 +71,14 @@ module T =
let xToY = (f, t: t) => let xToY = (f, t: t) =>
t t
|> toShape |> toPointSetDist
|> PointSetDist.T.xToY(f) |> PointSetDist.T.xToY(f)
|> MixedPoint.fmap(domainIncludedProbabilityMassAdjustment(t)); |> MixedPoint.fmap(domainIncludedProbabilityMassAdjustment(t));
let minX = shapeFn(PointSetDist.T.minX); let minX = pointSetDistFn(PointSetDist.T.minX);
let maxX = shapeFn(PointSetDist.T.maxX); let maxX = pointSetDistFn(PointSetDist.T.maxX);
let toDiscreteProbabilityMassFraction = let toDiscreteProbabilityMassFraction =
shapeFn(PointSetDist.T.toDiscreteProbabilityMassFraction); pointSetDistFn(PointSetDist.T.toDiscreteProbabilityMassFraction);
// This bit is kind of awkward, could probably use rethinking. // This bit is kind of awkward, could probably use rethinking.
let integral = (t: t) => let integral = (t: t) =>
@ -88,23 +88,23 @@ module T =
update(~integralCache=E.O.default(t.integralCache, integralCache), t); update(~integralCache=E.O.default(t.integralCache, integralCache), t);
let downsample = (i, t): t => let downsample = (i, t): t =>
updateShape(t |> toShape |> PointSetDist.T.downsample(i), t); updateShape(t |> toPointSetDist |> PointSetDist.T.downsample(i), t);
// todo: adjust for limit, maybe? // todo: adjust for limit, maybe?
let mapY = let mapY =
( (
~integralSumCacheFn=previousIntegralSum => None, ~integralSumCacheFn=previousIntegralSum => None,
~integralCacheFn=previousIntegralCache => None, ~integralCacheFn=previousIntegralCache => None,
~fn, ~fn,
{shape, _} as t: t, {pointSetDist, _} as t: t,
) )
: t => : t =>
PointSetDist.T.mapY(~integralSumCacheFn, ~fn, shape) PointSetDist.T.mapY(~integralSumCacheFn, ~fn, pointSetDist)
|> updateShape(_, t); |> updateShape(_, t);
// get the total of everything // get the total of everything
let integralEndY = (t: t) => { let integralEndY = (t: t) => {
PointSetDist.T.Integral.sum( PointSetDist.T.Integral.sum(
toShape(t), toPointSetDist(t),
); );
}; };
@ -112,18 +112,18 @@ module T =
let integralXtoY = (f, t: t) => { let integralXtoY = (f, t: t) => {
PointSetDist.T.Integral.xToY( PointSetDist.T.Integral.xToY(
f, f,
toShape(t), toPointSetDist(t),
) )
|> domainIncludedProbabilityMassAdjustment(t); |> domainIncludedProbabilityMassAdjustment(t);
}; };
// TODO: This part is broken when there is a limit, if this is supposed to be taken into account. // TODO: This part is broken when there is a limit, if this is supposed to be taken into account.
let integralYtoX = (f, t: t) => { let integralYtoX = (f, t: t) => {
PointSetDist.T.Integral.yToX(f, toShape(t)); PointSetDist.T.Integral.yToX(f, toPointSetDist(t));
}; };
let mean = (t: t) => { let mean = (t: t) => {
PointSetDist.T.mean(t.shape); PointSetDist.T.mean(t.pointSetDist);
}; };
let variance = (t: t) => PointSetDist.T.variance(t.shape); let variance = (t: t) => PointSetDist.T.variance(t.pointSetDist);
}); });

View File

@ -10,7 +10,7 @@ module type dist = {
t, t,
) => t ) => t
let xToY: (float, t) => PointSetTypes.mixedPoint let xToY: (float, t) => PointSetTypes.mixedPoint
let toShape: t => PointSetTypes.shape let toPointSetDist: t => PointSetTypes.pointSetDist
let toContinuous: t => option<PointSetTypes.continuousShape> let toContinuous: t => option<PointSetTypes.continuousShape>
let toDiscrete: t => option<PointSetTypes.discreteShape> let toDiscrete: t => option<PointSetTypes.discreteShape>
let normalize: t => t let normalize: t => t
@ -39,7 +39,7 @@ module Dist = (T: dist) => {
let mapY = T.mapY let mapY = T.mapY
let xToY = T.xToY let xToY = T.xToY
let downsample = T.downsample let downsample = T.downsample
let toShape = T.toShape let toPointSetDist = T.toPointSetDist
let toDiscreteProbabilityMassFraction = T.toDiscreteProbabilityMassFraction let toDiscreteProbabilityMassFraction = T.toDiscreteProbabilityMassFraction
let toContinuous = T.toContinuous let toContinuous = T.toContinuous
let toDiscrete = T.toDiscrete let toDiscrete = T.toDiscrete

View File

@ -43,7 +43,7 @@ module T = Dist({
min(Continuous.T.minX(continuous), Discrete.T.minX(discrete)) min(Continuous.T.minX(continuous), Discrete.T.minX(discrete))
let maxX = ({continuous, discrete}: t) => let maxX = ({continuous, discrete}: t) =>
max(Continuous.T.maxX(continuous), Discrete.T.maxX(discrete)) max(Continuous.T.maxX(continuous), Discrete.T.maxX(discrete))
let toShape = (t: t): PointSetTypes.shape => Mixed(t) let toPointSetDist = (t: t): PointSetTypes.pointSetDist => Mixed(t)
let updateIntegralCache = updateIntegralCache let updateIntegralCache = updateIntegralCache

View File

@ -11,7 +11,7 @@ type assumptions = {
let buildSimple = ( let buildSimple = (
~continuous: option<PointSetTypes.continuousShape>, ~continuous: option<PointSetTypes.continuousShape>,
~discrete: option<PointSetTypes.discreteShape>, ~discrete: option<PointSetTypes.discreteShape>,
): option<PointSetTypes.shape> => { ): option<PointSetTypes.pointSetDist> => {
let continuous = let continuous =
continuous |> E.O.default(Continuous.make(~integralSumCache=Some(0.0), {xs: [], ys: []})) continuous |> E.O.default(Continuous.make(~integralSumCache=Some(0.0), {xs: [], ys: []}))
let discrete = let discrete =

View File

@ -1,6 +1,6 @@
open Distributions open Distributions
type t = PointSetTypes.shape type t = PointSetTypes.pointSetDist
let mapToAll = ((fn1, fn2, fn3), t: t) => let mapToAll = ((fn1, fn2, fn3), t: t) =>
switch t { switch t {
| Mixed(m) => fn1(m) | Mixed(m) => fn1(m)
@ -36,12 +36,12 @@ let toMixed = mapToAll((
let combineAlgebraically = (op: ASTTypes.algebraicOperation, t1: t, t2: t): t => let combineAlgebraically = (op: ASTTypes.algebraicOperation, t1: t, t2: t): t =>
switch (t1, t2) { switch (t1, t2) {
| (Continuous(m1), Continuous(m2)) => | (Continuous(m1), Continuous(m2)) =>
Continuous.combineAlgebraically(op, m1, m2) |> Continuous.T.toShape Continuous.combineAlgebraically(op, m1, m2) |> Continuous.T.toPointSetDist
| (Continuous(m1), Discrete(m2)) | (Continuous(m1), Discrete(m2))
| (Discrete(m2), Continuous(m1)) => | (Discrete(m2), Continuous(m1)) =>
Continuous.combineAlgebraicallyWithDiscrete(op, m1, m2) |> Continuous.T.toShape Continuous.combineAlgebraicallyWithDiscrete(op, m1, m2) |> Continuous.T.toPointSetDist
| (Discrete(m1), Discrete(m2)) => Discrete.combineAlgebraically(op, m1, m2) |> Discrete.T.toShape | (Discrete(m1), Discrete(m2)) => Discrete.combineAlgebraically(op, m1, m2) |> Discrete.T.toPointSetDist
| (m1, m2) => Mixed.combineAlgebraically(op, toMixed(m1), toMixed(m2)) |> Mixed.T.toShape | (m1, m2) => Mixed.combineAlgebraically(op, toMixed(m1), toMixed(m2)) |> Mixed.T.toPointSetDist
} }
let combinePointwise = ( let combinePointwise = (
@ -70,12 +70,12 @@ let combinePointwise = (
} }
module T = Dist({ module T = Dist({
type t = PointSetTypes.shape type t = PointSetTypes.pointSetDist
type integral = PointSetTypes.continuousShape type integral = PointSetTypes.continuousShape
let xToY = (f: float) => mapToAll((Mixed.T.xToY(f), Discrete.T.xToY(f), Continuous.T.xToY(f))) let xToY = (f: float) => mapToAll((Mixed.T.xToY(f), Discrete.T.xToY(f), Continuous.T.xToY(f)))
let toShape = (t: t) => t let toPointSetDist = (t: t) => t
let toContinuous = t => None let toContinuous = t => None
let toDiscrete = t => None let toDiscrete = t => None

View File

@ -50,15 +50,15 @@ type mixedShape = {
integralCache: option<continuousShape>, integralCache: option<continuousShape>,
} }
type shapeMonad<'a, 'b, 'c> = type pointSetDistMonad<'a, 'b, 'c> =
| Mixed('a) | Mixed('a)
| Discrete('b) | Discrete('b)
| Continuous('c) | Continuous('c)
type shape = shapeMonad<mixedShape, discreteShape, continuousShape> type pointSetDist = pointSetDistMonad<mixedShape, discreteShape, continuousShape>
module ShapeMonad = { module ShapeMonad = {
let fmap = (t: shapeMonad<'a, 'b, 'c>, (fn1, fn2, fn3)): shapeMonad<'d, 'e, 'f> => let fmap = (t: pointSetDistMonad<'a, 'b, 'c>, (fn1, fn2, fn3)): pointSetDistMonad<'d, 'e, 'f> =>
switch t { switch t {
| Mixed(m) => Mixed(fn1(m)) | Mixed(m) => Mixed(fn1(m))
| Discrete(m) => Discrete(fn2(m)) | Discrete(m) => Discrete(fn2(m))
@ -68,13 +68,13 @@ module ShapeMonad = {
type generationSource = type generationSource =
| SquiggleString(string) | SquiggleString(string)
| Shape(shape) | Shape(pointSetDist)
type distributionUnit = type distributionUnit =
| UnspecifiedDistribution | UnspecifiedDistribution
type distPlus = { type distPlus = {
shape: shape, pointSetDist: pointSetDist,
domain: domain, domain: domain,
integralCache: continuousShape, integralCache: continuousShape,
unit: distributionUnit, unit: distributionUnit,

View File

@ -15,7 +15,6 @@ const samplesToContinuousPdf = (
return {xs: pdf.map(r => r.x), ys: pdf.map(r => r.y)}; return {xs: pdf.map(r => r.x), ys: pdf.map(r => r.y)};
}; };
module.exports = { module.exports = {
samplesToContinuousPdf, samplesToContinuousPdf,
}; };

View File

@ -11,7 +11,7 @@ module Internals = {
type outputs = { type outputs = {
continuousParseParams: option<samplingStats>, continuousParseParams: option<samplingStats>,
shape: option<PointSetTypes.shape>, pointSetDist: option<PointSetTypes.pointSetDist>,
} }
} }
@ -78,7 +78,7 @@ module Internals = {
} }
} }
let toShape = ( let toPointSetDist = (
~samples: Internals.T.t, ~samples: Internals.T.t,
~samplingInputs: ASTTypes.AST.samplingInputs, ~samplingInputs: ASTTypes.AST.samplingInputs,
(), (),
@ -127,17 +127,15 @@ let toShape = (
} }
: None : None
let shape = MixedShapeBuilder.buildSimple( let pointSetDist = MixedShapeBuilder.buildSimple(
~continuous=pdf |> E.O.fmap(fst), ~continuous=pdf |> E.O.fmap(fst),
~discrete=Some(discrete), ~discrete=Some(discrete),
) )
let samplesParse: Internals.Types.outputs = { let samplesParse: Internals.Types.outputs = {
continuousParseParams: pdf |> E.O.fmap(snd), continuousParseParams: pdf |> E.O.fmap(snd),
shape: shape, pointSetDist: pointSetDist,
} }
samplesParse samplesParse
} }
let fromSamples = (~samplingInputs, samples) => toShape(~samples, ~samplingInputs, ())

View File

@ -317,7 +317,7 @@ module T = {
| _ => #NoSolution | _ => #NoSolution
} }
let toShape = (sampleCount, d: symbolicDist): PointSetTypes.shape => let toPointSetDist = (sampleCount, d: symbolicDist): PointSetTypes.pointSetDist =>
switch d { switch d {
| #Float(v) => Discrete(Discrete.make(~integralSumCache=Some(1.0), {xs: [v], ys: [1.0]})) | #Float(v) => Discrete(Discrete.make(~integralSumCache=Some(1.0), {xs: [v], ys: [1.0]}))
| _ => | _ =>