Flocc

Agent-based modeling in JavaScript in the browser or on the server. [v0.4.8]

Utility Functions

Overview

The flocc.utils object contains a number of helpful utility functions.

Functions

utils.clamp(x, min, max)

Given a number x, clamps it to the range min → max.

utils.clamp(10, 5, 15);     // returns 10
utils.clamp(10, 50, 100);   // returns 50
utils.clamp(10, 1, 3);      // returns 3

utils.distance(pt1, pt2)

Returns the distance between pt1 and pt2. If the points are agent-like, then the function looks for .get('x').get('y'), and .get('z') on each. These values default to 0, so the correct distance is returned even if the agents only have a value at .get('x').

If the points are not agent-like, then the function looks for xy, and z values on the point objects themselves.

const agent = new Agent();
agent.set('x', 100);
agent.set('y', 100);

const point = {
    x: 50,
    y: 50
};

utils.distance(agent, point); // returns 70.71

utils.manhattanDistance(pt1, pt2)

Returns the Manhattan distance between pt1 and pt2 (see above).

const agent = new Agent();
agent.set('x', 0);
agent.set('y', 0);

const point = {
    x: 3,
    y: 4
};

utils.distance(agent, point);           // returns 5  = sqrt( 3^2 + 4^2 )
utils.manhattanDistance(agent, point);  // returns 7  = 3 + 4

utils.gaussian(mean, std)

Return a sampled value from a Gaussian/normal distribution with mean and standard deviation std. While it is possible for this function to return an extreme value, it will most often return a value within std of mean. This is useful for instantiating agents with diverse but statistically probable values.

utils.gaussian(100, 50);
// most likely to return a value between 50 and 150,
// but might return any value (though less and less likely
// farther from 100)

utils.lerp(a, b, t)

Linearly interpolate between the values a and b. If t is 0 or 1, the value returned will be a or b, respectively, otherwise the function will produce an interpolated value.

utils.max(arr)

Get the maximum of the values of the array arr. Expects that the array contains only numbers.

const arr = [1, 2, 3, 4, 5];
utils.max(arr); // returns 5

utils.mean(arr)

Get the arithmetic mean (average) of the values of the array arr. Expects that the array contains only numbers.

const arr = [1, 2, 3, 4, 5];
utils.mean(arr); // returns 3

utils.median(arr)

Get the median value from the array arr. Expects that the array contains only numbers. For an array with an even number of items, returns the mean of the two median values.

const arr1 = [5, 1, 2, 3, 4];
utils.median(arr1); // returns 3

const arr2 = [1, 2, 3, 4];
utils.median(arr2); // returns 2.5

utils.min(arr)

Get the minimum of the values of the array arr. Expects that the array contains only numbers.

const arr = [1, 2, 3, 4, 5];
utils.min(arr); // returns 1

utils.percentile(arr, n)

Calculates the n-th percentile value of an array of numbers, with n a number between 0 (0-th percentile, or minimum value) and 1 (100th percentile, or maximum value). If a percentile falls between discrete values of the array, it linearly interpolates between those values.

const arr = [1, 2, 3, 4, 5];
utils.percentile(arr, 0); // returns 1 (min)
utils.percentile(arr, 0.33); // returns 2.32
utils.percentile(arr, 0.5); // returns 3 (median)
utils.percentile(arr, 1); // returns 5 (max)

utils.random(min = 0, max = 1, float = false)

Returns a random integer between min and max (inclusive). If the third parameter, float, is set to true, returns a floating-point number between min and max.

utils.remap(x, sourceMin, sourceMax, targetMin, targetMax)

Maps the number x from the source range sourceMin → sourceMax onto the target range targetMin → targetMax.

utils.remap(70, 0, 100, 30, 50); // returns 44
utils.remap(0.62, 0, 1, 0, 100); // returns 62

utils.sample(arr) or utils.sample(arr, weights)

Returns a random value from the array arr. Optionally weights can be passed as the second parameter, an array of numbers equal in length to arr, which allows certain values to be selected more or less often. Given an array of three elements, if you want the first to be chosen about 10% of the time, the second about 15%, and the third about 75%, you can do this:

const arr = ["1st value", "2nd value", "3rd value"];
const randomValue = utils.sample(arr, [10, 15, 75]);

Although in the above example the weights add up to 100, this is just to make the code easier to read and reason about. The weights can add up to anything and it will still calculate the percentage based off of the sum of the weights — for example, weights [1, 1, 3] map to 20%, 20%, and 60%, respectively.

utils.shuffle(arr)

Get a shuffled/randomized version of the array arr. This does not change the ordering of arr itself, but creates and returns a copy.

const arr = [1, 2, 3, 4, 5];
utils.shuffle(arr); // might return [5, 1, 3, 2, 4]

utils.stdDev(arr)

Get the standard deviation of the values of the array arr. The standard deviation is a measure of how varied the values are — an array whose values are all the same number will have a standard deviation of 0, and an array whose values are widely disparate will have a higher standard deviation (the exact return value is relative to the values of the array).

const arr = [1, 2, 3, 4, 5];
utils.stdDev(arr); // returns 1.414

utils.sum(arr)

Get the sum of the values of the array arr.

const arr = [1, 2, 3, 4, 5];
utils.sum(arr); // returns 15

utils.zfill(str, width)

Like the Python str.zfill() function, this adds zeros to the left of str until it is width characters long. This is useful if you want to represent and order numbers within a set range, i.e. 0000, 0001, 0002, … 9999. Note that this function expects a string as input to be zfilled, not a number!

const n = 22;
const str = n.toString();
utils.zfill(str, 3); // returns "022"
utils.zfill(str, 5); // returns "00022"