First attempt at adding dist functionality
This commit is contained in:
parent
71f3c6290d
commit
5046a04c40
|
@ -22,6 +22,8 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@foretold/cdf": "^1.0.14",
|
||||||
|
"@foretold/guesstimator": "^1.0.10",
|
||||||
"antd": "3.17.0",
|
"antd": "3.17.0",
|
||||||
"autoprefixer": "^9.7.4",
|
"autoprefixer": "^9.7.4",
|
||||||
"bs-ant-design-alt": "2.0.0-alpha.31",
|
"bs-ant-design-alt": "2.0.0-alpha.31",
|
||||||
|
@ -46,4 +48,4 @@
|
||||||
"moduleserve": "^0.9.0",
|
"moduleserve": "^0.9.0",
|
||||||
"tailwindcss": "^1.2.0"
|
"tailwindcss": "^1.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ module TypeWithMetadata = {
|
||||||
let currentYear =
|
let currentYear =
|
||||||
make(
|
make(
|
||||||
~id="currentYear",
|
~id="currentYear",
|
||||||
~name="Current Year",
|
~name="Current Day",
|
||||||
~description=None,
|
~description=None,
|
||||||
~type_=
|
~type_=
|
||||||
DateTime({
|
DateTime({
|
||||||
|
|
4
src/lib/Types.re
Normal file
4
src/lib/Types.re
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
type distribution = {
|
||||||
|
xs: array(float),
|
||||||
|
ys: array(float),
|
||||||
|
};
|
|
@ -166,8 +166,8 @@ module Interface = {
|
||||||
|
|
||||||
let model: Prop.Model.t =
|
let model: Prop.Model.t =
|
||||||
Prop.{
|
Prop.{
|
||||||
name: "EA Funds: Donations & Payouts",
|
name: "CEA Funds: Donations & Payouts",
|
||||||
description: "Calculate the payments and payouts of EA Funds based on existing data.",
|
description: "Calculate the payments and payouts of CEA Funds based on existing data.",
|
||||||
version: "1.0.0",
|
version: "1.0.0",
|
||||||
author: "Ozzie Gooen",
|
author: "Ozzie Gooen",
|
||||||
inputTypes: [|
|
inputTypes: [|
|
||||||
|
|
160
src/utility/CdfLibrary.js
Normal file
160
src/utility/CdfLibrary.js
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
const {
|
||||||
|
Cdf,
|
||||||
|
ContinuousDistribution,
|
||||||
|
ContinuousDistributionCombination,
|
||||||
|
scoringFunctions,
|
||||||
|
} = require("@foretold/cdf/lib");
|
||||||
|
const _ = require("lodash");
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param xs
|
||||||
|
* @param ys
|
||||||
|
* @returns {{ys: *, xs: *}}
|
||||||
|
*/
|
||||||
|
function cdfToPdf({ xs, ys }) {
|
||||||
|
let cdf = new Cdf(xs, ys);
|
||||||
|
let pdf = cdf.toPdf();
|
||||||
|
return { xs: pdf.xs, ys: pdf.ys };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param xs
|
||||||
|
* @param ys
|
||||||
|
* @returns {{ys: *, xs: *}}
|
||||||
|
*/
|
||||||
|
function pdfToCdf({ xs, ys }) {
|
||||||
|
let cdf = new Pdf(xs, ys);
|
||||||
|
let pdf = cdf.toCdf();
|
||||||
|
return { xs: pdf.xs, ys: pdf.ys };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param sampleCount
|
||||||
|
* @param vars
|
||||||
|
* @returns {{ys: *, xs: *}}
|
||||||
|
*/
|
||||||
|
function mean(sampleCount, vars) {
|
||||||
|
let cdfs = vars.map(r => new Cdf(r.xs, r.ys));
|
||||||
|
let comb = new ContinuousDistributionCombination(cdfs);
|
||||||
|
let newCdf = comb.combineYsWithMean(sampleCount);
|
||||||
|
|
||||||
|
return { xs: newCdf.xs, ys: newCdf.ys };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param sampleCount
|
||||||
|
* @param predictionCdf
|
||||||
|
* @param resolutionCdf
|
||||||
|
*/
|
||||||
|
function scoreNonMarketCdfCdf(sampleCount, predictionCdf, resolutionCdf, resolutionUniformAdditionWeight=0) {
|
||||||
|
let toCdf = (r) => (new Cdf(r.xs, r.ys));
|
||||||
|
let prediction = toCdf(predictionCdf);
|
||||||
|
if (_.isFinite(resolutionUniformAdditionWeight)){
|
||||||
|
prediction = prediction.combineWithUniformOfCdf(
|
||||||
|
{
|
||||||
|
cdf: toCdf(resolutionCdf),
|
||||||
|
uniformWeight: resolutionUniformAdditionWeight,
|
||||||
|
sampleCount
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return scoringFunctions.distributionInputDistributionOutputMarketless({
|
||||||
|
predictionCdf: prediction,
|
||||||
|
resultCdf: toCdf(resolutionCdf),
|
||||||
|
sampleCount,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param sampleCount
|
||||||
|
* @param cdf
|
||||||
|
*/
|
||||||
|
function differentialEntropy(sampleCount, cdf) {
|
||||||
|
let toCdf = (r) => (new Cdf(r.xs, r.ys));
|
||||||
|
|
||||||
|
return scoringFunctions.differentialEntropy({
|
||||||
|
cdf: toCdf(cdf),
|
||||||
|
sampleCount: sampleCount
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* @param xs
|
||||||
|
* @param ys
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
function findY(x, { xs, ys }) {
|
||||||
|
let cdf = new Cdf(xs, ys);
|
||||||
|
return cdf.findY(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param y
|
||||||
|
* @param xs
|
||||||
|
* @param ys
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
function findX(y, { xs, ys }) {
|
||||||
|
let cdf = new Cdf(xs, ys);
|
||||||
|
return cdf.findX(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param xs
|
||||||
|
* @param ys
|
||||||
|
* @returns {number[]}
|
||||||
|
*/
|
||||||
|
function integral({ xs, ys }) {
|
||||||
|
if (_.includes(ys, NaN)){
|
||||||
|
return NaN;
|
||||||
|
}
|
||||||
|
else if (_.includes(ys, Infinity) && _.includes(ys, -Infinity)){
|
||||||
|
return NaN;
|
||||||
|
}
|
||||||
|
else if (_.includes(ys, Infinity)){
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
else if (_.includes(ys, -Infinity)){
|
||||||
|
return -Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
let integral = 0;
|
||||||
|
for (let i = 1; i < ys.length; i++) {
|
||||||
|
let thisY = ys[i];
|
||||||
|
let lastY = ys[i - 1];
|
||||||
|
let thisX = xs[i];
|
||||||
|
let lastX = xs[i - 1];
|
||||||
|
|
||||||
|
if (
|
||||||
|
_.isFinite(thisY) && _.isFinite(lastY) &&
|
||||||
|
_.isFinite(thisX) && _.isFinite(lastX)
|
||||||
|
) {
|
||||||
|
let sectionInterval = ((thisY + lastY) / 2) * (thisX - lastX);
|
||||||
|
integral = integral + sectionInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return integral;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
cdfToPdf,
|
||||||
|
pdfToCdf,
|
||||||
|
findY,
|
||||||
|
findX,
|
||||||
|
mean,
|
||||||
|
scoreNonMarketCdfCdf,
|
||||||
|
differentialEntropy,
|
||||||
|
integral,
|
||||||
|
};
|
||||||
|
|
56
src/utility/CdfLibrary.re
Normal file
56
src/utility/CdfLibrary.re
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
module JS = {
|
||||||
|
[@bs.deriving abstract]
|
||||||
|
type distJs = {
|
||||||
|
xs: array(float),
|
||||||
|
ys: array(float),
|
||||||
|
};
|
||||||
|
|
||||||
|
let distToJs = (d: Types.distribution) => distJs(~xs=d.xs, ~ys=d.ys);
|
||||||
|
|
||||||
|
let jsToDist = (d: distJs): Types.distribution => {
|
||||||
|
xs: xsGet(d),
|
||||||
|
ys: ysGet(d),
|
||||||
|
};
|
||||||
|
|
||||||
|
let doAsDist = (f, d: Types.distribution) => d |> distToJs |> f |> jsToDist;
|
||||||
|
|
||||||
|
[@bs.module "./CdfLibraryImporter.js"]
|
||||||
|
external cdfToPdf: distJs => distJs = "cdfToPdf";
|
||||||
|
|
||||||
|
[@bs.module "./CdfLibraryImporter.js"]
|
||||||
|
external pdfToCdf: distJs => distJs = "pdfToCdf";
|
||||||
|
|
||||||
|
[@bs.module "./CdfLibraryImporter.js"]
|
||||||
|
external findY: (float, distJs) => float = "findY";
|
||||||
|
|
||||||
|
[@bs.module "./CdfLibraryImporter.js"]
|
||||||
|
external findX: (float, distJs) => float = "findX";
|
||||||
|
|
||||||
|
[@bs.module "./CdfLibraryImporter.js"]
|
||||||
|
external integral: distJs => float = "integral";
|
||||||
|
|
||||||
|
[@bs.module "./CdfLibraryImporter.js"]
|
||||||
|
external differentialEntropy: (int, distJs) => distJs =
|
||||||
|
"differentialEntropy";
|
||||||
|
|
||||||
|
[@bs.module "./CdfLibraryImporter.js"]
|
||||||
|
external scoreNonMarketCdfCdf: (int, distJs, distJs, float) => distJs =
|
||||||
|
"scoreNonMarketCdfCdf";
|
||||||
|
|
||||||
|
[@bs.module "./GuesstimatorLibrary.js"]
|
||||||
|
external toGuesstimator: (string, int) => distJs = "run";
|
||||||
|
};
|
||||||
|
|
||||||
|
module Distribution = {
|
||||||
|
let toPdf = dist => dist |> JS.doAsDist(JS.cdfToPdf);
|
||||||
|
let toCdf = dist => dist |> JS.doAsDist(JS.cdfToPdf);
|
||||||
|
let findX = (y, dist) => dist |> JS.distToJs |> JS.findX(y);
|
||||||
|
let findY = (x, dist) => dist |> JS.distToJs |> JS.findY(x);
|
||||||
|
let fromString = (str: string, sampleCount: int) =>
|
||||||
|
JS.toGuesstimator(str, sampleCount) |> JS.jsToDist;
|
||||||
|
let integral = dist => dist |> JS.distToJs |> JS.integral;
|
||||||
|
let differentialEntropy = (maxCalculationLength, dist) =>
|
||||||
|
dist
|
||||||
|
|> JS.doAsDist(JS.differentialEntropy(maxCalculationLength))
|
||||||
|
|> integral;
|
||||||
|
};
|
46
src/utility/GuesstimatorLibrary.js
Normal file
46
src/utility/GuesstimatorLibrary.js
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import { Guesstimator } from '@foretold/guesstimator';
|
||||||
|
import { Samples } from '@foretold/cdf';
|
||||||
|
|
||||||
|
const toPdf = (values, min, max) => {
|
||||||
|
const samples = new Samples(values);
|
||||||
|
|
||||||
|
const ratioSize$ = ratioSize(samples);
|
||||||
|
const width = ratioSize$ === 'SMALL' ? 20 : 1;
|
||||||
|
|
||||||
|
const pdf = samples.toPdf({ size: 1000, width, min, max });
|
||||||
|
return {ys:pdf.ys, xs:pdf.xs};
|
||||||
|
};
|
||||||
|
|
||||||
|
let run = (text, sampleCount, inputs=[], min=false, max=false) => {
|
||||||
|
let [_error, item] = Guesstimator.parse({ text });
|
||||||
|
const { parsedInput } = item;
|
||||||
|
const { guesstimateType } = parsedInput;
|
||||||
|
|
||||||
|
const guesstimator = new Guesstimator({ parsedInput });
|
||||||
|
const value = guesstimator.sample(
|
||||||
|
sampleCount,
|
||||||
|
inputs,
|
||||||
|
);
|
||||||
|
const samplerType = guesstimator.samplerType();
|
||||||
|
|
||||||
|
const values = _.filter(value.values, _.isFinite);
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
value: event.target.value,
|
||||||
|
items: values,
|
||||||
|
});
|
||||||
|
|
||||||
|
let update;
|
||||||
|
if (values.length === 0) {
|
||||||
|
update = {xs: [], ys: []};
|
||||||
|
} else if (values.length === 1) {
|
||||||
|
update = {xs: [], ys: []};
|
||||||
|
} else {
|
||||||
|
update = toPdf(values, min, max);
|
||||||
|
}
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
run,
|
||||||
|
};
|
2
src/utility/GuesstimatorLibrary3.re
Normal file
2
src/utility/GuesstimatorLibrary3.re
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
// [@bs.module "./GuesstimatorLibrary.js"]
|
||||||
|
/* external toGuesstimator: (string, int) => CdfLibrary.JS.distJs = "run"*/
|
Loading…
Reference in New Issue
Block a user