Assorted common math functions & utilities for TypeScript/JavaScript applications
—
Additional mathematical utilities including prime numbers, permutations, safe operations, and specialized calculations.
Functions for working with prime numbers.
/**
* Returns generator of all prime numbers ≤ given x using Sieve of Eratosthenes
* @param x - Upper limit for prime generation
* @returns Generator yielding prime numbers in ascending order
*/
function primesUntil(x: number): Generator<number>;
/**
* Returns largest prime number ≤ given x
* @param x - Upper limit for prime search
* @returns Largest prime ≤ x, or -1 if x < 1
*/
function nearestPrime(x: number): number;Usage Examples:
import { primesUntil, nearestPrime } from "@thi.ng/math/prime";
// Generate all primes up to 30
const primes = [...primesUntil(30)]; // [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
// Find largest prime less than or equal to a number
const prime = nearestPrime(100); // 97
const noPrime = nearestPrime(1); // -1 (no primes ≤ 1)
// Use in algorithms requiring prime numbers
function generatePrimeTable(limit: number): number[] {
return [...primesUntil(limit)];
}Functions for combinatorial mathematics.
/**
* Computes factorial for n: n!
* @param n - Non-negative integer
* @returns n! (factorial of n)
* @throws Error if n < 0
*/
function factorial(n: number): number;
/**
* Computes n^k (permutations with repetition)
* @param n - Number of choices for each position
* @param k - Number of positions
* @returns Number of permutations with repetition
*/
function permutationsWithRep(n: number, k: number): number;
/**
* Computes n!/(n-k)! (permutations without repetition)
* @param n - Total number of items
* @param k - Number of items to choose
* @returns Number of permutations without repetition
*/
function permutationsWithoutRep(n: number, k: number): number;
/**
* Computes (n+k-1)!/(k!*(n-1)!) (combinations with repetition)
* @param n - Number of types of items
* @param k - Number of items to choose
* @returns Number of combinations with repetition
*/
function combinationsWithRep(n: number, k: number): number;
/**
* Computes n!/(k!*(n-k)!) (combinations without repetition)
* @param n - Total number of items
* @param k - Number of items to choose
* @returns Number of combinations without repetition (binomial coefficient)
*/
function combinationsWithoutRep(n: number, k: number): number;Usage Examples:
import {
factorial, permutationsWithRep, permutationsWithoutRep,
combinationsWithRep, combinationsWithoutRep
} from "@thi.ng/math/permutations";
// Basic factorial
const fact5 = factorial(5); // 120
// Password combinations: 4 digits, each 0-9
const passwords = permutationsWithRep(10, 4); // 10,000
// Arrange 5 people in 3 chairs (order matters)
const arrangements = permutationsWithoutRep(5, 3); // 60
// Choose 3 items from 4 types, repetition allowed
const withRep = combinationsWithRep(4, 3); // 20
// Choose 3 people from 5 (order doesn't matter)
const binomial = combinationsWithoutRep(5, 3); // 10 (C(5,3))Functions that handle edge cases and provide safe alternatives to standard operations.
/**
* Returns a divided by b, or zero if b = 0
* @param a - Dividend
* @param b - Divisor
* @returns a/b if b ≠ 0, otherwise 0
*/
function safeDiv(a: number, b: number): number;Usage Examples:
import { safeDiv } from "@thi.ng/math/safe-div";
// Safe division prevents NaN/Infinity results
const result1 = safeDiv(10, 2); // 5
const result2 = safeDiv(10, 0); // 0 (safe, not Infinity)
const result3 = safeDiv(0, 0); // 0 (safe, not NaN)
// Useful in algorithms where division by zero might occur
function average(values: number[]): number {
const sum = values.reduce((a, b) => a + b, 0);
return safeDiv(sum, values.length);
}
const avg1 = average([1, 2, 3, 4]); // 2.5
const avg2 = average([]); // 0 (safe handling of empty array)Functions for absolute value calculations and comparisons.
/**
* Returns the absolute difference between a and b
* @param a - First value
* @param b - Second value
* @returns |a - b|
*/
function absDiff(a: number, b: number): number;
/**
* Similar to Math.sign(), but uses eps to determine the zero value
* @param x - Input value
* @param eps - Epsilon threshold for zero determination
* @returns -1, 0, or 1 based on sign of x
*/
function sign(x: number, eps?: number): number;
/**
* Raises x to k power and multiplies it with the sign of x
* @param x - Base value
* @param k - Exponent
* @param eps - Epsilon threshold for zero determination
* @returns sign(x) * |x|^k
*/
function signedPow(x: number, k: number, eps?: number): number;Usage Examples:
import { absDiff, sign, signedPow } from "@thi.ng/math/abs";
// Absolute difference
const diff = absDiff(-5, 3); // 8
const same = absDiff(7, 7); // 0
// Epsilon-aware sign function
const s1 = sign(0.0000001, 1e-6); // 1 (above epsilon)
const s2 = sign(0.0000001, 1e-5); // 0 (within epsilon of zero)
const s3 = sign(-2.5); // -1
// Signed power preserves sign
const sp1 = signedPow(-2, 3); // -8 (negative cube root of 8)
const sp2 = signedPow(3, 2); // 9 (positive)
const sp3 = signedPow(-4, 0.5); // -2 (negative square root)Functions for working with ratios and fractions.
/**
* Simplifies a ratio by finding the GCD and reducing both terms
* @param num - Numerator
* @param denom - Denominator
* @returns Tuple [simplified_num, simplified_denom]
*/
function simplifyRatio(num: number, denom: number): [number, number];Usage Examples:
import { simplifyRatio } from "@thi.ng/math/ratio";
// Simplify fractions/ratios
const simple1 = simplifyRatio(8, 12); // [2, 3] (8/12 = 2/3)
const simple2 = simplifyRatio(15, 25); // [3, 5] (15/25 = 3/5)
const simple3 = simplifyRatio(7, 13); // [7, 13] (already simplified)
// Use in aspect ratio calculations
function simplifyAspectRatio(width: number, height: number): string {
const [w, h] = simplifyRatio(width, height);
return `${w}:${h}`;
}
const aspect1 = simplifyAspectRatio(1920, 1080); // "16:9"
const aspect2 = simplifyAspectRatio(1024, 768); // "4:3"Functions for detecting and classifying line crossings.
/**
* Returns true if line A rises up over B
* @param a1 - Start point of line A
* @param a2 - End point of line A
* @param b1 - Start point of line B
* @param b2 - End point of line B
* @returns True if A crosses over B
*/
function isCrossOver(a1: number, a2: number, b1: number, b2: number): boolean;
/**
* Returns true if line A crosses under B
* @param a1 - Start point of line A
* @param a2 - End point of line A
* @param b1 - Start point of line B
* @param b2 - End point of line B
* @returns True if A crosses under B
*/
function isCrossUnder(a1: number, a2: number, b1: number, b2: number): boolean;
/**
* Returns Crossing classifier indicating the relationship of line A to line B
* @param a1 - Start point of line A
* @param a2 - End point of line A
* @param b1 - Start point of line B
* @param b2 - End point of line B
* @param eps - Epsilon for equality testing
* @returns Crossing classification
*/
function classifyCrossing(
a1: number, a2: number, b1: number, b2: number, eps?: number
): Crossing;Usage Examples:
import { isCrossOver, isCrossUnder, classifyCrossing } from "@thi.ng/math/crossing";
// Detect line crossings (useful for technical analysis, signal processing)
const crossOver = isCrossOver(1, 3, 2, 1); // true (A goes from below to above B)
const crossUnder = isCrossUnder(3, 1, 2, 4); // true (A goes from above to below B)
// Classify crossing type
const classification = classifyCrossing(1, 3, 2, 2); // "over" (A crosses over flat B)
const equalLines = classifyCrossing(1, 2, 1, 2); // "equal" (identical lines)
// Use in trading algorithms
function detectGoldenCross(shortMA: number[], longMA: number[]): boolean {
const lastShort = shortMA[shortMA.length - 1];
const prevShort = shortMA[shortMA.length - 2];
const lastLong = longMA[longMA.length - 1];
const prevLong = longMA[longMA.length - 2];
return isCrossOver(prevShort, lastShort, prevLong, lastLong);
}Advanced minimization functions for optimization problems.
/**
* Recursively finds the parameter value that minimizes error between function output and target value
* @param fn - Function to minimize error for
* @param error - Error calculation function
* @param q - Target value
* @param res - Resolution (optional)
* @param iter - Maximum iterations (optional)
* @param start - Search start value (optional)
* @param end - Search end value (optional)
* @param eps - Convergence epsilon (optional)
* @returns Parameter value that minimizes error
*/
function minError<T>(
fn: (x: number) => T,
error: (p: T, q: T) => number,
q: T,
res?: number,
iter?: number,
start?: number,
end?: number,
eps?: number
): number;Usage Examples:
import { minError } from "@thi.ng/math/min-error";
// Find parameter that makes function output closest to target
const fn = (x: number) => x * x; // f(x) = x²
const errorFn = (a: number, b: number) => Math.abs(a - b);
const target = 25; // Want f(x) = 25
const bestX = minError(fn, errorFn, target); // Should find x ≈ 5
// Complex optimization example
const complexFn = (t: number) => Math.sin(t) * Math.cos(t * 2);
const targetValue = 0.5;
const optimalT = minError(complexFn, errorFn, targetValue, 0.01, 100, 0, Math.PI);Install with Tessl CLI
npx tessl i tessl/npm-thi-ng--math