Mathematical operations

Involutions and duals

Base.reverseMethod
reverse(i::BitIndex) = i' -> BitIndex
reverse(x::AbstractCliffordNumber) = x' -> typeof(x)

Performs the reverse operation on the basis blade indexed by b or the Clifford number x. The sign of the reverse depends on the grade of the basis blade g, and is positive for g % 4 in 0:1 and negative for g % 4 in 2:3.

source
CliffordNumbers.grade_involutionMethod
grade_involution(i::BitIndex) -> BitIndex
grade_involution(x::AbstractCliffordNumber) -> typeof(x)

Calculates the grade involution of the basis blade indexed by b or the Clifford number x. This effectively reflects all of the basis vectors of the space along their own mirror operation, which makes elements of odd grade flip sign.

source
Base.conjMethod
conj(i::BitIndex) -> BitIndex
conj(x::AbstractCliffordNumber) -> typeof(x)

Calculates the Clifford conjugate of the basis blade indexed by b or the Clifford number x. This is equal to grade_involution(reverse(x)).

source
CliffordNumbers.left_complementMethod
left_complement(b::BitIndex{Q}) -> BitIndex{Q}

Returns the left complement of b, define so that left_complement(b) * b generates the pseudoscalar index of elements of the algebra Q.

When the left complement is applied twice, the original BitIndex object is returned up to a change of sign, given by (-1)^(grade(b) * (dimension(Q) - grade(b))). This implies that in algebras of odd dimension, the left complement and [right complement](@ref right_complement) are identical because eithergrade(b)ordimension(Q) - grade(b)must be even. The complement is independent of the signature ofQ`, depending only on the dimension.

Lengyel's convention for the left complement is an underbar.

source
CliffordNumbers.right_complementMethod
right_complement(b::BitIndex{Q}) -> BitIndex{Q}

Returns the right complement of b, define so that b * right_complement(b) generates the pseudoscalar index of elements of the algebra Q.

When the right complement is applied twice, the original BitIndex object is returned up to a change of sign, given by (-1)^(grade(b) * (dimension(Q) - grade(b))). This implies that in algebras of odd dimension, the [left complement](@ref left_complement) and right complement are identical because eithergrade(b)ordimension(Q) - grade(b)must be even. The complement is independent of the signature ofQ`, depending only on the dimension.

Lengyel's convention for the right complement is an overbar.

source

Inverses

CliffordNumbers.versor_inverseFunction
CliffordNumbers.versor_inverse(x::AbstractCliffordNumber)

Calculates the versor inverse of x, equal to x' / abs2(x).

The versor inverse is only guaranteed to be an inverse for versors. Not all Clifford numbers have a well-defined inverse, (for instance, in algebras with 2 or more positive-squaring, dimensions, 1 + e₁ has no inverse). To validate the result, use inv(x) instead.

source
Base.invMethod
inv(x::AbstractCliffordNumber) -> AbstractCliffordNumber

Calculates the inverse of x, if it exists, using the versor inverse formula x' / abs2(x). The result is tested to check if its left and right products with x are approximately 1, and a CliffordNumbers.InverseException is thrown if this test does not pass.

source

Addition and subtraction

Addition and subtraction integrate seamlessly with those of the Julia Base number types, and no special documentation is included here.

Products

Products with scalars

