Random
Sources
Section titled “Sources”The Module Random module has a notion of a RandomSource. This just a function that returns a random value, matching the in-build Math.random semantics. This means that Math.random can always be used as a RandomSource for any ixfx function.
For example:
import { Random } from 'https://unpkg.com/ixfx';// Create sourceconst source = Random.integerSource();
// Generate a valuesource(); // Returns a random valueWhy the two-step process? It can sometimes be handy to ‘bake in’ some settings for random number generation in one place. For example, if you were generating random numbers within a particular range, you don’t want to have to repeat the range settings all through your code.
const source = Random.integerSource(10); // Random number 0..9const source = Random.integerSource({ min: -5, max: 20 }) // Random numbert -5...19If you for sure don’t need to reuse the number generator, you can use the following syntax. Note the extra () after the function parameters. This immediately invokes the function.
Random.integerSource(10)(); // Yields a random valueWe also need the RandomSource approach because sometimes we need to pass the random generation to some other function. For example, if we want get a random element from an array:
// Create weighted random number generatorconst source = Random.gaussianSource();// The array of dataconst v = [`blue`, `red`, `orange`];
// Returns a random element from arrayRandom.randomElement(v, source);Since randomElement can take any RandomSource, we can customise how it picks a random element by giving it a different source.
Functions which create RandomSources include:
- Random.floatSource: Generate floating-point values (ie. with decimal points)
- Random.integerSource: Generate integer values values (ie. whole numbers)
- Random.bipolarSource: Generate -1..1 random values
Weighted
Section titled “Weighted”Normally random values are evenly distributed - where no part of the range is privileged. This is akin to classic noise or static, it’s pretty much completely random. This is like rolling a dice. Each roll there’s a completely even chance of getting any side.
But there are times where you want to skew this distribution. You still want randomness, but you want more values from the middle of a range, for example. This would be akin to adding a bit of weight to one side of the dice. It will still give different values, but there’s a higher chance of some numbers depending on the position of the weight.
Random.gaussianSource produces gaussian-distributed random values (ie. more likely to be values from the middle of the range)
// repl-padimport { Random } from 'https://unpkg.com/ixfx';const source = Random.gaussianSource();
source(); // Generate valueModulation.weightedSource is from the Modulation module, and can produce weighted random values using an easing curve
import { Random } from 'https://unpkg.com/ixfx';const source = Random.weightedSource({ easing: `bell` }); // Create the source using the 'bell' easing curvesource(); // Generate a random value- Random.weightedSource: Generate weighted floating-point values
- Random.weightedIntegerSource: Generate integer values values that are
- Random.gaussianSource: Generate Gaussian-distributed random values (ie. weighted toward the middle)
Seeded
Section titled “Seeded”‘Seeded’ random generators allow you to create a predictable series of random values given a seed value. The ‘seed’ value essentially becomes a key to a stream of random values which will be the same each time your code runs — assuming the seed value is the same.
This technique is often used in procedural map generation such as in Minecraft. A player’s world is generated randomly based on a single seed value. If it turns out that seed produces an interesting map, players can share that seed with others and in principle their copy of Minecraft will generate the same world when the seed is given as input.
It’s likewise used in generative art where the artist wants to include randomness, but still have authorial control of finding the ‘right’ randomness.
The simplest is using the ‘mulberr32’ algorithm with Random.mulberrySource:
import { Random } from 'https://unpkg.com/ixfx';
// Create the sourceconst source = Random.mulberrySource({ seed: 10 });
// Each call to source() generates a predicatable random numbersource();Alternatives algorithms
Time intervals
Section titled “Time intervals”There are a few functions for producing random millisecond values. They are mostly for making your code more literate, and since they return millisecond values, can be plugged directly into something like setTimeout.
secondsMs(5000); // Generate random milliseconds from 0..5000minutesMs(1); // Generate random milliseconds corresponding to 0...60_1000
setTimeout(() => { // Do something after a random wait of 1..5 minutes}, minutesMs({ min: 1, max: 5 }));See:
- Random.minutesMsSource, Random.secondsMsSource: returns a
RandomSourcewhich can then produce a value - Random.minutesMs, Random.secondsMs: produce a value directly
Random.calculateNonZero uses a RandomSource, but skips values which are zero:
calculateNonZero(Math.random); // something other than 0Random.chance returns one value or another with a given chance:
// 90% of the time will return 110, 10% of the time will return 100.chance(0.9, 100, 110);Tip: Instead of fixed values for chance or the two values, you can use functions to dynamically determine it.
Random.integerUniqueGen returns a generator over unique integer values.
for (const v of integerUniqueGen(10)) { // Outputs a random sequence of 0..9}Random.shortGuid produces a short ‘globally unique id’. Essentially, a random six-digit string that’s unlikely to collide with another. You can use Random.string to produce a random string of a given number of characters.
Importing
Section titled “Importing”// Whole moduleimport * as Random from "@ixfx/random.js"
// Single functionimport { bipolar } from "@ixfx/random.js"
// And within your HTML's <HEAD> </HEAD> block:<script type="importmap">{ "imports": { "@ixfx":"/ixfx/core.js", "@ixfx/": "/ixfx/" } }</script>// Whole moduleimport * as Random from "@ixfx/random"
// Single functionimport { bipolar } from "@ixfx/random"// Single module from the bundleimport * as Random from "https://unpkg.com/ixfx/dist/random.js"
// Single functionimport { bipolar } from "https://unpkg.com/ixfx/dist/random.js"