random
Version:
Seedable random number generator supporting many common distributions.
934 lines (907 loc) • 25.2 kB
JavaScript
//#region src/rng.ts
var RNG = class {};
//#endregion
//#region \0@oxc-project+runtime@0.144.0/helpers/esm/typeof.js
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
return typeof o;
} : function(o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
//#endregion
//#region \0@oxc-project+runtime@0.144.0/helpers/esm/toPrimitive.js
function toPrimitive(t, r) {
if ("object" != _typeof(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != _typeof(i)) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
//#endregion
//#region \0@oxc-project+runtime@0.144.0/helpers/esm/toPropertyKey.js
function toPropertyKey(t) {
var i = toPrimitive(t, "string");
return "symbol" == _typeof(i) ? i : i + "";
}
//#endregion
//#region \0@oxc-project+runtime@0.144.0/helpers/esm/defineProperty.js
function _defineProperty(e, r, t) {
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
value: t,
enumerable: !0,
configurable: !0,
writable: !0
}) : e[r] = t, e;
}
//#endregion
//#region src/generators/function.ts
var FunctionRNG = class FunctionRNG extends RNG {
constructor(rngFn) {
super();
_defineProperty(this, "_name", void 0);
_defineProperty(this, "_rngFn", void 0);
this._name = rngFn.name || "function";
this._rngFn = rngFn;
}
get name() {
return this._name;
}
next() {
return this._rngFn();
}
clone() {
return new FunctionRNG(this._rngFn);
}
};
//#endregion
//#region src/generators/xoshiro128-star-star.ts
const UINT53_SIZE = 9007199254740992;
const UINT26_SIZE = 67108864;
function rotateLeft(value, shift) {
return value << shift | value >>> 32 - shift;
}
/**
* cyrb128, a compact non-cryptographic string hash for seed generation.
*
* @see https://stackoverflow.com/a/47593316
*/
function cyrb128(seed) {
const value = `${seed}`;
let s0 = 1779033703;
let s1 = 3144134277;
let s2 = 1013904242;
let s3 = 2773480762;
for (let i = 0; i < value.length; i++) {
const code = value.charCodeAt(i);
s0 = s1 ^ Math.imul(s0 ^ code, 597399067);
s1 = s2 ^ Math.imul(s1 ^ code, 2869860233);
s2 = s3 ^ Math.imul(s2 ^ code, 951274213);
s3 = s0 ^ Math.imul(s3 ^ code, 2716044179);
}
s0 = Math.imul(s2 ^ s0 >>> 18, 597399067);
s1 = Math.imul(s3 ^ s1 >>> 22, 2869860233);
s2 = Math.imul(s0 ^ s2 >>> 17, 951274213);
s3 = Math.imul(s1 ^ s3 >>> 19, 2716044179);
s0 ^= s1 ^ s2 ^ s3;
s1 ^= s0;
s2 ^= s0;
s3 ^= s0;
return [
s0 >>> 0,
s1 >>> 0,
s2 >>> 0,
s3 >>> 0
];
}
/**
* xoshiro128** is a small, fast, general-purpose pseudorandom number generator
* with 128 bits of state and a period of 2^128 - 1.
*
* It is not cryptographically secure.
*
* @see https://prng.di.unimi.it/xoshiro128starstar.c
*/
var Xoshiro128StarStarRNG = class Xoshiro128StarStarRNG extends RNG {
constructor(seed = crypto.randomUUID()) {
super();
_defineProperty(this, "_seed", void 0);
_defineProperty(this, "s0", 0);
_defineProperty(this, "s1", 0);
_defineProperty(this, "s2", 0);
_defineProperty(this, "s3", 0);
this._seed = seed;
this.setState(cyrb128(seed));
}
setState(state) {
this.s0 = state[0];
this.s1 = state[1];
this.s2 = state[2];
this.s3 = state[3];
if ((this.s0 | this.s1 | this.s2 | this.s3) === 0) this.s0 = 1831565813;
}
get name() {
return "xoshiro128**";
}
next() {
const high = this.nextUint32() >>> 5;
const low = this.nextUint32() >>> 6;
return (high * UINT26_SIZE + low) / UINT53_SIZE;
}
clone() {
const clone = new Xoshiro128StarStarRNG(this._seed);
clone.setState([
this.s0,
this.s1,
this.s2,
this.s3
]);
return clone;
}
nextUint32() {
const result = Math.imul(rotateLeft(Math.imul(this.s1, 5), 7), 9) >>> 0;
const t = this.s1 << 9;
this.s2 ^= this.s0;
this.s3 ^= this.s1;
this.s1 ^= this.s2;
this.s0 ^= this.s3;
this.s2 ^= t;
this.s3 = rotateLeft(this.s3, 11);
return result;
}
};
//#endregion
//#region src/utils.ts
function createRNG(seedOrRNG) {
switch (typeof seedOrRNG) {
case "object":
if (seedOrRNG instanceof RNG) return seedOrRNG;
break;
case "function": return new FunctionRNG(seedOrRNG);
case "number":
case "string":
case "undefined": return new Xoshiro128StarStarRNG(seedOrRNG);
}
throw new TypeError(`Invalid seed or RNG: ${String(seedOrRNG)}`);
}
/**
* Mixes a string seed into a key that is an array of integers, and returns a
* shortened string seed that is equivalent to the result key.
*/
function mixKey(seed, key) {
const seedStr = `${seed}`;
let smear = 0;
let j = 0;
while (j < seedStr.length) key[255 & j] = 255 & (smear ^= (key[255 & j] ?? 0) * 19) + seedStr.charCodeAt(j++);
if (!key.length) return [0];
return key;
}
function shuffleInPlace(gen, array) {
for (let i = array.length - 1; i > 0; i -= 1) {
const j = Math.floor(gen.next() * (i + 1));
const tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
}
/**
* Fisher-Yates sampling without replacement
* O(k) time and space, by using a hash table instead of a full copy of the array
* see https://arxiv.org/pdf/2104.05091 Algorithm 2
*/
function sparseFisherYates(gen, array, k) {
const H = /* @__PURE__ */ new Map();
const lastIndex = array.length - 1;
const result = Array.from({ length: k });
for (let i = 0; i < k; i++) {
const remaining = lastIndex - i + 1;
const r = Math.floor(gen.next() * remaining);
result[i] = array[H.get(r) ?? r];
H.set(r, H.get(lastIndex - i) ?? lastIndex - i);
}
return result;
}
//#endregion
//#region src/generators/arc4.ts
const _arc4_startdenom = 281474976710656;
const _arc4_significance = 4503599627370496;
const _arc4_overflow = 9007199254740992;
var ARC4RNG = class ARC4RNG extends RNG {
constructor(seed = crypto.randomUUID()) {
super();
_defineProperty(this, "_seed", void 0);
_defineProperty(this, "i", void 0);
_defineProperty(this, "j", void 0);
_defineProperty(this, "S", void 0);
this._seed = seed;
const key = mixKey(seed, []);
const S = [];
const keylen = key.length;
this.i = 0;
this.j = 0;
this.S = S;
let i = 0;
while (i <= 255) S[i] = i++;
for (let i = 0, j = 0; i <= 255; i++) {
const t = S[i];
j = 255 & j + key[i % keylen] + t;
S[i] = S[j];
S[j] = t;
}
this.g(256);
}
get name() {
return "arc4";
}
next() {
let n = this.g(6);
let d = _arc4_startdenom;
let x = 0;
while (n < _arc4_significance) {
n = (n + x) * 256;
d *= 256;
x = this.g(1);
}
while (n >= _arc4_overflow) {
n /= 2;
d /= 2;
x >>>= 1;
}
return (n + x) / d;
}
g(count) {
const { S } = this;
let { i, j } = this;
let r = 0;
while (count--) {
i = 255 & i + 1;
const t = S[i];
j = 255 & j + t;
S[i] = S[j];
S[j] = t;
r = r * 256 + S[255 & S[i] + t];
}
this.i = i;
this.j = j;
return r;
}
clone() {
const clone = new ARC4RNG(this._seed);
clone.i = this.i;
clone.j = this.j;
clone.S = [...this.S];
return clone;
}
};
//#endregion
//#region src/generators/math-random.ts
var MathRandomRNG = class MathRandomRNG extends RNG {
get name() {
return "Math.random";
}
next() {
return Math.random();
}
clone() {
return new MathRandomRNG();
}
};
//#endregion
//#region src/generators/xor128.ts
var XOR128RNG = class XOR128RNG extends RNG {
constructor(seed = crypto.randomUUID()) {
super();
_defineProperty(this, "_seed", void 0);
_defineProperty(this, "x", void 0);
_defineProperty(this, "y", void 0);
_defineProperty(this, "z", void 0);
_defineProperty(this, "w", void 0);
this._seed = seed;
this.x = 0;
this.y = 0;
this.z = 0;
this.w = 0;
let strSeed = "";
if (typeof seed === "number") this.x = seed;
else strSeed += `${seed}`;
for (let i = 0; i < strSeed.length + 64; ++i) {
this.x ^= strSeed.charCodeAt(i) | 0;
this.next();
}
if ((this.x | this.y | this.z | this.w) === 0) {
this.x = 1831565813;
for (let i = 0; i < 64; ++i) this.next();
}
}
get name() {
return "xor128";
}
next() {
const t = this.x ^ this.x << 11;
this.x = this.y;
this.y = this.z;
this.z = this.w;
this.w = this.w ^ (this.w >>> 19 ^ t ^ t >>> 8);
return (this.w >>> 0) / 4294967296;
}
clone() {
const clone = new XOR128RNG(this._seed);
clone.x = this.x;
clone.y = this.y;
clone.z = this.z;
clone.w = this.w;
return clone;
}
};
//#endregion
//#region src/validation.ts
function numberValidator(num) {
return new NumberValidator(num);
}
var NumberValidator = class {
constructor(num) {
_defineProperty(this, "n", void 0);
_defineProperty(this, "isInt", () => {
if (Number.isInteger(this.n)) return this;
throw new Error(`Expected number to be an integer, got ${this.n}`);
});
_defineProperty(this, "isPositive", () => {
if (this.n > 0) return this;
throw new Error(`Expected number to be positive, got ${this.n}`);
});
_defineProperty(this, "lessThan", (v) => {
if (this.n < v) return this;
throw new Error(`Expected number to be less than ${v}, got ${this.n}`);
});
_defineProperty(this, "lessThanOrEqual", (v) => {
if (this.n <= v) return this;
throw new Error(`Expected number to be less than or equal to ${v}, got ${this.n}`);
});
_defineProperty(this, "greaterThanOrEqual", (v) => {
if (this.n >= v) return this;
throw new Error(`Expected number to be greater than or equal to ${v}, got ${this.n}`);
});
_defineProperty(this, "greaterThan", (v) => {
if (this.n > v) return this;
throw new Error(`Expected number to be greater than ${v}, got ${this.n}`);
});
this.n = num;
}
};
//#endregion
//#region src/distributions/bates.ts
function bates(random, n = 1) {
numberValidator(n).isInt().isPositive();
const irwinHall = random.irwinHall(n);
return () => {
return irwinHall() / n;
};
}
//#endregion
//#region src/distributions/bernoulli.ts
function bernoulli(random, p = .5) {
numberValidator(p).greaterThanOrEqual(0).lessThanOrEqual(1);
return () => {
return Math.min(1, Math.floor(random.next() + p));
};
}
//#endregion
//#region src/distributions/binomial.ts
function binomial(random, n = 1, p = .5) {
numberValidator(n).isInt().isPositive();
numberValidator(p).greaterThanOrEqual(0).lessThan(1);
return () => {
let i = 0;
let x = 0;
while (i++ < n) if (random.next() < p) x++;
return x;
};
}
//#endregion
//#region src/distributions/exponential.ts
function exponential(random, lambda = 1) {
numberValidator(lambda).isPositive();
return () => {
return -Math.log(1 - random.next()) / lambda;
};
}
//#endregion
//#region src/distributions/geometric.ts
function geometric(random, p = .5) {
numberValidator(p).greaterThan(0).lessThan(1);
const invLogP = 1 / Math.log(1 - p);
return () => {
return Math.floor(1 + Math.log(random.next()) * invLogP);
};
}
//#endregion
//#region src/distributions/irwin-hall.ts
function irwinHall(random, n = 1) {
numberValidator(n).isInt().greaterThanOrEqual(0);
return () => {
let sum = 0;
for (let i = 0; i < n; ++i) sum += random.next();
return sum;
};
}
//#endregion
//#region src/distributions/log-normal.ts
function logNormal(random, mu = 0, sigma = 1) {
const normal = random.normal(mu, sigma);
return () => {
return Math.exp(normal());
};
}
//#endregion
//#region src/distributions/normal.ts
function normal(random, mu = 0, sigma = 1) {
return () => {
let x, y, r;
do {
x = random.next() * 2 - 1;
y = random.next() * 2 - 1;
r = x * x + y * y;
} while (!r || r > 1);
return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);
};
}
//#endregion
//#region src/distributions/pareto.ts
function pareto(random, alpha = 1) {
numberValidator(alpha).greaterThanOrEqual(0);
const invAlpha = 1 / alpha;
return () => {
return 1 / Math.pow(1 - random.next(), invAlpha);
};
}
//#endregion
//#region src/distributions/poisson.ts
const logFactorialTable = [
0,
0,
.6931471805599453,
1.791759469228055,
3.1780538303479458,
4.787491742782046,
6.579251212010101,
8.525161361065415,
10.60460290274525,
12.801827480081469
];
const logFactorial = (k) => {
return logFactorialTable[k];
};
const logSqrt2PI = .9189385332046727;
function poisson(random, lambda = 1) {
numberValidator(lambda).isPositive();
if (lambda < 10) {
const expMean = Math.exp(-lambda);
return () => {
let p = expMean;
let x = 0;
let u = random.next();
while (u > p) {
u = u - p;
p = lambda * p / ++x;
}
return x;
};
} else {
const smu = Math.sqrt(lambda);
const b = .931 + 2.53 * smu;
const a = -.059 + .02483 * b;
const invAlpha = 1.1239 + 1.1328 / (b - 3.4);
const vR = .9277 - 3.6224 / (b - 2);
return () => {
while (true) {
let u;
let v = random.next();
if (v <= .86 * vR) {
u = v / vR - .43;
return Math.floor((2 * a / (.5 - Math.abs(u)) + b) * u + lambda + .445);
}
if (v >= vR) u = random.next() - .5;
else {
u = v / vR - .93;
u = (u < 0 ? -.5 : .5) - u;
v = random.next() * vR;
}
const us = .5 - Math.abs(u);
if (us < .013 && v > us) continue;
const k = Math.floor((2 * a / us + b) * u + lambda + .445);
v = v * invAlpha / (a / (us * us) + b);
if (k >= 10) {
const t = (k + .5) * Math.log(lambda / k) - lambda - logSqrt2PI + k - (1 / 12 - (1 / 360 - 1 / (1260 * k * k)) / (k * k)) / k;
if (Math.log(v * smu) <= t) return k;
} else if (k >= 0) {
const f = logFactorial(k) ?? 0;
if (Math.log(v) <= k * Math.log(lambda) - lambda - f) return k;
}
}
};
}
}
//#endregion
//#region src/distributions/uniform.ts
function uniform(random, min, max) {
if (max === void 0) {
max = min === void 0 ? 1 : min;
min = 0;
}
min ?? (min = 0);
return () => {
return random.next() * (max - min) + min;
};
}
//#endregion
//#region src/distributions/uniform-boolean.ts
function uniformBoolean(random) {
return () => {
return random.next() >= .5;
};
}
//#endregion
//#region src/distributions/uniform-int.ts
function uniformInt(random, min, max) {
if (max === void 0) {
max = min === void 0 ? 1 : min;
min = 0;
}
min ?? (min = 0);
numberValidator(min).isInt();
numberValidator(max).isInt();
return () => {
return Math.floor(random.next() * (max - min + 1) + min);
};
}
//#endregion
//#region src/distributions/weibull.ts
function weibull(random, lambda, k) {
numberValidator(lambda).greaterThan(0);
numberValidator(k).greaterThan(0);
return () => {
const u = 1 - random.next();
return lambda * Math.pow(-Math.log(u), 1 / k);
};
}
//#endregion
//#region src/random.ts
/**
* Seedable random number generator supporting many common distributions.
*
* @name Random
* @class
*
* @param {RNG|function|string|number} [rng=Math.random] - Underlying random number generator or a seed for the default PRNG. Defaults to `Math.random`.
*/
var Random = class Random {
constructor(seedOrRNG = new MathRandomRNG()) {
_defineProperty(this, "_rng", void 0);
_defineProperty(this, "_cache", {});
this._rng = createRNG(seedOrRNG);
}
/**
* @member {RNG} rng - Underlying pseudo-random number generator.
*/
get rng() {
return this._rng;
}
/**
* Creates a new `Random` instance, optionally specifying parameters to
* set a new seed.
*/
clone(seedOrRNG = this.rng.clone()) {
return new Random(seedOrRNG);
}
/**
* Sets the underlying pseudorandom number generator.
*
* @example
* ```ts
* import random from 'random'
*
* random.use('example-seed')
* // or
* random.use(Math.random)
* ```
*/
use(seedOrRNG) {
this._rng = createRNG(seedOrRNG);
this._cache = {};
}
/**
* Convenience wrapper around `this.rng.next()`
*
* Returns a floating point number in [0, 1).
*
* @return {number}
*/
next() {
return this._rng.next();
}
/**
* Samples a uniform random floating point number, optionally specifying
* lower and upper bounds.
*
* Convenience wrapper around `random.uniform()`
*
* @param {number} [min=0] - Lower bound (float, inclusive)
* @param {number} [max=1] - Upper bound (float, exclusive)
*/
float(min, max) {
return this.uniform(min, max)();
}
/**
* Samples a uniform random integer, optionally specifying lower and upper
* bounds.
*
* Convenience wrapper around `random.uniformInt()`
*
* @param {number} [min=0] - Lower bound (integer, inclusive)
* @param {number} [max=1] - Upper bound (integer, inclusive)
*/
int(min, max) {
return this.uniformInt(min, max)();
}
/**
* Samples a uniform random integer, optionally specifying lower and upper
* bounds.
*
* Convenience wrapper around `random.uniformInt()`
*
* @alias `random.int`
*
* @param {number} [min=0] - Lower bound (integer, inclusive)
* @param {number} [max=1] - Upper bound (integer, inclusive)
*/
integer(min, max) {
return this.uniformInt(min, max)();
}
/**
* Samples a uniform random boolean value.
*
* Convenience wrapper around `random.uniformBoolean()`
*
* @alias `random.boolean`
*/
bool() {
return this.uniformBoolean()();
}
/**
* Samples a uniform random boolean value.
*
* Convenience wrapper around `random.uniformBoolean()`
*/
boolean() {
return this.uniformBoolean()();
}
/**
* Returns an item chosen uniformly at random from the given array.
* If weights are provided, returns an item based on weighted probabilities.
*
* Convenience wrapper around `random.uniformInt()` for uniform selection,
* or implements weighted selection using cumulative distribution.
*
* @param {Array<T>} [array] - Input array
* @param {Array<number>} [weights] - Optional weights for each item (must be same length as array)
*/
choice(array, weights) {
if (!Array.isArray(array)) throw new TypeError(`Random.choice expected input to be an array, got ${typeof array}`);
const length = array.length;
if (length === 0) return;
if (!weights) return array[this.uniformInt(0, length - 1)()];
if (!Array.isArray(weights)) throw new TypeError(`Random.choice expected weights to be an array, got ${typeof weights}`);
if (weights.length !== length) throw new Error(`Random.choice expected weights array length (${weights.length}) to match array length (${length})`);
for (const [i, weight] of weights.entries()) if (typeof weight !== "number" || weight < 0 || !Number.isFinite(weight)) throw new Error(`Random.choice expected all weights to be non-negative finite numbers, got ${weight} at index ${i}`);
const totalWeight = weights.reduce((sum, weight) => sum + weight, 0);
if (totalWeight === 0) throw new Error("Random.choice expected at least one positive weight, got all zeros");
const random = this.float(0, totalWeight);
let cumulativeWeight = 0;
for (let i = 0; i < length; i++) {
cumulativeWeight += weights[i];
if (random <= cumulativeWeight) return array[i];
}
return array[length - 1];
}
/**
* Returns a random subset of k items from the given array (without replacement).
*
* @param {Array<T>} [array] - Input array
*/
sample(array, k) {
if (!Array.isArray(array)) throw new TypeError(`Random.sample expected input to be an array, got ${typeof array}`);
if (k < 0 || k > array.length) throw new Error(`Random.sample: k must be between 0 and array.length (${array.length}), got ${k}`);
return sparseFisherYates(this.rng, array, k);
}
/**
* Generates a thunk which returns samples of size k from the given array.
*
* This is for convenience only; there is no gain in efficiency.
*
* @param {Array<T>} [array] - Input array
*/
sampler(array, k) {
if (!Array.isArray(array)) throw new TypeError(`Random.sampler expected input to be an array, got ${typeof array}`);
if (k < 0 || k > array.length) throw new Error(`Random.sampler: k must be between 0 and array.length (${array.length}), got ${k}`);
const gen = this.rng;
return () => {
return sparseFisherYates(gen, array, k);
};
}
/**
* Returns a shuffled copy of the given array.
*
* @param {Array<T>} [array] - Input array
*/
shuffle(array) {
if (!Array.isArray(array)) throw new TypeError(`Random.shuffle expected input to be an array, got ${typeof array}`);
const copy = [...array];
shuffleInPlace(this.rng, copy);
return copy;
}
/**
* Generates a thunk which returns shuffled copies of the given array.
*
* @param {Array<T>} [array] - Input array
*/
shuffler(array) {
if (!Array.isArray(array)) throw new TypeError(`Random.shuffler expected input to be an array, got ${typeof array}`);
const gen = this.rng;
const copy = [...array];
return () => {
shuffleInPlace(gen, copy);
return [...copy];
};
}
/**
* 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)
*/
uniform(min, max) {
return this._memoize("uniform", uniform, 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)
*/
uniformInt(min, max) {
return this._memoize("uniformInt", uniformInt, 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.
*/
uniformBoolean() {
return this._memoize("uniformBoolean", uniformBoolean);
}
/**
* Generates a [Normal distribution](https://en.wikipedia.org/wiki/Normal_distribution).
*
* @param {number} [mu=0] - Mean
* @param {number} [sigma=1] - Standard deviation
*/
normal(mu, sigma) {
return normal(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
*/
logNormal(mu, sigma) {
return logNormal(this, mu, sigma);
}
/**
* Generates a [Bernoulli distribution](https://en.wikipedia.org/wiki/Bernoulli_distribution).
*
* @param {number} [p=0.5] - Success probability of each trial.
*/
bernoulli(p) {
return bernoulli(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.
*/
binomial(n, p) {
return binomial(this, n, p);
}
/**
* Generates a [Geometric distribution](https://en.wikipedia.org/wiki/Geometric_distribution).
*
* @param {number} [p=0.5] - Success probability of each trial.
*/
geometric(p) {
return geometric(this, p);
}
/**
* Generates a [Poisson distribution](https://en.wikipedia.org/wiki/Poisson_distribution).
*
* @param {number} [lambda=1] - Mean (lambda > 0)
*/
poisson(lambda) {
return poisson(this, lambda);
}
/**
* Generates an [Exponential distribution](https://en.wikipedia.org/wiki/Exponential_distribution).
*
* @param {number} [lambda=1] - Inverse mean (lambda > 0)
*/
exponential(lambda) {
return exponential(this, lambda);
}
/**
* 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)
*/
irwinHall(n) {
return irwinHall(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)
*/
bates(n) {
return bates(this, n);
}
/**
* Generates a [Pareto distribution](https://en.wikipedia.org/wiki/Pareto_distribution).
*
* @param {number} [alpha=1] - Alpha
*/
pareto(alpha) {
return pareto(this, alpha);
}
/**
* Generates a [Weibull distribution](https://en.wikipedia.org/wiki/Weibull_distribution).
*
* @param {number} [lambda] - Lambda, the scale parameter
* @param {number} [k] - k, the shape parameter
*/
weibull(lambda, k) {
return weibull(this, lambda, k);
}
/**
* Memoizes distributions to ensure they're only created when necessary.
*
* Returns a thunk which that returns independent, identically distributed
* samples from the specified distribution.
*
* @internal
*
* @param {string} label - Name of distribution
* @param {function} getter - Function which generates a new distribution
* @param {...*} args - Distribution-specific arguments
*/
_memoize(label, getter, ...args) {
const key = `${args.join(";")}`;
let value = this._cache[label];
if (value === void 0 || value.key !== key) {
value = {
key,
distribution: getter(this, ...args)
};
this._cache[label] = value;
}
return value.distribution;
}
};
var random_default = new Random();
//#endregion
export { ARC4RNG, FunctionRNG, MathRandomRNG, RNG, Random, XOR128RNG, Xoshiro128StarStarRNG, createRNG, random_default as default, mixKey, shuffleInPlace, sparseFisherYates };
//# sourceMappingURL=index.js.map