Docstrings
Multivector types
GeometricAlgebra.AbstractMultivector
— TypeAbstractMultivector{Sig}
Supertype of all elements in the geometric algebra defined by the metric signature Sig
.
Subtypes
AbstractMultivector{Sig}
/ \
BasisBlade{Sig,K,T} Multivector{Sig,K,S}
BasisBlade
: a scalar multiple of a wedge product of orthogonal basis vectors.Multivector
: a homogeneous or inhomogeneous multivector; a sum of basis blades.
GeometricAlgebra.BasisBlade
— TypeBasisBlade{Sig,K,T}
A basis blade of grade K
and scalar coefficient of type T
.
Basis blades are scalar multiples of wedge products of orthogonal basis vectors.
Not every $k$-blade (i.e., wedge product of $k$ linearly independent vectors) is representable as a BasisBlade
. However, every $k$-blade is a Multivector
of grade k
.
Parameters
Sig
: Metric signature defining the geometric algebra, retrieved withsignature()
.K::Int
: Grade of the blade, equal tocount_ones(bits)
, retrieved withgrade()
.T
: Numerical type of the scalar coefficient, retrieved witheltype()
.
GeometricAlgebra.BasisBlade
— MethodBasisBlade{Sig}(bits, coeff)
Basis blade with indices encoded by bits
and scalar coefficient coeff
.
Indices are encoded in binary (e.g., $v₁∧v₃∧v₄$ has bits 0b1101
).
Examples
julia> BasisBlade{3}(42, 0b110) # a grade 2 blade in 3 dimensions
BasisBlade{3, 2, Int64}:
42 v23
GeometricAlgebra.Multivector
— TypeMultivector{Sig,K,S} <: AbstractMultivector{Sig}
A general multivector with parts of grade ∈ K
.
For homogeneous k
-vectors, the grade parameter K
is an integer. Inhomogeneous multivectors may be specified with a range or tuple of grades.
Parameters
Sig
: Metric signature defining the geometric algebra, retrieved withsignature()
.K
: Grade(s) present in the multivector. Can be an integer or a collection of integers (a range or tuple).S
: Storage type of the multivector components, usually a subtype ofAbstractVector
.
GeometricAlgebra.Multivector
— MethodMultivector{Sig,K}(comps)
Multivector with grade(s) K
and component vector comps
.
Components are ordered first by grade, then lexicographically by bits (see componentbits
).
Examples
julia> Multivector{3,0:3}(1:2^3)
8-component Multivector{3, 0:3, UnitRange{Int64}}:
1
2 v1 + 3 v2 + 4 v3
5 v12 + 6 v13 + 7 v23
8 v123
julia> grade(ans, 1)
3-component Multivector{3, 1, UnitRange{Int64}}:
2 v1
3 v2
4 v3
Base.zero
— Methodzero(::Type{Multivector{Sig,K,S})
zero(::Type{Multivector{Sig,K}}, [T])
Multivector of metric signature Sig
and grade(s) K
with components all equal to zero. If specified, the components array is of type S
, or is the default array type with element type T
.
GeometricAlgebra.componentindex
— Methodcomponentindex(a::Multivector, b::Union{Unsigned,BasisBlade})
Index of the component of a.comps
which corresponds to the basis blade b
.
GeometricAlgebra.dimension
— Methoddimension(sig)
dimension(::AbstractMultivector)
The dimension of the underlying vector space of the geometric algebra. See ncomponents
for the dimension of the algebra (i.e., the number of independent components of a general multivector).
GeometricAlgebra.grade
— Methodgrade(a)
Grade or grades present in a multivector a
.
The grade of a BasisBlade{Sig,K}
or Multivector{Sig,K}
is the second type parameter, K
. In the case of a multivector, K
may be an integer (if it is homogeneous) or a collection (a range or tuple of grades).
See also ishomogeneous
.
GeometricAlgebra.ishomogeneous
— Methodishomogeneous(a)
Whether a
is homogeneous, i.e., consists of nonzero parts of the same grade.
GeometricAlgebra.isscalar
— Methodisscalar(a)
Whether the only non-zero part of a multivector is its scalar part; a == scalar(a)
.
GeometricAlgebra.ncomponents
— Methodncomponents(::Multivector)
Number of independent components of a multivector instance (or type).
GeometricAlgebra.resulting_multivector_type
— Methodresulting_multivector_type(f, a, b, ...)
Return a Multivector{Sig,K,S}
type with parameters (signature Sig
, grade(s) K
and storage type S
) appropriate for representing the result of f(a, b)
.
Calls resulting_grades(f, dimension(Sig), grade(a), grade(b), ...)
to determine K
.
GeometricAlgebra.scalar
— Methodscalar(a) -> Number
The scalar component of a multivector.
GeometricAlgebra.signature
— Methodsignature(::AbstractMultivector{Sig}) = Sig
The metric signature type parameter of the multivector instance (or type).
Multivector operations
Base.:~
— Method~a
reversion(a::AbstractMultivector)
Reversion of a multivector.
Reversion is an anti-automorphism defined by reversing the order of the geometric product: ~(a*b) == ~b * ~a
. For a k
-vector a
, the reversion is reversion_sign(k)*a
where the sign is given by $(-1)^{k(k - 1)/2}$.
See also involution
and clifford_conj
.
GeometricAlgebra.:'ᶜ
— Methoda'ᶜ
clifford_conj(a)
Clifford conjugate of a multivector.
Equivalent to reversion(involution(a))
.
GeometricAlgebra.:∧
— Methoda ∧ b
wedge(a, b)
Wedge product of multivectors (a.k.a. the outer, exterior, progressive or alternating product, or join).
This is a grade-raising operation, equivalent to graded_prod(+, a, b)
. If a
and b
are of grades $p$ and $q$ respectively, then a ∧ b
is defined as the grade $p + q$ part of a*b
.
GeometricAlgebra.:∨
— Methoda ∨ b
antiwedge(a, b)
Anti-wedge product of multivectors (a.k.a. the regressive product or meet).
The anti-wedge product satisfies
\[D(a ∨ b) = (D a) ∧ (D b)\]
where $D$ is a duality operation such as ldual
, rdual
or, if $I^2 ≠ 0$, hodgedual
.
The anti-wedge product is metric independent like the wedge product, but does depend on the choice of orientation (the ordering of basis vectors).
GeometricAlgebra.:⊙
— Methoda ⊙ b
scalar_prod(a, b) -> Number
Scalar part of the geometric product a*b
.
GeometricAlgebra.:⋅
— Methoda ⋅ b
inner(a, b)
Inner product of multivectors.
This is a grade lowering operation, equivalent to graded_prod(abs∘-, a, b)
. If a
and b
are of grades $p$ and $q$ respectively, then a ⋅ b
is defined as the grade $|p - q|$ part of a*b
.
Note that for scalars a
and b
, the inner product reduces to scalar multiplication, in contrast to some authors (see [1] for discussion).
GeometricAlgebra.:⨼
— Methoda ⨼ b
lcontract(a, b)
Left contraction of multivectors.
Equivalent to graded_prod((p, q) -> q - p, a, b)
. If a
and b
are of grades $p$ and $q$ respectively, then a ⨼ b
is defined as the grade $q - p$ part of a*b
.
GeometricAlgebra.:⨽
— Methoda ⨽ b
rcontract(a, b)
Right contraction of multivectors.
Equivalent to graded_prod(-, a, b)
. If a
and b
are of grades $p$ and $q$ respectively, then a ⨽ b
is defined as the grade $p - q$ part of a*b
.
GeometricAlgebra.add!
— Methodadd!(a::Multivector, b::Blade)
add!(a::Multivector, bits, coeff)
Add the blade coefficient to the corresponding component of a multivector, if the multivector has such a component.
If the multivector cannot represent components of the required grade, it is returned unmodified.
This mutates and returns a
if it is a mutable type, otherwise it returns a new multivector of identical type. (Thus, the blade coefficient must be convertible to the multivector’s eltype.)
GeometricAlgebra.antiwedge
— Methoda ∨ b
antiwedge(a, b)
Anti-wedge product of multivectors (a.k.a. the regressive product or meet).
The anti-wedge product satisfies
\[D(a ∨ b) = (D a) ∧ (D b)\]
where $D$ is a duality operation such as ldual
, rdual
or, if $I^2 ≠ 0$, hodgedual
.
The anti-wedge product is metric independent like the wedge product, but does depend on the choice of orientation (the ordering of basis vectors).
GeometricAlgebra.clifford_conj
— Methoda'ᶜ
clifford_conj(a)
Clifford conjugate of a multivector.
Equivalent to reversion(involution(a))
.
GeometricAlgebra.flipdual
— Functionflipdual(a)
A dual of a multivector, for when the overall sign isn’t important.
For a unit a::BasisBlade
, the flipdual satisfies a*flipdual(a) == ±I
where ±I
is the unit pseudoscalar or its negative.
The flipdual
is cheap to compute and is its own inverse. It simply flips the bits of a BasisBlade
, or reverses the components vector of a Multivector
.
The flipdual
is metric independent (but depends on a choice of orientation, or the order of basis vectors).
See also hodgedual
.
GeometricAlgebra.geometric_prod
— Methoda * b
geometric_prod(a, b)
Geometric product of multivectors.
GeometricAlgebra.graded_multiply
— Methodgraded_multiply(f, a::AbstractMultivector)
Multiply the grade k
part of a
by f(k)
.
GeometricAlgebra.graded_prod
— Methodgraded_prod(grade_selector::Function, a, b)
A grade-filtered product of multivectors.
Terms of the geometric product a*b
are filtered according to grade_selector
. For instance, if grade(a) == p
and grade(b) == q
, then graded_prod(f, a, b)
is the grade f(p, q)
part of a*b
. The extends linearly to general multivectors $A$ and $B$ as
\[ (A, B) ↦ \sum_{p,q} ⟨⟨A⟩_p ⟨B⟩_q⟩_{f(p, q)}\]
where $⟨⋅⟩_k$ denotes the grade $k$ part.
The wedge $∧$, inner $⋅$ and contraction products are special cases of this product. For example, the wedge product is defined as:
wedge(a, b) = graded_prod(+, a, b)
GeometricAlgebra.hodgedual
— Functionhodgedual(a) = ~a*I
Hodge dual of a multivector.
The Hodge dual is defined by
\[H(a) = ã I\]
where $ã$ is the reversion of $a$ and $I$ is the unit pseudoscalar. For $k$-vectors $a$ and $b$, it is alternatively defined by
\[a ∧ H(b) = ⟨a, b⟩ I\]
where $⟨a, b⟩ = a ⊙ b̃$ is the induced inner product on $k$-vectors.
The Hodge dual is metric dependent, since it involves multiplication by I
.
See also invhodgedual
and ldual
, rdual
.
Examples
julia> u = Multivector{3,1}(1:3)
3-component Multivector{3, 1, UnitRange{Int64}}:
1 v1
2 v2
3 v3
julia> hodgedual(u)
3-component Multivector{3, 2, MVector{3, Int64}}:
3 v12
-2 v13
1 v23
GeometricAlgebra.inner
— Methoda ⋅ b
inner(a, b)
Inner product of multivectors.
This is a grade lowering operation, equivalent to graded_prod(abs∘-, a, b)
. If a
and b
are of grades $p$ and $q$ respectively, then a ⋅ b
is defined as the grade $|p - q|$ part of a*b
.
Note that for scalars a
and b
, the inner product reduces to scalar multiplication, in contrast to some authors (see [1] for discussion).
GeometricAlgebra.invhodgedual
— Functioninvhodgedual(a)
Inverse of the multivector Hodge dual.
In degenerate algebras (for which $I^2 = 0$), the Hodge dual is not invertible. However, if a
is a basis blade with a non-zero Hodge dual, then invhodgedual(hodgedual(a)) == a
holds.
See also hodgedual
.
GeometricAlgebra.involution
— Methodinvolution(a)
Involute of a multivector.
Involution is an automorphism defined by reflecting through the origin: for homogeneous multivectors, involution(a) == (-1)^grade(a)*a
.
See also reversion
and clifford_conj
.
GeometricAlgebra.lcontract
— Methoda ⨼ b
lcontract(a, b)
Left contraction of multivectors.
Equivalent to graded_prod((p, q) -> q - p, a, b)
. If a
and b
are of grades $p$ and $q$ respectively, then a ⨼ b
is defined as the grade $q - p$ part of a*b
.
GeometricAlgebra.ldual
— Functionldual(a)
rdual(a)
Left and right multivector duals (a.k.a., complements). The right dual is also called the Poincaré dual.
For a unit basis blade a
, the duals satisfy a*rdual(a) == I == ldual(a)*a
where I
is the unit pseudoscalar. If dimension(a)
is odd, rdual
and ldual
are identical and self-inverse; in general, they are inverses of each other.
The left and right duals are metric independent (but depend on a choice of orientation, or the order of basis vectors). This makes them useful in degenerate algebras where I^2 == 0
, since a non-zero multivector always has a non-zero dual, even if its Hodge dual is zero.
See also hodgedual
.
GeometricAlgebra.outermorphism
— Methodoutermorphism(mat, a)
Outermorphism of the multivector a
specified by the matrix mat
.
If $f$ is a linear map, then the outermorphism $f̲$ is a linear map satisfying $f̲(𝒖) = f(𝒖)$ on vectors $𝒖$ and $f̲(a ∧ b) = f̲(a) ∧ f̲(b)$ on general multivectors.
GeometricAlgebra.rcontract
— Methoda ⨽ b
rcontract(a, b)
Right contraction of multivectors.
Equivalent to graded_prod(-, a, b)
. If a
and b
are of grades $p$ and $q$ respectively, then a ⨽ b
is defined as the grade $p - q$ part of a*b
.
GeometricAlgebra.rdual
— Functionldual(a)
rdual(a)
Left and right multivector duals (a.k.a., complements). The right dual is also called the Poincaré dual.
For a unit basis blade a
, the duals satisfy a*rdual(a) == I == ldual(a)*a
where I
is the unit pseudoscalar. If dimension(a)
is odd, rdual
and ldual
are identical and self-inverse; in general, they are inverses of each other.
The left and right duals are metric independent (but depend on a choice of orientation, or the order of basis vectors). This makes them useful in degenerate algebras where I^2 == 0
, since a non-zero multivector always has a non-zero dual, even if its Hodge dual is zero.
See also hodgedual
.
GeometricAlgebra.reversion
— Method~a
reversion(a::AbstractMultivector)
Reversion of a multivector.
Reversion is an anti-automorphism defined by reversing the order of the geometric product: ~(a*b) == ~b * ~a
. For a k
-vector a
, the reversion is reversion_sign(k)*a
where the sign is given by $(-1)^{k(k - 1)/2}$.
See also involution
and clifford_conj
.
GeometricAlgebra.sandwich_prod
— Functionsandwich_prod(R, a)
Sandwich product R*a*~R
of multivector a
by a rotor R
.
GeometricAlgebra.scalar_prod
— Methoda ⊙ b
scalar_prod(a, b) -> Number
Scalar part of the geometric product a*b
.
GeometricAlgebra.wedge
— Methoda ∧ b
wedge(a, b)
Wedge product of multivectors (a.k.a. the outer, exterior, progressive or alternating product, or join).
This is a grade-raising operation, equivalent to graded_prod(+, a, b)
. If a
and b
are of grades $p$ and $q$ respectively, then a ∧ b
is defined as the grade $p + q$ part of a*b
.
GeometricAlgebra.inv_flv_method
— Methodinv_flv_method(::AbstractMultivector)
Inverse of a multivector using the Faddeev–LeVerrier algorithm [1].
This algorithm requires $2^{d - 1}$ many geometric multiplications, where $d$ is the dimension of the algebra.
GeometricAlgebra.matrix_repr
— Functionmatrix_repr(a::AbstractMultivector, k=0:dim)
Matrix representation of the grade k
parts of a multivector.
By default, the full $2^d × 2^d$ linear representation is used in $d$ dimensions. Smaller representations can be used for elements in
- the even subalgebra,
k=0:2:dim
- the scalar-pseudoscalar subalgebra,
k=(0, dim)
by restricting k
to those grades.
Examples
julia> @basis 2
[ Info: Defined basis blades v1, v2, v12, I in Main
julia> matrix_repr(1 + 7v12)
4×4 Matrix{Int64}:
1 0 0 -7
0 1 7 0
0 -7 1 0
7 0 0 1
julia> matrix_repr(1 + 7v12, (0, 2))
2×2 Matrix{Int64}:
1 -7
7 1
julia> matrix_repr(v1*v2) == matrix_repr(v1)matrix_repr(v2)
true
GeometricAlgebra.try_ensure_real
— Methodtry_ensure_real(a::Multivector)
Tries to convert a complex-valued Multivector
into an equivalent real one, returning the original multivector if it failed.
If an algebra $G$ has a commuting pseudoscalar squaring to $-1$, then there is a canonical map $G ⊗ ℂ ↦ G$ from the complexified algebra into itself given my sending the imaginary unit to the pseudoscalar.
Metric Signatures
GeometricAlgebra.Cl
— TypeCl(p, q=0, r=0)
Metric signature where p
, q
and r
are the number of basis vectors of norm +1
, -1
and 0
, respectively.
Examples
julia> basis(Cl(1,3))
4-element Vector{BasisBlade{Cl(1,3), 1, Int64}}:
1 v1
1 v2
1 v3
1 v4
julia> ans .^ 2
4-element Vector{BasisBlade{Cl(1,3), 0, Int64}}:
1
-1
-1
-1
GeometricAlgebra.Cl
— MethodCl(sig::String) -> Tuple
Shorthand for a tuple specifying a metric signature, e.g., Cl("-+++") === (-1, +1, +1, +1)
. String may contain '+'
, '-'
and '0'
.
For readability, AbstractMultivector
types with a tuple metric signature display the signature as Cl("...")
.
Examples
julia> Cl("+++") # 3D Euclidean metric signature
(1, 1, 1)
julia> basis(ans)
3-element Vector{BasisBlade{Cl("+++"), 1, Int64}}:
1 v1
1 v2
1 v3
julia> Multivector{(0,-1,1,1,1),2}
Multivector{Cl("0-+++"), 2} (pretty-printed Multivector{(0, -1, 1, 1, 1), 2})
GeometricAlgebra.canonicalize_signature
— Methodcanonicalize_signature(sig)
Canonical tuple representation of a metric signature.
Examples
julia> Cl(1,3)
Cl(1,3) (pretty-printed Cl{1, 3, 0}())
julia> GeometricAlgebra.canonicalize_signature(ans)
(1, -1, -1, -1)
GeometricAlgebra.cayleytable
— Methodcayleytable(sig, op=*)
cayleytable(objs, op=*)
Display a multivector multiplication table.
The first argument may be a metric signature or any vector of objects which can be combined with the binary operator op
.
The keyword argument title
sets the contents of the top-left cell.
Examples
julia> cayleytable(3)
(↓) * (→) │ 1 │ v1 v2 v3 │ v12 v13 v23 │ v123
───────────┼──────┼───────────────────┼───────────────────┼──────
1 │ 1 │ v1 v2 v3 │ v12 v13 v23 │ v123
───────────┼──────┼───────────────────┼───────────────────┼──────
v1 │ v1 │ 1 v12 v13 │ v2 v3 v123 │ v23
v2 │ v2 │ -v12 1 v23 │ -v1 -v123 v3 │ -v13
v3 │ v3 │ -v13 -v23 1 │ v123 -v1 -v2 │ v12
───────────┼──────┼───────────────────┼───────────────────┼──────
v12 │ v12 │ -v2 v1 v123 │ -1 -v23 v13 │ -v3
v13 │ v13 │ -v3 -v123 v1 │ v23 -1 -v12 │ v2
v23 │ v23 │ v123 -v3 v2 │ -v13 v12 -1 │ -v1
───────────┼──────┼───────────────────┼───────────────────┼──────
v123 │ v123 │ v23 -v13 v12 │ -v3 v2 -v1 │ -1
julia> cayleytable(basis((t=-1, x=1, y=1, z=1), 2), ∧)
(↓) ∧ (→) │ tx ty xy tz xz yz
───────────┼──────────────────────────────────────
tx │ 0 0 0 0 0 txyz
ty │ 0 0 0 0 -txyz 0
xy │ 0 0 0 txyz 0 0
tz │ 0 0 txyz 0 0 0
xz │ 0 -txyz 0 0 0 0
yz │ txyz 0 0 0 0 0
GeometricAlgebra.componentstype
— Methodcomponentstype(sig, N) -> Type{<:AbstractVector}
The component array type for N
-component multivectors with signature sig
.
You can redefine this method to customise the default array type. The fallback method returns MVector{N}
for N <= 16
, and Vector
otherwise.
GeometricAlgebra.ncomponents
— Methodncomponents(sig) = 2^dimension(sig)
ncomponents(sig, k) = binomial(dimension(sig), k)
Dimension of (the grade-k
subspace of) the geometric algebra of metric signature sig
, viewed as a vector space.
If the dimension of the underlying vector space (see dimension
) in $n$, then the algebra is $2^n$-dimensional, and its grade-$k$ subspace $\binom{n}{k}$-dimensional.
GeometricAlgebra.show_basis_blade
— Methodshow_basis_blade(io, sig, indices::Vector{Int})
Show the basis blade $𝒗_{i₁}⋯𝒗_{iₖ}$ with each $iⱼ$ in indices
in the geometric algebra defined by sig
. Methods dispatching on sig
should be added to customise basis blade labels for particular algebras.
Examples
julia> GeometricAlgebra.show_basis_blade(stdout, (1, 1, 1), [1, 3])
v13
julia> using GeometricAlgebra: subscript
julia> GeometricAlgebra.show_basis_blade(io, sig, indices) = print(io, join("𝒆".*subscript.(indices), "∧"))
julia> prod(basis(4))
BasisBlade{⟨++++⟩, 4, Int64} of grade 4:
1 𝒆₁∧𝒆₂∧𝒆₃∧𝒆₄
GeometricAlgebra.show_signature
— Methodshow_signature(io, sig)
Pretty-print the metric signature sig
.
This is used to display the metric signature type parameter in AbstractMultivector
subtypes to reduce visual noise. Methods may optionally be added for user-defined metric signatures, in a similar fashion to Base.show
.
Examples
julia> sig = (+1,-1,-1,-1)
(1, -1, -1, -1)
julia> GeometricAlgebra.show_signature(stdout, sig)
Cl("+---")
julia> BasisBlade{sig}
BasisBlade{Cl("+---")} (pretty-printed BasisBlade{(1, -1, -1, -1)})
GeometricAlgebra.BASIS_DISPLAY_STYLES
— ConstantGeometricAlgebra.BASIS_DISPLAY_STYLES
A dictionary specifying the BasisDisplayStyle
to use for each metric signature key.
The style for the key sig
must have the same dimension as sig
.
To use the default display style, remove the entry for sig
with delete!(GeometricAlgebra.BASIS_DISPLAY_STYLES, sig)
or remove all with empty!
.
GeometricAlgebra.BasisDisplayStyle
— TypeBasisDisplayStyle(dim, blades[, blade_order]; kwargs...)
BasisDisplayStyle(dim, blades_and_order; kwargs...)
Specifies how basis blades are displayed and ordered. The default style for multivectors of metric signature sig
can be set with GeometricAlgebra.BASIS_DISPLAY_STYLES[sig] = style
.
dim::Int
is the dimension of the algebra (number of basis vectors).blades::Dict{UInt,Vector{Int}}
encodes the order of basis vectors in basis blades. E.g.,0b101 => [1, 3]
is the default style.blade_order::Dict{Int,Vector{UInt}}
specifies the order of basis blades in a single grade. E.g.,3 => [0b011, 0b101, 0b110]
is the default ordering.blades_and_order::Dict{Int,Vector{Int}}
gives a way of specifying the previous two mappings at once. E.g.,3 => [[1,2], [1,3], [2,3]]
.
Keyword arguments
indices=1:dim
specifies the symbols used for each basis vector.prefix="v"
is the prefix string for basis blades (ifsep == nothing
) or for each basis vector.sep=nothing
is a string (e.g.,"∧"
) to separate each basis vector in a blade. Ifsep
isnothing
, blades are shown as e.g.,v123
, whereas an empty string results inv1v2v3
.labels
is a dictionary allowing individual basis blades to be given custom labels. E.g.,[3,2] => "𝒊"
means4v32
is displayed as4𝒊
(so long as the order0b110 => [3,2]
is also specified in theblades
argument — otherwise it would display as the default-4v23
).
BasisDisplayStyle
only affects how multivectors are displayed. The actual internal layout of multivectors is never affected. However, the active style for sig
can affect the value of basis(sig)
.
Examples
julia> Multivector{Cl(0,3),2}([3, -2, 1])
3-component Multivector{Cl(0,3), 2, Vector{Int64}}:
3 v12
-2 v13
1 v23
julia> cyclical_style = BasisDisplayStyle(
3, Dict(2 => [[2,3], [3,1], [1,2]]);
indices = "₁₂₃",
prefix = "e",
sep = "",
labels = Dict([1,2,3] => "I"),
);
julia> GeometricAlgebra.BASIS_DISPLAY_STYLES[Cl(0,3)] = cyclical_style;
julia> Multivector{Cl(0,3),2}([3, -2, 1])
3-component Multivector{Cl(0,3), 2, Vector{Int64}}:
1 e₂e₃
2 e₃e₁
3 e₁e₂
julia> ans*rdual(ans) # pseudoscalar `e₁e₂e₃` displayed as `I`
4-component Multivector{Cl(0,3), 1:2:3, MVector{4, Int64}}:
14 I
To recover the default style:
julia> delete!(GeometricAlgebra.BASIS_DISPLAY_STYLES, Cl(0,3))
IdDict{Any, BasisDisplayStyle}()
GeometricAlgebra.basis
— Functionbasis(sig, k=1)
Vector of BasisBlade
s of specified grade(s) k
for the geometric algebra defined by the metric signature sig
. The value k=:all
is a shortcut for 0:dimension(sig)
.
The particular basis blades returned by basis
and their order reflects the signature’s BasisDisplayStyle
. You can guarantee the default style by using
BasisBlade{sig}.(1, componentbits(dimension(sig), k))
instead of basis(sig, k)
.
See also @basis
.
Examples
julia> basis(3)
3-element Vector{BasisBlade{3, 1, Int64}}:
1 v1
1 v2
1 v3
julia> basis("-+++", 0:2:4)
8-element Vector{BasisBlade{Cl("-+++"), _A, Int64} where _A}:
1
1 v12
1 v13
1 v23
1 v14
1 v24
1 v34
1 v1234
julia> basis(Cl(1,3), :all) |> sum
16-component Multivector{Cl(1,3), 0:4, MVector{16, Int64}}:
1
1 v1 + 1 v2 + 1 v3 + 1 v4
1 v12 + 1 v13 + 1 v23 + 1 v14 + 1 v24 + 1 v34
1 v123 + 1 v124 + 1 v134 + 1 v234
1 v1234
GeometricAlgebra.basis
— Methodbasis(::Type{<:Multivector})
Create a generator which iterates over basis elements of the given multivector type.
Examples
julia> basis(Multivector{3,1}) |> collect
3-element Vector{Multivector{3, 1, MVector{3, Int64}}}:
v1
v2
v3
julia> basis(Multivector{2,0:2,Vector{Bool}}) |> collect
4-element Vector{Multivector{2, 0:2, Vector{Bool}}}:
(1)
(v1)
(v2)
(v12)
GeometricAlgebra.@basis
— Macro@basis sig grades=:all scalar=false pseudoscalar=:I allperms=false prefix=nothing
Populate namespace with basis blades for the geometric algebra defined by metric signature sig
.
Variable names are generated with show_basis_blade()
.
Keyword arguments
grades
: which grades to define basis blades for (default:all
).scalar
: whether to include the unit scalar blade (e.g.,v
).pseudoscalar
: alias for unit pseudoscalar (default:I
).pseudoscalar=nothing
defines no alias.allperms
: include all permutations of each basis blade (e.g., definev21
as well asv12
).prefix
: prefix for basis blades names (nothing
leaves default names unchanged).
This defines 2^dimension(sig)
variables with grades=:all
, and more with allperms=true
!
Examples
julia> @basis 3
[ Info: Defined basis blades v1, v2, v3, v12, v13, v23, v123, I in Main
julia> 1v2 + 3v12
8-component Multivector{3, 0:3, MVector{8, Int64}}:
1 v2
3 v12
julia> @basis "0++" prefix=:e
[ Info: Defined basis blades e1, e2, e3, e12, e13, e23, e123, I in Main
julia> @basis 2 allperms=true scalar=true pseudoscalar=nothing
[ Info: Defined basis blades v, v1, v2, v12, v21 in Main
julia> @basis (t=1,x=-1,y=-1,z=-1) grades=2 allperms=true
[ Info: Defined basis blades tx, xt, ty, yt, xy, yx, tz, zt, xz, zx, yz, zy in Main
Logic for bits and grades
GeometricAlgebra.BitPermutations
— TypeBitPermutations{T}(n)
Infinite iterator returning all unsigned integers of type T
, in ascending order, for which Base.count_ones
is n
.
GeometricAlgebra.bits_of_grade
— Methodbits_of_grade(k[, dim])
Generate basis blade bits of grade k
in ascending order. Yields all basis blades in the dimension dim
, if given, otherwise iterates indefinitely.
Examples
julia> GeometricAlgebra.bits_of_grade(2, 4) .|> UInt8 .|> bitstring
6-element Vector{String}:
"00000011"
"00000101"
"00000110"
"00001001"
"00001010"
"00001100"
GeometricAlgebra.bits_to_indices
— Methodbits_to_indices(bits)
Return the positions of the ones in the unsigned integer bits
.
Used to convert between representations of a unit basis blade. Inverse of indices_to_bits
.
Examples
julia> GeometricAlgebra.bits_to_indices(0b1001101)
4-element Vector{Int64}:
1
3
4
7
GeometricAlgebra.componentbits
— Methodcomponentbits(n, k)
componentbits(::Val{N}, ::Val{K})
Vector of bits corresponding to components of an n
-dimensional Multivector
of grade(s) k
.
Bits are ordered first by grade (count_ones
), then lexicographically (in ascending numerical order).
Passing Val
arguments calls a faster, memoized method.
Examples
julia> componentbits(4, 2) .|> UInt8 .|> bitstring
6-element Vector{String}:
"00000011"
"00000101"
"00000110"
"00001001"
"00001010"
"00001100"
julia> componentbits(3, 0:3) .|> UInt8 .|> bitstring
8-element Vector{String}:
"00000000"
"00000001"
"00000010"
"00000100"
"00000011"
"00000101"
"00000110"
"00000111"
GeometricAlgebra.factor_from_squares
— Methodfactor_from_squares(sig, bits::Unsigned)
Compute the overall factor arising from the geometric product between repeated basis vectors.
GeometricAlgebra.geometric_prod_factor
— Methodgeometric_prod_factor(sig, a::Unsigned, b::Unsigned)
The scalar factor resulting from the geometric product between unit blades.
GeometricAlgebra.indices_to_bits
— Functionindices_to_bits(indices, T=UInt)
Create unsigned integer with bits at the positions given in the vector indices
.
Used to convert between representations of a unit basis blade. Inverse of bits_to_indices
.
Only correct if maximum(indices)
does not exceed number of bits in T
.
Examples
julia> GeometricAlgebra.indices_to_bits([1, 2, 5], UInt8) |> bitstring
"00010011"
GeometricAlgebra.next_bit_permutation
— MethodReturn the smallest uint larger than the one given which has the same number of binary ones. Algorithm is Gosper’s hack.
Examples
julia> GeometricAlgebra.next_bit_permutation(0b1011) |> bitstring
"00001101"
GeometricAlgebra.reversion_sign
— Methodreversion_sign(k) = mod(k, 4) <= 1 ? +1 : -1
Sign from reversing a $k$-vector, equal to $(-1)^{k(k - 1)/2}$.
GeometricAlgebra.sign_from_swaps
— Methodsign_from_swaps(a::Unsigned, b::Unsigned)
Compute sign flips of blade product due to transposing basis vectors into sorted order. (The full sign of the product will also depend on the basis norms.)
Base.getindex
— Methoda[k]
getindex(a::Multivector, k)
Get the grade(s) k
part of a multivector a
if k ⊆ grade(a)
. The components of the resulting Multivector
are a view into the components of a
, so modifying a[k].comps
changes a
.
GeometricAlgebra.componentindices
— Methodcomponentindices(a, k)
Indices of the components of grade(s) k
in multivector a
. Throws an error if k ∉ grade(a)
.
The grade k
may be an integer (returning a range) or a collection of grades (returning a vector of indices).
GeometricAlgebra.grade
— Methodgrade(::AbstractMultivector{Sig}, k) -> Multivector{Sig,k}
Construct a Multivector{Sig,k}
from the grade k
parts of a blade or multivector. Multiple grades may be specified with a range or tuple.
The operators +
and -
may be used as shortcuts for the even and odd parts, respectively.
If the return type must be inferable, use grade(a, Val(k))
.
Examples
julia> grade(BasisBlade{3}(42, 0b101), 2)
3-component Multivector{3, 2, MVector{3, Int64}}:
0 v12
42 v13
0 v23
julia> a = Multivector{3, 0:3}(1:8);
julia> grade(a, 1)
3-component Multivector{3, 1, UnitRange{Int64}}:
2 v1
3 v2
4 v3
julia> grade(a, 0:3:3)
2-component Multivector{3, 0:3:3, MVector{2, Int64}}:
1
8 v123
julia> grade(a, +) # only even grades
4-component Multivector{3, 0:2:2, MVector{4, Int64}}:
1
5 v12 + 6 v13 + 7 v23
GeometricAlgebra.promote_grades
— Methodpromote_grades(dim, k)
Canonicalize the grade type parameter k
.
Returns a subset of 0:dim
, while attempting to normalize equivalent representations, such as 0:1:3 => 0:3
or (3, 0) => (0, 3)
.
GeometricAlgebra.promote_grades
— Methodpromote_grades(dim, p, q, ...)
Return a suitable grade type parameter which contains the grades p ∪ q ∪ ...
.
In order to reduce the number of possible type parameters, the result may be larger than the exact union. Specifically, when combining different grades, promote_grades
will try to return the narrowest grade(s) out of:
- an integer
k ∈ 0:dim
for homogeneous elements (fewest components) 0:dim:dim
, for elements in the scalar-pseudoscalar subalgebra0:2:dim
, for elements in the even subalgebra0:dim
, for general inhomogeneous elements (most components)
Examples
julia> promote_grades(4, 0:4, 2, 7)
0:4
julia> promote_grades(4, 0, 2) # even multivectors are worth representing specifically
0:2:4
julia> promote_grades(4, 0, 3) # not worth having a specific type for grades (0, 3) in 4 dims
0:4
GeometricAlgebra.resulting_grades
— Methodresulting_grades(combine, dim, p, q)
Non-zero grade(s) resulting from the application of combine
on dim
-dimensional multivectors of grade(s) p
and q
.
Display methods
GeometricAlgebra.show_blade
— MethodDisplay blade with parentheses surrounding coefficient if necessary.
Example
julia> GeometricAlgebra.show_blade(stdout, BasisBlade{(x=1,)}(1 + im, 0b1))
(1 + 1im) x
GeometricAlgebra.show_multivector
— Methodshow_multivector(io, a; kwargs...)
Display multivector components in a column or inline, optionally grouping by grade.
Keyword arguments
inline::Bool
: print on one line (defaulttrue
)groupgrades::Bool
: visually group components by grade (defaulttrue
). If inline, prints parentheses around parts of each grade; if multiline, prints each grade on its own lineshowzeros::Bool
: whether to omit zero components from displayindent::Integer
: indentation widthparseable::Bool
: use parseable style (used byrepr
) instead of human-readable style
Examples
julia> a = Multivector{2,0:2}((1:4) .^ 2);
julia> GeometricAlgebra.show_multivector(stdout, a; inline=false, groupgrades=false)
1
4 v1
9 v2
16 v12
julia> GeometricAlgebra.show_multivector(stdout, a; inline=false, groupgrades=true)
1
4 v1 + 9 v2
16 v12
julia> GeometricAlgebra.show_multivector(stdout, a; inline=true, groupgrades=true)
(1) + (4 v1 + 9 v2) + (16 v12)
julia> GeometricAlgebra.show_multivector(stdout, a; inline=true, groupgrades=false)
1 + 4 v1 + 9 v2 + 16 v12
julia> GeometricAlgebra.show_multivector(stdout, a; parseable=true)
Multivector{2, 0:2}([1, 4, 9, 16])
Code generation
GeometricAlgebra.make_symbolic
— Methodmake_symbolic(a, label)
Multivector with symbolic components of the same type as the Multivector
instance or type a
.
See also symbolic_components
.
Example
julia> GeometricAlgebra.make_symbolic(Multivector{3,1}, :A)
3-component Multivector{3, 1, Vector{Any}}:
A[1] v1
A[2] v2
A[3] v3
GeometricAlgebra.symbolic_components
— Methodsymbolic_components(label::Symbol, dims::Integer...)
Create an array of symbolic values of the specified shape.
See also make_symbolic
.
Example
julia> GeometricAlgebra.symbolic_components(:a, 2, 3)
2×3 Matrix{Any}:
a[1, 1] a[1, 2] a[1, 3]
a[2, 1] a[2, 2] a[2, 3]
julia> prod(ans)
a[1, 1]*a[1, 2]*a[1, 3]*a[2, 1]*a[2, 2]*a[2, 3]
GeometricAlgebra.symbolic_multivector_eval
— Methodsymbolic_multivector_eval(compstype, f, x::AbstractMultivector...)
Evaluate f(x...)
using symbolically generated code, returning a Multivector
with components array of type compstype
.
This is a generated function which first evaluates f
on symbolic versions of the multivector arguments x
and then converts the symbolic result into unrolled code.
Calling symbolic_multivector_eval(Expr, compstype, f, x...)
with Expr
as the first argument returns the expression to be compiled.
See also @symbolic_optim
.
Example
julia> A, B = Multivector{2,1}([1, 2]), Multivector{2,1}([3, 4]);
julia> symbolic_multivector_eval(Expr, MVector, geometric_prod, A, B)
quote # prettified for readability
let a = Multivector(args[1]).comps, b = Multivector(args[2]).comps
comps = SymbolicUtils.Code.create_array(
MVector, Int64, Val(1), Val((2,)),
a[1]*b[1] + a[2]*b[2],
a[1]*b[2] - a[2]*b[1],
)
Multivector{2, 0:2:2}(comps)
end
end
julia> @btime symbolic_multivector_eval(MVector, geometric_prod, A, B);
86.928 ns (3 allocations: 192 bytes)
julia> @btime geometric_prod(Val(:nosym), A, B); # opt-out of symbolic optim
4.879 μs (30 allocations: 1.22 KiB)
GeometricAlgebra.use_symbolic_optim
— Methoduse_symbolic_optim(sig) -> Bool
Whether to use symbolic optimization in algebras of metric signature sig
.
By default, this is enabled if dimension(sig) ≤ 8
(in many dimensions, algebraic expressions may become too unwieldy).
GeometricAlgebra.@symbolic_optim
— Macro@symbolic_optim <method definition>
Convert a single method definition f(args...)
into two methods:
- The original method
f(Val(:nosym), args...)
, called withVal(:nosym)
as the first argument. This calls the original method, without any symbolic optimization. - An optimized method
f(args...)
which callssymbolic_multivector_eval
. Code for this method is generated by callingf(Val(:nosym), args...)
with symbolic versions of theMultivector
arguments.
This is to reduce boilerplate when writing symbolically optimized versions of each method. It only makes sense for methods with at least one AbstractMultivector
argument for which the exact return type is inferable.
Example
# This macro call...
@symbolic_optim foo(a, b) = (a + b)^2
# ...is equivalent to the following two method definitions:
foo(::Val{:nosym}, a, b) = (a + b) ^ 2
function foo(a, b)
if use_symbolic_optim(foo, a, b)
symbolic_optim(foo, Val(:nosym), a, b)
else
foo(Val(:nosym), a, b)
end
end
GeometricAlgebra.@symbolicga
— Macro@symbolicga sig mv_grades expr [result_type]
Evaluate a symbolically optimised geometric algebra expression.
Upon macro expansion, expr
is evaluated with symbolic multivectors (specified by mv_grades
) in the algebra defined by metric signature sig
. The resulting symbolic expression is then compiled and executed at runtime.
The mv_grades
argument is a NamedTuple
where keys(mv_grades)
defines the identifiers in expr
to be interpreted as Multivector
s, while values(mv_grades)
defines their respective grades. The identifiers must exist at runtime, and can be a Multivector
with matching signature/grade or any iterable with the correct number of components.
If result_type
is given, then the components of the resulting multivector are converted to that type. The result type T
should implement T(::Tuple)
, e.g., Tuple
or MVector
.
Operations that are not amenable to symbolic evaluation (such as exp
, log
, sqrt
, etc) are not supported.
(You may test if operations work on symbolic multivectors created with GeometricAlgebra.make_symbolic
.)
Examples
julia> v = (1, 2, 0); R = exp(Multivector{3,2}([0, π/8, 0]));
julia> # Rotate a tuple (interpreted as a grade 1 vector)
# by a rotor, returning a tuple.
@symbolicga 3 (v=1, R=0:2:4) grade(R*v*~R, 1) Tuple
(0.7071067811865475, 2.0, -0.7071067811865476)
# This macro call...
@symbolicga 3 (a=1, b=1) a∧b
# ...is equivalent to the following:
let a = Multivector{3, 1}(a).comps, b = Multivector{3, 1}(b).comps
Multivector{3, 2}(MVector(
a[1]*b[2] - a[2]*b[1],
a[1]*b[3] - a[3]*b[1],
a[2]*b[3] - a[3]*b[2],
))
end
Utilities
GeometricAlgebra.SingletonVector
— TypeSingletonVector(el, index, length)
Efficient representation of a vector of all zeros except for the single element el
at the given index.