Last active
August 29, 2015 14:26
-
-
Save ramhiser/692c52644db04d1afcc4 to your computer and use it in GitHub Desktop.
Weighted random sample from a vector in JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Weighted random sample from a vector | |
// | |
// By default, the `weights` are set to 1. This equates to equal weighting. | |
// Loosely based on http://codereview.stackexchange.com/a/4265 | |
// | |
// If any weight is `null`, revert to default weights (i.e., all 1). | |
// | |
// A random-number generator (RNG) seed is optionally set via seedrandom.js. | |
// NOTE: The JS file is loaded via jQuery. | |
// Details: https://github.com/davidbau/seedrandom | |
// | |
// @param vector to sample | |
// @param weights optional array of weights | |
// @param seed optional RNG seed to reproduce | |
// @return random selection from `vector` | |
var sample = function(vector, weights, seed) { | |
weights_undefined = typeof weights === 'undefined'; | |
has_null_weights = false; | |
if (!weights_undefined) { | |
has_null_weights = weights.some(function(x) {return x === null;}) | |
} | |
if (weights_undefined || has_null_weights) { | |
weights = Array(vector.length); | |
for (i = 0; i < weights.length; i++) { | |
weights[i] = 1; | |
} | |
} | |
// Normalize weights to sum to 1 | |
// For vector sum, source: http://stackoverflow.com/a/3762623/234233 | |
weights_sum = weights.reduce(function(x, y) { return x + y; }, 0); | |
for (i = 0; i < weights.length; i++) { | |
weights[i] = weights[i] / weights_sum; | |
} | |
// Set RNG seed (if given) | |
var random_draw = null; | |
if (!(typeof seed === 'undefined')) { | |
$.getScript('http://cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.0/seedrandom.min.js') | |
.done(function() { | |
console.log('seedrandom.js loaded properly with seed: ' + seed); | |
Math.seedrandom(seed); | |
random_draw = Math.random(); | |
}).fail(function() { | |
console.log('seedrandom.js failed to load'); | |
}); | |
} | |
if (!random_draw) { | |
random_draw = Math.random(); | |
} | |
var cum_weights = 0; | |
for (i = 0; i < vector.length; i++) { | |
cum_weights += weights[i]; | |
if (random_draw < cum_weights) { | |
return(vector[i]); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The RNG seed is set via seedrandom.js. NOTE: This file is loaded using jQuery's
$.getScript
.