The standard multiplication and division operations (*, /, //) between Clifford numbers and scalars behave as expected. Base.muladd has been overloaded to take advantage of fma instructions available on some hardware platforms.

Base.muladdMethod
muladd(x::Union{Real,Complex}, y::AbstractCliffordNumber{Q}, z::AbstractCliffordNumber{Q})
muladd(x::AbstractCliffordNumber{Q}, y::Union{Real,Complex}, z::AbstractCliffordNumber{Q})

Multiplies a scalar with a Clifford number and adds another Clifford number, utilizing optimizations made available with scalar muladd, such as fma if hardware support is available.

source

Geometric products

Base.:*Function
*(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
(x::AbstractCliffordNumber{Q})(y::AbstractCliffordNumber{Q})

Calculates the geometric product of x and y, returning the smallest type which is able to represent all nonzero basis blades of the result.

source
CliffordNumbers.:⨼Function
left_contraction(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
⨼(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the left contraction of x and y.

For basis blades A of grade m and B of grade n, the left contraction is zero if n < m, otherwise it is KVector{n-m,Q}(A*B).

source
CliffordNumbers.:⨽Function
right_contraction(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
⨽(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the right contraction of x and y.

For basis blades A of grade m and B of grade n, the right contraction is zero if m < n, otherwise it is KVector{m-n,Q}(A*B).

source
CliffordNumbers.dotFunction
CliffordNumbers.dot(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the dot product of x and y.

For basis blades A of grade m and B of grade n, the dot product is equal to the left contraction when m >= n and is equal to the right contraction (up to sign) when n >= m.

Why is this function not exported?

The LinearAlgebra package also defines a dot function, and if both packages are used together, this will cause a name conflict if CliffordNumbers.dot is exported. In the future, we will try to resolve this without requiring a LinearAlgebra dependency.

Additionally, there is reason to prefer the use of the left and right contractions over the dot product because the contractions require fewer exceptions in their definitions and properties.

source
CliffordNumbers.hestenes_dotFunction
CliffordNumbers.hestenes_dot(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Returns the Hestenes product: this is equal to the dot product given by dot(x, y) but is equal to to zero when either x or y is a scalar.

Why is this function not exported?

In almost every case, left and right contractions are preferable - the dot product and the Hestenes product are less regular in algebraic sense, and the conditionals present in its implementation slow it down relative to contractions. It is provided for the sake of exact reproducibility of results which use it.

source
CliffordNumbers.:∧Function
∧(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
wedge(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the wedge (outer) product of two Clifford numbers x and y with quadratic form Q.

Note that the wedge product, in general, is not equal to the commutator product (or antisymmetric product), which may be invoked with the commutator function or the × operator.

source
CliffordNumbers.:∨Function
∨(x::AbstractCliffordNumber, y::AbstractCliffordNumber)
regressive(x::AbstractCliffordNumber, y::AbstractCliffordNumber)

Calculates the regressive product of x and y. This is accomplished by taking the wedge product of the left complements of x and y, then taking the right complement of the result.

source
CliffordNumbers.:×Function
×(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
commutator(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the commutator (or antisymmetric) product, equal to 1//2 * (x*y - y*x).

Note that the commutator product, in general, is not equal to the wedge product, which may be invoked with the wedge function or the operator.

Type promotion

Because of the rational 1//2 factor in the product, inputs with scalar types subtyping Integer will be promoted to Rational subtypes.

source
CliffordNumbers.:⨰Function
⨰(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
anticommutator(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the anticommutator (or symmetric) product, equal to 1//2 * (x*y + y*x).

Note that the dot product, in general, is not equal to the anticommutator product, which may be invoked with dot. In some cases, the preferred operators might be the left and right contractions, which use infix operators and respectively.

Type promotion

Because of the rational 1//2 factor in the product, inputs with scalar types subtyping Integer will be promoted to Rational subtypes.

source

Scalar products and normalization

CliffordNumbers.scalar_productFunction
scalar_product(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the scalar product of two Clifford numbers with quadratic form Q. The result is a Real or Complex number. This can be converted back to an AbstractCliffordNumber.

The result is equal to scalar(x * y), but does not calculate the coefficients associated with any other basis blades.

source
Base.abs2Method
abs2(x::AbstractCliffordNumber{Q,T}) -> T

Calculates the modulus of x by calculating the scalar product of x with its reverse: scalar_product(x, x'). In positive-definite metrics, this value is positive for any nonzero multivector and equal to zero(T) for any multivector equal to zero.

source
Base.absMethod
abs(x::AbstractCliffordNumber{Q}) -> Union{Real,Complex}

Calculates the norm of x, equal to sqrt(abs(abs2(x))).

The inclusion of abs in this expression accounts for the possibility that the algebra Q contains 1-blades with a negative square, which would result in abs(x) being imaginary. In these cases, abs(x) may not be a norm, but it is used internally by normalize(x) to calculate a normalization factor.

source
CliffordNumbers.normalizeFunction
normalize(x::AbstractCliffordNumber{Q}) -> AbstractCliffordNumber{Q}

Normalizes x so that its modulus (as calculated by abs2) is 1, 0, or -1. This procedure cannot change the sign of the modulus.

If abs2(x) is zero (possible in any non-positive-definite metric), x is returned unchanged.

source

Exponentiation

Base.expMethod
exp(x::AbstractCliffordNumber{Q})

Returns the natural exponential of a Clifford number.

For special cases where m squares to a scalar, the following shortcuts can be used to calculate exp(x):

  • When x^2 < 0: exp(x) === cos(abs(x)) + x * sin(abs(x)) / abs(x)
  • When x^2 > 0: exp(x) === cosh(abs(x)) + x * sinh(abs(x)) / abs(x)
  • When x^2 == 0: exp(x) == 1 + x

See also: exppi, exptau.

source
CliffordNumbers.exppiFunction
exppi(x::AbstractCliffordNumber)

Returns the natural exponential of π * x with greater accuracy than exp(π * x) in the case where x^2 is a negative scalar, especially for large values of abs(x).

See also: exp, exptau.

source
CliffordNumbers.exptauFunction
exptau(x::AbstractCliffordNumber)

Returns the natural exponential of 2π * x with greater accuracy than exp(2π * x) in the case where x^2 is a negative scalar, especially for large values of abs(x).

See also: exp, exppi.

source