Skip to content

geometric_algebra: deprecate [DFM] conventions, add corrected operations - #255

Draft
inducer wants to merge 2 commits into
mainfrom
lengyel-ga-fixes
Draft

geometric_algebra: deprecate [DFM] conventions, add corrected operations#255
inducer wants to merge 2 commits into
mainfrom
lengyel-ga-fixes

Conversation

@inducer

@inducerinducer commented Sep 3, 2026

Copy link
Copy Markdown
Owner

The operators in this module follow the conventions of Dorst/Fontijne/Mann (GA4CS), which have been shown to rest on shaky foundations; see Eric Lengyel's Poor Foundations in Geometric Algebra. Incorporate the corrections from that article. All existing behavior is preserved and deprecated, not removed.

New operations (validated against independent geometric-product references in the new test):

  • MultiVector.inner: the (metric) inner product <A B~>_0, the unique extension of the metric to the full exterior algebra. Scalar, vanishes across grades, and induces the norm (A.inner(A) == A.norm_squared()).
  • MultiVector.left_contraction / right_contraction: the corrected interior products <B A~>{grB-grA} and <B~ A>{grA-grB}. For equal-grade blades these reduce to the inner product (the [DFM] contractions reduced to the scalar product), and the geometric product decomposes as aB = B.right_contraction(a) + a^B.
  • MultiVector.hodge_dual: the Hodge dual A~ I (equivalently, the right complement of GA). Satisfies A ^ B.hodge_dual() == A.inner(B) * A.I and has a consistent orientation (the [DFM] dual A I^-1 flips, e.g., the dual of e0 in 3D).

Deprecated (DeprecationWarning + doc notes):

  • The |, <<, and >> operators. | can produce non-scalars, so it is an interior product rather than an inner product; for k-blades, A | A == (-1)**(k(k-1)/2) * A.inner(A). The [DFM] contractions differ from the corrected ones by a grade-dependent sign.
  • scalar_product (the superfluous reversed-Gram-determinant form); use inner instead.
  • dual (the [DFM] dualization mapping A I^-1); use hodge_dual instead.

Other changes:

  • norm_squared computes A.inner(A) directly (identical values, no longer routed through the deprecated scalar product).

  • The module docstring gains a "Conventions and known issues" section (ga-conventions) and a doctest contrasting the new and deprecated operations; the operator table and method docstrings point at the replacements.

  • The pre-existing GA test keeps exercising the [DFM] conventions (with a targeted filterwarnings); a new test covers the corrected conventions and their exact relationship to the deprecated operators.

Decisions and trade-offs:

  • Backward compatibility comes first: downstream users keep working, but will see deprecation warnings where they use |, <<, >>, scalar_product, or dual. Migration path: | -> inner / left_contraction / right_contraction, dual -> hodge_dual, scalar_product -> inner.
  • The new operations are implemented for orthogonal (diagonal-metric) spaces only, consistent with every other product in the module (NotImplementedError otherwise). The general-metric definitions (A^T G B for the inner product, the right complement of GA for the dual) are documented as the natural extension; supporting non-orthogonal or degenerate (e.g. PGA) metrics is a separate, larger effort.
  • The article's "clean" Hodge-dual definitions of the contractions (A* vee B) are internally inconsistent as stated; the blade identities <B A~> / <B~ A>, which reduce to the inner product for equal grades and
    fix the vector decomposition, are implemented instead.

Assisted-by: Zed:Qwen3.8-27B-FP8

@inducer
inducer marked this pull request as draft September 3, 2026 18:39
@inducer
inducerforce-pushed the lengyel-ga-fixes branch 3 times, most recently from 568ae28 to bd58246CompareSeptember 4, 2026 21:48
The [DFM] (Dorst, Fontijne, Mann) conventions implemented in this module
rest on foundations that have been shown to be flawed; see in particular
Eric Lengyel's "Poor Foundations in Geometric Algebra":
https://terathon.com/blog/poor-foundations-ga.html
Add the corrected operations (orthogonal metrics only, consistent with
the
rest of the module):
- MultiVector.inner: the (metric) inner product A.B = <A B~>_0, the
unique
extension of the metric's bilinear form to the exterior algebra.
Scalar,
zero for blades of different grade. norm_squared() now uses this
(identical values).
- MultiVector.left_contraction: A|B = <B A~>_(grB-grA)
- MultiVector.right_contraction: B||A = <A~ B>_(grB-grA)
- MultiVector.hodge_dual: A* = A~ I, satisfying the defining property of
the Hodge star, A^B* = (A.B) I, for equal-grade blades (the [DFM]
dualization mapping A I^-1 does not satisfy it).
Deprecate, do not remove, the [DFM]-convention operators and methods
(__or__/__ror__, __lshift__/__rlshift__, __rshift__/__rrshift__,
scalar_product(), dual()). Each carries a .. deprecated:: note plus a
@typing_extensions.deprecated decorator, which emits the same
DeprecationWarning at the call site and sets __deprecated__ for static
analysis. [DFM] behavior is unchanged.
Also rename the dead-code __inv__ to __invert__ so that `~mv` actually
dispatches. This breaks direct calls to mv.__inv__(); accepted, since
__inv__ was never a real dunder.
Decisions and trade-offs:
- The corrected contractions are implemented via the article's explicit
grade-extraction identities rather than its Hodge-dual definitions
(A|B = A_* v B, A||B = A v B*, where v is the "antiwedge"). The
article
never defines the antiwedge; per Lengyel's RGA wiki it is Grassmann's
regressive product (adds antigrades, hence grade p+q-n, defined via
the
complements), and under that reading the Hodge-dual definitions are
self-consistent with the grade-extraction identities. The identities
are
self-contained, so we use them directly.
- The new operations raise NotImplementedError for non-orthogonal (i.e.,
non-diagonal) metrics, matching the module's existing treatment of
such
spaces.
- Existing tests keep exercising the deprecated [DFM] conventions (with
a
DeprecationWarning filter); a new test verifies the corrected
operations
against geometric-product-only references and exact old/new sign
relations in dims 2-4 with random +/-1 diagonal metrics.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@inducer