Skip to main content

Kingdon

https://img.shields.io/pypi/v/kingdon.svg Documentation Status https://coveralls.io/repos/github/tBuLi/kingdon/badge.svg?branch=master PyPI - Downloads

Pythonic Geometric Algebra Package

✨ Try kingdon in your browser ✨

Cite as:

@misc{roelfs2025willingkingdoncliffordalgebra,
      title={The Willing Kingdon Clifford Algebra Library},
      author={Martin Roelfs},
      year={2025},
      eprint={2503.10451},
      archivePrefix={arXiv},
      primaryClass={cs.MS},
      url={https://arxiv.org/abs/2503.10451},
}

Features

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 code generation.

  • Leverage sparseness of input.

  • ganja.js enabled graphics in jupyter notebooks.

  • Agnostic to the input types: work with GA’s over numpy arrays, torch tensors, sympy expressions, etc. Any object that overloads addition, subtraction and multiplication makes for valid multivector coefficients in kingdon.

  • Automatic broadcasting, such that transformations can be applied to e.g. point-clouds.

  • Compatible with einops if you import kingdon.einops_backend before you do your einops magic.

  • Compatible with numba and other JIT compilers to speed-up numerical computations.

Teahouse Menu

If you are thirsty for some examples, please visit the teahouse. A small selection of our items:

docs/_static/pga2d_distances_and_angles.png

Land measurement 101

docs/_static/pga2d_inverse_kinematics.png

Dimension agnostic IK

docs/_static/pga2d_project_and_reject.png

2D projection and intersection

docs/_static/pga3d_distances_and_angles.png

Land measurement 420

docs/_static/pga2d_hypercube_on_string.png

Best-seller: Tesseract on a string!

docs/_static/pga3d_points_and_lines.png

3D projection and intersection

docs/_static/exercise_spider6.png

Build-A-Spider Workshop!

docs/_static/cga2d_points_and_circles.png

Project and intersect, but round

docs/_static/pga2d_fivebar.png

Fivebar mechanism

docs/_static/csga2d_opns.jpg

2DCSGA!

docs/_static/mga3d_points_and_lines.jpg

Mother Algebra

docs/_static/ccga3d_points_quadrics.jpg

3DCCGA

Code Example

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.

Symbolic usage

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) 𝐞₂

Overview of Operators

Operators

Operation

Expression

Infix

Inline

Geometric product

$ab$

a*b

a.gp(b)

Inner

$a \cdot b$

a|b

a.ip(b)

Scalar product

$\langle a \cdot b \rangle_0$

a.sp(b)

Left-contraction

$a \rfloor b$

a.lc(b)

Right-contraction

$a \lfloor b$

a.rc(b)

Outer (Exterior)

$a \wedge b$

a ^ b

a.op(b)

Regressive

$a \vee b$

a & b

a.rp(b)

Conjugate a by b with \(\widetilde{b}b = 1\)

$\left(-1\right)^{\text{grade}\left(b\right) \text{grade}\left(a\right)} b a \widetilde{b}$

b >> a

b.sw(a)

Project a onto b with \(\widetilde{b}b = 1\)

$(a \cdot b) \widetilde{b}$

a @ b

a.proj(b)

Commutator of a and b

$a \times b = \tfrac{1}{2} [a, b]$

a.cp(b)

Anti-commutator of a and b

$\tfrac{1}{2} \{a, b\}$

a.acp(b)

Sum of a and b

$a + b$

a + b

a.add(b)

Difference of a and b

$a - b$

a - b

a.sub(b)

“Divide” a by b

$a b^{-1}$

a / b

a.div(b)

Inverse of a

$a^{-1}$

a.inv()

Reverse of a

$\widetilde{a}$

~a

a.reverse()

Grade Involution of a

$\hat{a}$

a.involute()

Clifford Conjugate of a

$\bar{a} = \hat{\widetilde{a}}$

a.conjugate()

Squared norm of a

$a \widetilde{a}$

a.normsq()

Norm of a

$\sqrt{a \widetilde{a}}$

a.norm()

Normalize a

$a / \sqrt{a \widetilde{a}}$

a.normalized()

Square root of a

$\sqrt{a}$

a.sqrt()

