159 lines
4.2 KiB
TypeScript
159 lines
4.2 KiB
TypeScript
//pin implementations
|
|
const random = Math.random;
|
|
const ceil = Math.ceil;
|
|
const floor = Math.floor;
|
|
|
|
/**
|
|
* Rounds a number to one decimal places.
|
|
* @param num The number to round.
|
|
* @returns The input number rounded to one decimal places.
|
|
*/
|
|
export function roundTo1(num: number): number {
|
|
return Math.round((num + Number.EPSILON) * 10) / 10;
|
|
}
|
|
|
|
/**
|
|
* Rounds a number to two decimal places.
|
|
* @param num The number to round.
|
|
* @returns The input number rounded to two decimal places.
|
|
*/
|
|
export function roundTo2(num: number): number {
|
|
return Math.round((num + Number.EPSILON) * 100) / 100;
|
|
}
|
|
|
|
/**
|
|
* Calculates the mean (average) of an array of numbers.
|
|
* @param array An array of numbers.
|
|
* @returns The mean of the input array.
|
|
*/
|
|
export function mean(array: number[]): number {
|
|
try {
|
|
return (
|
|
array.reduce((previous, current) => (current += previous)) / array.length
|
|
);
|
|
} catch (e) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculates the standard deviation of an array of numbers.
|
|
* @param array An array of numbers.
|
|
* @returns The standard deviation of the input array.
|
|
*/
|
|
export function stdDev(array: number[]): number {
|
|
try {
|
|
const n = array.length;
|
|
const meanValue = mean(array);
|
|
return Math.sqrt(
|
|
array.map((x) => Math.pow(x - meanValue, 2)).reduce((a, b) => a + b) / n,
|
|
);
|
|
} catch (e) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculates the median of an array of numbers.
|
|
* https://www.w3resource.com/javascript-exercises/fundamental/javascript-fundamental-exercise-88.php
|
|
* @param arr An array of numbers.
|
|
* @returns The median of the input array.
|
|
*/
|
|
export function median(arr: number[]): number {
|
|
try {
|
|
const mid = Math.floor(arr.length / 2),
|
|
nums = [...arr].sort((a, b) => a - b);
|
|
return arr.length % 2 !== 0
|
|
? (nums[mid] as number)
|
|
: ((nums[mid - 1] as number) + (nums[mid] as number)) / 2;
|
|
} catch (e) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculates consistency by mapping COV from [0, +infinity) to [100, 0).
|
|
* The mapping function is a version of the sigmoid function tanh(x) that is closer to the identity function tanh(arctanh(x)) in [0, 1).
|
|
* @param cov The coefficient of variation of an array of numbers (standard deviation / mean).
|
|
* @returns Consistency
|
|
*/
|
|
export function kogasa(cov: number): number {
|
|
return (
|
|
100 * (1 - Math.tanh(cov + Math.pow(cov, 3) / 3 + Math.pow(cov, 5) / 5))
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Gets an integer between min and max, both are inclusive.
|
|
* @param min
|
|
* @param max
|
|
* @returns Random integer betwen min and max.
|
|
*/
|
|
export function randomIntFromRange(min: number, max: number): number {
|
|
const minNorm = ceil(min);
|
|
const maxNorm = floor(max);
|
|
return floor(random() * (maxNorm - minNorm + 1) + minNorm);
|
|
}
|
|
|
|
/**
|
|
* Maps a value from one range to another.
|
|
* @param value The value to map.
|
|
* @param inMin Input range minimum.
|
|
* @param inMax Input range maximum.
|
|
* @param outMin Output range minimum.
|
|
* @param outMax Output range maximum.
|
|
* @param clamp If true, the result is clamped to the output range. Default true.
|
|
* @returns The mapped value.
|
|
*/
|
|
export function mapRange(
|
|
value: number,
|
|
inMin: number,
|
|
inMax: number,
|
|
outMin: number,
|
|
outMax: number,
|
|
clamp = true,
|
|
): number {
|
|
if (inMin === inMax) {
|
|
return outMin;
|
|
}
|
|
|
|
const result =
|
|
((value - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
|
|
|
|
if (clamp) {
|
|
if (outMin < outMax) {
|
|
return Math.min(Math.max(result, outMin), outMax);
|
|
} else {
|
|
return Math.max(Math.min(result, outMin), outMax);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is a safe number. Safe numbers are finite and not NaN.
|
|
* @param value The value to check.
|
|
* @returns True if the value is a safe number, false otherwise.
|
|
*/
|
|
export function isSafeNumber(value: unknown): value is number {
|
|
if (typeof value === "number") {
|
|
return !isNaN(value) && isFinite(value);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Converts a number to a safe number or undefined. NaN, Infinity, and -Infinity are converted to undefined.
|
|
* @param value The value to convert.
|
|
* @returns The input number if it is safe, undefined otherwise.
|
|
*/
|
|
export function safeNumber(
|
|
value: number | undefined | null,
|
|
): number | undefined {
|
|
if (isSafeNumber(value)) {
|
|
return value;
|
|
}
|
|
return undefined;
|
|
}
|