I’ve been working on a new Julia package, CliffordNumbers.jl, that aims to provide an easy-to-use and high-performance implementation of geometric algebras.
My thought process when developing this package was that the Julia Number
abstract type encompasses Real
and Complex
, and the Quaternions.jl package provides Quaternion <: Number
. Since all of these systems are Clifford algebras, it stands to reason that a multivector implementation can also subtype Number
!
This leads to a few interesting decisions. For instance, multivectors (which are represented by the AbstractCliffordNumber{Q,T}
type, behave like scalars for the sake of broadcasting. While they can be indexed, they can only be indexed with a BitIndex
object, not an Integer
: the whole point is to index by basis blades of the algebra, not by elements of the underlying Tuple
.
Along with the full-grade CliffordNumber{Q,T,L}
we provide shorter types, EvenCliffordNumber{Q,T,L}
, OddCliffordNumber{Q,T,L}
(which are both aliases for CliffordNumbers.Z2CliffordNumber{P,Q,T,L}
, where P
is a Bool
that determines grade parity), and KVector{K,Q,T,L}
. These are all statically-sized types that can be stored inline in an array.
Algebras with arbitrary signatures and an orthogonal basis are supported when constructing types as the Q
parameter. I’d like to support non-orthogonal basis vectors in the future. The generic Signature
type specifies any combination of positive-squaring, negative-squaring, and zero-squaring basis vectors, but other types like VGA
, PGA
, and CGA
are provided to simplify implementation.
Multivector products are implemented in terms of a multiply kernel, CliffordNumbers.mul(::AbstractCliffordNumber{Q,T}, ::AbstractCliffordNumber{Q,T}, ::CliffordNumbers.GradeFilter)
, which uses the CliffordNumbers.GradeFilter
argument to filter out multiplications which go to zero for certain products. This is a generated function that uses aggressive constant propagation to achieve extremely high performance. Aside from several common products (geometric product, contractions, dot, Hestenes dot, wedge, regressive, commutator, and anticommutator) this package supports other basic arithmetic operations, exponentation, grade automorphisms, and complements.
This package has no dependences, not even LinearAlgebra or StaticArrays, so it is extremely lightweight and its load time is miniscule. In the future I will have package extensions that can integrate some of the functionality of this package with the two aforementioned packages. I’m not opposed to taking hard dependencies, I just haven’t found it necessary yet. (In the future, some functionality I’ve written that’s not specific to GA may be split off into different packages.)
Of course, a lot is subject to change with the API, but if you have feedback about how things can/should change, I’d love to hear it! The goal is to provide an easy point of entry for programmers who are curious about GA but don’t know where to start.