package phantom-algebra

  1. Overview
  2. Docs
include Interface.S
include Interface.Dim
type +_ dim

Dimension for vectors and matrix, 1d vectors are considered scalars

val dim_to_int : _ dim -> int
type +_ rank
module Rank : Interface.Rank with type 'a rank := 'a rank

Rank-related types

include Interface.Core
type (+'dim, +'rank) t

Tensor core type:

  • rank is either 2 (for matrix), 1 (for vector) or zero for scalars
  • dim belongs to {1,2,3,4}.
val pp : Format.formatter -> ('dim, 'rank) t -> unit

Printer function

type +'x scalar = ('a Type_functions.one, 'b Type_functions.z) t constraint 'x = 'a * 'b

Type abreviations

type +'x vec2 = ('a Type_functions.two, 'b Type_functions.one) t constraint 'x = 'a * 'b
type +'x vec3 = ('a Type_functions.three, 'b Type_functions.one) t constraint 'x = 'a * 'b
type +'x vec4 = ('a Type_functions.four, 'b Type_functions.one) t constraint 'x = 'a * 'b
type +'x mat2 = ('a Type_functions.two, 'b Type_functions.two) t constraint 'x = 'a * 'b
type +'x mat3 = ('a Type_functions.three, 'b Type_functions.two) t constraint 'x = 'a * 'b
type +'x mat4 = ('a Type_functions.four, 'b Type_functions.two) t constraint 'x = 'a * 'b
val scalar : Interface.k -> _ scalar

Constructors

val (~+) : Interface.k -> _ scalar

scalar f build a scalar from the naked scalar type. It can be abbreviated to (+s).

val vec2 : Interface.k -> Interface.k -> _ vec2
val vec3 : Interface.k -> Interface.k -> Interface.k -> _ vec3
val mat2 : _ vec2 -> _ vec2 -> _ mat2
val mat3 : _ vec3 -> _ vec3 -> _ vec3 -> _ mat3
val mat4 : _ vec4 -> _ vec4 -> _ vec4 -> _ vec4 -> _ mat4

Vector stretching and concatenation

vec$n' v extends a vector of dimension d <= n to a vector of dimension n by repeating the last value of the vector

