Published
Edited
Jul 12, 2020
2 forks
Importers
15 stars
Insert cell
Insert cell
Insert cell
function gen_expon(lambda){
return -Math.log(1-Math.random())/lambda;
}
Insert cell
gen_expon(15)
Insert cell
Insert cell
function gen_pois(lambda, max_its = 1000){
let i = -1, cum_sum = 0;
while(cum_sum < 1 && i < max_its){
i++;
cum_sum += -Math.log(1-Math.random())/lambda; // Or use gen_expon()
}
return i;
}
Insert cell
gen_pois(15)
Insert cell
Insert cell
function gen_discrete_unif(min = 0, max = 100){
const range = max - min;
return Math.round(Math.random()*range) + min;
}
Insert cell
gen_discrete_unif(0, 20)
Insert cell
Insert cell
Insert cell
function copy_array(arr){
return arr.map(obj => Object.assign({}, obj));
}
Insert cell
copy_array([{a: 1, b: 2}, {a: 2, b: 5}])
Insert cell
Insert cell
seq = function({ range, n, step, pad = 0 }) {
const [from, to] = range;
const width = to - from - 2 * pad;
let step_size, length;

if (n) {
length = n;
step_size = width / (length - 1);
} else {
step_size = step;
length = Math.ceil(width / step_size) + 1;
}

return Float32Array.from({ length }).map(
(_, i) => from + pad + step_size * i
);
}
Insert cell
seq({ range: [0, 2], n: 5, pad: 0.1 })
Insert cell
seq({ range: [0, 2], step: 0.2 })
Insert cell
Insert cell
function weighted_sample(weights, values){
const random_val = Math.random();
let cumulative_prob = 0, i;
for(i = 0; i < weights.length; i++){
cumulative_prob += weights[i];
if(cumulative_prob > random_val) break;
}
// If we have values, return which one, otherwise just return index
return values ? values[i]: i;
}
Insert cell
weighted_sample([0.1, 0.6, 0.3], ['a', 'b', 'c']);
Insert cell
weighted_sample([0.1, 0.6, 0.3]);
Insert cell
Insert cell
function weighted_samples({ vec, weight_id = null, n }) {
// Leaving weight_id as empty will do an unweighted sample
let total_weight = 0;
let to_sample = [];

vec.forEach((d, i) => {
const w = weight_id ? d[weight_id] : 1;
if (w > 0) {
// Only try sampling values with non-zero weights
total_weight += w;
to_sample.push({ w, i });
}
});

const sampled = [];

for (let k = 0; k < n; k++) {
const end_weight = Math.random() * total_weight;

let cumulative_weight = 0;
for (let j = 0; j < to_sample.length; j++) {
const { w, i } = to_sample[j];
cumulative_weight += w;
if (cumulative_weight >= end_weight) {
total_weight -= w;
sampled.push(to_sample.splice(j, 1)[0]);
break;
}
// sanity check to make sure we've got a value to go with.
if (total_weight === 0 || to_sample.length === 0) break;
}
}

return sampled.map(d => vec[d.i]);
}
Insert cell
weighted_samples({
vec: [
{ id: "a", w: 5 },
{ id: "b", w: 4 },
{ id: "c", w: 3 },
{ id: "d", w: 2 }
],
weight_id: "w",
n: 3
})
Insert cell
{
const n_sims = 50000;
const n_samples = 10;
const n_els = 40;

const data = Array.from({ length: n_els }).map((_, i) => ({
id: i,
w: 1 / (i + 1)
}));

const times_sampled = {};

data.forEach(d => (times_sampled[d.id] = 0));

for (let i = 0; i < n_sims; i++) {
const samples = weighted_samples({
vec: data,
weight_id: "w",
n: n_samples
});

samples.forEach(({ id }) => {
times_sampled[id]++;
});
}

const total_samples = n_sims * n_samples;
const props_sampled = [];
Object.keys(times_sampled).forEach(id =>
props_sampled.push({ id: +id, p: times_sampled[id] / total_samples })
);

return vegalite({
title: `Proportion of times sampled in ${n_samples} weighted draws over ${n_sims} simulations`,
width: width / 1.5,
data: { values: props_sampled },
mark: "bar",
encoding: {
x: {
field: "id",
title: "element",
type: "ordinal"
},
y: {
field: "p",
title: "prop sampled",
type: "quantitative"
}
}
});
}
Insert cell
Insert cell
function product(arr){
return arr.reduce((p, d) => p*d, 1);
}
Insert cell
product([1,2,3])
Insert cell
Insert cell
function sum(arr){
return arr.reduce((s, el) => s + el, 0);
}
Insert cell
sum([1,2,3,4])
Insert cell
Insert cell
function normalize(arr){
const total_size = arr.reduce((s, el) => s + el, 0);
// or sum(arr);
return arr.map(el => el/total_size);
}
Insert cell
normalize([1,2,3,4])
Insert cell
sum(normalize([2,3,4,6,7]))
Insert cell
Insert cell
function intersection(arr1, arr2){
return arr1.filter(n => arr2.includes(n));
}
Insert cell
intersection(
['a', 'b', 'c'],
['b', 'c', 'd']
)
Insert cell
Insert cell
function flatten(arr){
return [].concat(...arr);
}
Insert cell
flatten([
['a', 'b'],
['c', 'd'],
['e', 'f']
])
Insert cell
Insert cell
function unique(vec){
return [...new Set(vec)];
}
Insert cell
unique(['a', 'a', 'b', 'c', 'c', 'd'])
Insert cell
Insert cell
function init_array(n, fill = (_,i) => i){
return Array.from({length: n},
fill === null
? undefined
: typeof fill === 'function'
? fill
: () => fill);
}
Insert cell
init_array(4, (d,i) => i + 1).reverse()
Insert cell
// Defaults to filling with index
init_array(5);
Insert cell
// Can simply supply empty array
init_array(5, null);
Insert cell
// Fill with constant
init_array(5, 'a');
Insert cell
// Combine with probability functions
init_array(5, () => gen_pois(10));
Insert cell
Insert cell
Insert cell
all_equal = function(a, b) {
if (!b) return false;

const a_keys = Object.keys(a);
const b_keys = Object.keys(b);

// If number of keys differ then they cant be the same
if (a_keys.length !== b_keys.length) return false;

// If the union of the two keys is not the same length then they have different keys
const all_keys = new Set([...a_keys, ...b_keys]);
if (all_keys.size !== a_keys.length) return false;

// Now that we know all the keys are the same, test equality of values
for (let key in a) {
if (a[key] !== b[key]) return false;
}

return true;
}
Insert cell
all_equal({ a: 1, b: 2, c: 3 }, { a: 1, b: 2, c: 3 })
Insert cell
all_equal({ a: 1, b: 2, c: 4 }, { a: 1, b: 2, c: 3 })
Insert cell
all_equal({ a: 1, b: 2, c: 4 }, { a: 1, b: 2, c: 4, d: 5 })
Insert cell
vegalite = require("@observablehq/vega-lite@0.1")
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more