-
Notifications
You must be signed in to change notification settings - Fork 2
API documentation
Make sure you've read the README for how to access MathicallJS functions
Debugging Standard functions Integer functions Vectors Matrices Complex numbers Arrays
By default, functions in MathicallJS do not validate their input. To perform these checks, some functions can be called through the sublibrary's debug property - e.g. vector.rect.debug.dot([1, 2], [3, 4]). This feature is currently incomplete.
Several common maths functions are available in the standard sublibrary.
- Undefined behaviour may result from non-Number inputs.
lerp(x, y, r)
(Number) A value linearly interpolated between x and y by ratio r.
(Number) x | The start value.
(Number) y | The end value.
(Number) r | The ratio by which to interpolate.
lerp(7, 9, 0.2); //7.4mod(x, m)
(Number) The difference between x and the largest multiple of m that is smaller than x.
(Number) x | A number.
(Number) m | The modulus.
mod(33, 7); //5fract(x)
(Number) The fractional part of x.
(Number) x | A number.
fract(3.041); //0.041
fract(-7.3); //-0.3deg(radians)
(Number) The input value radians converted to degrees.
(Number) radians | An angle in radians.
deg(3.141592); //180rad(degrees)
(Number) The input value degrees converted to radians.
(Number) degrees | An angle in degrees.
rad(180); //3.141592...linmap(x, domain, range)
(Number) x mapped linearly from the interval domain to the interval range
(Number) x | A value to be mapped
(Array/TypedArray) domain | The input range
(Array/TypedArray) range | The mapped range
linmap(0.5, [0, 1], [10, 20]); //15
linmap(-3, [-1, 5], [0, 1]); //-0.3333333...The integer sublibrary provides integer maths, such as combinatorics and common factors.
- Behaviour only defined for integer inputs of type Number.
- Output values larger than
Number.MAX_SAFE_INTEGERare approximate. - Results exceeding
Number.MAX_VALUEreturnNumber.MAX_VALUE.
- Factorial
- n choose r
- n permute r
- Greatest common divisor
- Lowest common multiple
- Modular exponentiation
factorial(n)
(Number) n factorial, often denoted n!.
(Number) n | A non-negative integer.
factorial(4); //24Negative input will return undefined.
Values of n greater than 170 will overflow Javascript's Number type.
computeFactorials(n)
(Float64Array) An array of all factorials up to n!.
(Number) n | A non-negative integer.
factorial(4); //24Negative input will return an empty array.
Values of n greater than 170 will overflow Javascript's Number type.
choose(n, r)
(Number) The possible number of unordered combinations of r items from a group of n items.
(Number) n | The total number of items.
(Number) r | The selected number of items.
choose(10, 2); //45Returns 0 if n < 0, r < 0 or r > n.
precomputeBinomials(n)
This internally pre-computes all choose(n, r) up to the provided n, which is beneficial if a program calls choose(n, r) frequently. By default, values are precomputed up to n = 30.
(Number) n | The maximum value of n to be precomputed.
precomputeBinomials(100);permute(n, r)
(Number) The possible number of ordered permutations of r items from a group of n items.
(Number) n | The total number of items.
(Number) r | The selected number of items.
permute(12, 4); //11880gcd(a, b)
(Number) The greatest common divisor of a and b.
(Number) a, b | An integer.
gcd(63, 14); //7gcd(0, 0) returns 0.
Otherwise, the returned value is always positive, even for negative input.
lcm(a, b)
(Number) The lowest common multiple of a and b.
(Number) a, b | An integer.
lcm(24, 10); //120The returned value is always non-negative.
mpow(base, exp, m)
(Number) The remainder when base to the power of exp is divided by m.
(Number) base | The base.
(Number) exp | The exponent.
(Number) m | The modulus.
mpow(168, 51, 17); //9The vector sublibrary provides vector operations. Vectors are represented as an Array or TypedArray, with n elements for an n-dimensional vector. For example, [13, -12, 17.5] is a 3D vector. vector is split into sublibraries for rectangular and polar form, with more support for the former.
- For functions which return a vector, you can use the optional
targetparameter to provide an existing array into which the output will be stored. If no target is provided, a new Float64Array is returned. - Most functions have variants optimised for common dimensions (2D, 3D & 4D).
- Angles are in radians.
Working with rectangular form can be done from the vector.rect sublibrary. Since rectangular form is far more common than polar, all functions in vector.rect are also accessible directly from vector.
- Dot product
- Cross product
- Scalar multiplication
- Addition
- Subtraction
- Magnitude
- Normalizing
- Contained angle
- Fractional part
- Convert to polar
dot(vec1, vec2)
(Number) The dot product of vec1 and vec2.
(Array/TypedArray) vec1, vec2 | A vector.
dot2(vec1, vec2) | Assumes vec1 and vec2 are 2D.
dot3(vec1, vec2) | Assumes vec1 and vec2 are 3D.
dot4(vec1, vec2) | Assumes vec1 and vec2 are 4D.
dot([3, 4], [1.5, 2.5]); //14.5cross3(vec1, vec2, ?target)
(Float64Array) The cross product of vec1 and vec2.
(Array/TypedArray) vec1, vec2 | A 3D vector.
cross3([12.5, 6, -4], [-1, -1.5, 3]); //[12, -33.5, -12.75]scale(vec, k, ?target)
(Float64Array) vec scaled by factor k.
(Array/TypedArray) vec | A vector.
(Number) k | The scale factor.
scale2(vec, k, ?target) | Assumes vec is 2D.
scale3(vec, k, ?target) | Assumes vec is 3D.
scale4(vec, k, ?target) | Assumes vec is 4D.
scale([6.4, 10, 5, -4], 2.5); //[16, 25, 12.5, -10]add(vec1, vec2, ?target)
(Float64Array) The sum of vec1 and vec2.
(Array/TypedArray) vec1, vec2 | A vector.
add2(vec1, vec2, ?target) | Assumes vec1 and vec2 are 2D.
add3(vec1, vec2, ?target) | Assumes vec1 and vec2 are 3D.
add4(vec1, vec2, ?target) | Assumes vec1 and vec2 are 4D.
add([1, 2, 3, 4], [-2, 1, 4, 5.5]); //[-1, 3, 7, 9.5]sub(vec1, vec2, ?target)
(Float64Array) vec1 minus vec2.
(Array/TypedArray) vec1, vec2 | A vector.
sub2(vec1, vec2, ?target) | Assumes vec1 and vec2 are 2D.
sub3(vec1, vec2, ?target) | Assumes vec1 and vec2 are 3D.
sub4(vec1, vec2, ?target) | Assumes vec1 and vec2 are 4D.
let result = Mathicall.vec.sub([2, 3], [1, 7.5]);
//[1, -4.5]mag(vec)
(Number) The magnitude of vec.
(Array/TypedArray) vec | A vector.
mag2(vec) | Assumes vec is 2D.
mag3(vec) | Assumes vec is 3D.
mag4(vec) | Assumes vec is 4D.
mag([3, 4]); //5.normalize(vec, ?target)
(Float64Array) A unit vector in the direction of vec.
(Array/TypedArray) vec | A vector.
normalize2(vec, ?target) | Assumes vec is 2D.
normalize3(vec, ?target) | Assumes vec is 3D.
normalize4(vec, ?target) | Assumes vec is 4D.
normalize([3, 4]); //[0.6, 0.8]angle(vec1, vec2)
(Number) The angle between vec1 and vec2, in radians.
(Array/TypedArray) vec1, vec2 | A vector.
angle2(vec) | Assumes vec1 and vec2 are 2D.
angle3(vec) | Assumes vec1 and vec2 are 3D.
angle4(vec) | Assumes vec1 and vec2 are 4D.
angle([0, 1], [1, 0]); //1.5707...fract(vec, ?target)
(Float64Array) The fractional part of each component in vec.
(Array/TypedArray) vec | A vector.
fract2(vec, ?target) | Assumes vec is 2D.
fract3(vec, ?target) | Assumes vec is 3D.
fract4(vec, ?target) | Assumes vec is 4D.
fract([10.70, 9, -38.012, 73.99]); //[0.70, 0, -0.012, 0.99]Currently, only 2D vectors can be converted to polar form.
toPolar2(vec, ?target)
(Float64Array) vec represented in polar form.
(Array/TypedArray) vec | A 2D vector in rectangular form.
toPolar2([3, 4]); //[5, 0.927295218]Working with polar form should be done from the vector.polar sublibrary. This currently supports the 2D functions dot2, scale2, normalize2 and rect2, as well as the function mag which will work with any dimension. Full documentation will be provided in future.
dot2(vec1, vec2)
(Number) The dot product of vec1 and vec2.
(Array/TypedArray) vec1, vec2 | A polar vector.
dot2([1, 0], [2, Math.PI / 2]); //1.41...mag(vec)
(Number) The magnitude of vec.
(Array/TypedArray) vec | A polar vector.
mag([3, Math.PI]); //3scale2(vec, k, ?target)
(Float64Array) vec scaled by factor k.
(Array/TypedArray) vec | A polar vector.
(Number) k | The scale factor.
scale2([4, Math.PI], 2.5); //[10, Math.PI]
scale2([4, Math.PI], -2.5); //[10, 0].normalize2(vec, ?target)
(Float64Array) A unit vector in the direction of vec.
(Array/TypedArray) vec | A polar vector.
normalize2([0.1, 0.57]); //[1, 1.57]
normalize2([0, 1.57]); //undefinedIf the input vector has a magnitude of 0, the output is undefined.
toRect2(vec, ?target)
(Float64Array) vec represented in rectangular form.
(Array/TypedArray) vec | A 2D vector in polar form.
toRect2([20, Math.PI / 6]); //[17.32, 10]The matrix sublibrary provides matrix operations. Matrices are represented as a single array in row-major form, with the additional properties .nrows and .ncols.
- Flatten 2D matrix
- Constant matrix
- Zeros matrix
- Identity matrix
- Matrix multiplication
- Scalar multiplication
- Vector premultiplication
- Vector postmultiplication
- Determinant
- Inverse
- Transposing
- Size
- Equality
To create a matrix from a nested array literal, use flatten. Each sub-array is interpreted as a row.
let myMatrix = matrix.flatten([ [1, -2, 3], [4, 5, 6], [10, 10, 10], [6, 3.2, 5] ]);constant(nrows, ncols, value)
(Array) A matrix of size nrows x ncols in which all entries are value.
(Number) nrows | The number of rows.
(Number) ncols | The number of columns.
(Number) value | The value of each entry.
let mat = matrix.constant(2, 3, 7.2);
// [7.2, 7.2, 7.2, 7.2, 7.2, 7.2]
mat.nrows; //2
mat.ncols; //3zeros(nrows, ncols)
(Array) A matrix of size nrows x ncols containing all 0s.
(Number) nrows | The number of rows.
(Number) ncols | The number of columns.
zeros(2, 3); //[0, 0, 0, 0, 0, 0]identity(n)
(Array) A square identity matrix of size nxn.
(Number) n | The number of rows and columns in the matrix.
identity(4);
/* [ 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 ] */mult(mat1, mat2)
(Array) The matrix product of mat1 and mat2.
(Array) mat1 | A matrix.
(Array) mat2 | A matrix.
const firstMat = matrix.flatten([ [1, -5.5, 4], [50.86, 6, -1] ]);
const secondMat = matrix.flatten([ [0, 4], [3.14, -4], [12, 12] ]);
let product = matrix.mult(firstMat, secondMat);
/* [ -17.27, 26,
18.84, 179.44 ] */If the input matrices are not conformable, an error may be thrown. To be conformable, the number of columns in mat1 and number of rows in mat2 must be equal.
scale(mat, k, ?target)
(Array/TypedArray) mat scaled by a factor of k.
(Array/TypedArray) mat | A matrix.
(Number) k | The scale factor.
let inMat = [ 4, 5, 1, -1]
inMat.nrows = 2;
inMat.ncols = 2;
let scaledMat = matrix.scale(inMat, 3);
/* [ 12, 15,
3, -3 ] */.vmult(vec, mat)
(Float64Array) The vector obtained when mat is pre-multiplied by vec.
(Array) vec | A vector.
(Array) mat | A matrix
vmult2x2 | Assumes mat is 2x2 and vec is 2D.
const vec = [1, 2, -3];
const mat = matrix.flatten([ [0, 1], [-1, 5], [12, 10] ]);
let result = mat.vmult(vec, mat);
// [-38, -19]The input vector is treated as a row-vector. The number of components in vec and the number of rows in mat must be equal, else an error may be thrown.
.multv(mat, vec)
(Float64Array) The vector result of mat post-multiplied by vec.
(Array) vec | A vector.
(Array) mat | A matrix.
const mat = matrix.flatten([ [8, 7, 6], [-1, 2, 1] ]);
const vec = [1, 2, -3];
let product = mat.multv(mat, vec);
// [4, 0]The input vector is treated as a column-vector. The number of columns in mat and the number of components in vec must be equal, else an error may be thrown.
Currently, only the determinant of a 2x2 matrix can be computed.
det2x2(mat)
(Array) The determinant of mat.
(Array) mat | A 2x2 matrix.
det2x2([1, 2, 3, -4]); //-10Currently, only the inverse of a 2x2 matrix can be computed.
inverse2x2(mat, ?target)
(Array) The inverse of mat.
(Array) mat | A 2x2 matrix.
inverse2x2([1, 2, 3, -4]); //[0.4, 0.2, 0.3, -0.1]If the input matrix is singular, the function returns undefined.
Transposing is available for 2x2, 3x3 and 4x4 matrices.
transpose2x2(mat, ?target) transpose3x3(mat, ?target) transpose4x4(mat, ?target)
(Array) The transposed matrix of mat, equivalent to swapping rows and columns.
(Array) mat | A matrix.
let mat = matrix.flatten([ [4, 5, 1], [1, -1, 4], [0, 0, 5] ]);
transpose3x3(mat);
/* [ 4, 1, 0,
5, -1, 0,
1, 4, 5 ] */size(mat)
(Array) An array [m, n], where m is the number of rows in mat and n the number of columns.
(Array) mat | A matrix.
let mat = matrix.flatten([ [4, 5], [1, -1], [0, 0] ]);
matrix.size(mat); // [3, 2]isEqual(mat1, mat2)
(Boolean) true if the given matrices are equal, and false otherwise.
(Array) mat1, mat2 | A matrix.
const mat1 = matrix.flatten([ [4, 5], [1, -1], [0, 0] ]);
const mat2 = matrix.flatten([ [4, 5], [1, -1], [0, 0] ]);
matrix.isEqual(mat1, mat2); //trueOperations on complex numbers are available in the complex sublibrary. A complex number is represented as an array with two elements; for example, [3, 4]. By default, functions accessed through complex interpret these numbers in rectangular form; polar functions can be accessed through complex.polar.
- For functions which return a complex number, you can use the optional
targetparameter to provide an existing array into which the output will be stored. If no target is provided, a new Float64Array is returned. - Angles are in radians.
The following functions are available for both rectangular and polar complex numbers.
conj(z, ?target)
Returns the complex conjugate of z.
real(z)
Returns the real part of z.
imag(z)
Returns the imaginary part of z.
arg(z)
Returns the argument of z: the angle it makes with the real axis, from 0 to 2 * Math.PI.
abs(z)
Returns the absolute value (magnitude) of z.
mult(z1, z2, ?target)
Returns the product of z1 and z2.
div(z1, z2, ?target)
Returns z1 divided by z2. Will not work if z2 is [0, 0].
scale(z, k, ?target)
Returns z scaled by factor k.
inverse(z, ?target)
Returns the multiplicative inverse of z.
add(z1, z2, ?target)
Returns the sum of z1 and z2.
sub(z1, z2, ?target)
Returns z1 minus z2.
toPolar(z, ?target)
Returns z represented in polar form.
pow(z, n, ?target)
Returns z raised to the power n, where n is any real number.
toRect(z, ?target)
Returns z represented in rectangular form.
The array sublibrary provides array operations. Several of these are inbuilt into javascript, but are reimplimented here to take advantage of sorted data.
indexOf(arr, value, ?sorted)
(Number) The index of value in the array arr, or -1 if value is not contained.
(Array/TypedArray) arr | The array to be searched.
(Number) value | The value to be found.
let index1 = array.indexOf([1, 2, 3, 4], 3); //2
let index2 = array.indexOf([1, 2, 3, 4], 5); //-1unique(arr, ?sorted)
(Array) An array containing each unique value from arr.
(Array/TypedArray) arr | The array to be unique-ified.
array.unique([1, 1, 5, 6, -1, 5, 0.3, 0.31, 9, -1]) //[1, 5, 6, -1, 0.3, 0.31, 9]min(arr, ?sorted)
(Number) The lowest value in arr.
(Array/TypedArray) arr | The array to be searched.
let lowest = array.min([8, 7, 6, 1, -5, 4.2]); //-5The corresponding imin function will return the index of the smallest element.
max(arr, ?sorted)
(Number) The highest value in arr.
(Array/TypedArray) arr | The array to be searched.
let highest = array.max([8, 7, 6, 1, -5, 4.2]); //8The corresponding imax function will return the index of the largest element.
sum(arr)
(Number) The sum of the elements in arr.
(Array/TypedArray) arr | The array to be summed.
let total = array.sum([8, 7, 6, 1, -5, 4.2]); //21.2prod(arr)
(Number) The product of the elements in arr.
(Array/TypedArray) arr | The array whose elements are to be multiplied.
let product = array.prod([3, 4, 5]); //60count(arr, value, ?sorted)
(Number) The number of occurrences of value in arr.
array.count([1, 2, 3, 3, 4], 3); //2isEqual(arr1, arr2)
Returns true if the arrays have the same length and corresponding elements are equal, and false otherwise.
array.isEqual([1, 2, 3, 4], [1, 2, 3, 4]); //true
array.isEqual([4, 3, 2, 1], [1, 2, 3, 4]); //falseCurrently radix sort is only implemented for Uint8Arrays.
sortUint8(arr, ?target)
random contains functions for generating seeded and unseeded pseudorandom numbers, as well as Perlin noise.
The following functions use Math.random() to generate values according to the given distribution. If count is defined they return an array containing the appropriate number of random values; if count is undefined, they return a single value.
unif(?a, ?b, ?count) //Uniformly distributed real number(s) between a and b int(a, b, ?count) //Uniformly distributed integer(s) between a and b norm(?mean, ?sd, ?count) //Normally distributed number(s) centred at 'mean' with standard deviation 'sd'. exp(?lambda, ?count) //Exponentially distributed number(s) with mean 'lambda'
A seeded sequence can be created using one of the following initialisers, corresponding with their unseeded counterparts.
If provided, seed should be an integer from 1 to 214748364.
Unif(?a, ?b, ?seed) Int(a, b, ?seed) Norm(?mean, ?sd, ?seed) Exp(?lambda, ?seed)
Below is an example using the Unif generator:
const rand = Mathicall.random.Unif(10, 20, 10456);
rand(); // 13.456742...
rand(3); //[14.563478, 19.95867, 11.0133]
rand.seed(); //10456 [current seed]
rand.seed(10456); //Reset sequence with current seed
rand(); //13.456742...
rand.seed(1345) //Set new seed
rand() //17.59743 [different sequence]
rand.range(); //[10, 20]
rand.range(0, 3) //Change range
rand() //1.1992...A Perlin noise generator can be created similarly to other seeded random generators.
Perlin2D(?range, ?seed)
Here, range is an array defining the smallest and largest output values. It defaults to [0, 1]. Below is an example of generating a single value at a point (x, y):
const perlin = Mathicall.random.Perlin2D([0, 256]); //Seeded automatically
perlin(3.2, 0.1); //25.829
perlin(3.25, 0.15) //27.01 [nearby positions have similar values]You can also generate layered 'fractal' perlin noise as well as a grid of single-layer noise, using the following properties of perlin.
.fbm(x, y, octaves, lacunarity, persistence)
(Number) The sum of several octaves of noise at point (x, y).
(Number) x | The x-coordinate.
(Number) y | The y-coordinate.
(Number) (optional) octaves | The number of noise layers, known as octaves. Defaults to 1.
(Number) (optional) lacunarity | The increase in noise frequency with each new layer. Defaults to 1.5.
(Number) (optional) persistence | The strength of each new layer relative to the last. Typically smaller than 1. Defaults to 0.7.
let noiseValue = perlin.fbm(3.1, 29.67, 3, 1.5, 0.7); //Example return value: 0.151502.grid(xMin, yMin, xCount, yCount, xStep, yStep)
(Float32Array) An array of noise values, ordered by row.
(Number) xMin | The starting x-coordinate.
(Number) yMin | The starting y-coordinate.
(Number) xCount | The number of samples along the width of the grid.
(Number) yCount | The number of samples along the height of the grid.
(Number) xStep | The horizontal distance between samples. Should be considerably smaller than 1.
(Number) yStep | The vertical distance between samples. Should be considerably smaller than 1.
See the perlin2d.html example in the examples directory.
You can also initialise a random mapping, which converts an input to a random number between zero and one; the same input will always return the same output. These are used internally in creating Perlin noise.
Float1to1(?seed) Float2to1(?seed)
const floatMap = Mathicall.random.Float1to1(10432) //Initialise a generator with seed 10432
floatMap(2.3) //0.985
floatMap(2.31) //0.195
floatMap(2.3) //0.985
const vecMap = Mathicall.random.Float2to1(999)
vecMap([6, 7]) //0.735
vecMap([6.1, 0.6]) //0.10912
vecMap([6, 7]) //0.735Numerical approximations are available in the numerical sublibrary.
frac(num, ?tolerance)
Approximates num as a fraction, to within tolerance. The output is an array [numerator, denominator].
deriv(f, x)
The approximate derivative of function f evaluated at x. For example:
const deriv = Mathicall.numerical.deriv;
function xPlus1Squared(x) {
return (x + 1) * (x + 1)
}
deriv(xPlus1Squared, 2.5) //6.999...Working on it!