Skip to content

feat(ga): add Cl(p,q,r) kingdon-like interface for Clifford algebras#550

Merged
utensil merged 3 commits intopygae:masterfrom
utiberious:fix/issue-524-kingdon-interface
Mar 30, 2026
Merged

feat(ga): add Cl(p,q,r) kingdon-like interface for Clifford algebras#550
utensil merged 3 commits intopygae:masterfrom
utiberious:fix/issue-524-kingdon-interface

Conversation

@utiberious
Copy link
Copy Markdown
Contributor

Summary

Adds a Cl(p, q, r) convenience function that creates a geometric algebra from its signature, following the convention popularized by ganja.js and kingdon. This provides an intuitive entry point for users coming from those libraries.

Fixes #524

Changes

  • galgebra/ga.py: Add Cl(p, q=0, r=0) function that:
    • Builds basis names e_1, e_2, ...
    • Constructs diagonal metric from signature (+1, -1, 0)
    • Returns (Ga, *basis_vectors) tuple
  • galgebra/__init__.py: Export Cl
  • test/test_test.py: Add tests for Cl(3), Cl(1,3), Cl(2,0,1) with metric verification

Example

from galgebra import Cl

ga, e1, e2, e3 = Cl(3)          # 3D Euclidean
ga, e1, e2, e3, e4 = Cl(1, 3)   # Spacetime
ga, e1, e2, e3 = Cl(2, 0, 1)    # 2D PGA

Test plan

  • Unit tests pass
  • Full CI with nbval notebooks passes

Adds a Cl(p, q, r) convenience function that constructs a Clifford
algebra Cl(p,q,r) from its signature: p positive, q negative, r
degenerate basis vectors. This follows the interface popularized by
ganja.js and kingdon.

The function is importable from both galgebra.ga and the top-level
galgebra package.

Fixes #10
@utensil
Copy link
Copy Markdown
Member

utensil commented Mar 30, 2026

Thanks for this! A few things before merging:

  1. Move Cl to galgebra/interop.py: ga.py is core algebra; Cl is a compatibility shim. Keeping them separate makes the purpose clear.

  2. Namespace-based conventions instead of a parameter: rather than convention='kingdon' as an argument, provide Cl via namespaces:

    • galgebra.interop.Cl — galgebra defaults (no surprises for existing users)
    • galgebra.interop.kingdon.Cl — kingdon convention (dual mode 'Iinv+', etc.)

    The import path is the documentation — from galgebra.interop.kingdon import Cl is self-explanatory. A string argument is harder to discover, harder to type-check, and silently changes behavior mid-code. Conventions are better expressed as namespaces.

    Default stays galgebra so existing users aren't affected.

  3. Docstring: mention ganja.js popularized Cl(p,q,r), kingdon adopted it; and document the known incompatibilities:

- galgebra.interop.Cl: galgebra defaults (1-indexed, I+ dual)
- galgebra.interop.kingdon.Cl: kingdon conventions (0-indexed, Iinv+ dual)
- Remove Cl from ga.py (keep ga.py for core algebra only)
- Document known incompatibilities (basis naming, dual convention)
@utiberious
Copy link
Copy Markdown
Contributor Author

Restructured per review. Pushed in 35026b6:

  1. Moved Cl to galgebra/interop/: ga.py is now core-only.

  2. Namespace-based conventions:

    • from galgebra.interop import Cl -- galgebra defaults (1-indexed basis, I+ dual)
    • from galgebra.interop.kingdon import Cl -- kingdon conventions (0-indexed basis, Iinv+ dual)
    • from galgebra import Cl still works (re-exported from interop)
  3. Docstrings updated with:

    • ganja.js/kingdon attribution
    • Known incompatibilities: basis naming (1-indexed vs 0-indexed) and dual convention (I+ vs Iinv+)
  4. Tests added for both test_Cl (interop) and test_Cl_kingdon (0-indexed, Iinv+ dual mode verified and restored).

@utensil
Copy link
Copy Markdown
Member

utensil commented Mar 30, 2026