val (|+|) : (('dim1, 'dim2, 'dim3, _) Type_functions.nat_sum, [< _ Type_functions.one | _ Type_functions.z ]) t -> ('dim2, [< _ Type_functions.one | _ Type_functions.z ]) t -> ('dim3, _ Type_functions.one) t

Vector concatenation : v |+| w is (v_0, v_1, … , v_{dim-1}, w_0, …, w_{dim-1})

Map functions

val map : (Interface.k -> Interface.k) -> ('dim, 'rank) t -> ('dim, 'rank) t
val map2 : (Interface.k -> Interface.k -> Interface.k) -> ('dim, 'rank) t -> ('dim, 'rank) t -> ('dim, 'rank) t

Core linear algebra functions

val (+) : ('dim1, ('rank1, 'rank2, 'rank3, 'dim1, 'dim2, 'dim3, _) Type_functions.sum) t -> ('dim2, 'rank2) t -> ('dim3, 'rank3) t

x + y is the standard vector sum, except for scalar argument which are broadcasted to a constant tensor

val (<+>) : ('dim, 'rank) t -> ('dim, 'rank) t -> ('dim, 'rank) t

x <+> y is the standard vector sum, without broadcasting

val (~-) : ('dim, 'rank) t -> ('dim, 'rank) t

~-x is the standard addition inverse

val (-) : ('a, ('rank1, 'rank2, 'rank3, 'dim1, 'dim2, 'dim3, _) Type_functions.sum) t -> ('a, 'rank2) t -> ('a, 'rank3) t

x - y is the standard vector difference, except for scalar argument which are broadcasted to a constant tensor

val (<->) : ('dim, 'rank) t -> ('dim, 'rank) t -> ('dim, 'rank) t

x <-> y is the standard vector difference, without broadcasting

val (*) : ('dim1, ('rank1, 'rank2, 'rank3, 'dim1, 'dim2, 'dim3, _) Type_functions.product) t -> ('dim2, 'rank2) t -> ('dim3, 'rank3) t

x * y is:

  • the external product if x or y is a scalar
  • the matrix product if x or y is a matrix
  • the element-wise (hadamard) product otherwise
val (/) : ('dim1, ('rank1, 'rank2, 'rank3, 'dim1, 'dim2, 'dim3, _) Type_functions.div) t -> ('dim2, 'rank2) t -> ('dim3, 'rank3) t

x / y is:

  • the external product division if x or y is a scalar
  • the right matrix division if y is a matrix and x is either a matrix or a vector
  • the element-wise division if both x and y are vectors

Exponentiation functions

val (**) : ('dim, 'rank) t -> int -> ('dim, 'rank) t

t ** k is t * … * t k-times

val exp : ('dim, 'rank) t -> ('dim, 'rank) t

exp is the algebraic exponential: exp m = 1 + m + m ** 2 / 2 + m **3 / 3! + …

Scalar products and norms

val (|*|) : ('dim, 'rank) t -> ('dim, 'rank) t -> Interface.k

(x|*|y) is the canonical scalar product

val norm : ('dim, 'rank) t -> Interface.k

norm x is the canonical 2-norm of x

val normalize : ('dim, 'rank) t -> ('dim, 'rank) t

normalize x is x / scalar (norm x)

val orthonormalize : ('dim, _ Type_functions.one) t list -> ('dim, _ Type_functions.one) t list

orthonomalize [v_0;...;v_n] returns a list of orthonormal vectors [w_0;...;w_k] that spans the same vector subspace as v_0;...;v_n. If the family [v_0;...;v_n] was free then k = n, otherwise k<n.

val distance : ('dim, 'rank) t -> ('dim, 'rank) t -> Interface.k

distance x y is norm (x - y)

val norm_1 : ('dim, 'rank) t -> Interface.k

norm_1 x is ∑ |x_i|

val norm_q : float -> ('dim, 'rank) t -> Interface.k

norm_q q x is (∑ |x_i|^q) ^ 1/q

Cross and external product

val cross : (('dim, 'dim2 * 'rank2, _) Type_functions.cross, _ Type_functions.one) t -> ('dim, _ Type_functions.one) t -> ('dim2, 'rank2) t

cross v w is the cross product, it maps either two 3d vectors to a 3d pseudo-vector, or two 2d vectors to a scalar

val (^) : ('dim, _ Type_functions.one) t -> ('dim, _ Type_functions.one) t -> ('dim, _ Type_functions.two) t

See cross for the 2d and 3d cross-product for vectors v ^ w is the infinitesimal rotation matrix in the plane generated by v and w with an amplitude |v||w| sin θ . In other words the matrix representation of the 2-form dv ^ dw in the corresponding graded algebra.

More linear algebra functions

val commutator : ('dim, _ Type_functions.two) t -> ('dim, _ Type_functions.two) t -> ('dim, _ Type_functions.two) t

commutator m n is m * n - n * m

val anticommutator : ('dim, _ Type_functions.two) t -> ('dim, _ Type_functions.two) t -> ('dim, _ Type_functions.two) t

anticommutator m n is m * n + n * m

val trace : ('dim, _ Type_functions.two) t -> Interface.k

trace m is ∑_i m_ii

val det : ('dim, _ Type_functions.two) t -> Interface.k

det m is the signed volume of the convex hull of of the matrix rows

val transpose : ('dim, _ Type_functions.two) t -> ('dim, _ Type_functions.two) t

transpose m is the matrix with row and column reversed

include Interface.Index
type (+'dim, +'len, +'rank, +'group) index

An index of type (+'dim,'+len,+'rank,'group) index can be used to index a tensor, each type parameter informs on which kind of tensor can be used ('dim and 'rank), on the type of the resulting vector ('len and 'rank), or on with which indices it can be combined when swizzling. More precisely,

  • `dim is the list of tensor dimension compatible with the index, for instance `x` works for all dimension, whereas `w` is only meaningful for a 4-vector.
  • `rank is the number of coordinate specified by the index, a tensor can be indexed only if its own rank is equal or superior to the index rank. For instance, xx is a rank 2 tensor and can only index matrices, whereas x is a valid index for both vector and tensor. When slicing, the rank of the slice will be the difference between the tensor rank and the index rank. For a vector v and a matrix m, v.%x is a scalar (1 - 1 = 0) like m.%[xx] ( 2 - 2 = 0) but m.%x is a vector (2-1=0) corresponding to the first row of the matrix
  • 'len is the number of indices combined in the aggregated index by swizzling, if 'len > 1 it increases the rank of the resulting tensor by one and sets its dimension to 'len. See the slice function for more information.
  • 'group corresponds to the index namespace, only index of the same namespace can be combined by swizzling. Availaibles namespace are `xyzx,`rgba and `stpq.
val (&) : ('dim, ('len1, 'len2, 'len3, _) Type_functions.simple_sum, 'rank, 'group) index -> ('dim, 'len2, 'rank, 'group) index -> ('dim, 'len3, 'rank, 'group) index

Index concatenation

val zx' : ([< _ Type_functions.three | `four ], _ Type_functions.one, _ Type_functions.two, [ `xyzw ]) index
val br' : ([< _ Type_functions.three | `four ], _ Type_functions.one, _ Type_functions.two, [ `rgba ]) index
val ps' : ([< _ Type_functions.three | `four ], _ Type_functions.one, _ Type_functions.two, [ `stpq ]) index
include Interface.Indexing with type ('a, 'b, 'c, 'd) index := ('a, 'b, 'c, 'd) index and type ('a, 'b) t := ('a, 'b) t
val slice : ('dim1, ('rank1, 'rank2, 'rank3, 'dim1, 'dim3, 'len, _) Type_functions.superindexing) t -> ('dim1, 'len, 'rank2, 'group) index -> ('dim3, 'rank3) t

slice t n or t.%[n] computes a slice of rank tensor_rank - index_rank, in other words for a vector v and a matrix m, v.%[x] and m.%[xx] are a scalar, whereas m.%[x] is the first row vector of the matrix m

val (.%[]) : ('dim1, ('rank1, 'rank2, 'rank3, 'dim1, 'dim3, 'len, _) Type_functions.superindexing) t -> ('dim1, 'len, 'rank2, 'group) index -> ('dim3, 'rank3) t
val get : ('dim, 'rank) t -> ('dim, _ Type_functions.one, 'rank, 'group) index -> Interface.k

t.%(x) returns the value of the tensor at index x

val (.%()) : ('dim, 'rank) t -> ('dim, _ Type_functions.one, 'rank, 'group) index -> Interface.k
include Interface.Basic with type 'a dim := 'a dim and type 'a rank := 'a rank and type ('a, 'b) tensor := ('a, 'b) t
val zero : 'dim dim -> 'rank rank -> ('dim, 'rank) t

zero dim rank is the zero scalar, vector or matrix with dimension dim

val id : 'dim dim -> 'rank rank -> ('dim, 'rank) t

id rank dim t ** 0 for any tensor of corresponding rank and dimension

val eye : 'a dim -> ('a, _ Type_functions.two) t

eye dim is id matrix dim, the identity matrix with ones on the diagonal

val diag : ('dim, _ Type_functions.one) t -> ('dim, _ Type_functions.two) t

diag vec is the diagonal matrix with vec on the diagonal

val rotation : ('dim, _ Type_functions.one) t -> ('dim, _ Type_functions.one) t -> Interface.k -> ('dim, _ Type_functions.two) t

rotation x y θ computes the rotation matrix in the plane spanned by x y with a θ angle.

include Interface.Matching with type 'a dim := 'a dim and type 'a rank := 'a rank
val rank_match : [< `zero of 'a & 'r | `one of 'b & 'r | `two of 'c & 'r ] rank -> (_ Type_functions.z rank -> 'a) -> (_ Type_functions.one rank -> 'b) -> (_ Type_functions.two rank -> 'c) -> 'r
val dim_match : [< `one of 'a & 'r | `two of 'b & 'r | `three of 'c & 'r | `four of 'd & 'r ] dim -> (_ Type_functions.one dim -> 'a) -> (_ Type_functions.two dim -> 'b) -> (_ Type_functions.three dim -> 'c) -> (_ Type_functions.four dim -> 'd) -> 'r
include Interface.Cloning with type ('a, 'b) t := ('a, 'b) t
val clone_2 : ([< `one of ('dim1 * 'dim2) as 't & _ Type_functions.one * _ Type_functions.one | `two of 't & _ Type_functions.two * _ Type_functions.two | `three of 't & _ Type_functions.three * _ Type_functions.three | `four of 't & _ Type_functions.four * _ Type_functions.four ], [< `zero of ('rank1 * 'rank2) as 'r & _ Type_functions.z * _ Type_functions.z | `one of 'r & _ Type_functions.one * _ Type_functions.one | `two of 'r & _ Type_functions.two * _ Type_functions.two ]) t -> ('dim1, 'rank1) t * ('dim2, 'rank2) t

clone_2 v returns two clones x,y of the value v with the same types as the original type of  v

val clone_3 : ([< `one of ('dim1 * 'dim2 * 'dim3) as 't & _ Type_functions.one * _ Type_functions.one * _ Type_functions.one | `two of 't & _ Type_functions.two * _ Type_functions.two * _ Type_functions.two | `three of 't & _ Type_functions.three * _ Type_functions.three * _ Type_functions.three | `four of 't & _ Type_functions.four * _ Type_functions.four * _ Type_functions.four ], [< `zero of ('rank1 * 'rank2 * 'rank3) as 'r & _ Type_functions.z * _ Type_functions.z * _ Type_functions.z | `one of 'r & _ Type_functions.one * _ Type_functions.one * _ Type_functions.one | `two of 'r & _ Type_functions.two * _ Type_functions.two * _ Type_functions.two ]) t -> ('dim1, 'rank1) t * ('dim2, 'rank2) t * ('dim3, 'rank3) t

clone_k are not strictly required, but they are here to avoid the pattern

let a, t = clone_2 t in
let b, t = clone_2 t in
…

required by the sole use of clone_2

val clone_7 : ([< `one of ('dim1 * 'dim2 * 'dim3 * 'dim4 * 'dim5 * 'dim6 * 'dim7) as 'd & _ Type_functions.one * _ Type_functions.one * _ Type_functions.one * _ Type_functions.one * _ Type_functions.one * _ Type_functions.one * _ Type_functions.one | `two of 'd & _ Type_functions.two * _ Type_functions.two * _ Type_functions.two * _ Type_functions.two * _ Type_functions.two * _ Type_functions.two * _ Type_functions.two | `three of 'd & _ Type_functions.three * _ Type_functions.three * _ Type_functions.three * _ Type_functions.three * _ Type_functions.three * _ Type_functions.three * _ Type_functions.three | `four of 'd & _ Type_functions.four * _ Type_functions.four * _ Type_functions.four * _ Type_functions.four * _ Type_functions.four * _ Type_functions.four * _ Type_functions.four ], [< `zero of ('rank1 * 'rank2 * 'rank3 * 'rank4 * 'rank5 * 'rank6 * 'rank7) as 'r & _ Type_functions.z * _ Type_functions.z * _ Type_functions.z * _ Type_functions.z * _ Type_functions.z * _ Type_functions.z * _ Type_functions.z | `one of 'r & _ Type_functions.one * _ Type_functions.one * _ Type_functions.one * _ Type_functions.one * _ Type_functions.one * _ Type_functions.one * _ Type_functions.one | `two of 'r & _ Type_functions.two * _ Type_functions.two * _ Type_functions.two * _ Type_functions.two * _ Type_functions.two * _ Type_functions.two * _ Type_functions.two ]) t -> ('dim1, 'rank1) t * ('dim2, 'rank2) t * ('dim3, 'rank3) t * ('dim4, 'rank4) t * ('dim5, 'rank5) t * ('dim6, 'rank6) t * ('dim7, 'rank7) t
OCaml

Innovation. Community. Security.