529 lines
14 KiB
JavaScript
529 lines
14 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.RNGFactory = exports.RNG = undefined;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _owLite = require('ow-lite');
|
|
|
|
var _owLite2 = _interopRequireDefault(_owLite);
|
|
|
|
var _rng = require('./rng');
|
|
|
|
var _rng2 = _interopRequireDefault(_rng);
|
|
|
|
var _rngFactory = require('./rng-factory');
|
|
|
|
var _rngFactory2 = _interopRequireDefault(_rngFactory);
|
|
|
|
var _uniform2 = require('./distributions/uniform');
|
|
|
|
var _uniform3 = _interopRequireDefault(_uniform2);
|
|
|
|
var _uniformInt2 = require('./distributions/uniform-int');
|
|
|
|
var _uniformInt3 = _interopRequireDefault(_uniformInt2);
|
|
|
|
var _uniformBoolean2 = require('./distributions/uniform-boolean');
|
|
|
|
var _uniformBoolean3 = _interopRequireDefault(_uniformBoolean2);
|
|
|
|
var _normal2 = require('./distributions/normal');
|
|
|
|
var _normal3 = _interopRequireDefault(_normal2);
|
|
|
|
var _logNormal2 = require('./distributions/log-normal');
|
|
|
|
var _logNormal3 = _interopRequireDefault(_logNormal2);
|
|
|
|
var _bernoulli2 = require('./distributions/bernoulli');
|
|
|
|
var _bernoulli3 = _interopRequireDefault(_bernoulli2);
|
|
|
|
var _binomial2 = require('./distributions/binomial');
|
|
|
|
var _binomial3 = _interopRequireDefault(_binomial2);
|
|
|
|
var _geometric2 = require('./distributions/geometric');
|
|
|
|
var _geometric3 = _interopRequireDefault(_geometric2);
|
|
|
|
var _poisson2 = require('./distributions/poisson');
|
|
|
|
var _poisson3 = _interopRequireDefault(_poisson2);
|
|
|
|
var _exponential2 = require('./distributions/exponential');
|
|
|
|
var _exponential3 = _interopRequireDefault(_exponential2);
|
|
|
|
var _irwinHall2 = require('./distributions/irwin-hall');
|
|
|
|
var _irwinHall3 = _interopRequireDefault(_irwinHall2);
|
|
|
|
var _bates2 = require('./distributions/bates');
|
|
|
|
var _bates3 = _interopRequireDefault(_bates2);
|
|
|
|
var _pareto2 = require('./distributions/pareto');
|
|
|
|
var _pareto3 = _interopRequireDefault(_pareto2);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
exports.RNG = _rng2.default;
|
|
exports.RNGFactory = _rngFactory2.default;
|
|
|
|
/**
|
|
* Seedable random number generator supporting many common distributions.
|
|
*
|
|
* Defaults to Math.random as its underlying pseudorandom number generator.
|
|
*
|
|
* @name Random
|
|
* @class
|
|
*
|
|
* @param {RNG|function} [rng=Math.random] - Underlying pseudorandom number generator.
|
|
*/
|
|
|
|
var Random = function () {
|
|
function Random(rng) {
|
|
_classCallCheck(this, Random);
|
|
|
|
if (rng) (0, _owLite2.default)(rng, _owLite2.default.object.instanceOf(_rng2.default));
|
|
|
|
this._cache = {};
|
|
this.use(rng);
|
|
}
|
|
|
|
/**
|
|
* @member {RNG} Underlying pseudo-random number generator
|
|
*/
|
|
|
|
|
|
_createClass(Random, [{
|
|
key: 'clone',
|
|
|
|
|
|
/**
|
|
* Creates a new `Random` instance, optionally specifying parameters to
|
|
* set a new seed.
|
|
*
|
|
* @see RNG.clone
|
|
*
|
|
* @param {string} [seed] - Optional seed for new RNG.
|
|
* @param {object} [opts] - Optional config for new RNG options.
|
|
* @return {Random}
|
|
*/
|
|
value: function clone() {
|
|
if (arguments.length) {
|
|
return new Random(_rngFactory2.default.apply(undefined, arguments));
|
|
} else {
|
|
return new Random(this.rng.clone());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the underlying pseudorandom number generator used via
|
|
* either an instance of `seedrandom`, a custom instance of RNG
|
|
* (for PRNG plugins), or a string specifying the PRNG to use
|
|
* along with an optional `seed` and `opts` to initialize the
|
|
* RNG.
|
|
*
|
|
* @example
|
|
* const random = require('random')
|
|
*
|
|
* random.use('example_seedrandom_string')
|
|
* // or
|
|
* random.use(seedrandom('kittens'))
|
|
* // or
|
|
* random.use(Math.random)
|
|
*
|
|
* @param {...*} args
|
|
*/
|
|
|
|
}, {
|
|
key: 'use',
|
|
value: function use() {
|
|
this._rng = _rngFactory2.default.apply(undefined, arguments);
|
|
}
|
|
|
|
/**
|
|
* Patches `Math.random` with this Random instance's PRNG.
|
|
*/
|
|
|
|
}, {
|
|
key: 'patch',
|
|
value: function patch() {
|
|
if (this._patch) {
|
|
throw new Error('Math.random already patched');
|
|
}
|
|
|
|
this._patch = Math.random;
|
|
Math.random = this.uniform();
|
|
}
|
|
|
|
/**
|
|
* Restores a previously patched `Math.random` to its original value.
|
|
*/
|
|
|
|
}, {
|
|
key: 'unpatch',
|
|
value: function unpatch() {
|
|
if (this._patch) {
|
|
Math.random = this._patch;
|
|
delete this._patch;
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Uniform utility functions
|
|
// --------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Convenience wrapper around `this.rng.next()`
|
|
*
|
|
* Returns a floating point number in [0, 1).
|
|
*
|
|
* @return {number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'next',
|
|
value: function next() {
|
|
return this._rng.next();
|
|
}
|
|
|
|
/**
|
|
* Samples a uniform random floating point number, optionally specifying
|
|
* lower and upper bounds.
|
|
*
|
|
* Convence wrapper around `random.uniform()`
|
|
*
|
|
* @param {number} [min=0] - Lower bound (float, inclusive)
|
|
* @param {number} [max=1] - Upper bound (float, exclusive)
|
|
* @return {number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'float',
|
|
value: function float(min, max) {
|
|
return this.uniform(min, max)();
|
|
}
|
|
|
|
/**
|
|
* Samples a uniform random integer, optionally specifying lower and upper
|
|
* bounds.
|
|
*
|
|
* Convence wrapper around `random.uniformInt()`
|
|
*
|
|
* @param {number} [min=0] - Lower bound (integer, inclusive)
|
|
* @param {number} [max=1] - Upper bound (integer, inclusive)
|
|
* @return {number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'int',
|
|
value: function int(min, max) {
|
|
return this.uniformInt(min, max)();
|
|
}
|
|
|
|
/**
|
|
* Samples a uniform random integer, optionally specifying lower and upper
|
|
* bounds.
|
|
*
|
|
* Convence wrapper around `random.uniformInt()`
|
|
*
|
|
* @alias `random.int`
|
|
*
|
|
* @param {number} [min=0] - Lower bound (integer, inclusive)
|
|
* @param {number} [max=1] - Upper bound (integer, inclusive)
|
|
* @return {number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'integer',
|
|
value: function integer(min, max) {
|
|
return this.uniformInt(min, max)();
|
|
}
|
|
|
|
/**
|
|
* Samples a uniform random boolean value.
|
|
*
|
|
* Convence wrapper around `random.uniformBoolean()`
|
|
*
|
|
* @alias `random.boolean`
|
|
*
|
|
* @return {boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'bool',
|
|
value: function bool() {
|
|
return this.uniformBoolean()();
|
|
}
|
|
|
|
/**
|
|
* Samples a uniform random boolean value.
|
|
*
|
|
* Convence wrapper around `random.uniformBoolean()`
|
|
*
|
|
* @return {boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'boolean',
|
|
value: function boolean() {
|
|
return this.uniformBoolean()();
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Uniform distributions
|
|
// --------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Generates a [Continuous uniform distribution](https://en.wikipedia.org/wiki/Uniform_distribution_(continuous)).
|
|
*
|
|
* @param {number} [min=0] - Lower bound (float, inclusive)
|
|
* @param {number} [max=1] - Upper bound (float, exclusive)
|
|
* @return {function}
|
|
*/
|
|
|
|
}, {
|
|
key: 'uniform',
|
|
value: function uniform(min, max) {
|
|
return this._memoize('uniform', _uniform3.default, min, max);
|
|
}
|
|
|
|
/**
|
|
* Generates a [Discrete uniform distribution](https://en.wikipedia.org/wiki/Discrete_uniform_distribution).
|
|
*
|
|
* @param {number} [min=0] - Lower bound (integer, inclusive)
|
|
* @param {number} [max=1] - Upper bound (integer, inclusive)
|
|
* @return {function}
|
|
*/
|
|
|
|
}, {
|
|
key: 'uniformInt',
|
|
value: function uniformInt(min, max) {
|
|
return this._memoize('uniformInt', _uniformInt3.default, min, max);
|
|
}
|
|
|
|
/**
|
|
* Generates a [Discrete uniform distribution](https://en.wikipedia.org/wiki/Discrete_uniform_distribution),
|
|
* with two possible outcomes, `true` or `false.
|
|
*
|
|
* This method is analogous to flipping a coin.
|
|
*
|
|
* @return {function}
|
|
*/
|
|
|
|
}, {
|
|
key: 'uniformBoolean',
|
|
value: function uniformBoolean() {
|
|
return this._memoize('uniformBoolean', _uniformBoolean3.default);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Normal distributions
|
|
// --------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Generates a [Normal distribution](https://en.wikipedia.org/wiki/Normal_distribution).
|
|
*
|
|
* @param {number} [mu=0] - Mean
|
|
* @param {number} [sigma=1] - Standard deviation
|
|
* @return {function}
|
|
*/
|
|
|
|
}, {
|
|
key: 'normal',
|
|
value: function normal(mu, sigma) {
|
|
return (0, _normal3.default)(this, mu, sigma);
|
|
}
|
|
|
|
/**
|
|
* Generates a [Log-normal distribution](https://en.wikipedia.org/wiki/Log-normal_distribution).
|
|
*
|
|
* @param {number} [mu=0] - Mean of underlying normal distribution
|
|
* @param {number} [sigma=1] - Standard deviation of underlying normal distribution
|
|
* @return {function}
|
|
*/
|
|
|
|
}, {
|
|
key: 'logNormal',
|
|
value: function logNormal(mu, sigma) {
|
|
return (0, _logNormal3.default)(this, mu, sigma);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Bernoulli distributions
|
|
// --------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Generates a [Bernoulli distribution](https://en.wikipedia.org/wiki/Bernoulli_distribution).
|
|
*
|
|
* @param {number} [p=0.5] - Success probability of each trial.
|
|
* @return {function}
|
|
*/
|
|
|
|
}, {
|
|
key: 'bernoulli',
|
|
value: function bernoulli(p) {
|
|
return (0, _bernoulli3.default)(this, p);
|
|
}
|
|
|
|
/**
|
|
* Generates a [Binomial distribution](https://en.wikipedia.org/wiki/Binomial_distribution).
|
|
*
|
|
* @param {number} [n=1] - Number of trials.
|
|
* @param {number} [p=0.5] - Success probability of each trial.
|
|
* @return {function}
|
|
*/
|
|
|
|
}, {
|
|
key: 'binomial',
|
|
value: function binomial(n, p) {
|
|
return (0, _binomial3.default)(this, n, p);
|
|
}
|
|
|
|
/**
|
|
* Generates a [Geometric distribution](https://en.wikipedia.org/wiki/Geometric_distribution).
|
|
*
|
|
* @param {number} [p=0.5] - Success probability of each trial.
|
|
* @return {function}
|
|
*/
|
|
|
|
}, {
|
|
key: 'geometric',
|
|
value: function geometric(p) {
|
|
return (0, _geometric3.default)(this, p);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Poisson distributions
|
|
// --------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Generates a [Poisson distribution](https://en.wikipedia.org/wiki/Poisson_distribution).
|
|
*
|
|
* @param {number} [lambda=1] - Mean (lambda > 0)
|
|
* @return {function}
|
|
*/
|
|
|
|
}, {
|
|
key: 'poisson',
|
|
value: function poisson(lambda) {
|
|
return (0, _poisson3.default)(this, lambda);
|
|
}
|
|
|
|
/**
|
|
* Generates an [Exponential distribution](https://en.wikipedia.org/wiki/Exponential_distribution).
|
|
*
|
|
* @param {number} [lambda=1] - Inverse mean (lambda > 0)
|
|
* @return {function}
|
|
*/
|
|
|
|
}, {
|
|
key: 'exponential',
|
|
value: function exponential(lambda) {
|
|
return (0, _exponential3.default)(this, lambda);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Misc distributions
|
|
// --------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Generates an [Irwin Hall distribution](https://en.wikipedia.org/wiki/Irwin%E2%80%93Hall_distribution).
|
|
*
|
|
* @param {number} [n=1] - Number of uniform samples to sum (n >= 0)
|
|
* @return {function}
|
|
*/
|
|
|
|
}, {
|
|
key: 'irwinHall',
|
|
value: function irwinHall(n) {
|
|
return (0, _irwinHall3.default)(this, n);
|
|
}
|
|
|
|
/**
|
|
* Generates a [Bates distribution](https://en.wikipedia.org/wiki/Bates_distribution).
|
|
*
|
|
* @param {number} [n=1] - Number of uniform samples to average (n >= 1)
|
|
* @return {function}
|
|
*/
|
|
|
|
}, {
|
|
key: 'bates',
|
|
value: function bates(n) {
|
|
return (0, _bates3.default)(this, n);
|
|
}
|
|
|
|
/**
|
|
* Generates a [Pareto distribution](https://en.wikipedia.org/wiki/Pareto_distribution).
|
|
*
|
|
* @param {number} [alpha=1] - Alpha
|
|
* @return {function}
|
|
*/
|
|
|
|
}, {
|
|
key: 'pareto',
|
|
value: function pareto(alpha) {
|
|
return (0, _pareto3.default)(this, alpha);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Internal
|
|
// --------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Memoizes distributions to ensure they're only created when necessary.
|
|
*
|
|
* Returns a thunk which that returns independent, identically distributed
|
|
* samples from the specified distribution.
|
|
*
|
|
* @private
|
|
*
|
|
* @param {string} label - Name of distribution
|
|
* @param {function} getter - Function which generates a new distribution
|
|
* @param {...*} args - Distribution-specific arguments
|
|
*
|
|
* @return {function}
|
|
*/
|
|
|
|
}, {
|
|
key: '_memoize',
|
|
value: function _memoize(label, getter) {
|
|
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
args[_key - 2] = arguments[_key];
|
|
}
|
|
|
|
var key = '' + args.join(';');
|
|
var value = this._cache[label];
|
|
|
|
if (value === undefined || value.key !== key) {
|
|
value = { key: key, distribution: getter.apply(undefined, [this].concat(args)) };
|
|
this._cache[label] = value;
|
|
}
|
|
|
|
return value.distribution;
|
|
}
|
|
}, {
|
|
key: 'rng',
|
|
get: function get() {
|
|
return this._rng;
|
|
}
|
|
}]);
|
|
|
|
return Random;
|
|
}();
|
|
|
|
// defaults to Math.random as its RNG
|
|
|
|
|
|
exports.default = new Random();
|
|
//# sourceMappingURL=random.js.map
|