UNPKG

3.45 kBJavaScriptView Raw
1import { factory } from '../../utils/factory'
2import { isMatrix } from '../../utils/is'
3import { createRng } from './util/seededRNG'
4import { randomMatrix } from './util/randomMatrix'
5
6const name = 'random'
7const dependencies = ['typed', 'config', '?on']
8
9export const createRandom = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, on }) => {
10 // seeded pseudo random number generator
11 let rng = createRng(config.randomSeed)
12
13 if (on) {
14 on('config', function (curr, prev) {
15 if (curr.randomSeed !== prev.randomSeed) {
16 rng = createRng(curr.randomSeed)
17 }
18 })
19 }
20
21 /**
22 * Return a random number larger or equal to `min` and smaller than `max`
23 * using a uniform distribution.
24 *
25 * Syntax:
26 *
27 * math.random() // generate a random number between 0 and 1
28 * math.random(max) // generate a random number between 0 and max
29 * math.random(min, max) // generate a random number between min and max
30 * math.random(size) // generate a matrix with random numbers between 0 and 1
31 * math.random(size, max) // generate a matrix with random numbers between 0 and max
32 * math.random(size, min, max) // generate a matrix with random numbers between min and max
33 *
34 * Examples:
35 *
36 * math.random() // returns a random number between 0 and 1
37 * math.random(100) // returns a random number between 0 and 100
38 * math.random(30, 40) // returns a random number between 30 and 40
39 * math.random([2, 3]) // returns a 2x3 matrix with random numbers between 0 and 1
40 *
41 * See also:
42 *
43 * randomInt, pickRandom
44 *
45 * @param {Array | Matrix} [size] If provided, an array or matrix with given
46 * size and filled with random values is returned
47 * @param {number} [min] Minimum boundary for the random value, included
48 * @param {number} [max] Maximum boundary for the random value, excluded
49 * @return {number | Array | Matrix} A random number
50 */
51 return typed(name, {
52 '': () => _random(0, 1),
53 number: (max) => _random(0, max),
54 'number, number': (min, max) => _random(min, max),
55 'Array | Matrix': (size) => _randomMatrix(size, 0, 1),
56 'Array | Matrix, number': (size, max) => _randomMatrix(size, 0, max),
57 'Array | Matrix, number, number': (size, min, max) => _randomMatrix(size, min, max)
58 })
59
60 function _randomMatrix (size, min, max) {
61 const res = randomMatrix(size.valueOf(), () => _random(min, max))
62 return isMatrix(size) ? size.create(res) : res
63 }
64
65 function _random (min, max) {
66 return min + rng() * (max - min)
67 }
68})
69
70// number only implementation of random, no matrix support
71// TODO: there is quite some duplicate code in both createRandom and createRandomNumber, can we improve that?
72export const createRandomNumber = /* #__PURE__ */ factory(name, ['typed', 'config', '?on'], ({ typed, config, on, matrix }) => {
73 // seeded pseudo random number generator1
74 let rng = createRng(config.randomSeed)
75
76 if (on) {
77 on('config', function (curr, prev) {
78 if (curr.randomSeed !== prev.randomSeed) {
79 rng = createRng(curr.randomSeed)
80 }
81 })
82 }
83
84 return typed(name, {
85 '': () => _random(0, 1),
86 number: (max) => _random(0, max),
87 'number, number': (min, max) => _random(min, max)
88 })
89
90 function _random (min, max) {
91 return min + rng() * (max - min)
92 }
93})