Dual of a

$a*$

a.dual()

Undual of a

a.undual()

Grade k part of a

$\langle a \rangle_k$

a.grade(k)

Credits

This package was inspired by GAmphetamine.js.

History

0.1.0 (2023-08-12)

  • First release on PyPI.

0.2.0 (2024-01-09)

  • Multivectors now have map and filter methods to apply element-wise operations to the coefficients.

  • Make matrix representations of expressions using expr_as_matrix.

  • Bugfixes.

0.3.0 (2024-03-11)

  • Much faster codegen by the introduction of a GAmphetamine.js inspired RationalPolynomial class, which now replaces SymPy for codegen. Particularly for inverses this is orders of magnitude faster.

  • Performed a numbotomy: numba is no longer a dependency since it actually didn’t add much in most cases. Instead the user can now provide the Algebra with any wrapper function, which is applied to the generated functions. This can be numba.njit, but also any other decorator.

0.3.2 (2024-03-18)

  • Fixed a high priority bug in the graph function.

  • Fixed a bug that stopped multivectors from being callable.

1.0.0 (2024-04-17)

  • Kingdon now has proper support for ganja.js animations and the graphs are interactive!

  • Indexing a multivector will no longer access coefficients. The whole promise of GA is coordinate independence, so why would you need to access coefficients? Instead, slicing a multivector will pass on that information to the underlying datastructures (e.g. numpy array or pytorch tensor), and will return a new multivector. Moreover, you can use the new slicing syntax to set values as well. If you really still need access to the coefficients, there is always the getattr syntax or the .values() method.

1.0.5 (2024-06-26)

  • Blades by grade syntax: alg.blades.grade(2).

  • Fixed “define” error in ganja.js integration, kingdon now works with reveal.js voila template.

1.0.6 (2024-07-10)

Bugfixes to ganja.js integration: * Make sure camera is an object before checking for ‘mv’ key. * Improved draggable points for PGA.

1.1.0 (2024-08-10)

  • Map and filter now support two argument functions. If such a funtion is provided, map/filter is applied on key, value pairs.

  • Added exponential function for simple objects.

  • Raising a mv to 0.5 is now correctly interpreted as a square root. This enables e.g. automatic differentiation.

1.1.2 (2024-11-15)

  • Improved printing, especially for multivector with array or multivector coefficients.

  • pretty_blade options added to algebra, to allow users to choose the printing of basis blades.

  • getattr bugfix

1.2.0 (2024-12-16)

  • Binary operators are now broadcasted across lists and tuples, e.g. R >> [point1, point2].

  • Projection (@) and conjugation (>>) are now symbolically optimized by default.

  • Matrix reps made with expr_as_matrix now have better support for numerical (and multidimensional) multivectors.

1.3.0 (2025-03-10)

  • Added custom basis support! You can now choose your own basis, to reduce the number of sign swaps. E.g. e31 instead of e13 for the j quaternion.

  • Added Algebra.fromname alternative constructor, to initiate popular algebras with optimized bases, identical to GAmphetamine.js.

  • Codegen has been made 2-15 times faster for basic operators.

  • Updated the documentation.

1.3.1 (2025-06-06)

Bugfix release: * matrix reps are now correct in all signatures (including custom signatures). * Fixed setattr discrepancy when trying to set a basis blade with setattr. * Support copying multivectors

1.4.0 (2025-07-11)

Massive large algebra improvement! * In theory up to 36 dimensions are supported* * Above d > 6 kingdon switches to large algebra mode and attempts to make optimizations * Exotic algebras like 2DCSGA (R5,3), Mother Algebra (R4,4) and 3DCCGA (R6,3) are no longer out of reach, see teahouse! * Bugfix: multivectors now take priority over numpy arrays in binary operators even when the numpy array is on the left.

2.0.0 (2026-03-03)

  • Length of a multivector is now defined such that multivectors are sequences if their coefficients are arrays. This allows users to iterate over e.g. point clouds naturally.

  • Improved documentation for array syntax.

  • Large algebra performance improvements.

