Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implements simple sampling with replacement, which, in contrast to the existing sample method, allows an item to be chosen more than once. Fixes #173
- Loading branch information
Showing
3 changed files
with
61 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
'use strict'; | ||
/* @flow */ | ||
|
||
/** | ||
* Sampling with replacement is a type of sampling that allows the same | ||
* item to be picked out of a population more than once. | ||
* | ||
* @param {Array} population an array of any kind of element | ||
* @param {number} n count of how many elements to take | ||
* @param {Function} [randomSource=Math.random] an optional entropy source | ||
* @return {Array} shuffled version of input | ||
* @example | ||
* var sample = sampleWithReplacement([1, 2, 3, 4], 2); | ||
* sampleWithReplacement; // = [2, 4] or any other random permutation | ||
*/ | ||
function sampleWithReplacement/*::<T>*/(population/*:Array<T>*/, | ||
n /*: number */, | ||
randomSource/*:Function*/) { | ||
|
||
if (population.length === 0) { | ||
return []; | ||
} | ||
|
||
// a custom random number source can be provided if you want to use | ||
// a fixed seed or another random number generator, like | ||
// [random-js](https://www.npmjs.org/package/random-js) | ||
randomSource = randomSource || Math.random; | ||
|
||
var length = population.length; | ||
var sample = []; | ||
|
||
for (var i = 0; i < n; i++) { | ||
var index = Math.floor(randomSource() * length); | ||
|
||
sample.push(population[index]); | ||
} | ||
|
||
return sample; | ||
} | ||
|
||
module.exports = sampleWithReplacement; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* eslint no-shadow: 0 */ | ||
'use strict'; | ||
|
||
var test = require('tap').test; | ||
var Random = require('random-js'); | ||
var random = new Random(Random.engines.mt19937().seed(0)); | ||
var ss = require('../'); | ||
|
||
function rng() { return random.real(0, 1); } | ||
|
||
test('sampleWithReplacement', function(t) { | ||
var input = [1, 2, 3, 4, 5, 6]; | ||
t.deepEqual(ss.sampleWithReplacement(input, 2, rng), [6, 5]); | ||
t.deepEqual(ss.sampleWithReplacement(input, 3, rng), [3, 6, 4]); | ||
t.deepEqual(ss.sampleWithReplacement(input, 4, rng), [5, 2, 3, 4]); | ||
t.deepEqual(ss.sampleWithReplacement(input, 0, rng), []); | ||
t.deepEqual(ss.sampleWithReplacement([], 1, rng), []); | ||
t.end(); | ||
}); |