Allows for simple arrays representing samples

This commit is contained in:
Ozzie Gooen 2020-04-11 14:22:13 +01:00
parent 92ac693736
commit 2e5f285a9e
7 changed files with 115 additions and 119 deletions

View File

@ -51,8 +51,8 @@
"moduleserve": "0.9.1",
"moment": "2.24.0",
"parcel-bundler": "1.12.4",
"parcel-plugin-bundle-visualiser": "^1.2.0",
"parcel-plugin-less-js-enabled": "1.0.2",
"parcel-plugin-bundle-visualiser": "1.2.0",
"pdfast": "^0.2.0",
"postcss-cli": "7.1.0",
"rationale": "0.2.0",

View File

@ -24,6 +24,7 @@ module Dist = (T: dist) => {
type integral = T.integral;
let minX = T.minX;
let maxX = T.maxX;
let integral = T.integral;
let xTotalRange = (t: t) => maxX(t) -. minX(t);
let mapY = T.mapY;
let xToY = T.xToY;
@ -244,6 +245,7 @@ module Mixed = {
let toContinuous = ({continuous}: t) => Some(continuous);
let toDiscrete = ({discrete}: t) => Some(discrete);
let toDiscreteProbabilityMass = ({discreteProbabilityMassFraction}: t) => discreteProbabilityMassFraction;
let xToY = (f, {discrete, continuous} as t: t) => {
let c =
continuous

View File

@ -1,15 +1,36 @@
let runSymbolic =
(guesstimatorString, length) =>{
let graph = MathJsParser.fromString(guesstimatorString);
graph |> E.R.fmap(g => RenderTypes.ShapeRenderer.Symbolic.make(g, SymbolicDist.toShape(length,g)))
}
// This transforms an array intesperced with spaces or newlines with a normally formatted one.
// "3 4 5 3 2 1 " -> "[3,4,5,3,2,1]""
let formatMessyArray = str => {
let split = Js.String.splitByRe([%re "/\\n|\\r|\\s/"], str);
if (E.A.length(split) > 6) {
let inner = split |> Js.Array.joinWith(",");
{j|[$inner]|j};
} else {
str;
};
};
let formatString = str => {
str |> formatMessyArray;
};
let runSymbolic = (guesstimatorString, length) => {
let str = formatString(guesstimatorString);
let graph = MathJsParser.fromString(str);
graph
|> E.R.fmap(g =>
RenderTypes.ShapeRenderer.Symbolic.make(
g,
SymbolicDist.toShape(length, g),
)
);
};
let run =
(
inputs: RenderTypes.ShapeRenderer.Combined.inputs
)
(inputs: RenderTypes.ShapeRenderer.Combined.inputs)
: RenderTypes.ShapeRenderer.Combined.outputs => {
let symbolic = runSymbolic(inputs.guesstimatorString, inputs.symbolicInputs.length);
let symbolic =
runSymbolic(inputs.guesstimatorString, inputs.symbolicInputs.length);
let sampling =
switch (symbolic) {
| Ok(_) => None

View File

@ -107,7 +107,11 @@ module T = {
};
let toShape =
(~samples: t, ~samplingInputs: RenderTypes.ShapeRenderer.Sampling.Inputs.fInputs, ()) => {
(
~samples: t,
~samplingInputs: RenderTypes.ShapeRenderer.Sampling.Inputs.fInputs,
(),
) => {
Array.fast_sort(compare, samples);
let (continuousPart, discretePart) = E.A.Sorted.Floats.split(samples);
let length = samples |> E.A.length |> float_of_int;
@ -161,6 +165,16 @@ module T = {
samplesParse;
};
let fromSamples =
(
~samplingInputs=RenderTypes.ShapeRenderer.Sampling.Inputs.empty,
samples,
) => {
let samplingInputs =
RenderTypes.ShapeRenderer.Sampling.Inputs.toF(samplingInputs);
toShape(~samples, ~samplingInputs, ());
};
let fromGuesstimatorString =
(
~guesstimatorString,
@ -169,13 +183,17 @@ module T = {
) => {
let hasValidSamples =
Guesstimator.stringToSamples(guesstimatorString, 10) |> E.A.length > 0;
let samplingInputs = RenderTypes.ShapeRenderer.Sampling.Inputs.toF(samplingInputs);
let _samplingInputs =
RenderTypes.ShapeRenderer.Sampling.Inputs.toF(samplingInputs);
switch (hasValidSamples) {
| false => None
| true =>
let samples =
Guesstimator.stringToSamples(guesstimatorString, samplingInputs.sampleCount);
Some(toShape(~samples, ~samplingInputs, ()));
Guesstimator.stringToSamples(
guesstimatorString,
_samplingInputs.sampleCount,
);
Some(fromSamples(~samplingInputs, samples));
};
};
};

View File

@ -177,6 +177,28 @@ module MathAdtToDistDst = {
};
};
let arrayParser = (args:array(arg)):result(SymbolicDist.bigDist, string) => {
let samples = args
|> E.A.fmap(
fun
| Value(n) => Some(n)
| _ => None
)
|> E.A.O.concatSomes
let outputs = Samples.T.fromSamples(samples);
let pdf = outputs.shape |> E.O.bind(_,Distributions.Shape.T.toContinuous)
let shape = pdf |> E.O.fmap(pdf => {
let _pdf = Distributions.Continuous.T.scaleToIntegralSum(~cache=None, ~intendedSum=1.0, pdf);
let cdf = Distributions.Continuous.T.integral(~cache=None, _pdf);
SymbolicDist.ContinuousShape.make(_pdf, cdf)
})
switch(shape){
| Some(s) => Ok(`Simple(`ContinuousShape(s)))
| None => Error("Rendering did not work")
}
}
let rec functionParser = (r): result(SymbolicDist.bigDist, string) =>
r
|> (
@ -228,7 +250,7 @@ module MathAdtToDistDst = {
fun
| Fn(_) => functionParser(r)
| Value(r) => Ok(`Simple(`Float(r)))
| Array(_) => Error("Array not valid as top level")
| Array(r) => arrayParser(r)
| Symbol(_) => Error("Symbol not valid as top level")
| Object(_) => Error("Object not valid as top level")
);

View File

@ -31,6 +31,8 @@ type triangular = {
high: float,
};
type continuousShape = {pdf: DistTypes.continuousShape, cdf: DistTypes.continuousShape}
type contType = [ | `Continuous | `Discrete];
type dist = [
@ -41,6 +43,7 @@ type dist = [
| `Exponential(exponential)
| `Cauchy(cauchy)
| `Triangular(triangular)
| `ContinuousShape(continuousShape)
| `Float(float)
];
@ -48,6 +51,17 @@ type pointwiseAdd = array((dist, float));
type bigDist = [ | `Simple(dist) | `PointwiseCombination(pointwiseAdd)];
module ContinuousShape = {
type t = continuousShape;
let make = (pdf, cdf):t => ({pdf, cdf});
let pdf = (x, t: t) => Distributions.Continuous.T.xToY(x,t.pdf).continuous
let inv = (p, t: t) => Distributions.Continuous.T.xToY(p,t.pdf).continuous
// TODO: Fix the sampling, to have it work correctly.
let sample = (t:t) => 3.0;
let toString = (t) => {j|CustomContinuousShape|j};
let contType: contType = `Continuous;
};
module Exponential = {
type t = exponential;
let pdf = (x, t: t) => Jstat.exponential##pdf(x, t.rate);
@ -153,6 +167,7 @@ module GenericSimple = {
| `Uniform(n) => Uniform.pdf(x, n)
| `Beta(n) => Beta.pdf(x, n)
| `Float(n) => Float.pdf(x, n)
| `ContinuousShape(n) => ContinuousShape.pdf(x,n)
};
let contType = (dist:dist):contType =>
@ -165,6 +180,7 @@ module GenericSimple = {
| `Uniform(_) => Uniform.contType
| `Beta(_) => Beta.contType
| `Float(_) => Float.contType
| `ContinuousShape(_) => ContinuousShape.contType
};
let inv = (x, dist) =>
@ -177,6 +193,7 @@ module GenericSimple = {
| `Uniform(n) => Uniform.inv(x, n)
| `Beta(n) => Beta.inv(x, n)
| `Float(n) => Float.inv(x, n)
| `ContinuousShape(n) => ContinuousShape.inv(x,n)
};
let sample: dist => float =
@ -188,7 +205,8 @@ module GenericSimple = {
| `Lognormal(n) => Lognormal.sample(n)
| `Uniform(n) => Uniform.sample(n)
| `Beta(n) => Beta.sample(n)
| `Float(n) => Float.sample(n);
| `Float(n) => Float.sample(n)
| `ContinuousShape(n) => ContinuousShape.sample(n)
let toString: dist => string =
fun
@ -199,7 +217,8 @@ module GenericSimple = {
| `Lognormal(n) => Lognormal.toString(n)
| `Uniform(n) => Uniform.toString(n)
| `Beta(n) => Beta.toString(n)
| `Float(n) => Float.toString(n);
| `Float(n) => Float.toString(n)
| `ContinuousShape(n) => ContinuousShape.toString(n)
let min: dist => float =
fun
@ -210,6 +229,7 @@ module GenericSimple = {
| `Lognormal(n) => Lognormal.inv(minCdfValue, n)
| `Uniform({low}) => low
| `Beta(n) => Beta.inv(minCdfValue, n)
| `ContinuousShape(n) => ContinuousShape.inv(minCdfValue,n)
| `Float(n) => n;
let max: dist => float =
@ -220,6 +240,7 @@ module GenericSimple = {
| `Normal(n) => Normal.inv(maxCdfValue, n)
| `Lognormal(n) => Lognormal.inv(maxCdfValue, n)
| `Beta(n) => Beta.inv(maxCdfValue, n)
| `ContinuousShape(n) => ContinuousShape.inv(maxCdfValue,n)
| `Uniform({high}) => high
| `Float(n) => n;
@ -236,11 +257,16 @@ module GenericSimple = {
let toShape =
(~xSelection: [ | `Linear | `ByWeight]=`Linear, dist: dist, sampleCount)
: DistTypes.shape => {
switch(dist){
| `ContinuousShape(n) => n.pdf |> Distributions.Continuous.T.toShape
| dist => {
let xs = interpolateXs(~xSelection, dist, sampleCount);
let ys = xs |> E.A.fmap(r => pdf(r, dist));
XYShape.T.fromArrays(xs, ys)
|> Distributions.Continuous.make(`Linear, _)
|> Distributions.Continuous.T.toShape;
}
}
};
};

View File

@ -2418,11 +2418,6 @@ bser@2.1.1:
dependencies:
node-int64 "^0.4.0"
btoa@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73"
integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==
buffer-equal@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b"
@ -3802,11 +3797,6 @@ ee-first@1.1.1:
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
ejs@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.0.2.tgz#745b01cdcfe38c1c6a2da3bbb2d9957060a31226"
integrity sha512-IncmUpn1yN84hy2shb0POJ80FWrfGNY0cxO9f4v+/sG7qcBvAtVWUA1IdzY/8EYUmOVhoKJVdJjNd3AZcnxOjA==
electron-to-chromium@^1.3.341:
version "1.3.345"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.345.tgz#2569d0d54a64ef0f32a4b7e8c80afa5fe57c5d98"
@ -3942,7 +3932,7 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
escape-html@^1.0.3, escape-html@~1.0.3:
escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
@ -4469,7 +4459,7 @@ glob-to-regexp@^0.3.0:
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab"
integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=
glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
version "7.1.6"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
@ -4559,14 +4549,6 @@ gzip-size@^4.1.0:
duplexer "^0.1.1"
pify "^3.0.0"
gzip-size@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274"
integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==
dependencies:
duplexer "^0.1.1"
pify "^4.0.1"
hammerjs@^2.0.8:
version "2.0.8"
resolved "https://registry.yarnpkg.com/hammerjs/-/hammerjs-2.0.8.tgz#04ef77862cff2bb79d30f7692095930222bf60f1"
@ -5050,11 +5032,6 @@ is-directory@^0.3.1:
resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=
is-docker@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.0.0.tgz#2cb0df0e75e2d064fe1864c37cdeacb7b2dcf25b"
integrity sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==
is-extendable@^0.1.0, is-extendable@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
@ -6595,14 +6572,6 @@ onetime@^5.1.0:
dependencies:
mimic-fn "^2.1.0"
open@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/open/-/open-7.0.3.tgz#db551a1af9c7ab4c7af664139930826138531c48"
integrity sha512-sP2ru2v0P290WFfv49Ap8MF6PkzGNnGlAwHweB4WR4mr5d2d0woiCluUeJ218w7/+PmoBy9JmYgD5A4mLcWOFA==
dependencies:
is-docker "^2.0.0"
is-wsl "^2.1.1"
opn@^5.1.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc"
@ -6818,7 +6787,7 @@ parcel-bundler@1.12.4, parcel-bundler@^1.12.3:
v8-compile-cache "^2.0.0"
ws "^5.1.1"
parcel-plugin-bundle-visualiser@1.2.0:
parcel-plugin-bundle-visualiser@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/parcel-plugin-bundle-visualiser/-/parcel-plugin-bundle-visualiser-1.2.0.tgz#b24cde64233c8e8ce2561ec5d864a7543d8e719d"
integrity sha512-/O+26nsOwXbl1q6A/X9lEJWAPwZt5VauTV32omC3a/09bfUgHTogkAIYB/BqrGQm6OyuoG5FATToT3AGGk9RTA==
@ -7035,11 +7004,6 @@ pify@^3.0.0:
resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
pify@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
pinkie-promise@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
@ -8640,13 +8604,6 @@ rimraf@^3.0.0:
dependencies:
glob "^7.1.3"
rimraf@~2.6.2:
version "2.6.3"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
dependencies:
glob "^7.1.3"
ripemd160@^2.0.0, ripemd160@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
@ -8975,24 +8932,6 @@ sort-keys@^1.0.0:
dependencies:
is-plain-obj "^1.0.0"
source-map-explorer@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.4.2.tgz#fb23f86c3112eacde5683f24efaf4ddc9f677985"
integrity sha512-3ECQLffCFV8QgrTqcmddLkWL4/aQs6ljYfgWCLselo5QtizOfOeUCKnS4rFn7MIrdeZLM6TZrseOtsrWZhWKoQ==
dependencies:
btoa "^1.2.1"
chalk "^3.0.0"
convert-source-map "^1.7.0"
ejs "^3.0.2"
escape-html "^1.0.3"
glob "^7.1.6"
gzip-size "^5.1.1"
lodash "^4.17.15"
open "^7.0.3"
source-map "^0.7.3"
temp "^0.9.1"
yargs "^15.3.1"
source-map-resolve@^0.5.0:
version "0.5.3"
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a"
@ -9427,13 +9366,6 @@ tailwindcss@1.2.0:
reduce-css-calc "^2.1.6"
resolve "^1.14.2"
temp@^0.9.1:
version "0.9.1"
resolved "https://registry.yarnpkg.com/temp/-/temp-0.9.1.tgz#2d666114fafa26966cd4065996d7ceedd4dd4697"
integrity sha512-WMuOgiua1xb5R56lE0eH6ivpVmg/lq2OHm4+LtT/xtEtPQ+sz6N3bBM6WZ5FvO1lO4IKIOb43qnhoc4qxP5OeA==
dependencies:
rimraf "~2.6.2"
terminal-link@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994"
@ -10111,14 +10043,6 @@ yargs-parser@^16.1.0:
camelcase "^5.0.0"
decamelize "^1.2.0"
yargs-parser@^18.1.1:
version "18.1.2"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.2.tgz#2f482bea2136dbde0861683abea7756d30b504f1"
integrity sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==
dependencies:
camelcase "^5.0.0"
decamelize "^1.2.0"
yargs-parser@^9.0.2:
version "9.0.2"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077"
@ -10178,23 +10102,6 @@ yargs@^15.0.0, yargs@^15.0.2:
y18n "^4.0.0"
yargs-parser "^16.1.0"
yargs@^15.3.1:
version "15.3.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b"
integrity sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==
dependencies:
cliui "^6.0.0"
decamelize "^1.2.0"
find-up "^4.1.0"
get-caller-file "^2.0.1"
require-directory "^2.1.1"
require-main-filename "^2.0.0"
set-blocking "^2.0.0"
string-width "^4.2.0"
which-module "^2.0.0"
y18n "^4.0.0"
yargs-parser "^18.1.1"
zen-observable-ts@^0.8.20:
version "0.8.20"
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.20.tgz#44091e335d3fcbc97f6497e63e7f57d5b516b163"