=======
Kingdon
=======
.. image:: https://img.shields.io/pypi/v/kingdon.svg
:target: https://pypi.python.org/pypi/kingdon
.. image:: https://readthedocs.org/projects/kingdon/badge/?version=latest
:target: https://kingdon.readthedocs.io/en/latest/?version=latest
.. image:: https://coveralls.io/repos/github/tBuLi/kingdon/badge.svg?branch=master
:target: https://coveralls.io/github/tBuLi/kingdon?branch=master
Pythonic Geometric Algebra Package
* Free software: MIT license
* Documentation: https://kingdon.readthedocs.io.
`✨ Try kingdon in your browser ✨ <https://tbuli.github.io/teahouse/>`_
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, :code:`kingdon` uses :code:`ganja.js` for visualization in notebooks,
making it an extremely well rounded GA package.
In bullet points:
- Symbolically optimized.
- Leverage sparseness of input.
- :code:`ganja.js` enabled graphics in jupyter notebooks.
- Agnostic to the input types: work with GA's over :code:`numpy` arrays, :code:`PyTorch` tensors, :code:`sympy` expressions, etc. Any object that overloads addition, subtraction and multiplication makes for valid multivector coefficients in :code:`kingdon`.
- Automatic broadcasting, such that transformations can be applied to e.g. point-clouds.
- Compatible with :code:`numba` and other JIT compilers to speed-up numerical computations.
Code Example
------------
In order to demonstrate the power of :code:`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 :code:`Algebra`. When calling :code:`Algebra` we must provide the signature of the
algebra, in this case we shall go for 3DPGA, which is the algebra :math:`\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 :code:`locals().update(alg.blades)`:
.. code-block:: python
>>> 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 :code:`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, :code:`kingdon` knows that in this case only :code:`e2` can be non-zero.
Symbolic usage
--------------
If only a name is provided for a multivector, :code:`kingdon` will automatically populate all
relevant fields with symbols. This allows us to easily perform symbolic computations.
.. code-block:: python
>>> 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:
.. code-block:: python
>>> 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 :code:`kingdon` MultiVector with symbols is callable. So in order to evaluate :code:`w` from the previous example,
for a specific value of :code:`b12`, simply call :code:`w`:
.. code-block:: python
>>> w(b12=10)
3 𝐞₀ + -10 𝐞₂
Overview of Operators
=====================
.. list-table:: Operators
:widths: 50 25 25 25
:header-rows: 1
* - Operation
- Expression
- Infix
- Inline
* - Geometric product
- $ab$
- :code:`a*b`
- :code:`a.gp(b)`
* - Inner
- $a \\cdot b$
- :code:`a|b`
- :code:`a.ip(b)`
* - Scalar product
- $\\langle a \\cdot b \\rangle_0$
-
- :code:`a.sp(b)`
* - Left-contraction
- $a \\rfloor b$
-
- :code:`a.lc(b)`
* - Right-contraction
- $a \\lfloor b$
-
- :code:`a.rc(b)`
* - Outer (Exterior)
- $a \\wedge b$
- :code:`a ^ b`
- :code:`a.op(b)`
* - Regressive
- $a \\vee b$
- :code:`a & b`
- :code:`a.rp(b)`
* - Conjugate :code:`b` by :code:`a`
- $a b \\widetilde{a}$
- :code:`a >> b`
- :code:`a.sw(b)`
* - Project :code:`a` onto :code:`b`
- $(a \\cdot b) \\widetilde{b}$
- :code:`a @ b`
- :code:`a.proj(b)`
* - Commutator of :code:`a` and :code:`b`
- $a \\times b = \\tfrac{1}{2} [a, b]$
-
- :code:`a.cp(b)`
* - Anti-commutator of :code:`a` and :code:`b`
- $\\tfrac{1}{2} \\{a, b\\}$
-
- :code:`a.acp(b)`
* - Sum of :code:`a` and :code:`b`
- $a + b$
- :code:`a + b`
- :code:`a.add(b)`
* - Difference of :code:`a` and :code:`b`
- $a - b$
- :code:`a - b`
- :code:`a.sub(b)`
* - Reverse of :code:`a`
- $\\widetilde{a}$
- :code:`~a`
- :code:`a.reverse()`
* - Squared norm of :code:`a`
- $a \\widetilde{a}$
-
- :code:`a.normsq()`
* - Norm of :code:`a`
- $\\sqrt{a \\widetilde{a}}$
-
- :code:`a.norm()`
* - Normalize :code:`a`
- $a / \\sqrt{a \\widetilde{a}}$
-
- :code:`a.normalized()`
* - Square root of :code:`a`
- $\\sqrt{a}$
-
- :code:`a.sqrt()`
* - Dual of :code:`a`
- $a*$
-
- :code:`a.dual()`
* - Undual of :code:`a`
-
-
- :code:`a.undual()`
* - Grade :code:`k` part of :code:`a`
- $\\langle a \\rangle_k$
-
- :code:`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.
Raw data
{
"_id": null,
"home_page": "https://github.com/tbuli/kingdon",
"name": "kingdon",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "kingdon",
"author": "Martin Roelfs",
"author_email": "martinroelfs@yahoo.com",
"download_url": "https://files.pythonhosted.org/packages/7a/0e/c6ba50df471beaa7a22e3df596c5877996ac668c57cfd956949929d0223e/kingdon-1.2.0.tar.gz",
"platform": null,
"description": "=======\nKingdon\n=======\n\n\n.. image:: https://img.shields.io/pypi/v/kingdon.svg\n :target: https://pypi.python.org/pypi/kingdon\n \n.. image:: https://readthedocs.org/projects/kingdon/badge/?version=latest\n :target: https://kingdon.readthedocs.io/en/latest/?version=latest\n \n.. image:: https://coveralls.io/repos/github/tBuLi/kingdon/badge.svg?branch=master\n :target: https://coveralls.io/github/tBuLi/kingdon?branch=master\n \n\n\nPythonic Geometric Algebra Package\n\n\n* Free software: MIT license\n* Documentation: https://kingdon.readthedocs.io.\n\n`\u2728 Try kingdon in your browser \u2728 <https://tbuli.github.io/teahouse/>`_\n\nFeatures\n--------\n\nKingdon is a Geometric Algebra (GA) library which combines a Pythonic API with\nsymbolic simplification and just-in-time compilation to achieve high-performance in a single package.\nIt support both symbolic and numerical GA computations.\nMoreover, :code:`kingdon` uses :code:`ganja.js` for visualization in notebooks,\nmaking it an extremely well rounded GA package.\n\nIn bullet points:\n\n- Symbolically optimized.\n- Leverage sparseness of input.\n- :code:`ganja.js` enabled graphics in jupyter notebooks.\n- Agnostic to the input types: work with GA's over :code:`numpy` arrays, :code:`PyTorch` tensors, :code:`sympy` expressions, etc. Any object that overloads addition, subtraction and multiplication makes for valid multivector coefficients in :code:`kingdon`.\n- Automatic broadcasting, such that transformations can be applied to e.g. point-clouds.\n- Compatible with :code:`numba` and other JIT compilers to speed-up numerical computations.\n\nCode Example\n------------\nIn order to demonstrate the power of :code:`Kingdon`, let us first consider the common use-case of the\ncommutator product between a bivector and vector.\n\nIn order to create an algebra, use :code:`Algebra`. When calling :code:`Algebra` we must provide the signature of the\nalgebra, in this case we shall go for 3DPGA, which is the algebra :math:`\\mathbb{R}_{3,0,1}`.\nThere are a number of ways to make elements of the algebra. It can be convenient to work with the basis blades directly.\nWe can add them to the local namespace by calling :code:`locals().update(alg.blades)`:\n\n.. code-block:: python\n\n >>> from kingdon import Algebra\n >>> alg = Algebra(3, 0, 1)\n >>> locals().update(alg.blades)\n >>> b = 2 * e12\n >>> v = 3 * e1\n >>> b * v\n -6 \ud835\udc1e\u2082\n\nThis example shows that only the :code:`e2` coefficient is calculated, despite the fact that there are\n6 bivector and 4 vector coefficients in 3DPGA. But by exploiting the sparseness of the input and by performing symbolic\noptimization, :code:`kingdon` knows that in this case only :code:`e2` can be non-zero.\n\nSymbolic usage\n--------------\nIf only a name is provided for a multivector, :code:`kingdon` will automatically populate all\nrelevant fields with symbols. This allows us to easily perform symbolic computations.\n\n.. code-block:: python\n\n >>> from kingdon import Algebra\n >>> alg = Algebra(3, 0, 1)\n >>> b = alg.bivector(name='b')\n >>> b\n b01 \ud835\udc1e\u2080\u2081 + b02 \ud835\udc1e\u2080\u2082 + b03 \ud835\udc1e\u2080\u2083 + b12 \ud835\udc1e\u2081\u2082 + b13 \ud835\udc1e\u2081\u2083 + b23 \ud835\udc1e\u2082\u2083\n >>> v = alg.vector(name='v')\n >>> v\n v0 \ud835\udc1e\u2080 + v1 \ud835\udc1e\u2081 + v2 \ud835\udc1e\u2082 + v3 \ud835\udc1e\u2083\n >>> b.cp(v)\n (b01*v1 + b02*v2 + b03*v3) \ud835\udc1e\u2080 + (b12*v2 + b13*v3) \ud835\udc1e\u2081 + (-b12*v1 + b23*v3) \ud835\udc1e\u2082 + (-b13*v1 - b23*v2) \ud835\udc1e\u2083\n\nIt is also possible to define some coefficients to be symbolic by inputting a string, while others can be numeric:\n\n.. code-block:: python\n\n >>> from kingdon import Algebra, symbols\n >>> alg = Algebra(3, 0, 1)\n >>> b = alg.bivector(e12='b12', e03=3)\n >>> b\n 3 \ud835\udc1e\u2080\u2083 + b12 \ud835\udc1e\u2081\u2082\n >>> v = alg.vector(e1=1, e3=1)\n >>> v\n 1 \ud835\udc1e\u2081 + 1 \ud835\udc1e\u2083\n >>> w = b.cp(v)\n >>> w\n 3 \ud835\udc1e\u2080 + (-b12) \ud835\udc1e\u2082\n\n\nA :code:`kingdon` MultiVector with symbols is callable. So in order to evaluate :code:`w` from the previous example,\nfor a specific value of :code:`b12`, simply call :code:`w`:\n\n.. code-block:: python\n\n >>> w(b12=10)\n 3 \ud835\udc1e\u2080 + -10 \ud835\udc1e\u2082\n\n\nOverview of Operators\n=====================\n.. list-table:: Operators\n :widths: 50 25 25 25\n :header-rows: 1\n\n * - Operation\n - Expression\n - Infix\n - Inline\n * - Geometric product\n - $ab$\n - :code:`a*b`\n - :code:`a.gp(b)`\n * - Inner\n - $a \\\\cdot b$\n - :code:`a|b`\n - :code:`a.ip(b)`\n * - Scalar product\n - $\\\\langle a \\\\cdot b \\\\rangle_0$\n -\n - :code:`a.sp(b)`\n * - Left-contraction\n - $a \\\\rfloor b$\n -\n - :code:`a.lc(b)`\n * - Right-contraction\n - $a \\\\lfloor b$\n -\n - :code:`a.rc(b)`\n * - Outer (Exterior)\n - $a \\\\wedge b$\n - :code:`a ^ b`\n - :code:`a.op(b)`\n * - Regressive\n - $a \\\\vee b$\n - :code:`a & b`\n - :code:`a.rp(b)`\n * - Conjugate :code:`b` by :code:`a`\n - $a b \\\\widetilde{a}$\n - :code:`a >> b`\n - :code:`a.sw(b)`\n * - Project :code:`a` onto :code:`b`\n - $(a \\\\cdot b) \\\\widetilde{b}$\n - :code:`a @ b`\n - :code:`a.proj(b)`\n * - Commutator of :code:`a` and :code:`b`\n - $a \\\\times b = \\\\tfrac{1}{2} [a, b]$\n -\n - :code:`a.cp(b)`\n * - Anti-commutator of :code:`a` and :code:`b`\n - $\\\\tfrac{1}{2} \\\\{a, b\\\\}$\n -\n - :code:`a.acp(b)`\n * - Sum of :code:`a` and :code:`b`\n - $a + b$\n - :code:`a + b`\n - :code:`a.add(b)`\n * - Difference of :code:`a` and :code:`b`\n - $a - b$\n - :code:`a - b`\n - :code:`a.sub(b)`\n * - Reverse of :code:`a`\n - $\\\\widetilde{a}$\n - :code:`~a`\n - :code:`a.reverse()`\n * - Squared norm of :code:`a`\n - $a \\\\widetilde{a}$\n -\n - :code:`a.normsq()`\n * - Norm of :code:`a`\n - $\\\\sqrt{a \\\\widetilde{a}}$\n -\n - :code:`a.norm()`\n * - Normalize :code:`a`\n - $a / \\\\sqrt{a \\\\widetilde{a}}$\n -\n - :code:`a.normalized()`\n * - Square root of :code:`a`\n - $\\\\sqrt{a}$\n -\n - :code:`a.sqrt()`\n * - Dual of :code:`a`\n - $a*$\n -\n - :code:`a.dual()`\n * - Undual of :code:`a`\n -\n -\n - :code:`a.undual()`\n * - Grade :code:`k` part of :code:`a`\n - $\\\\langle a \\\\rangle_k$\n -\n - :code:`a.grade(k)`\n\nCredits\n-------\n\nThis package was inspired by GAmphetamine.js.\n\n\n=======\nHistory\n=======\n\n0.1.0 (2023-08-12)\n------------------\n\n* First release on PyPI.\n\n0.2.0 (2024-01-09)\n------------------\n\n* Multivectors now have `map` and `filter` methods to apply element-wise operations to the coefficients.\n* Make matrix representations of expressions using `expr_as_matrix`.\n* Bugfixes.\n\n0.3.0 (2024-03-11)\n------------------\n* Much faster codegen by the introduction of a GAmphetamine.js inspired RationalPolynomial class, which now replaces\n SymPy for codegen. Particularly for inverses this is orders of magnitude faster.\n* Performed a numbotomy: numba is no longer a dependency since it actually didn't add much in most cases.\n Instead the user can now provide the Algebra with any wrapper function, which is applied to the generated functions.\n This can be numba.njit, but also any other decorator.\n\n0.3.2 (2024-03-18)\n------------------\n* Fixed a high priority bug in the graph function.\n* Fixed a bug that stopped multivectors from being callable.\n\n1.0.0 (2024-04-17)\n------------------\n* Kingdon now has proper support for ganja.js animations and the graphs are interactive!\n* Indexing a multivector will no longer access coefficients.\n The whole promise of GA is coordinate independence, so why would you need to access coefficients?\n Instead, slicing a multivector will pass on that information to the underlying datastructures\n (e.g. numpy array or pytorch tensor), and will return a new multivector.\n Moreover, you can use the new slicing syntax to set values as well.\n If you really still need access to the coefficients, there is always the getattr syntax or the .values() method.\n\n1.0.5 (2024-06-26)\n------------------\n* Blades by grade syntax: alg.blades.grade(2).\n* Fixed \"define\" error in ganja.js integration, kingdon now works with reveal.js voila template.\n\n1.0.6 (2024-07-10)\n------------------\nBugfixes to ganja.js integration:\n* Make sure camera is an object before checking for 'mv' key.\n* Improved draggable points for PGA.\n\n1.1.0 (2024-08-10)\n------------------\n* Map and filter now support two argument functions. If such a funtion is provided,\n map/filter is applied on key, value pairs.\n* Added exponential function for simple objects.\n* Raising a mv to 0.5 is now correctly interpreted as a square root.\n This enables e.g. automatic differentiation.\n\n1.1.2 (2024-11-15)\n------------------\n* Improved printing, especially for multivector with array or multivector coefficients.\n* `pretty_blade` options added to algebra, to allow users to choose the printing of basis blades.\n* getattr bugfix\n\n1.2.0 (2024-12-16)\n------------------\n* Binary operators are now broadcasted across lists and tuples, e.g. `R >> [point1, point2]`.\n* Projection (@) and conjugation (>>) are now symbolically optimized by default.\n* Matrix reps made with `expr_as_matrix` now have better support for numerical (and multidimensional) multivectors.\n",
"bugtrack_url": null,
"license": "MIT license",
"summary": "Pythonic Geometric Algebra Package",
"version": "1.2.0",
"project_urls": {
"Homepage": "https://github.com/tbuli/kingdon"
},
"split_keywords": [
"kingdon"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "fea73ca0cd471ee2f12fdb9695f300bc1f17ae3e1c2b04ed7f6c633d0ca4f00f",
"md5": "2edfff14e3209fc17641b3e085b7f060",
"sha256": "2f90ee40a23087bb8c15df8daf9ca333675b8a6a00132037eadb251a466ab1b7"
},
"downloads": -1,
"filename": "kingdon-1.2.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "2edfff14e3209fc17641b3e085b7f060",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=3.8",
"size": 40164,
"upload_time": "2024-12-16T16:37:22",
"upload_time_iso_8601": "2024-12-16T16:37:22.366811Z",
"url": "https://files.pythonhosted.org/packages/fe/a7/3ca0cd471ee2f12fdb9695f300bc1f17ae3e1c2b04ed7f6c633d0ca4f00f/kingdon-1.2.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "7a0ec6ba50df471beaa7a22e3df596c5877996ac668c57cfd956949929d0223e",
"md5": "b2dec66fb7b9b9cf71ae001176624cfe",
"sha256": "a3e74de915b8914134b42e5f2729d01337c765653cc188a6e76e2628bebb6433"
},
"downloads": -1,
"filename": "kingdon-1.2.0.tar.gz",
"has_sig": false,
"md5_digest": "b2dec66fb7b9b9cf71ae001176624cfe",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 133526,
"upload_time": "2024-12-16T16:37:24",
"upload_time_iso_8601": "2024-12-16T16:37:24.804452Z",
"url": "https://files.pythonhosted.org/packages/7a/0e/c6ba50df471beaa7a22e3df596c5877996ac668c57cfd956949929d0223e/kingdon-1.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-16 16:37:24",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "tbuli",
"github_project": "kingdon",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "numpy",
"specs": []
},
{
"name": "sympy",
"specs": []
},
{
"name": "anywidget",
"specs": []
}
],
"tox": true,
"lcname": "kingdon"
}