Pythonic Geometric Algebra Package
- Free software: MIT license
- Documentation: https://kingdon.readthedocs.io.
✨ Try kingdon in your browser ✨
Kingdon is a Geometric Algebra (GA) library which combines a Pythonic API with
symbolic simplification and just-in-time compilation to achieve high-performance in a single package.
It support both symbolic and numerical GA computations.
Moreover, kingdon
uses ganja.js
for visualization in notebooks,
making it an extremely well rounded GA package.
In bullet points:
- Symbolically optimized.
- Leverage sparseness of input.
ganja.js
enabled graphics in jupyter notebooks.- Agnostic to the input types: work with GA's over
numpy
arrays,PyTorch
tensors,sympy
expressions, etc. Any object that overloads addition, subtraction and multiplication makes for valid multivector coefficients inkingdon
. - Automatic broadcasting, such that transformations can be applied to e.g. point-clouds.
- Compatible with
numba
and other JIT compilers to speed-up numerical computations.
In order to demonstrate the power of Kingdon
, let us first consider the common use-case of the
commutator product between a bivector and vector.
In order to create an algebra, use Algebra
. When calling Algebra
we must provide the signature of the
algebra, in this case we shall go for 3DPGA, which is the algebra \mathbb{R}_{3,0,1}.
There are a number of ways to make elements of the algebra. It can be convenient to work with the basis blades directly.
We can add them to the local namespace by calling locals().update(alg.blades)
:
>>> from kingdon import Algebra
>>> alg = Algebra(3, 0, 1)
>>> locals().update(alg.blades)
>>> b = 2 * e12
>>> v = 3 * e1
>>> b * v
-6 𝐞₂
This example shows that only the e2
coefficient is calculated, despite the fact that there are
6 bivector and 4 vector coefficients in 3DPGA. But by exploiting the sparseness of the input and by performing symbolic
optimization, kingdon
knows that in this case only e2
can be non-zero.
If only a name is provided for a multivector, kingdon
will automatically populate all
relevant fields with symbols. This allows us to easily perform symbolic computations.
>>> from kingdon import Algebra
>>> alg = Algebra(3, 0, 1)
>>> b = alg.bivector(name='b')
>>> b
b01 𝐞₀₁ + b02 𝐞₀₂ + b03 𝐞₀₃ + b12 𝐞₁₂ + b13 𝐞₁₃ + b23 𝐞₂₃
>>> v = alg.vector(name='v')
>>> v
v0 𝐞₀ + v1 𝐞₁ + v2 𝐞₂ + v3 𝐞₃
>>> b.cp(v)
(b01*v1 + b02*v2 + b03*v3) 𝐞₀ + (b12*v2 + b13*v3) 𝐞₁ + (-b12*v1 + b23*v3) 𝐞₂ + (-b13*v1 - b23*v2) 𝐞₃
It is also possible to define some coefficients to be symbolic by inputting a string, while others can be numeric:
>>> from kingdon import Algebra, symbols
>>> alg = Algebra(3, 0, 1)
>>> b = alg.bivector(e12='b12', e03=3)
>>> b
3 𝐞₀₃ + b12 𝐞₁₂
>>> v = alg.vector(e1=1, e3=1)
>>> v
1 𝐞₁ + 1 𝐞₃
>>> w = b.cp(v)
>>> w
3 𝐞₀ + (-b12) 𝐞₂
A kingdon
MultiVector with symbols is callable. So in order to evaluate w
from the previous example,
for a specific value of b12
, simply call w
:
>>> w(b12=10)
3 𝐞₀ + -10 𝐞₂
Operation | Expression | Infix | Inline |
---|---|---|---|
Geometric product | a*b |
a.gp(b) |
|
Inner | a|b |
a.ip(b) |
|
Scalar product | a.sp(b) |
||
Left-contraction | a.lc(b) |
||
Right-contraction | a.rc(b) |
||
Outer (Exterior) | a ^ b |
a.op(b) |
|
Regressive | a & b |
a.rp(b) |
|
Conjugate b by a
|
a >> b |
a.sw(b) |
|
Project a onto b
|
a @ b |
a.proj(b) |
|
Commutator of a and b
|
a.cp(b) |
||
Anti-commutator of a and b
|
a.acp(b) |
||
Sum of a and b
|
a + b |
a.add(b) |
|
Difference of a and b
|
a - b |
a.sub(b) |
|
Reverse of a
|
~a |
a.reverse() |
|
Squared norm of a
|
a.normsq() |
||
Norm of a
|
a.norm() |
||
Normalize a
|
a.normalized() |
||
Square root of a
|
a.sqrt() |
||
Dual of a
|
a.dual() |
||
Undual of a
|
a.undual() |
||
Grade k part of a
|
a.grade(k) |
This package was inspired by GAmphetamine.js.