lumenize
Version:
Illuminating the forest AND the trees in your data.
103 lines (88 loc) • 3.28 kB
JavaScript
// Generated by CoffeeScript 1.10.0
(function() {
var RandomPicker;
RandomPicker = (function() {
/*
@class RandomPicker
Takes a config object like the one shown below, with the same format as is output by Lumenize.histogram()
config =
histogram: [
{ label: '< 10', count: 1 }, # histogram fields index, startOn, and endBelow are ignored, but returned by getRow() if provided
{ label: '10-20', count: 10 },
{ label: '20-30', count: 102 },
{ label: '30-40', count: 45},
{ label: '>= 40', count: 7}
]
So that it will make more sense when used with hand generated distributions, it will also take the following
config =
distribution: [
{ value: -1.0, p: 0.25 }
{ value: 2.0, p: 0.50 },
{ value: 8.0, p: 0.25 }
]
Note, that it runs the same exact code, just replacing what fields are used for the frequencyField and returnValueField
Similarly, you can override these by explicitly including them in your config.
Also, note that you need not worry about making your 'p' values add up to 1.0. It figures out the portion of the total
*/
function RandomPicker(config) {
var cumulative, i, j, k, len, len1, len2, r, ref, ref1, ref2, total;
this.config = config;
if (this.config.histogram != null) {
this.table = this.config.histogram;
} else if (this.config.distribution != null) {
this.table = this.config.distribution;
} else {
throw new Error('Must provide either a histogram or distribution in your config.');
}
if (this.config.frequencyField == null) {
if (this.config.histogram != null) {
this.config.frequencyField = 'count';
} else if (this.config.distribution != null) {
this.config.frequencyField = 'p';
}
}
if (this.config.returnValueField == null) {
if (this.config.histogram != null) {
this.config.returnValueField = 'label';
} else if (this.config.distribution != null) {
this.config.returnValueField = 'value';
}
}
total = 0;
ref = this.table;
for (i = 0, len = ref.length; i < len; i++) {
r = ref[i];
total += r[this.config.frequencyField];
}
ref1 = this.table;
for (j = 0, len1 = ref1.length; j < len1; j++) {
r = ref1[j];
r._p = r[this.config.frequencyField] / total;
}
cumulative = 0;
ref2 = this.table;
for (k = 0, len2 = ref2.length; k < len2; k++) {
r = ref2[k];
cumulative += r._p;
r._pCumulative = cumulative;
}
}
RandomPicker.prototype.getRow = function() {
var i, len, n, r, ref;
n = Math.random();
ref = this.table;
for (i = 0, len = ref.length; i < len; i++) {
r = ref[i];
if (n < r._pCumulative) {
return r;
}
}
return this.table[this.table.length - 1];
};
RandomPicker.prototype.get = function() {
return this.getRow()[this.config.returnValueField];
};
return RandomPicker;
})();
exports.RandomPicker = RandomPicker;
}).call(this);