Fixes inputs
This commit is contained in:
parent
dcea2c70af
commit
5354d5be02
|
@ -34,11 +34,15 @@ module Styles = {
|
|||
module DemoDist = {
|
||||
[@react.component]
|
||||
let make = (~guesstimatorString: string) => {
|
||||
let (ys, xs) = DistEditor.getPdfFromUserInput(guesstimatorString);
|
||||
let (ys, xs, isEmpty) =
|
||||
DistEditor.getPdfFromUserInput(guesstimatorString);
|
||||
let continuous: DistTypes.xyShape = {xs, ys};
|
||||
<Antd.Card title={"Distribution" |> E.ste}>
|
||||
<div className=Styles.spacer />
|
||||
<DistributionPlot continuous />
|
||||
{isEmpty
|
||||
? "Nothing to show. Try to change the distribution description."
|
||||
|> E.ste
|
||||
: <DistributionPlot continuous />}
|
||||
</Antd.Card>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -68,14 +68,18 @@ export class CdfChartD3 {
|
|||
* @returns {CdfChartD3}
|
||||
*/
|
||||
data(data) {
|
||||
const continuousXs = _.get(data, 'continuous.xs', []);
|
||||
const continuousYs = _.get(data, 'continuous.ys', []);
|
||||
const discreteXs = _.get(data, 'discrete.xs', []);
|
||||
const discreteYs = _.get(data, 'discrete.ys', []);
|
||||
this.attrs.data = data;
|
||||
this.attrs.data.continuous = data.continuous || {
|
||||
xs: [],
|
||||
ys: [],
|
||||
this.attrs.data.continuous = {
|
||||
xs: continuousXs,
|
||||
ys: continuousYs,
|
||||
};
|
||||
this.attrs.data.discrete = data.discrete || {
|
||||
xs: [],
|
||||
ys: [],
|
||||
this.attrs.data.discrete = {
|
||||
xs: discreteXs,
|
||||
ys: discreteYs,
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[@bs.module "./main.js"]
|
||||
external getPdfFromUserInput: string => (array(float), array(float)) =
|
||||
external getPdfFromUserInput: string => (array(float), array(float), bool) =
|
||||
"get_pdf_from_user_input";
|
||||
|
|
|
@ -11,12 +11,22 @@ const bst = require("binary-search-tree");
|
|||
const NUM_MC_SAMPLES = 300;
|
||||
const OUTPUT_GRID_NUMEL = 300;
|
||||
|
||||
/**
|
||||
* @param start
|
||||
* @param stop
|
||||
* @param numel
|
||||
* @returns {*[]}
|
||||
*/
|
||||
function evenly_spaced_grid(start, stop, numel) {
|
||||
return Array(numel)
|
||||
.fill(0)
|
||||
.map((_, idx) => start + (idx / numel) * (stop - start));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param substrings
|
||||
* @returns {*}
|
||||
*/
|
||||
function get_distributions(substrings) {
|
||||
// Takes an array of strings like "normal(0, 1)" and
|
||||
// returns the corresponding distribution objects
|
||||
|
@ -25,6 +35,19 @@ function get_distributions(substrings) {
|
|||
return pdfs;
|
||||
}
|
||||
|
||||
// update the binary search tree with bin points of
|
||||
// deterministic_pdf transformed by tansform func
|
||||
// (transfrom func can be a stocahstic func with parameters
|
||||
// sampled from mc_distrs)
|
||||
/**
|
||||
* @param transform_func
|
||||
* @param deterministic_pdf
|
||||
* @param mc_distrs
|
||||
* @param track_idx
|
||||
* @param num_mc_samples
|
||||
* @param bst_pts_and_idxs
|
||||
* @returns {(number)[]}
|
||||
*/
|
||||
function update_transformed_divider_points_bst(
|
||||
transform_func,
|
||||
deterministic_pdf,
|
||||
|
@ -33,10 +56,6 @@ function update_transformed_divider_points_bst(
|
|||
num_mc_samples,
|
||||
bst_pts_and_idxs
|
||||
) {
|
||||
// update the binary search tree with bin points of
|
||||
// deterministic_pdf transformed by tansform func
|
||||
// (transfrom func can be a stocahstic func with parameters
|
||||
// sampled from mc_distrs)
|
||||
var transformed_pts = [];
|
||||
var pdf_inner_idxs = [];
|
||||
var factors = [];
|
||||
|
@ -97,10 +116,16 @@ function update_transformed_divider_points_bst(
|
|||
return [start_pt, end_pt];
|
||||
}
|
||||
|
||||
// Take the binary search tree with transformed bin points,
|
||||
// and an array of pdf values associated with the bins,
|
||||
// and return a pdf over an evenly spaced grid
|
||||
/**
|
||||
* @param pdf_vals
|
||||
* @param bst_pts_and_idxs
|
||||
* @param output_grid
|
||||
* @returns {[]}
|
||||
*/
|
||||
function get_final_pdf(pdf_vals, bst_pts_and_idxs, output_grid) {
|
||||
// Take the binary search tree with transformed bin points,
|
||||
// and an array of pdf values associated with the bins,
|
||||
// and return a pdf over an evenly spaced grid
|
||||
var offset = output_grid[1] / 2 - output_grid[0] / 2;
|
||||
var active_intervals = new Map();
|
||||
var active_endpoints = new bst.AVLTree();
|
||||
|
@ -152,47 +177,65 @@ function get_final_pdf(pdf_vals, bst_pts_and_idxs, output_grid) {
|
|||
return final_pdf_vals;
|
||||
}
|
||||
|
||||
// Entrypoint. Pass user input strings to this function,
|
||||
// get the corresponding pdf values and input points back.
|
||||
// If the pdf requires monte carlo (it contains a between-distr function)
|
||||
// we first determing which distr to have deterministic
|
||||
// and which to sample from. This is decided based on which
|
||||
// choice gives the least variance.
|
||||
/**
|
||||
* @param user_input_string
|
||||
* @returns {([]|*[])[]}
|
||||
*/
|
||||
function get_pdf_from_user_input(user_input_string) {
|
||||
// Entrypoint. Pass user input strings to this function,
|
||||
// get the corresponding pdf values and input points back.
|
||||
// If the pdf requires monte carlo (it contains a between-distr function)
|
||||
// we first determing which distr to have deterministic
|
||||
// and whih to sample from. This is decided based on which
|
||||
// choice gives the least variance.
|
||||
let parsed = parse.parse_initial_string(user_input_string);
|
||||
let mm_args = parse.separate_mm_args(parsed.mm_args_string);
|
||||
const is_mm = mm_args.distrs.length > 0;
|
||||
let tree = new bst.AVLTree();
|
||||
let possible_start_pts = [];
|
||||
let possible_end_pts = [];
|
||||
let all_vals = [];
|
||||
let weights = is_mm ? math.compile(mm_args.weights).evaluate()._data : [1];
|
||||
let weights_sum = weights.reduce((a, b) => a + b);
|
||||
weights = weights.map(x => x / weights_sum);
|
||||
let n_iters = is_mm ? mm_args.distrs.length : 1;
|
||||
for (let i = 0; i < n_iters; ++i) {
|
||||
let distr_string = is_mm ? mm_args.distrs[i] : parsed.outer_string;
|
||||
var [deterministic_pdf, mc_distrs] = choose_pdf_func(distr_string);
|
||||
var grid_transform = get_grid_transform(distr_string);
|
||||
var [start_pt, end_pt] = update_transformed_divider_points_bst(
|
||||
grid_transform,
|
||||
deterministic_pdf,
|
||||
mc_distrs,
|
||||
i,
|
||||
NUM_MC_SAMPLES,
|
||||
tree
|
||||
);
|
||||
possible_start_pts.push(start_pt);
|
||||
possible_end_pts.push(end_pt);
|
||||
all_vals.push(deterministic_pdf.pdf_vals.map(x => x * weights[i]));
|
||||
try{
|
||||
let parsed = parse.parse_initial_string(user_input_string);
|
||||
let mm_args = parse.separate_mm_args(parsed.mm_args_string);
|
||||
|
||||
const is_mm = mm_args.distrs.length > 0;
|
||||
if (!parsed.outer_string) return [[], [], true];
|
||||
|
||||
let tree = new bst.AVLTree();
|
||||
let possible_start_pts = [];
|
||||
let possible_end_pts = [];
|
||||
let all_vals = [];
|
||||
let weights = is_mm ? math.compile(mm_args.weights).evaluate()._data : [1];
|
||||
let weights_sum = weights.reduce((a, b) => a + b);
|
||||
weights = weights.map(x => x / weights_sum);
|
||||
let n_iters = is_mm ? mm_args.distrs.length : 1;
|
||||
|
||||
for (let i = 0; i < n_iters; ++i) {
|
||||
let distr_string = is_mm ? mm_args.distrs[i] : parsed.outer_string;
|
||||
var [deterministic_pdf, mc_distrs] = choose_pdf_func(distr_string);
|
||||
var grid_transform = get_grid_transform(distr_string);
|
||||
var [start_pt, end_pt] = update_transformed_divider_points_bst(
|
||||
grid_transform,
|
||||
deterministic_pdf,
|
||||
mc_distrs,
|
||||
i,
|
||||
NUM_MC_SAMPLES,
|
||||
tree
|
||||
);
|
||||
possible_start_pts.push(start_pt);
|
||||
possible_end_pts.push(end_pt);
|
||||
all_vals.push(deterministic_pdf.pdf_vals.map(x => x * weights[i]));
|
||||
}
|
||||
|
||||
start_pt = Math.min(...possible_start_pts);
|
||||
end_pt = Math.max(...possible_end_pts);
|
||||
|
||||
let output_grid = evenly_spaced_grid(start_pt, end_pt, OUTPUT_GRID_NUMEL);
|
||||
let final_pdf_vals = get_final_pdf(all_vals, tree, output_grid);
|
||||
return [final_pdf_vals, output_grid, false];
|
||||
} catch (e) {
|
||||
return [[], [], true];
|
||||
}
|
||||
start_pt = Math.min(...possible_start_pts);
|
||||
end_pt = Math.max(...possible_end_pts);
|
||||
let output_grid = evenly_spaced_grid(start_pt, end_pt, OUTPUT_GRID_NUMEL);
|
||||
let final_pdf_vals = get_final_pdf(all_vals, tree, output_grid);
|
||||
return [final_pdf_vals, output_grid];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param vals
|
||||
* @returns {number}
|
||||
*/
|
||||
function variance(vals) {
|
||||
var vari = 0;
|
||||
for (let i = 0; i < vals[0].length; ++i) {
|
||||
|
@ -209,14 +252,23 @@ function variance(vals) {
|
|||
return vari;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array
|
||||
* @param idx
|
||||
* @returns {*[]}
|
||||
*/
|
||||
function pluck_from_array(array, idx) {
|
||||
return [array[idx], array.slice(0, idx).concat(array.slice(idx + 1))];
|
||||
}
|
||||
|
||||
// If distr_string requires MC, try all possible
|
||||
// choices for the deterministic distribution,
|
||||
// and pick the one with the least variance.
|
||||
/**
|
||||
* @param distr_string
|
||||
* @returns {(*|*[])[]|*[]}
|
||||
*/
|
||||
function choose_pdf_func(distr_string) {
|
||||
// If distr_string requires MC, try all possible
|
||||
// choices for the deterministic distribution,
|
||||
// and pick the one with the least variance.
|
||||
var variances = [];
|
||||
let transform_func = get_grid_transform(distr_string);
|
||||
let substrings = parse.get_distr_substrings(distr_string);
|
||||
|
@ -259,6 +311,10 @@ function choose_pdf_func(distr_string) {
|
|||
return [pdfs[best_idx], mc_distrs];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param distr_string
|
||||
* @returns {function(*): *}
|
||||
*/
|
||||
function get_grid_transform(distr_string) {
|
||||
let substrings = parse.get_distr_substrings(distr_string);
|
||||
let arg_strings = [];
|
||||
|
|
Loading…
Reference in New Issue
Block a user