Thanks for the clean refactor! One note: galgebra.interop.kingdon.Cl sets Ga.dual_mode('Iinv+') globally — this is a session-wide side effect. Worth adding a note in the docstring that callers should save/restore Ga.dual_mode_value if mixing conventions in the same session (as the test already shows). Otherwise good to merge.

@utiberious
Copy link
Copy Markdown
Contributor Author

Added a warning block in the kingdon.Cl docstring about the session-wide side effect and the save/restore pattern. Pushed in 524e3f2.

@utensil utensil merged commit 97b3c7f into pygae:master Mar 30, 2026
6 checks passed
@utensil utensil added component: core Ga, Mv, Metric, etc enhancement state: needs changelog Needs a changelog entry before the next release. Remove this label when the changelog is done. labels Mar 31, 2026
@utensil utensil added this to the 0.6.0 milestone Mar 31, 2026
utiberious added a commit to utiberious/galgebra that referenced this pull request Apr 1, 2026
Groups new entries by: features, bug fixes, examples/docs, tests/maintenance.

Features: Cl() kingdon interface (pygae#550, closes pygae#524), Mv.__rtruediv__
(pygae#543, closes pygae#512), shirokov_inverse/hitzer_inverse (pygae#530).

Bugs: interop dual mode contamination (pygae#556, closes pygae#555), norm() Abs
wrapping (pygae#554, closes pygae#522), is_versor() improvement (pygae#536, closes pygae#533).

Examples/docs: sundial + cheatsheet tests (pygae#549+pygae#557, closes pygae#506),
coords tutorial (pygae#551), README ops (pygae#548, closes pygae#523).

Tests/maintenance: lt.matrix() regression tests (pygae#558, closes pygae#461),
extra-cdot regression test (pygae#545), er_blade + ReciprocalFrame refactors
(pygae#552+pygae#553), CI fix (pygae#535).
utensil pushed a commit that referenced this pull request Apr 1, 2026
* docs: add 0.6.0 changelog entries

Groups new entries by: features, bug fixes, examples/docs, tests/maintenance.

Features: Cl() kingdon interface (#550, closes #524), Mv.__rtruediv__
(#543, closes #512), shirokov_inverse/hitzer_inverse (#530).

Bugs: interop dual mode contamination (#556, closes #555), norm() Abs
wrapping (#554, closes #522), is_versor() improvement (#536, closes #533).

Examples/docs: sundial + cheatsheet tests (#549+#557, closes #506),
coords tutorial (#551), README ops (#548, closes #523).

Tests/maintenance: lt.matrix() regression tests (#558, closes #461),
extra-cdot regression test (#545), er_blade + ReciprocalFrame refactors
(#552+#553), CI fix (#535).

* docs: add missing issue link for #551 entry

* docs: add changelog entry for #560 (Lt callable zero fix)

* docs: move Lt zero fix into bug group, use issue #540 as reference
utiberious added a commit to utiberious/galgebra that referenced this pull request Apr 2, 2026
* docs: add 0.6.0 changelog entries

Groups new entries by: features, bug fixes, examples/docs, tests/maintenance.

Features: Cl() kingdon interface (pygae#550, closes pygae#524), Mv.__rtruediv__
(pygae#543, closes pygae#512), shirokov_inverse/hitzer_inverse (pygae#530).

Bugs: interop dual mode contamination (pygae#556, closes pygae#555), norm() Abs
wrapping (pygae#554, closes pygae#522), is_versor() improvement (pygae#536, closes pygae#533).

Examples/docs: sundial + cheatsheet tests (pygae#549+pygae#557, closes pygae#506),
coords tutorial (pygae#551), README ops (pygae#548, closes pygae#523).

Tests/maintenance: lt.matrix() regression tests (pygae#558, closes pygae#461),
extra-cdot regression test (pygae#545), er_blade + ReciprocalFrame refactors
(pygae#552+pygae#553), CI fix (pygae#535).

* docs: add missing issue link for pygae#551 entry

* docs: add changelog entry for pygae#560 (Lt callable zero fix)

* docs: move Lt zero fix into bug group, use issue pygae#540 as reference
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: core Ga, Mv, Metric, etc enhancement state: needs changelog Needs a changelog entry before the next release. Remove this label when the changelog is done.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Provide a kingdon-like interface, and run cross-library test cases

2 participants