mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-18 14:59:29 +00:00
add pickMultipleRandom function
This commit is contained in:
parent
7511d4288d
commit
c5e40b40ef
@ -8,7 +8,7 @@ module.exports = {
|
||||
'description':
|
||||
'Create a distribution object of a specific type. ' +
|
||||
'A distribution object contains functions `random([size,] [min,] [max])`, ' +
|
||||
'`randomInt([size,] [min,] [max])`, and `pickRandom(array)`. ' +
|
||||
'`randomInt([size,] [min,] [max])`, `pickRandom(array)` and `pickMultipleRandom(array)`. ' +
|
||||
'Available types of distributions: "uniform", "normal". ' +
|
||||
'Note that the function distribution is currently not available via the expression parser.',
|
||||
'examples': [
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
module.exports = {
|
||||
'name': 'pickMultipleRandom',
|
||||
'category': 'Probability',
|
||||
'syntax': [
|
||||
'pickMultipleRandom(array, number)'
|
||||
],
|
||||
'description':
|
||||
'Pick a given number of random entries from a given array.',
|
||||
'examples': [
|
||||
'pickRandom([1, 3, 1, 6], 2)'
|
||||
],
|
||||
'seealso': ['random', 'randomInt', 'pickRandom']
|
||||
};
|
||||
@ -16,5 +16,5 @@ module.exports = {
|
||||
'random(10, 20)',
|
||||
'random([2, 3])'
|
||||
],
|
||||
'seealso': ['pickRandom', 'randomInt']
|
||||
'seealso': ['pickRandom', 'pickMultipleRandom', 'randomInt']
|
||||
};
|
||||
|
||||
@ -14,5 +14,5 @@ module.exports = {
|
||||
'randInt(10, 20)',
|
||||
'randInt([2, 3], 10)'
|
||||
],
|
||||
'seealso': ['pickRandom', 'random']
|
||||
'seealso': ['pickRandom', 'pickMultipleRandom', 'random']
|
||||
};
|
||||
@ -207,6 +207,7 @@ function factory (construction, config, load, typed) {
|
||||
docs.multinomial = require('./function/probability/multinomial');
|
||||
docs.permutations = require('./function/probability/permutations');
|
||||
docs.pickRandom = require('./function/probability/pickRandom');
|
||||
docs.pickMultipleRandom = require('./function/probability/pickMultipleRandom');
|
||||
docs.random = require('./function/probability/random');
|
||||
docs.randomInt = require('./function/probability/randomInt');
|
||||
|
||||
|
||||
@ -24,13 +24,14 @@ function factory (type, config, load, typed) {
|
||||
*
|
||||
* See also:
|
||||
*
|
||||
* random, randomInt, pickRandom
|
||||
* random, randomInt, pickRandom, pickMultipleRandom
|
||||
*
|
||||
* @param {string} name Name of a distribution. Choose from 'uniform', 'normal'.
|
||||
* @return {Object} Returns a distribution object containing functions:
|
||||
* `random([size] [, min] [, max])`,
|
||||
* `randomInt([min] [, max])`,
|
||||
* `pickRandom(array)`
|
||||
* `pickRandom(array)`,
|
||||
* `pickMultipleRandom(array, number)`
|
||||
*/
|
||||
function distribution(name) {
|
||||
if (!distributions.hasOwnProperty(name))
|
||||
@ -142,8 +143,43 @@ function factory (type, config, load, typed) {
|
||||
|
||||
// TODO: add support for multi dimensional matrices
|
||||
return possibles[Math.floor(Math.random() * possibles.length)];
|
||||
}
|
||||
},
|
||||
|
||||
pickMultipleRandom: function(possibles, number) {
|
||||
if (arguments.length !== 2) {
|
||||
throw new ArgumentsError('pickMultipleRandom', arguments.length, 2);
|
||||
}
|
||||
if (possibles && possibles.isMatrix === true) {
|
||||
possibles = possibles.valueOf(); // get Array
|
||||
}
|
||||
else if (!Array.isArray(possibles)) {
|
||||
throw new TypeError('Unsupported type of value in function pickMultipleRandom');
|
||||
}
|
||||
|
||||
if (array.size(possibles).length > 1) {
|
||||
throw new Error('Only one dimensional vectors supported');
|
||||
}
|
||||
|
||||
var length = possibles.length;
|
||||
|
||||
if (length == 0) {
|
||||
return [];
|
||||
} else if (number >= length) {
|
||||
return possibles;
|
||||
}
|
||||
|
||||
var result = [];
|
||||
var pick;
|
||||
|
||||
while (result.length < number) {
|
||||
pick = possibles[Math.floor(Math.random() * length)];
|
||||
if (result.indexOf(pick) == -1) {
|
||||
result.push(pick);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
var _random = function(min, max) {
|
||||
|
||||
@ -7,6 +7,7 @@ module.exports = [
|
||||
require('./multinomial'),
|
||||
require('./permutations'),
|
||||
require('./pickRandom'),
|
||||
require('./pickMultipleRandom'),
|
||||
require('./random'),
|
||||
require('./randomInt')
|
||||
];
|
||||
|
||||
34
lib/function/probability/pickMultipleRandom.js
Normal file
34
lib/function/probability/pickMultipleRandom.js
Normal file
@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
function factory (type, config, load, typed) {
|
||||
var distribution = load(require('./distribution'));
|
||||
|
||||
/**
|
||||
* Random pick a specified number of values from a one dimensional array.
|
||||
* Array elements are picked using a random function with uniform distribution.
|
||||
*
|
||||
* Syntax:
|
||||
*
|
||||
* math.pickMultipleRandom(array, int)
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* math.pickMultipleRandom([3, 6, 12, 2], 2); // returns two of the values in the array
|
||||
*
|
||||
* See also:
|
||||
*
|
||||
* random, randomInt, pickRandom, pickMultipleRandom
|
||||
*
|
||||
* @param {Array} array A one dimensional array
|
||||
* @param {number} num A one dimensional array
|
||||
* @return {array} An array with n elements of the provided input array
|
||||
*/
|
||||
var pickMultipleRandom = distribution('uniform').pickMultipleRandom;
|
||||
|
||||
pickMultipleRandom.toTex = undefined; // use default template
|
||||
|
||||
return pickMultipleRandom;
|
||||
}
|
||||
|
||||
exports.name = 'pickMultipleRandom';
|
||||
exports.factory = factory;
|
||||
@ -25,7 +25,7 @@ function factory (type, config, load, typed) {
|
||||
*
|
||||
* See also:
|
||||
*
|
||||
* randomInt, pickRandom
|
||||
* randomInt, pickRandom, pickMultipleRandom
|
||||
*
|
||||
* @param {Array | Matrix} [size] If provided, an array or matrix with given
|
||||
* size and filled with random values is returned
|
||||
|
||||
@ -23,7 +23,7 @@ function factory (type, config, load, typed) {
|
||||
*
|
||||
* See also:
|
||||
*
|
||||
* random, pickRandom
|
||||
* random, pickRandom, pickMultipleRandom
|
||||
*
|
||||
* @param {Array | Matrix} [size] If provided, an array or matrix with given
|
||||
* size and filled with random values is returned
|
||||
|
||||
@ -282,6 +282,91 @@ describe('distribution', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('pickMultipleRandom', function() {
|
||||
|
||||
it('should pick the given number of values from the given array', function() {
|
||||
var possibles = [11, 22, 33, 44, 55],
|
||||
number = 3,
|
||||
picked = [];
|
||||
|
||||
assert.equal(uniformDistrib.pickMultipleRandom(possibles, number).length, number);
|
||||
});
|
||||
|
||||
it('should return the given array if the given number is equal its length', function() {
|
||||
var possibles = [11, 22, 33, 44, 55],
|
||||
number = 5,
|
||||
picked = [];
|
||||
|
||||
assert.equal(uniformDistrib.pickMultipleRandom(possibles, number), possibles);
|
||||
});
|
||||
|
||||
it('should return the given array if the given number is greater than its length', function() {
|
||||
var possibles = [11, 22, 33, 44, 55],
|
||||
number = 6,
|
||||
picked = [];
|
||||
|
||||
assert.equal(uniformDistrib.pickMultipleRandom(possibles, number), possibles);
|
||||
});
|
||||
|
||||
it('should pick numbers from the given array following an uniform distribution', function() {
|
||||
var possibles = [11, 22, 33, 44, 55],
|
||||
number = 2,
|
||||
picked = [],
|
||||
count;
|
||||
|
||||
_.times(1000, function() {
|
||||
picked.push(uniformDistrib.pickMultipleRandom(possibles, number));
|
||||
});
|
||||
|
||||
count = _.filter(picked, function(val) { return val.indexOf(11) !== -1 }).length;
|
||||
assert.equal(math.round(count/(picked.length*number), 1), 0.2);
|
||||
|
||||
count = _.filter(picked, function(val) { return val.indexOf(22) !== -1 }).length;
|
||||
assert.equal(math.round(count/(picked.length*number), 1), 0.2);
|
||||
|
||||
count = _.filter(picked, function(val) { return val.indexOf(33) !== -1 }).length;
|
||||
assert.equal(math.round(count/(picked.length*number), 1), 0.2);
|
||||
|
||||
count = _.filter(picked, function(val) { return val.indexOf(44) !== -1 }).length;
|
||||
assert.equal(math.round(count/(picked.length*number), 1), 0.2);
|
||||
|
||||
count = _.filter(picked, function(val) { return val.indexOf(55) !== -1 }).length;
|
||||
assert.equal(math.round(count/(picked.length*number), 1), 0.2);
|
||||
});
|
||||
|
||||
it('should pick numbers from the given matrix following an uniform distribution', function() {
|
||||
var possibles = math.matrix([11, 22, 33, 44, 55]),
|
||||
number = 3,
|
||||
picked = [],
|
||||
count;
|
||||
|
||||
_.times(1000, function() {
|
||||
picked.push(uniformDistrib.pickMultipleRandom(possibles, number));
|
||||
});
|
||||
|
||||
count = _.filter(picked, function(val) { return val.indexOf(11) !== -1 }).length;
|
||||
assert.equal(math.round(count/(picked.length*number), 1), 0.2);
|
||||
|
||||
count = _.filter(picked, function(val) { return val.indexOf(22) !== -1 }).length;
|
||||
assert.equal(math.round(count/(picked.length*number), 1), 0.2);
|
||||
|
||||
count = _.filter(picked, function(val) { return val.indexOf(33) !== -1 }).length;
|
||||
assert.equal(math.round(count/(picked.length*number), 1), 0.2);
|
||||
|
||||
count = _.filter(picked, function(val) { return val.indexOf(44) !== -1 }).length;
|
||||
assert.equal(math.round(count/(picked.length*number), 1), 0.2);
|
||||
|
||||
count = _.filter(picked, function(val) { return val.indexOf(55) !== -1 }).length;
|
||||
assert.equal(math.round(count/(picked.length*number), 1), 0.2);
|
||||
});
|
||||
|
||||
it('should throw an error when providing a multi dimensional matrix', function() {
|
||||
assert.throws(function () {
|
||||
uniformDistrib.pickMultipleRandom(math.matrix([[1,2], [3,4]]), 2);
|
||||
}, /Only one dimensional vectors supported/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('distribution.normal', function() {
|
||||
|
||||
it('should pick numbers in [0, 1] following a normal distribution', function() {
|
||||
|
||||
17
test/function/probability/pickMultipleRandom.test.js
Normal file
17
test/function/probability/pickMultipleRandom.test.js
Normal file
@ -0,0 +1,17 @@
|
||||
var assert = require('assert'),
|
||||
math = require('../../../index');
|
||||
|
||||
describe('pickMultipleRandom', function () {
|
||||
// Note: pickMultipleRandom is a convenience function generated by distribution
|
||||
// it is tested in distribution.test.js
|
||||
|
||||
it('should have a function pickMultipleRandom', function () {
|
||||
assert.equal(typeof math.pickMultipleRandom, 'function');
|
||||
})
|
||||
|
||||
it('should LaTeX pickMultipleRandom', function () {
|
||||
var expression = math.parse('pickMultipleRandom([1,2,3], 2)');
|
||||
assert.equal(expression.toTex(), '\\mathrm{pickMultipleRandom}\\left(\\begin{bmatrix}1\\\\2\\\\3\\\\\\end{bmatrix},2\\right)');
|
||||
});
|
||||
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user