-
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.4
mod(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); //5
fract(x)
(Number) The fractional part of x
.
(Number) x
| A number.
fract(3.041); //0.041
fract(-7.3); //-0.3
deg(radians)
(Number) The input value radians
converted to degrees.
(Number) radians
| An angle in radians.
deg(3.141592); //180
rad(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_INTEGER
are approximate. - Results exceeding
Number.MAX_VALUE
returnNumber.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); //24
Negative 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); //24
Negative 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); //45
Returns 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); //11880
gcd(a, b)
(Number) The greatest common divisor of a
and b
.
(Number) a
, b
| An integer.
gcd(63, 14); //7
gcd(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); //120
The 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); //9
The 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
target
parameter 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.5
cross3(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]); //3
scale2(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]); //undefined
If 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; //3
zeros(nrows, ncols)
(Array) A matrix of size nrows x ncols
containing all 0
s.
(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 n
xn
.
(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]); //-10
Currently, 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); //true
Operations 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
target
parameter 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); //-1
unique(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]); //-5
The 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]); //8
The 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.2
prod(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]); //60
count(arr, value, ?sorted)
(Number) The number of occurrences of value
in arr
.
array.count([1, 2, 3, 3, 4], 3); //2
isEqual(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]); //false
Currently radix sort is only implemented for Uint8Array
s.
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.735
Numerical 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!