# 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 `x``y`, 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"``````