From b4b9f2cc9f45a2b905790cf3bef9ea65815c6260 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 15 Mar 2020 00:08:13 +0000 Subject: [PATCH] Start of refactor to directly tie to pdfast --- package.json | 1 + src/components/DistBuilder.re | 6 ++--- src/distributions/DistPlusIngredients.re | 7 ++++++ src/distributions/XYShape.re | 2 ++ src/utility/Guesstimator.re | 32 ++++++++++++++++++++++-- src/utility/GuesstimatorLibrary.js | 17 ++++++------- yarn.lock | 2 +- 7 files changed, 52 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 889d5eeb..404a3efe 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "moment": "2.24.0", "parcel-bundler": "1.12.4", "parcel-plugin-less-js-enabled": "1.0.2", + "pdfast": "^0.2.0", "postcss-cli": "7.1.0", "rationale": "0.2.0", "react": "16.12.0", diff --git a/src/components/DistBuilder.re b/src/components/DistBuilder.re index 94dc47da..785a9d31 100644 --- a/src/components/DistBuilder.re +++ b/src/components/DistBuilder.re @@ -157,9 +157,9 @@ let make = () => { unitType: "UnspecifiedDistribution", zero: MomentRe.momentNow(), unit: "days", - sampleCount: "10000", - outputXYPoints: "5000", - truncateTo: "1000", + sampleCount: "1000", + outputXYPoints: "1000", + truncateTo: "500", }, (), ); diff --git a/src/distributions/DistPlusIngredients.re b/src/distributions/DistPlusIngredients.re index 2f6be1a1..4636017a 100644 --- a/src/distributions/DistPlusIngredients.re +++ b/src/distributions/DistPlusIngredients.re @@ -16,6 +16,13 @@ let toDistPlus = t: distPlusIngredients, ) : option(distPlus) => { + let test = + Guesstimator.toMixed( + t.guesstimatorString, + sampleCount, + outputXYPoints, + 30, + ); let shape = Guesstimator.stringToMixedShape( ~string=t.guesstimatorString, diff --git a/src/distributions/XYShape.re b/src/distributions/XYShape.re index 384fb931..30bf0dc3 100644 --- a/src/distributions/XYShape.re +++ b/src/distributions/XYShape.re @@ -61,6 +61,8 @@ module T = { let xMap = (fn, t: t): t => {xs: E.A.fmap(fn, t.xs), ys: t.ys}; let fromArray = ((xs, ys)): t => {xs, ys}; let fromArrays = (xs, ys): t => {xs, ys}; + let fromZippedArray = (is: array((float, float))): t => + is |> Belt.Array.unzip |> fromArray; module Combine = { let combineLinear = (t1: t, t2: t, fn: (float, float) => float) => { diff --git a/src/utility/Guesstimator.re b/src/utility/Guesstimator.re index 81613ff4..6923e83f 100644 --- a/src/utility/Guesstimator.re +++ b/src/utility/Guesstimator.re @@ -32,7 +32,8 @@ module Internals = { external stringToSamples: (string, int) => array(float) = "stringToSamples"; [@bs.module "./GuesstimatorLibrary.js"] - external samplesToContinuousPdf: (array(float), int, int) => array(float) = + external samplesToContinuousPdf: + (array(float), int, int) => CdfLibrary.JS.distJs = "samplesToContinuousPdf"; // todo: Format to correct mass, also normalize the pdf. @@ -66,4 +67,31 @@ let stringToMixedShape = (), ) => Internals.toCombinedFormat(string, sampleCount, outputXYPoints, width) - |> Internals.toMixedShape(~truncateTo); \ No newline at end of file + |> Internals.toMixedShape(~truncateTo); + +let toMixed = (string, sampleCount, returnLength, width) => { + let samples = Internals.stringToSamples(string, sampleCount); + let length = samples |> E.A.length; + Array.sort(compare, samples); + let items = + E.A.uniq(samples) + |> E.A.fmap(r => (r, samples |> E.A.filter(n => n == r) |> E.A.length)); + let (discretePart, continuousPart) = + Belt.Array.partition(items, ((_, count)) => count > 1); + let discrete: DistTypes.xyShape = + discretePart + |> E.A.fmap(((x, count)) => + (x, float_of_int(count) /. float_of_int(length)) + ) + |> XYShape.T.fromZippedArray; + let pdf: DistTypes.xyShape = + continuousPart |> E.A.length > 20 + ? { + Internals.samplesToContinuousPdf(samples, returnLength, width) + |> CdfLibrary.JS.jsToDist; + } + : {xs: [||], ys: [||]}; + let continuous = pdf |> Distributions.Continuous.fromShape; + let shape = MixedShapeBuilder.buildSimple(~continuous, ~discrete); + shape; +}; \ No newline at end of file diff --git a/src/utility/GuesstimatorLibrary.js b/src/utility/GuesstimatorLibrary.js index eda4803e..be8c2045 100644 --- a/src/utility/GuesstimatorLibrary.js +++ b/src/utility/GuesstimatorLibrary.js @@ -3,6 +3,7 @@ const { } = require("@foretold/cdf/lib/samples"); const _ = require("lodash"); const { Guesstimator } = require('@foretold/guesstimator/src'); +const pdfast = require('pdfast'); /** * @param values @@ -89,10 +90,7 @@ const stringToSamples = ( sampleCount, inputs = [], ) => { - const [_error, item] = Guesstimator.parse({ text }); - if (_error){ - return [] - } + const [_error, item] = Guesstimator.parse({ text:"=" + text }); const { parsedInput } = item; const guesstimator = new Guesstimator({ parsedInput }); @@ -106,15 +104,16 @@ const stringToSamples = ( const samplesToContinuousPdf = ( samples, - outputResolutionCount, + size, width, min = false, max = false, ) => { - const values = _.filter(samples, _.isFinite); - const _samples = new Samples(values); - const pdf = _samples.toPdf({ size: outputResolutionCount, width, min, max }); - return pdf; + let _samples = _.filter(samples, _.isFinite); + if (_.isFinite(min)) { _samples = _.filter(_samples, r => r > min) }; + if (_.isFinite(max)) { _samples = _.filter(_samples, r => r < max) }; + let pdf = pdfast.create(_samples, { size, width }); + return {xs: pdf.map(r => r.x), ys: pdf.map(r => r.x)}; }; module.exports = { diff --git a/yarn.lock b/yarn.lock index f536bd31..027e60e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7570,7 +7570,7 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" -pdfast@0.2.0: +pdfast@0.2.0, pdfast@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/pdfast/-/pdfast-0.2.0.tgz#8cbc556e1bf2522177787c0de2e0d4373ba885c9" integrity sha1-jLxVbhvyUiF3eHwN4uDUNzuohck=