2.1.0 (2026-03-12)

  • The conjugation operator >> now implements the twisted Clifford-Lipschitz action, meaning that it correctly implements sign flips on the basis of grade. Moreover, it now assumes that \(R\tilde{R}=1\), which allows us to carry out performance improvements in the future. See #123. This also means that if this not what you desire, you should implement your own sandwich operator.

  • The projection @ now assumes that the second argument is a versor (k-reflection).

  • Graphs can now be updated on the fly with the GraphWidget.update method.

  • The options provided to GraphWidget now also include a style argument, which allows you to set arbitrary arguments on canvas.style and so the graphs can now be customized to a much larger degree.

2.1.1 (2026-04-14)

Bugfix: width and height should be direct options to Algebra.graph

3.0.0 (2026-09-04)

  • Kingdon now has a type system, inspired by GAmphetamine.js. Multivector types such as point, direction, translation and bireflection are defined by a layout: either a dict of basis blades, or a classmethod holding a GA expression, from which kingdon derives which coefficients are free and which are structural constants. Constants are no longer stored or computed with, so the generated code is shorter: the counts in the CSE table of the docs are now reached by the built-in operators. Register your own types with the extra_types (or types) argument to Algebra.

  • The Algebra option graded has been renamed to full_layout, since it now enforces that every multivector carries the full layout of its type.

  • Algebra.register has been deprecated in favor of Algebra.add_operator, which is what it really does: it adds a new operator to the algebra. The old name still works but raises a FutureWarning.

  • MultiVector is no longer callable. To evaluate an expression for numerical values, build the multivector numerically or compile the expression with Algebra.add_operator/Algebra.compile.

  • Einops is now supported on Multivectors, allowing users to write einops expressions on multivector coefficients and seamlessly mix them with kingdon operations. See #46.

  • GAmphetamine.js inspired Common Subexpression Elimination (CSE) has been implemented, resulting in code that is as fast as hand optimized code for known test cases.

  • The Algebra.add_operator decorator now uses the new CSE by default, so compiled functions are now even faster without any changes to user code.

  • Algebra.compile is no longer a decorator: it now takes the expression followed by the symbolic multivectors to compile it for, and returns a CompiledExpression.

  • Algebra.graph now accepts multivectors whose coefficients are arrays, so meshes and point clouds are a single subject instead of thousands. The shape of the multivector decides what is drawn: (N,) gives N separate elements, (N, 2) line segments and (N, 3) filled triangles. The coefficients are sent to ganja.js as a single binary buffer, which is much faster than graphing the elements one by one. See the “Meshes and point clouds” section of the docs.

  • RationalPolynomial now has a diff method similar to that of SymPy.

  • The set method of Multivectors can be used within compiled functions to update coefficients in-place instead of returning a multivector.

  • Large algebras (large=True) have no multivector types: every multivector is a plain MultiVector. The k-vector constructors such as alg.vector and alg.pseudovector are still but they simply construct a MultiVector of that grade. Algebra.add_operator requires symbolic=True in a large algebra.

Metadata

Release files for kingdon 3.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for kingdon 3.0.0
File Size Uploaded
kingdon-3.0.0.tar.gz 1.3 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for kingdon 3.0.0
File Interpreter ABI Platform
kingdon-3.0.0-py2.py3-none-any.whl Python 3, Python 2 none any Details

Total release size: 1.4 MB

Release files / kingdon-3.0.0.tar.gz

Download URL kingdon-3.0.0.tar.gz
Size 1.3 MB
Tags Source
SHA-256 checksum
How to use checksums
77e6f3442b30f75daae33c73dc6086f175e9c70e5c2809bf411ecf7ff97d6e92
BLAKE2b-256 checksum
How to use checksums
ccff8c181d0bcd4ed41e122efd14cbb457379ff16cbcab56e5c3d6ee7f6f013d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / kingdon-3.0.0-py2.py3-none-any.whl

Download URL kingdon-3.0.0-py2.py3-none-any.whl
Size 73.1 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
5ed2e6706e7f9b72054506060ba7901572a867103cdde4532f21a2228ebd58ed
BLAKE2b-256 checksum
How to use checksums
1eb223032bb727738351bd68f5e7b988bf07a4a057335693e54741359da6a01f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

3.0.0 This release

2 release files

2.1.1

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.4.0

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.6

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page