880 lines
31 KiB
JavaScript
880 lines
31 KiB
JavaScript
'use strict';
|
|
|
|
var Curry = require("@rescript/std/lib/js/curry.js");
|
|
var Belt_Array = require("@rescript/std/lib/js/belt_Array.js");
|
|
var Caml_option = require("@rescript/std/lib/js/caml_option.js");
|
|
var E_A$QuriSquiggleLang = require("../Utility/E/E_A.bs.js");
|
|
var E_O$QuriSquiggleLang = require("../Utility/E/E_O.bs.js");
|
|
var E_R$QuriSquiggleLang = require("../Utility/E/E_R.bs.js");
|
|
var XYShape$QuriSquiggleLang = require("../Utility/XYShape.bs.js");
|
|
var E_Tuple2$QuriSquiggleLang = require("../Utility/E/E_Tuple2.bs.js");
|
|
var Operation$QuriSquiggleLang = require("../Utility/Operation.bs.js");
|
|
var MagicNumbers$QuriSquiggleLang = require("../MagicNumbers.bs.js");
|
|
var PointSetDist$QuriSquiggleLang = require("./PointSetDist/PointSetDist.bs.js");
|
|
var SymbolicDist$QuriSquiggleLang = require("./SymbolicDist/SymbolicDist.bs.js");
|
|
var SampleSetDist$QuriSquiggleLang = require("./SampleSetDist/SampleSetDist.bs.js");
|
|
var DistributionTypes$QuriSquiggleLang = require("./DistributionTypes.bs.js");
|
|
|
|
function isPointSet(t) {
|
|
switch (t.TAG | 0) {
|
|
case /* PointSet */0 :
|
|
return true;
|
|
case /* SampleSet */1 :
|
|
case /* Symbolic */2 :
|
|
return false;
|
|
|
|
}
|
|
}
|
|
|
|
function isSampleSetSet(t) {
|
|
switch (t.TAG | 0) {
|
|
case /* SampleSet */1 :
|
|
return true;
|
|
case /* PointSet */0 :
|
|
case /* Symbolic */2 :
|
|
return false;
|
|
|
|
}
|
|
}
|
|
|
|
function isSymbolic(t) {
|
|
switch (t.TAG | 0) {
|
|
case /* PointSet */0 :
|
|
case /* SampleSet */1 :
|
|
return false;
|
|
case /* Symbolic */2 :
|
|
return true;
|
|
|
|
}
|
|
}
|
|
|
|
function sampleN(t, n) {
|
|
switch (t.TAG | 0) {
|
|
case /* PointSet */0 :
|
|
return PointSetDist$QuriSquiggleLang.sampleNRendered(n, t._0);
|
|
case /* SampleSet */1 :
|
|
return SampleSetDist$QuriSquiggleLang.sampleN(t._0, n);
|
|
case /* Symbolic */2 :
|
|
return SymbolicDist$QuriSquiggleLang.T.sampleN(n, t._0);
|
|
|
|
}
|
|
}
|
|
|
|
function sample(t) {
|
|
return E_O$QuriSquiggleLang.toExn(E_A$QuriSquiggleLang.first(sampleN(t, 1)), "Should not have happened");
|
|
}
|
|
|
|
function toSampleSetDist(t, n) {
|
|
return E_R$QuriSquiggleLang.errMap(SampleSetDist$QuriSquiggleLang.make(sampleN(t, n)), DistributionTypes$QuriSquiggleLang.$$Error.sampleErrorToDistErr);
|
|
}
|
|
|
|
function fromFloat(f) {
|
|
return {
|
|
TAG: 2,
|
|
_0: SymbolicDist$QuriSquiggleLang.Float.make(f),
|
|
[Symbol.for("name")]: "Symbolic"
|
|
};
|
|
}
|
|
|
|
function toString(t) {
|
|
switch (t.TAG | 0) {
|
|
case /* PointSet */0 :
|
|
return "Point Set Distribution";
|
|
case /* SampleSet */1 :
|
|
return "Sample Set Distribution";
|
|
case /* Symbolic */2 :
|
|
return SymbolicDist$QuriSquiggleLang.T.toString(t._0);
|
|
|
|
}
|
|
}
|
|
|
|
function normalize(t) {
|
|
switch (t.TAG | 0) {
|
|
case /* PointSet */0 :
|
|
return {
|
|
TAG: 0,
|
|
_0: Curry._1(PointSetDist$QuriSquiggleLang.T.normalize, t._0),
|
|
[Symbol.for("name")]: "PointSet"
|
|
};
|
|
case /* SampleSet */1 :
|
|
case /* Symbolic */2 :
|
|
return t;
|
|
|
|
}
|
|
}
|
|
|
|
function integralEndY(t) {
|
|
switch (t.TAG | 0) {
|
|
case /* PointSet */0 :
|
|
return Curry._1(PointSetDist$QuriSquiggleLang.T.integralEndY, t._0);
|
|
case /* SampleSet */1 :
|
|
case /* Symbolic */2 :
|
|
return 1.0;
|
|
|
|
}
|
|
}
|
|
|
|
function isNormalized(t) {
|
|
return Math.abs(integralEndY(t) - 1.0) < 1e-7;
|
|
}
|
|
|
|
function toFloatOperation(t, toPointSetFn, distToFloatOperation) {
|
|
if (typeof distToFloatOperation !== "object" && !(distToFloatOperation === "Mean" || distToFloatOperation === "Min" || distToFloatOperation === "Max" || distToFloatOperation === "Sample")) {
|
|
if (distToFloatOperation === "IntegralSum") {
|
|
return {
|
|
TAG: 0,
|
|
_0: integralEndY(t),
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
}
|
|
switch (t.TAG | 0) {
|
|
case /* SampleSet */1 :
|
|
var s = t._0;
|
|
if (distToFloatOperation === "Stdev") {
|
|
return {
|
|
TAG: 0,
|
|
_0: SampleSetDist$QuriSquiggleLang.stdev(s),
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
} else if (distToFloatOperation === "Mode") {
|
|
return {
|
|
TAG: 0,
|
|
_0: SampleSetDist$QuriSquiggleLang.mode(s),
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
} else {
|
|
return {
|
|
TAG: 0,
|
|
_0: SampleSetDist$QuriSquiggleLang.variance(s),
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
}
|
|
case /* PointSet */0 :
|
|
case /* Symbolic */2 :
|
|
return {
|
|
TAG: 1,
|
|
_0: /* NotYetImplemented */0,
|
|
[Symbol.for("name")]: "Error"
|
|
};
|
|
|
|
}
|
|
}
|
|
var trySymbolicSolution;
|
|
switch (t.TAG | 0) {
|
|
case /* PointSet */0 :
|
|
case /* SampleSet */1 :
|
|
trySymbolicSolution = undefined;
|
|
break;
|
|
case /* Symbolic */2 :
|
|
trySymbolicSolution = E_R$QuriSquiggleLang.toOption(SymbolicDist$QuriSquiggleLang.T.operate(distToFloatOperation, t._0));
|
|
break;
|
|
|
|
}
|
|
var trySampleSetSolution;
|
|
switch (t.TAG | 0) {
|
|
case /* SampleSet */1 :
|
|
var sampleSet = t._0;
|
|
if (typeof distToFloatOperation === "object") {
|
|
var variant = distToFloatOperation.NAME;
|
|
trySampleSetSolution = variant === "Cdf" ? SampleSetDist$QuriSquiggleLang.cdf(sampleSet, distToFloatOperation.VAL) : (
|
|
variant === "Inv" ? SampleSetDist$QuriSquiggleLang.percentile(sampleSet, distToFloatOperation.VAL) : undefined
|
|
);
|
|
} else {
|
|
trySampleSetSolution = distToFloatOperation === "Sample" ? SampleSetDist$QuriSquiggleLang.sample(sampleSet) : (
|
|
distToFloatOperation === "Max" ? SampleSetDist$QuriSquiggleLang.max(sampleSet) : (
|
|
distToFloatOperation === "Min" ? SampleSetDist$QuriSquiggleLang.min(sampleSet) : (
|
|
distToFloatOperation === "Mean" ? SampleSetDist$QuriSquiggleLang.mean(sampleSet) : undefined
|
|
)
|
|
)
|
|
);
|
|
}
|
|
break;
|
|
case /* PointSet */0 :
|
|
case /* Symbolic */2 :
|
|
trySampleSetSolution = undefined;
|
|
break;
|
|
|
|
}
|
|
if (trySymbolicSolution !== undefined) {
|
|
return {
|
|
TAG: 0,
|
|
_0: trySymbolicSolution,
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
} else if (trySampleSetSolution !== undefined) {
|
|
return {
|
|
TAG: 0,
|
|
_0: trySampleSetSolution,
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
} else {
|
|
return E_R$QuriSquiggleLang.fmap(Curry._1(toPointSetFn, t), (function (param) {
|
|
return PointSetDist$QuriSquiggleLang.operate(distToFloatOperation, param);
|
|
}));
|
|
}
|
|
}
|
|
|
|
function toPointSet(t, xyPointLength, sampleCount, xSelectionOpt, param) {
|
|
var xSelection = xSelectionOpt !== undefined ? xSelectionOpt : "ByWeight";
|
|
switch (t.TAG | 0) {
|
|
case /* PointSet */0 :
|
|
return {
|
|
TAG: 0,
|
|
_0: t._0,
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
case /* SampleSet */1 :
|
|
return E_R$QuriSquiggleLang.errMap(SampleSetDist$QuriSquiggleLang.toPointSetDist(t._0, {
|
|
sampleCount: sampleCount,
|
|
outputXYPoints: xyPointLength,
|
|
kernelWidth: undefined,
|
|
pointSetDistLength: xyPointLength
|
|
}), (function (x) {
|
|
return {
|
|
TAG: 3,
|
|
_0: x,
|
|
[Symbol.for("name")]: "PointSetConversionError"
|
|
};
|
|
}));
|
|
case /* Symbolic */2 :
|
|
return {
|
|
TAG: 0,
|
|
_0: SymbolicDist$QuriSquiggleLang.T.toPointSetDist(xSelection, xyPointLength, t._0),
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
|
|
}
|
|
}
|
|
|
|
function argsMake(esti, answ, prior, env) {
|
|
var toPointSetFn = function (t) {
|
|
return toPointSet(t, env.xyPointLength, env.sampleCount, "ByWeight", undefined);
|
|
};
|
|
var prior$p = prior !== undefined ? toPointSetFn(prior) : undefined;
|
|
var twoDists = function (toPointSetFn, esti$p, answ$p) {
|
|
return E_R$QuriSquiggleLang.merge(Curry._1(toPointSetFn, esti$p), Curry._1(toPointSetFn, answ$p));
|
|
};
|
|
if (answ.TAG === /* Score_Dist */0) {
|
|
var answ$p = answ._0;
|
|
if (prior$p === undefined) {
|
|
return E_R$QuriSquiggleLang.fmap(twoDists(toPointSetFn, esti, answ$p), (function (param) {
|
|
return {
|
|
TAG: 0,
|
|
_0: {
|
|
estimate: param[0],
|
|
answer: param[1],
|
|
prior: undefined
|
|
},
|
|
[Symbol.for("name")]: "DistAnswer"
|
|
};
|
|
}));
|
|
}
|
|
if (prior$p.TAG !== /* Ok */0) {
|
|
return {
|
|
TAG: 1,
|
|
_0: prior$p._0,
|
|
[Symbol.for("name")]: "Error"
|
|
};
|
|
}
|
|
var prior$p$p = prior$p._0;
|
|
return E_R$QuriSquiggleLang.fmap(twoDists(toPointSetFn, esti, answ$p), (function (param) {
|
|
return {
|
|
TAG: 0,
|
|
_0: {
|
|
estimate: param[0],
|
|
answer: param[1],
|
|
prior: prior$p$p
|
|
},
|
|
[Symbol.for("name")]: "DistAnswer"
|
|
};
|
|
}));
|
|
}
|
|
var answ$p$1 = answ._0;
|
|
if (prior$p === undefined) {
|
|
return E_R$QuriSquiggleLang.fmap(toPointSetFn(esti), (function (esti$p$p) {
|
|
return {
|
|
TAG: 1,
|
|
_0: {
|
|
estimate: esti$p$p,
|
|
answer: answ$p$1,
|
|
prior: undefined
|
|
},
|
|
[Symbol.for("name")]: "ScalarAnswer"
|
|
};
|
|
}));
|
|
}
|
|
if (prior$p.TAG !== /* Ok */0) {
|
|
return {
|
|
TAG: 1,
|
|
_0: prior$p._0,
|
|
[Symbol.for("name")]: "Error"
|
|
};
|
|
}
|
|
var prior$p$p$1 = prior$p._0;
|
|
return E_R$QuriSquiggleLang.fmap(toPointSetFn(esti), (function (esti$p$p) {
|
|
return {
|
|
TAG: 1,
|
|
_0: {
|
|
estimate: esti$p$p,
|
|
answer: answ$p$1,
|
|
prior: prior$p$p$1
|
|
},
|
|
[Symbol.for("name")]: "ScalarAnswer"
|
|
};
|
|
}));
|
|
}
|
|
|
|
function logScore(estimate, answer, prior, env) {
|
|
return E_R$QuriSquiggleLang.bind(argsMake(estimate, answer, prior, env), (function (x) {
|
|
return E_R$QuriSquiggleLang.errMap(PointSetDist$QuriSquiggleLang.logScore(x), (function (y) {
|
|
return {
|
|
TAG: 2,
|
|
_0: y,
|
|
[Symbol.for("name")]: "OperationError"
|
|
};
|
|
}));
|
|
}));
|
|
}
|
|
|
|
function toSparkline(t, sampleCount, bucketCountOpt, param) {
|
|
var bucketCount = bucketCountOpt !== undefined ? bucketCountOpt : 20;
|
|
return E_R$QuriSquiggleLang.bind(toPointSet(t, Math.imul(bucketCount, 3), sampleCount, "Linear", undefined), (function (r) {
|
|
return E_R$QuriSquiggleLang.errMap(PointSetDist$QuriSquiggleLang.toSparkline(r, bucketCount), (function (x) {
|
|
return {
|
|
TAG: 4,
|
|
_0: x,
|
|
[Symbol.for("name")]: "SparklineError"
|
|
};
|
|
}));
|
|
}));
|
|
}
|
|
|
|
function trySymbolicSimplification(leftCutoff, rightCutoff, t) {
|
|
if (leftCutoff !== undefined) {
|
|
if (rightCutoff !== undefined) {
|
|
switch (t.TAG | 0) {
|
|
case /* PointSet */0 :
|
|
case /* SampleSet */1 :
|
|
return ;
|
|
case /* Symbolic */2 :
|
|
var match = t._0;
|
|
if (typeof match === "object" && match.NAME === "Uniform" && leftCutoff < rightCutoff) {
|
|
return {
|
|
TAG: 2,
|
|
_0: {
|
|
NAME: "Uniform",
|
|
VAL: SymbolicDist$QuriSquiggleLang.Uniform.truncate(leftCutoff, rightCutoff, match.VAL)
|
|
},
|
|
[Symbol.for("name")]: "Symbolic"
|
|
};
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
} else if (rightCutoff === undefined) {
|
|
return ;
|
|
}
|
|
switch (t.TAG | 0) {
|
|
case /* PointSet */0 :
|
|
case /* SampleSet */1 :
|
|
return ;
|
|
case /* Symbolic */2 :
|
|
var match$1 = t._0;
|
|
if (typeof match$1 === "object" && match$1.NAME === "Uniform") {
|
|
return {
|
|
TAG: 2,
|
|
_0: {
|
|
NAME: "Uniform",
|
|
VAL: SymbolicDist$QuriSquiggleLang.Uniform.truncate(leftCutoff, rightCutoff, match$1.VAL)
|
|
},
|
|
[Symbol.for("name")]: "Symbolic"
|
|
};
|
|
} else {
|
|
return ;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
function run(t, toPointSetFn, leftCutoffOpt, rightCutoffOpt, param) {
|
|
var leftCutoff = leftCutoffOpt !== undefined ? Caml_option.valFromOption(leftCutoffOpt) : undefined;
|
|
var rightCutoff = rightCutoffOpt !== undefined ? Caml_option.valFromOption(rightCutoffOpt) : undefined;
|
|
var doesNotNeedCutoff = E_O$QuriSquiggleLang.isNone(leftCutoff) && E_O$QuriSquiggleLang.isNone(rightCutoff);
|
|
if (doesNotNeedCutoff) {
|
|
return {
|
|
TAG: 0,
|
|
_0: t,
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
}
|
|
var r = trySymbolicSimplification(leftCutoff, rightCutoff, t);
|
|
if (r !== undefined) {
|
|
return {
|
|
TAG: 0,
|
|
_0: r,
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
}
|
|
switch (t.TAG | 0) {
|
|
case /* SampleSet */1 :
|
|
var r$1 = SampleSetDist$QuriSquiggleLang.truncate(t._0, leftCutoff, rightCutoff);
|
|
if (r$1.TAG === /* Ok */0) {
|
|
return {
|
|
TAG: 0,
|
|
_0: {
|
|
TAG: 1,
|
|
_0: r$1._0,
|
|
[Symbol.for("name")]: "SampleSet"
|
|
},
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
} else {
|
|
return {
|
|
TAG: 1,
|
|
_0: {
|
|
TAG: 0,
|
|
_0: r$1._0,
|
|
[Symbol.for("name")]: "SampleSetError"
|
|
},
|
|
[Symbol.for("name")]: "Error"
|
|
};
|
|
}
|
|
case /* PointSet */0 :
|
|
case /* Symbolic */2 :
|
|
break;
|
|
|
|
}
|
|
return E_R$QuriSquiggleLang.fmap(Curry._1(toPointSetFn, t), (function (t) {
|
|
return {
|
|
TAG: 0,
|
|
_0: Curry._1(PointSetDist$QuriSquiggleLang.T.normalize, Curry._3(PointSetDist$QuriSquiggleLang.T.truncate, leftCutoff, rightCutoff, t)),
|
|
[Symbol.for("name")]: "PointSet"
|
|
};
|
|
}));
|
|
}
|
|
|
|
function run$1(t1, t2, toPointSetFn, arithmeticOperation) {
|
|
if (arithmeticOperation === "Logarithm") {
|
|
var isDistGreaterThanZero = function (t) {
|
|
return E_R$QuriSquiggleLang.fmap(toFloatOperation(t, toPointSetFn, {
|
|
NAME: "Cdf",
|
|
VAL: MagicNumbers$QuriSquiggleLang.Epsilon.ten
|
|
}), (function (r) {
|
|
return r > 0;
|
|
}));
|
|
};
|
|
var items = E_A$QuriSquiggleLang.R.firstErrorOrOpen([
|
|
isDistGreaterThanZero(t1),
|
|
isDistGreaterThanZero(t2)
|
|
]);
|
|
if (items.TAG !== /* Ok */0) {
|
|
return items._0;
|
|
}
|
|
var match = items._0;
|
|
if (match.length !== 2) {
|
|
return /* Unreachable */1;
|
|
}
|
|
var match$1 = match[0];
|
|
if (match$1) {
|
|
return {
|
|
TAG: 6,
|
|
_0: "First input must be completely greater than 0",
|
|
[Symbol.for("name")]: "LogarithmOfDistributionError"
|
|
};
|
|
}
|
|
var match$2 = match[1];
|
|
if (match$2) {
|
|
return {
|
|
TAG: 6,
|
|
_0: "Second input must be completely greater than 0",
|
|
[Symbol.for("name")]: "LogarithmOfDistributionError"
|
|
};
|
|
} else {
|
|
return ;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
function convolution(toPointSet, arithmeticOperation, t1, t2) {
|
|
return E_R$QuriSquiggleLang.fmap(E_R$QuriSquiggleLang.fmap(E_R$QuriSquiggleLang.merge(Curry._1(toPointSet, t1), Curry._1(toPointSet, t2)), (function (param) {
|
|
return PointSetDist$QuriSquiggleLang.combineAlgebraically(arithmeticOperation, param[0], param[1]);
|
|
})), (function (r) {
|
|
return {
|
|
TAG: 0,
|
|
_0: r,
|
|
[Symbol.for("name")]: "PointSet"
|
|
};
|
|
}));
|
|
}
|
|
|
|
function monteCarlo(toSampleSet, arithmeticOperation, t1, t2) {
|
|
var fn = function (param, param$1) {
|
|
return Operation$QuriSquiggleLang.Algebraic.toFn(arithmeticOperation, param, param$1);
|
|
};
|
|
return E_R$QuriSquiggleLang.fmap(E_R$QuriSquiggleLang.bind(E_R$QuriSquiggleLang.merge(Curry._1(toSampleSet, t1), Curry._1(toSampleSet, t2)), (function (param) {
|
|
return E_R$QuriSquiggleLang.errMap(SampleSetDist$QuriSquiggleLang.map2(fn, param[0], param[1]), (function (x) {
|
|
return {
|
|
TAG: 0,
|
|
_0: x,
|
|
[Symbol.for("name")]: "SampleSetError"
|
|
};
|
|
}));
|
|
})), (function (r) {
|
|
return {
|
|
TAG: 1,
|
|
_0: r,
|
|
[Symbol.for("name")]: "SampleSet"
|
|
};
|
|
}));
|
|
}
|
|
|
|
function symbolic(arithmeticOperation, t1, t2) {
|
|
switch (t1.TAG | 0) {
|
|
case /* PointSet */0 :
|
|
case /* SampleSet */1 :
|
|
return "NoSolution";
|
|
case /* Symbolic */2 :
|
|
switch (t2.TAG | 0) {
|
|
case /* PointSet */0 :
|
|
case /* SampleSet */1 :
|
|
return "NoSolution";
|
|
case /* Symbolic */2 :
|
|
return SymbolicDist$QuriSquiggleLang.T.tryAnalyticalSimplification(t1._0, t2._0, arithmeticOperation);
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
function expectedConvolutionCost(x) {
|
|
switch (x.TAG | 0) {
|
|
case /* PointSet */0 :
|
|
var m = x._0;
|
|
switch (m.TAG | 0) {
|
|
case /* Mixed */0 :
|
|
return MagicNumbers$QuriSquiggleLang.OpCost.mixedCost;
|
|
case /* Discrete */1 :
|
|
return XYShape$QuriSquiggleLang.T.length(m._0.xyShape);
|
|
case /* Continuous */2 :
|
|
return MagicNumbers$QuriSquiggleLang.OpCost.continuousCost;
|
|
|
|
}
|
|
case /* SampleSet */1 :
|
|
return MagicNumbers$QuriSquiggleLang.OpCost.wildcardCost;
|
|
case /* Symbolic */2 :
|
|
var match = x._0;
|
|
if (typeof match === "object" && match.NAME === "Float") {
|
|
return MagicNumbers$QuriSquiggleLang.OpCost.floatCost;
|
|
} else {
|
|
return MagicNumbers$QuriSquiggleLang.OpCost.symbolicCost;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
function hasSampleSetDist(t1, t2) {
|
|
if (isSampleSetSet(t1)) {
|
|
return true;
|
|
} else {
|
|
return isSampleSetSet(t2);
|
|
}
|
|
}
|
|
|
|
function preferConvolutionToMonteCarlo(t1, t2, arithmeticOperation) {
|
|
if (!hasSampleSetDist(t1, t2) && Operation$QuriSquiggleLang.Convolution.canDoAlgebraicOperation(arithmeticOperation)) {
|
|
return Math.imul(expectedConvolutionCost(t1), expectedConvolutionCost(t2)) < MagicNumbers$QuriSquiggleLang.OpCost.monteCarloCost;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function run$2(t1, t2, arithmeticOperation) {
|
|
var match = symbolic(arithmeticOperation, t1, t2);
|
|
if (typeof match === "object") {
|
|
return "AsSymbolic";
|
|
} else if (preferConvolutionToMonteCarlo(t1, t2, arithmeticOperation)) {
|
|
return "AsConvolution";
|
|
} else {
|
|
return "AsMonteCarlo";
|
|
}
|
|
}
|
|
|
|
function run$3(strategy, t1, toPointSetFn, toSampleSetFn, arithmeticOperation, t2) {
|
|
var invalidOperationError = run$1(t1, t2, toPointSetFn, arithmeticOperation);
|
|
if (invalidOperationError !== undefined) {
|
|
return {
|
|
TAG: 1,
|
|
_0: invalidOperationError,
|
|
[Symbol.for("name")]: "Error"
|
|
};
|
|
}
|
|
switch (strategy) {
|
|
case /* AsDefault */0 :
|
|
var chooseStrategy = run$2(t1, t2, arithmeticOperation);
|
|
if (chooseStrategy === "AsSymbolic") {
|
|
var match = symbolic(arithmeticOperation, t1, t2);
|
|
if (typeof match === "object") {
|
|
if (match.NAME === "Error") {
|
|
return {
|
|
TAG: 1,
|
|
_0: {
|
|
TAG: 2,
|
|
_0: match.VAL,
|
|
[Symbol.for("name")]: "OperationError"
|
|
},
|
|
[Symbol.for("name")]: "Error"
|
|
};
|
|
} else {
|
|
return {
|
|
TAG: 0,
|
|
_0: {
|
|
TAG: 2,
|
|
_0: match.VAL,
|
|
[Symbol.for("name")]: "Symbolic"
|
|
},
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
}
|
|
} else {
|
|
return {
|
|
TAG: 1,
|
|
_0: /* Unreachable */1,
|
|
[Symbol.for("name")]: "Error"
|
|
};
|
|
}
|
|
}
|
|
if (chooseStrategy !== "AsConvolution") {
|
|
return monteCarlo(toSampleSetFn, arithmeticOperation, t1, t2);
|
|
}
|
|
var convOp = Operation$QuriSquiggleLang.Convolution.fromAlgebraicOperation(arithmeticOperation);
|
|
if (convOp !== undefined) {
|
|
return convolution(toPointSetFn, convOp, t1, t2);
|
|
} else {
|
|
return {
|
|
TAG: 1,
|
|
_0: /* Unreachable */1,
|
|
[Symbol.for("name")]: "Error"
|
|
};
|
|
}
|
|
case /* AsSymbolic */1 :
|
|
var match$1 = symbolic(arithmeticOperation, t1, t2);
|
|
if (typeof match$1 === "object") {
|
|
if (match$1.NAME === "Error") {
|
|
return {
|
|
TAG: 1,
|
|
_0: {
|
|
TAG: 2,
|
|
_0: match$1.VAL,
|
|
[Symbol.for("name")]: "OperationError"
|
|
},
|
|
[Symbol.for("name")]: "Error"
|
|
};
|
|
} else {
|
|
return {
|
|
TAG: 0,
|
|
_0: {
|
|
TAG: 2,
|
|
_0: match$1.VAL,
|
|
[Symbol.for("name")]: "Symbolic"
|
|
},
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
}
|
|
} else {
|
|
return {
|
|
TAG: 1,
|
|
_0: {
|
|
TAG: 5,
|
|
_0: "No analytic solution for inputs",
|
|
[Symbol.for("name")]: "RequestedStrategyInvalidError"
|
|
},
|
|
[Symbol.for("name")]: "Error"
|
|
};
|
|
}
|
|
case /* AsMonteCarlo */2 :
|
|
return monteCarlo(toSampleSetFn, arithmeticOperation, t1, t2);
|
|
case /* AsConvolution */3 :
|
|
var convOp$1 = Operation$QuriSquiggleLang.Convolution.fromAlgebraicOperation(arithmeticOperation);
|
|
if (convOp$1 !== undefined) {
|
|
return convolution(toPointSetFn, convOp$1, t1, t2);
|
|
}
|
|
var errString = "Convolution not supported for " + Operation$QuriSquiggleLang.Algebraic.toString(arithmeticOperation) + "";
|
|
return {
|
|
TAG: 1,
|
|
_0: {
|
|
TAG: 5,
|
|
_0: errString,
|
|
[Symbol.for("name")]: "RequestedStrategyInvalidError"
|
|
},
|
|
[Symbol.for("name")]: "Error"
|
|
};
|
|
|
|
}
|
|
}
|
|
|
|
function pointwiseCombination(t1, toPointSetFn, algebraicCombination, t2) {
|
|
return E_R$QuriSquiggleLang.bind(E_R$QuriSquiggleLang.merge(Curry._1(toPointSetFn, t1), Curry._1(toPointSetFn, t2)), (function (param) {
|
|
return E_R$QuriSquiggleLang.errMap(E_R$QuriSquiggleLang.fmap(PointSetDist$QuriSquiggleLang.combinePointwise(undefined, undefined, undefined, (function (param, param$1) {
|
|
return Operation$QuriSquiggleLang.Algebraic.toFn(algebraicCombination, param, param$1);
|
|
}), param[0], param[1]), (function (r) {
|
|
return {
|
|
TAG: 0,
|
|
_0: r,
|
|
[Symbol.for("name")]: "PointSet"
|
|
};
|
|
})), (function (err) {
|
|
return {
|
|
TAG: 2,
|
|
_0: err,
|
|
[Symbol.for("name")]: "OperationError"
|
|
};
|
|
}));
|
|
}));
|
|
}
|
|
|
|
function pointwiseCombinationFloat(t, toPointSetFn, algebraicCombination, f) {
|
|
var executeCombination = function (arithOp) {
|
|
return E_R$QuriSquiggleLang.bind(Curry._1(toPointSetFn, t), (function (t) {
|
|
var integralSumCacheFn = Operation$QuriSquiggleLang.Scale.toIntegralSumCacheFn(arithOp);
|
|
var integralCacheFn = Operation$QuriSquiggleLang.Scale.toIntegralCacheFn(arithOp);
|
|
return E_R$QuriSquiggleLang.errMap(Curry._4(PointSetDist$QuriSquiggleLang.T.mapYResult, Curry._1(integralSumCacheFn, f), Curry._1(integralCacheFn, f), t, (function (param) {
|
|
return Operation$QuriSquiggleLang.Scale.toFn(arithOp, param, f);
|
|
})), (function (x) {
|
|
return {
|
|
TAG: 2,
|
|
_0: x,
|
|
[Symbol.for("name")]: "OperationError"
|
|
};
|
|
}));
|
|
}));
|
|
};
|
|
var m = typeof algebraicCombination === "object" ? executeCombination({
|
|
NAME: "LogarithmWithThreshold",
|
|
VAL: algebraicCombination.VAL
|
|
}) : (
|
|
algebraicCombination === "Multiply" || algebraicCombination === "Divide" || algebraicCombination === "Power" || algebraicCombination === "Logarithm" ? executeCombination(algebraicCombination) : ({
|
|
TAG: 1,
|
|
_0: /* DistributionVerticalShiftIsInvalid */2,
|
|
[Symbol.for("name")]: "Error"
|
|
})
|
|
);
|
|
return E_R$QuriSquiggleLang.fmap(m, (function (r) {
|
|
return {
|
|
TAG: 0,
|
|
_0: r,
|
|
[Symbol.for("name")]: "PointSet"
|
|
};
|
|
}));
|
|
}
|
|
|
|
function mixture(values, scaleMultiplyFn, pointwiseAddFn, env) {
|
|
var allValuesAreSampleSet = function (v) {
|
|
return E_A$QuriSquiggleLang.every(v, (function (param) {
|
|
return isSampleSetSet(param[0]);
|
|
}));
|
|
};
|
|
if (E_A$QuriSquiggleLang.isEmpty(values)) {
|
|
return {
|
|
TAG: 1,
|
|
_0: {
|
|
TAG: 7,
|
|
_0: "Mixture error: mixture must have at least 1 element",
|
|
[Symbol.for("name")]: "OtherError"
|
|
},
|
|
[Symbol.for("name")]: "Error"
|
|
};
|
|
}
|
|
if (allValuesAreSampleSet(values)) {
|
|
var withSampleSetValues = E_A$QuriSquiggleLang.fmap(values, (function (param) {
|
|
var value = param[0];
|
|
var tmp;
|
|
switch (value.TAG | 0) {
|
|
case /* SampleSet */1 :
|
|
tmp = {
|
|
TAG: 0,
|
|
_0: [
|
|
value._0,
|
|
param[1]
|
|
],
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
break;
|
|
case /* PointSet */0 :
|
|
case /* Symbolic */2 :
|
|
tmp = {
|
|
TAG: 1,
|
|
_0: "Unreachable",
|
|
[Symbol.for("name")]: "Error"
|
|
};
|
|
break;
|
|
|
|
}
|
|
return E_R$QuriSquiggleLang.toExn(tmp, "Mixture coding error: SampleSet expected. This should be inaccessible.");
|
|
}));
|
|
var sampleSetMixture = SampleSetDist$QuriSquiggleLang.mixture(withSampleSetValues, env.sampleCount);
|
|
if (sampleSetMixture.TAG === /* Ok */0) {
|
|
return {
|
|
TAG: 0,
|
|
_0: {
|
|
TAG: 1,
|
|
_0: sampleSetMixture._0,
|
|
[Symbol.for("name")]: "SampleSet"
|
|
},
|
|
[Symbol.for("name")]: "Ok"
|
|
};
|
|
} else {
|
|
return {
|
|
TAG: 1,
|
|
_0: DistributionTypes$QuriSquiggleLang.$$Error.sampleErrorToDistErr(sampleSetMixture._0),
|
|
[Symbol.for("name")]: "Error"
|
|
};
|
|
}
|
|
}
|
|
var totalWeight = E_A$QuriSquiggleLang.Floats.sum(E_A$QuriSquiggleLang.fmap(values, E_Tuple2$QuriSquiggleLang.second));
|
|
var properlyWeightedValues = E_A$QuriSquiggleLang.R.firstErrorOrOpen(E_A$QuriSquiggleLang.fmap(values, (function (param) {
|
|
return Curry._2(scaleMultiplyFn, param[0], param[1] / totalWeight);
|
|
})));
|
|
return E_R$QuriSquiggleLang.bind(properlyWeightedValues, (function (values) {
|
|
return E_A$QuriSquiggleLang.fold_left(Belt_Array.sliceToEnd(values, 1), {
|
|
TAG: 0,
|
|
_0: E_A$QuriSquiggleLang.unsafe_get(values, 0),
|
|
[Symbol.for("name")]: "Ok"
|
|
}, (function (acc, x) {
|
|
return E_R$QuriSquiggleLang.bind(acc, (function (acc) {
|
|
return Curry._2(pointwiseAddFn, acc, x);
|
|
}));
|
|
}));
|
|
}));
|
|
}
|
|
|
|
var Score = {
|
|
logScore: logScore
|
|
};
|
|
|
|
var truncate = run;
|
|
|
|
var algebraicCombination = run$3;
|
|
|
|
exports.sampleN = sampleN;
|
|
exports.sample = sample;
|
|
exports.toSampleSetDist = toSampleSetDist;
|
|
exports.fromFloat = fromFloat;
|
|
exports.toString = toString;
|
|
exports.normalize = normalize;
|
|
exports.isNormalized = isNormalized;
|
|
exports.toFloatOperation = toFloatOperation;
|
|
exports.Score = Score;
|
|
exports.toPointSet = toPointSet;
|
|
exports.toSparkline = toSparkline;
|
|
exports.truncate = truncate;
|
|
exports.algebraicCombination = algebraicCombination;
|
|
exports.pointwiseCombination = pointwiseCombination;
|
|
exports.pointwiseCombinationFloat = pointwiseCombinationFloat;
|
|
exports.mixture = mixture;
|
|
exports.isSymbolic = isSymbolic;
|
|
exports.isPointSet = isPointSet;
|
|
/* E_A-QuriSquiggleLang Not a pure module */
|