Pacioli's built-in matrix operations.
_ :: One abs :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v abs_min :: for_unit a, b, P!u, Q!v, P!x, Q!y: for_index P, Q: (a*P!u per Q!v, b*P!x per Q!y) -> a*P!u per Q!v acos :: for_index P, Q: (P! per Q!) -> radian*P! per Q! asin :: for_index P, Q: (P! per Q!) -> radian*P! per Q! atan :: for_index P, Q: (P! per Q!) -> radian*P! per Q! atan2 :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> radian*P! per Q! bottom :: for_unit a, P!u, Q!v: for_index P, Q: (1, a*P!u per Q!v) -> a*P!u per Q!v cbrt :: for_unit a, P!u, Q!v: for_index P, Q: (a^3*P!u^3 per Q!v^3) -> a*P!u per Q!v ceiling :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v cholesky_decomposition :: for_unit a, P!u: for_index P: (a^2/P!u per P!u) -> a/P!u per P! closure :: for_unit P!u: for_index P: (P!u per P!u) -> P!u per P!u column :: for_unit a, P!v: for_index P, Q: (a*P!v per Q!, Q) -> a*P!v column_domain :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> List(Q) column_unit :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> Q!v columns :: for_unit a, P!u: for_index P, Q: (a*P!u per Q!) -> List(a*P!u) compare_index :: for_index P: (P, P) -> 1 complement :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v cos :: for_index P, Q: (radian*P! per Q!) -> P! per Q! delta :: for_index P: (P) -> P! diagonal :: for_unit a, P!u: for_index P: (a*P!u) -> a*P!u per P!u diagonal2 :: for_unit a, P!u: for_index P: (a*P!u) -> a*P!u per P! diagonal3 :: for_unit a, P!u: for_index P: (a*P!u) -> P! per P! dim_div :: for_unit a, D!b, E!c, f, H!g: for_index D, E, H: (a*D!b per E!c, f*H!g per E!c) -> a*D!b per f*H!g dim_inv :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> Q!v per a*P!u div :: for_unit a, b, P!u, Q!v, P!x, Q!y: for_index P, Q: (a*P!u per Q!v, b*P!x per Q!y) -> a*P!u/P!x per b*Q!v/Q!y divide :: for_unit a, b, P!u, Q!v, P!x, Q!y: for_index P, Q: (a*P!u per Q!v, b*P!x per Q!y) -> a*P!u/P!x per b*Q!v/Q!y eigenvalue_decomposition :: for_unit a, P!u: for_index P: (a*P!u per P!u) -> Tuple(a*P!u per P!u, a*P!u per P!u) eigenvalue_list :: for_unit a, P!u: for_index P: (a*P!u per P!u) -> List(Tuple(a, a, P!u)) exp :: for_index P, Q: (P! per Q!) -> P! per Q! expt :: for_index P, Q: (P! per Q!, 1) -> P! per Q! floor :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v gcd :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> P! per Q! get :: for_unit a: for_index P, Q: (a*P! per Q!, P, Q) -> a get_num :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, P, Q) -> 1 greater :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> Boole greater_eq :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> Boole index_less :: for_index P: (P, P) -> Boole inner :: for_unit a, b, P!u: for_index P: (a*P!u, b/P!u) -> a*b inverse :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> Q!v per a*P!u is_zero :: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c) -> Boole is_zero_column :: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c, E) -> Boole is_zero_row :: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c, D) -> Boole kleene :: for_unit P!u: for_index P: (P!u per P!u) -> P!u per P!u left_divide :: for_unit a, b, P!u, Q!v, P!x, Q!y: for_index P, Q: (a*P!u per Q!v, b*P!x per Q!y) -> a*P!x/P!u per b*Q!y/Q!v left_division :: for_unit a, b, P!u, Q!v, R!w: for_index P, Q, R: (a*P!u per Q!v, b*P!u per R!w) -> b*Q!v per a*R!w left_identity :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> P!u per P!u left_inverse :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> Q!v per a*P!u less :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> Boole less_eq :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> Boole ln :: for_index P, Q: (P! per Q!) -> P! per Q! log :: for_index P, Q: (P! per Q!, 1) -> P! per Q! lscale_down :: for_unit a, b, P!u, Q!v: for_index P, Q: (a, b*P!u per Q!v) -> a*P!u per b*Q!v magnitude :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> P! per Q! make_matrix :: for_unit a: for_index P, Q: (List(Tuple(P, Q, a))) -> a*P! per Q! map_matrix :: for_unit a, b: for_index P, Q: ((a) -> b, a*P! per Q!) -> b*P! per Q! mapnz :: for_unit a, P!u, Q!v: for_index P, Q: ((1) -> 1, a*P!u per Q!v) -> a*P!u per Q!v max :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> a*P!u per Q!v mexpt :: for_unit P!u: for_index P: (P!u per P!u, 1) -> P!u per P!u min :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> a*P!u per Q!v minus :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> a*P!u per Q!v mmult :: for_unit a, b, P!u, Q!v, R!w: for_index P, Q, R: (a*P!u per Q!v, b*Q!v per R!w) -> a*b*P!u per R!w mod :: for_unit a, b, P!u, Q!v, P!x, Q!y: for_index P, Q: (a*P!u per Q!v, b*P!x per Q!y) -> a*P!u per Q!v multiply :: for_unit a, b, P!u, P!w, Q!v, Q!z: for_index P, Q: (a*P!u per Q!v, b*P!w per Q!z) -> a*b*P!u*P!w per Q!v*Q!z neg :: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c) -> a*D!b per E!c negative :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v negative_support :: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c) -> D! per E! negatives :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v norm :: for_unit a: for_index P: (a*P!) -> a normalized :: for_unit a: for_index P: (a*P!) -> a*P! outer :: for_unit a, b, P!u, Q!v: for_index P, Q: (a*P!u, b*Q!v) -> a*b*P!u per Q!v^-1 plu_decomposition :: for_unit a, P!u: for_index P: (a*P!u per P!u) -> Tuple(P!u per P!u, P!u per P!u, a*P!u per P!u) positive_support :: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c) -> D! per E! positives :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v precision :: () -> decimals qr_decomposition :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> Tuple(P!u per P!u, a*P!u per Q!v) random :: () -> 1 ranking :: for_unit a: for_index P, Q: (a*P! per Q!) -> P! per Q! reciprocal :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a^-1*P!u^-1 per Q!v^-1 rem :: for_index P, Q: for_unit a, b, P!u, Q!v, P!x, Q!y: (a*P!u per Q!v, b*P!x per Q!y) -> a*P!u per Q!v right_division :: for_unit a, b, P!u, Q!v, R!w: for_index P, Q, R: (a*P!u per Q!v, b*R!w per Q!v) -> a*P!u per b*R!w right_identity :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> Q!v per Q!v right_inverse :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> Q!v per a*P!u round :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v row :: for_unit a, Q!v: for_index P, Q: (a*P! per Q!v, P) -> a per Q!v row_domain :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> List(P) row_unit :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> P!u rows :: for_unit a, Q!v: for_index P, Q: (a*P! per Q!v) -> List(a per Q!v) rscale :: for_unit a, b, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, b) -> a*b*P!u per Q!v scalar_unit :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a scale :: for_unit a, b, P!u, Q!v: for_index P, Q: (a, b*P!u per Q!v) -> a*b*P!u per Q!v scale_down :: for_unit a, b, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, b) -> a*P!u per b*Q!v set_precision :: (decimals) -> Void signum :: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c) -> D! per E! sin :: for_index P, Q: (radian*P! per Q!) -> P! per Q! singular_value_list :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> List(Tuple(a, P!u, Q!v^-1)) solve :: for_unit a, b, P!u, Q!v, R!w: for_index P, Q, R: (a*P!u per Q!v, b*P!u per R!w) -> a^-1*b*Q!v per R!w sqrt :: for_unit a, P!u, Q!v: for_index P, Q: (a^2*P!u^2 per Q!v^2) -> a*P!u per Q!v sum :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> a*P!u per Q!v support :: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c) -> D! per E! tan :: for_index P, Q: (radian*P! per Q!) -> P! per Q! top :: for_unit a, P!u, Q!v: for_index P, Q: (1, a*P!u per Q!v) -> a*P!u per Q!v total :: for_unit a: for_index P, Q: (a*P! per Q!) -> a transpose :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*Q!v^-1 per P!u^-1 truncate :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v unit :: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v
:: One
The single entry for the One index set. Shorthand for One@_
Use this as index for a column vector (n by 1 matrix) or a row vector (1 by n matrix).
For example get(x, 2, _) gets the 2 entry from a column
vector.
If x is a scalar then get(x, _, _) equals x.
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v
Absolute value of a matrix. Each entry is negated if it is negative.
get(abs(A), p, q) = abs(get(A, p, q))
Primitive function
:: for_unit a, b, P!u, Q!v, P!x, Q!y: for_index P, Q: (a*P!u per Q!v, b*P!x per Q!y) -> a*P!u per Q!v
Element-wise absolute minimum.
The difference with the mod and rem functions is that the value is always between -B/2 and B/2.
Could be defined as
abs_min(A, B) = A - B*round(A/B)
Primitive function
:: for_index P, Q: (P! per Q!) -> radian*P! per Q!
Element-wise arccos. The inverse of the cosine function.
:: for_index P, Q: (P! per Q!) -> radian*P! per Q!
Element-wise arcsin. The inverse of the sine function.
:: for_index P, Q: (P! per Q!) -> radian*P! per Q!
Element-wise arctan. The inverse of the tangent function.
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> radian*P! per Q!
Element-wise arctan2. The complete inverse of the tangent function.
:: for_unit a, P!u, Q!v: for_index P, Q: (1, a*P!u per Q!v) -> a*P!u per Q!v
Matrix with only the x least elements. Every entry not in the bottom x is changed to zero.
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a^3*P!u^3 per Q!v^3) -> a*P!u per Q!v
Element-wise cube root.
get_num(cbrt(A), p, q) = cbrt(get_num(A, p, q))
or using the element-wise product *
cbrt(A) * cbrt(A) * cbrt(A) = cbrt(A)^3 = A
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v
Element-wise ceiling.
Primitive function
:: for_unit a, P!u: for_index P: (a^2/P!u per P!u) -> a/P!u per P!
The Cholesky decomposition of a matrix.
Decomposes a matrix into product L '*' L^T, with L a lower triangular matrix.
It is an error if the matrix is not symmetric or is not positive definite.
Primitive function
:: for_unit P!u: for_index P: (P!u per P!u) -> P!u per P!u
Kleene closure for matrices.
Equals the series
A + A'^'2 + A'^'3 ...
:: for_unit a, P!v: for_index P, Q: (a*P!v per Q!, Q) -> a*P!v
Extracts a single column from a matrix.
The matrix must be dimensionally uniform in the column dimension.
For all indices p it satisfies
get_num(column(A, x), p, _) = get_num(A, p, x)
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> List(Q)
The matrix column domain. The index set elements for the column dimension.
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> Q!v
The matrix's units in column dimension. The co-variant part of the matrix units.
Is part of the unit of a matrix. For any matrix A:
unit(A) = scalar_unit(A) '.*' row_unit(A) per column_unit(A)
Primitive function
:: for_unit a, P!u: for_index P, Q: (a*P!u per Q!) -> List(a*P!u)
The columns of a matrix.
:: for_index P: (P, P) -> 1
Comparison of indices. Negative if x comes before y, positive if y comes before x, zero if x and y are equal.
Is the order of the indices in the index set definition. See index_less
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v
Logical complement.
Is defined as:
complement(A) = unit(A) - A
For example, with definitions
defindex Nibble = {bit0, bit1, bit2, bit3};
defmatrix nibble :: Nibble! = {
bit0 -> 1,
bit3 -> 1
};
expression complement(nibble) gives
Nibble Value
-------------------
bit1 1
bit2 1
:: for_index P, Q: (radian*P! per Q!) -> P! per Q!
Element-wise cosine function.
get(cos(A), p, q) = cos(get(A, p, q))
Primitive function
:: for_index P: (P) -> P!
Kronecker delta.
For example delta(Geom3@x) gives a base vector in the x direction
in 3D space.
get(delta(p), x, _) = if p = x then 1 else 0 end
:: for_unit a, P!u: for_index P: (a*P!u) -> a*P!u per P!u
:: for_unit a, P!u: for_index P: (a*P!u) -> a*P!u per P!
:: for_unit a, P!u: for_index P: (a*P!u) -> P! per P!
:: for_unit a, D!b, E!c, f, H!g: for_index D, E, H: (a*D!b per E!c, f*H!g per E!c) -> a*D!b per f*H!g
Dimensional division. Equals multiplying with the dimensional inverse.
Corresponds with symbol per: A per B is parsed as
dim_div(A, B).
dim_div(A, B) = A '*' B^D
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> Q!v per a*P!u
The dimensional inverse of a matrix.
Corresponds to the postfix ^D operator: dim_inv(A) = A^D.
Combines the transpose and the reciprocal: A^D = A^R^T = A^T^R
Primitive function
:: for_unit a, b, P!u, Q!v, P!x, Q!y: for_index P, Q: (a*P!u per Q!v, b*P!x per Q!y) -> a*P!u/P!x per b*Q!v/Q!y
Element-wise integer division of two matrices.
For any a and b the following holds:
a = div(a, b) * b + rem(a, b)
Primitive function
:: for_unit a, b, P!u, Q!v, P!x, Q!y: for_index P, Q: (a*P!u per Q!v, b*P!x per Q!y) -> a*P!u/P!x per b*Q!v/Q!y
Element-wise division of two matrices.
Corresponds with operator /. Expression A / B
is parsed as divide(A, B).
For all indices p and q it satisfies
get(A / B, p, q) = get_num(A, p, q) / get_num(B, p, q)
Primitive function
:: for_unit a, P!u: for_index P: (a*P!u per P!u) -> Tuple(a*P!u per P!u, a*P!u per P!u)
The eigenvalue decomposition of a matrix.
A pair of matrices (D, V) such that A = V '*' D '*' V'^'-1.
The input matrix A, and the output matrices D and V are n x n matrices.
Matrix D is a diagonal matrix. The diagonal elements are the eigenvalues. The colunms of V are the corresponding eigenvectors.
Primitive function
:: for_unit a, P!u: for_index P: (a*P!u per P!u) -> List(Tuple(a, a, P!u))
List form of the eigenvalue decomposition of a matrix.
List of pairs (c, v) such that A '*' v = c '.*' v.
The scalars c are the eigenvalues. The vectors v are the corresponding eigenvectors.
Primitive function
:: for_index P, Q: (P! per Q!) -> P! per Q!
Element-wise natural exponent e^x. Only defined for dimensionless
matrices.
get(exp(A), p, q) = exp(get(A, p, q))
Primitive function
:: for_index P, Q: (P! per Q!, 1) -> P! per Q!
Element-wise exponent of the matrix entries.
For all indices p and q it satisfies
get(expt(A, x), p, q) = expt(get(A, p, q), x)
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v
Element wise floor.
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> P! per Q!
Element-wise greatest common divisor of two matrices.
Primitive function
:: for_unit a: for_index P, Q: (a*P! per Q!, P, Q) -> a
Gets a single entry from a matrix.
The matrix must be dimensionally uniform.
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, P, Q) -> 1
Gets the magnitude of a single entry from a matrix. Using it breaks unit safety so use with care!
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> Boole
Is every entry in matrix A greater than the corresponding entry in matrix B?
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> Boole
Is every entry in matrix A greater than or equal to the corresponding entry in matrix B?
Primitive function
:: for_index P: (P, P) -> Boole
Order on indices.
Is the order of the indices in the index set definition.
Primitive function
:: for_unit a, b, P!u: for_index P: (a*P!u, b/P!u) -> a*b
The inner product between two vectors. The usual product x^T '*' y
between two vectors.
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> Q!v per a*P!u
The inverse of a matrix. Solution to XA=AX=I
:: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c) -> Boole
Is every entry in the matrix zero?
Primitive function
:: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c, E) -> Boole
Is every entry in the column zero?
:: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c, D) -> Boole
Is every entry in the row zero?
:: for_unit P!u: for_index P: (P!u per P!u) -> P!u per P!u
Kleene star for matrices.
Equals the series
I + A + A'^'2 + A'^'3 ...
:: for_unit a, b, P!u, Q!v, P!x, Q!y: for_index P, Q: (a*P!u per Q!v, b*P!x per Q!y) -> a*P!x/P!u per b*Q!y/Q!v
Element-wise left division of two matrices.
Corresponds with operator \. Expression A \ B
is parsed as left_divide(A, B).
Satisfies
left_divide(A, B) = divide(B, A)
Primitive function
:: for_unit a, b, P!u, Q!v, R!w: for_index P, Q, R: (a*P!u per Q!v, b*P!u per R!w) -> b*Q!v per a*R!w
Left division of matrices. Matrix division means multiplying with the inverse.
Corresponds with operator '\'. Expression A '\' B
is parsed as left_division(A, B).
Defined as:
left_division(x,y) = inverse(x) '*' y
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> P!u per P!u
The left identify of a matrix. Solution to X '*' A = A
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> Q!v per a*P!u
The left_inverse of a matrix. Solution to XA=I
In code:
left_inverse(A) '*' A = right_identity(A)
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> Boole
Is every entry in matrix A less than the corresponding entry in matrix B?
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> Boole
Is every entry in matrix A less than or equal to the corresponding entry in matrix B?
Primitive function
:: for_index P, Q: (P! per Q!) -> P! per Q!
Element-wise natural logarithm
get(ln(A), p, q) = ln(get(A, p, q))
Primitive function
:: for_index P, Q: (P! per Q!, 1) -> P! per Q!
Element-wise log.
get_num(log(A), p, q) = log(get_num(A, p, q))
Inverse of the exponent exp function. For scalars the following
holds:
expt(b, log(x, b)) = x
Primitive function
:: for_unit a, b, P!u, Q!v: for_index P, Q: (a, b*P!u per Q!v) -> a*P!u per b*Q!v
Divides a scalar factor by a matrix.
Corresponds with operator './'. Expression x '/.' A
is parsed as lscale_down(x, A).
get_num(lscale_down(x, A), p, q) = x / get_num(A, p, q)
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> P! per Q!
The magnitude of a matrix. The magnitude of a dimensioned number is the scaling factor without the unit of measurement.
A dimensioned matrix A is an element-wise product RU with R a dimensionless magnitude matrix and U a unit matrix.
Using function unit this can be expressed as:
A = magnitude(A) * unit(A)
Primitive function
:: for_unit a: for_index P, Q: (List(Tuple(P, Q, a))) -> a*P! per Q!
Constructs a dimensionally uniform matrix from a list of entries. Each entry is a tuple with the entry's indices and the value.
For example
defindex Direction = {longitude, lattitude};
define foo =
make_matrix([
tuple(Direction@longitude, _, 10*|degree|),
tuple(Direction@lattitude, _, 20*|degree|)]);
creates a vector of type degree*Direction!
Primitive function
:: for_unit a, b: for_index P, Q: ((a) -> b, a*P! per Q!) -> b*P! per Q!
Applies a function to every matrix entry.
The matrix must be dimensionally uniform.
For example
map_matrix((x) -> x + 10*|metre|, A)
adds 10 metre to each matrix entry of A.
:: for_unit a, P!u, Q!v: for_index P, Q: ((1) -> 1, a*P!u per Q!v) -> a*P!u per Q!v
Maps only the non-zero matrix elements. Experiment for more efficient handling of sparse matrices.
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> a*P!u per Q!v
Element-wise maximum of two matrices.
Primitive function
:: for_unit P!u: for_index P: (P!u per P!u, 1) -> P!u per P!u
Exponent of a matrix.
For any matrices A and B it satisfies
get(expt(A, x), p, q) = expt(get(A, p, q), x)
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> a*P!u per Q!v
Element-wise minimum of two matrices.
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> a*P!u per Q!v
Difference of two matrices.
Corresponds with operator -. Expression A - B
is parsed as minus(A, B).
For all indices p and q it satisfies
get_num(A - B, p, q) = get_num(A, p, q) - get_num(B, p, q)
Primitive function
:: for_unit a, b, P!u, Q!v, R!w: for_index P, Q, R: (a*P!u per Q!v, b*Q!v per R!w) -> a*b*P!u per R!w
Matrix multiplication.
Corresponds with operator '*'. Expression A '*' B
is parsed as mmult(A, B).
Primitive function
:: for_unit a, b, P!u, Q!v, P!x, Q!y: for_index P, Q: (a*P!u per Q!v, b*P!x per Q!y) -> a*P!u per Q!v
Element-wise mod of two matrices.
Could be defined as
mod(A, B) = A - abs(B)*floor(A/abs(B))
Primitive function
:: for_unit a, b, P!u, P!w, Q!v, Q!z: for_index P, Q: (a*P!u per Q!v, b*P!w per Q!z) -> a*b*P!u*P!w per Q!v*Q!z
Element-wise product of two matrices.
Corresponds with operator *. Expression A * B
is parsed as multiply(A, B).
For all indices p and q it satisfies
get(A * B, p, q) = get_num(A, p, q) * get_num(B, p, q)
Primitive function
:: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c) -> a*D!b per E!c
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v
The negation of a matrix.
Corresponds with prefix operator '-'. Expression -A
is parsed as negative(A).
get_num(negative(A), p, q) = -get_num(A, p, q)
Primitive function
:: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c) -> D! per E!
A matrix's support is a mask for the non-zero entries. It contains a 1 where the original is negative and a 0 where the original is zero.
Satisfies:
get(support(A), p, q) = if get_num(A, p, q) < 0 then 1 else 0 end
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v
Matrix with only the negative entries. The positive entries become zero.
A matrix A can be factored in a positive and negative part as follows:
A = positives(A) + negatives(A)
:: for_unit a: for_index P: (a*P!) -> a
The norm of a vector. The square root of the inner product
sqrt(x^T '*' x)
The vector must be dimensionally uniform.
:: for_unit a: for_index P: (a*P!) -> a*P!
Vector in the same direction with norm 1. Scales the vector by dividing by the vector's norm.
:: for_unit a, b, P!u, Q!v: for_index P, Q: (a*P!u, b*Q!v) -> a*b*P!u per Q!v^-1
The outer product between two vectors. The usual product x '*' y^T
between a column and row vector.
:: for_unit a, P!u: for_index P: (a*P!u per P!u) -> Tuple(P!u per P!u, P!u per P!u, a*P!u per P!u)
The PLU decomposition of a matrix.
Decomposes the matrix in product A=PLU with P a permutation matrix, L a lower triangular matrix, and U an upper triangular matrix.
Primitive function
:: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c) -> D! per E!
A matrix's support is a bit matrix that indicates the positive entries of another matrix. It contains a 1 where the matrix is positive and a 0 where the matrix is zero.
Satisfies:
get(support(A), p, q) = if get_num(A, p, q) > 0 then 1 else 0 end
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v
Matrix with only the positive entries. The negative entries become zero.
A matrix A can be factored in a positive and negative part as follows:
A = positives(A) + negatives(A)
:: () -> decimals
The number of decimals that is used as treshold in approximations.
It is also used as a treshold to determine if a matrix entry is printed.
See set_precision
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> Tuple(P!u per P!u, a*P!u per Q!v)
The QR decomposition of a matrix.
Decomposes the matrix in product A=QR with Q an orthonormal matrix and R an upper triangular matrix.
Primitive function
:: () -> 1
A random number at least zero and below one.
Primitive function
:: for_unit a: for_index P, Q: (a*P! per Q!) -> P! per Q!
Replaces each entry with its position when ordered.
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a^-1*P!u^-1 per Q!v^-1
The element-wise reciprocal of a matrix.
Corresponds with postfix operator ^R. Expression A^R
is parsed as reciprocal(A).
get_num(reciprocal(A), p, q) = 1/get_num(A, p, q)
Primitive function
:: for_index P, Q: for_unit a, b, P!u, Q!v, P!x, Q!y: (a*P!u per Q!v, b*P!x per Q!y) -> a*P!u per Q!v
Element-wise integer division remainder of two matrices.
Could be defined as
rem(A, B) = A - B*truncate(A/B)
For any a and b the following holds:
a = div(a, b) * b + rem(a, b)
Primitive function
:: for_unit a, b, P!u, Q!v, R!w: for_index P, Q, R: (a*P!u per Q!v, b*R!w per Q!v) -> a*P!u per b*R!w
Division of matrices. Matrix division means multiplying with the inverse.
Corresponds with operator '/'. Expression A '/' B
is parsed as right_division(A, B).
Defined as:
right_division(x,y) = x '*' inverse(y)
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> Q!v per Q!v
The right identify of a matrix. Solution to A '*' X = A
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> Q!v per a*P!u
The right-inverse of a matrix. Solution to AX=I
In code:
A '*' right_inverse(A) = left_identity(A)
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v
Rounds every matrix entry to the nearest integer. Halves are rounded up.
Could be defined as
round(A) = floor(A + 0.5 '.*' unit(A))
Primitive function
:: for_unit a, Q!v: for_index P, Q: (a*P! per Q!v, P) -> a per Q!v
Extracts a single row from a matrix.
The matrix must be dimensionally uniform in the row dimension.
For all indices q it satisfies
get_num(row(A, x), _, q) = get_num(A, x, q)
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> List(P)
The matrix row domain. The index set elements for the row dimension.
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> P!u
The matrix's units in row dimension. The contra-variant part of the matrix units.
Is part of the unit of a matrix. For any matrix A:
unit(A) = scalar_unit(A) '.*' row_unit(A) per column_unit(A)
Primitive function
:: for_unit a, Q!v: for_index P, Q: (a*P! per Q!v) -> List(a per Q!v)
The rows of a matrix.
:: for_unit a, b, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, b) -> a*b*P!u per Q!v
Multiplies a matrix by a scalar factor.
Corresponds with operator '*.'. Expression A '*.' x
is parsed as rscale(A, x).
get_num(rscale(A, x), p, q) = get_num(A, p, q) * x
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a
The scalar unit factor of a matrix.
Is part of the unit of a matrix. For any matrix A:
unit(A) = scalar_unit(A) '.*' row_unit(A) per column_unit(A)
Primitive function
:: for_unit a, b, P!u, Q!v: for_index P, Q: (a, b*P!u per Q!v) -> a*b*P!u per Q!v
Multiplies a matrix with a scalar factor.
Corresponds with operator '.*'. Expression x '.*' A
is parsed as scale(x, A).
get_num(scale(x, A), p, q) = x * get_num(A, p, q)
Primitive function
:: for_unit a, b, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, b) -> a*P!u per b*Q!v
Divides a matrix by a scalar factor.
Corresponds with operator '/.'. Expression A '/.' x
is parsed as scale_down(A, x).
get_num(scale_down(A, x), p, q) = get_num(A, p, q) / x
Primitive function
:: (decimals) -> Void
Sets the number of decimals that is used in approximations.
It is also used as a treshold to determine if a matrix entry is printed.
This is a global effect.
See function precision
:: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c) -> D! per E!
A matrix with the sign of the matrix entries. An entry is 1 if the original value is positive, -1 if the value is negative, and 0 when the value is zero.
Satisfies:
signum(A) = positive_support(A) - negative_support(A)
Primitive function
:: for_index P, Q: (radian*P! per Q!) -> P! per Q!
Element-wise sine function.
get(sin(A), p, q) = sin(get(A, p, q))
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> List(Tuple(a, P!u, Q!v^-1))
List form of the singular value decomposition of a matrix.
List of tuples (s,v,w) such that
A = sum[s '.*' v '*' w^T | (s,v,w) <- svd(A)]
with scalar s the singular values, and vectors v and w the singular vectors.
Note: for dimensionally non-uniform matrices the inner product is not defined. Therefore the orthogonality of the singular vectors assumes the identity metric instead of the inner product (which is equivalent to ignoring the units). See function gsvd from the metrics library for a more general version that accepts other metrics.
Primitive function
:: for_unit a, b, P!u, Q!v, R!w: for_index P, Q, R: (a*P!u per Q!v, b*P!u per R!w) -> a^-1*b*Q!v per R!w
Solves AX=B. Generalization of vector case Ax=b.
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a^2*P!u^2 per Q!v^2) -> a*P!u per Q!v
Element-wise square root.
get_num(sqrt(A), p, q) = sqrt(get_num(A, p, q))
or using the element-wise product *
sqrt(A) * sqrt(A) = sqrt(A)^2 = A
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v, a*P!u per Q!v) -> a*P!u per Q!v
Sum of two matrices.
Corresponds with operator +. Expression A + B
is parsed as sum(A, B).
For all indices p and q it satisfies
get_num(A + B, p, q) = get_num(A, p, q) + get_num(B, p, q)
Primitive function
:: for_unit a, D!b, E!c: for_index D, E: (a*D!b per E!c) -> D! per E!
A matrix's support is a mask for the non-zero entries. It contains a 1 where the original is non-zero and a 0 where the original is zero.
Satisfies:
get(support(A), p, q) = if get_num(A, p, q) = 0 then 0 else 1 end
Primitive function
:: for_index P, Q: (radian*P! per Q!) -> P! per Q!
Element-wise tangent function.
get(tan(A), p, q) = tan(get(A, p, q))
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (1, a*P!u per Q!v) -> a*P!u per Q!v
Matrix with only the x greates elements. Every entry not in the top x is changed to zero.
Primitive function
:: for_unit a: for_index P, Q: (a*P! per Q!) -> a
The sum of all matrix entries.
The matrix must be dimensionally uniform.
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*Q!v^-1 per P!u^-1
The transpose of a matrix. Swaps the row and column dimensions.
Corresponds with postfix operator ^T: A^T
Is parsed as transpose(A).
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v
Gives the integral part of every matrix entry. Rounds towards zero.
Could be defined as
ceiling(negatives(A)) + floor(positives(A))
Primitive function
:: for_unit a, P!u, Q!v: for_index P, Q: (a*P!u per Q!v) -> a*P!u per Q!v
The unit of a matrix.
Is defined as:
unit(A) = scalar_unit(A) '.*' row_unit(A) per column_unit(A)
Any matrix A is the product of a magnitude and a unit:
A = magnitude(A) * unit(A)
Version v0.6.0, 2026-03-05T15:49:19.223374150+01:00[Europe/Amsterdam]