Context
PR #550 added galgebra.interop.Cl (galgebra defaults) and galgebra.interop.kingdon.Cl (kingdon conventions). PR #544 showed that 'Iinv+' is the mathematically correct default for dual(), but changing the global default is a breaking change deferred past 0.6.0.
Remaining problem
Ga.dual_mode_value is a class-level attribute — session-wide global state. galgebra.interop.kingdon.Cl currently calls Ga.dual_mode('Iinv+') to set kingdon conventions, but this persists for the rest of the session. Any subsequent use of galgebra.interop.Cl (which promises galgebra defaults including 'I+' dual) silently inherits 'Iinv+':
from galgebra.interop.kingdon import Cl as KCl
from galgebra.interop import Cl
ga_k, *_ = KCl(3) # sets Iinv+ globally
ga_g, *_ = Cl(3) # does NOT reset — silently still Iinv+!
ga_g.mv('a', 'vector').dual() # wrong convention for galgebra.interop.Cl
Short-term fix (0.6.0)
- Make
galgebra.interop.Cl explicitly call Ga.dual_mode('I+') to reset to galgebra defaults, mirroring what kingdon.Cl does for Iinv+.
- Add a docstring note on both
Cl variants documenting the session-wide nature of the dual mode and the interaction between the two.
- Update the
.. warning:: in kingdon.Cl accordingly.
This preserves the existing Ga.dual_mode() global API and is safe for 0.6.0.
Long-term fix (post-0.6.0)
Make dual_mode_value a per-instance attribute on Ga. Since mv.py already reads self.Ga.dual_mode_value (instance-lookup syntax), the structural change is minimal:
Ga.__init__: self.dual_mode_value = kwargs.pop('dual_mode', Ga.dual_mode_value) — snapshot the class default (or accept an explicit override) at creation time.
Ga.build(): forward dual_mode= kwarg.
galgebra.interop.Cl: pass dual_mode='I+' to Ga.build() instead of mutating global state.
galgebra.interop.kingdon.Cl: pass dual_mode='Iinv+' to Ga.build() instead of mutating global state.
- Remove the
.. warning:: save/restore block from kingdon.Cl — no longer needed.
Ga.dual_mode() class setter keeps working for backward compat. mv.py needs no changes.
References
Context
PR #550 added
galgebra.interop.Cl(galgebra defaults) andgalgebra.interop.kingdon.Cl(kingdon conventions). PR #544 showed that'Iinv+'is the mathematically correct default fordual(), but changing the global default is a breaking change deferred past 0.6.0.Remaining problem
Ga.dual_mode_valueis a class-level attribute — session-wide global state.galgebra.interop.kingdon.Clcurrently callsGa.dual_mode('Iinv+')to set kingdon conventions, but this persists for the rest of the session. Any subsequent use ofgalgebra.interop.Cl(which promises galgebra defaults including'I+'dual) silently inherits'Iinv+':Short-term fix (0.6.0)
galgebra.interop.Clexplicitly callGa.dual_mode('I+')to reset to galgebra defaults, mirroring whatkingdon.Cldoes forIinv+.Clvariants documenting the session-wide nature of the dual mode and the interaction between the two... warning::inkingdon.Claccordingly.This preserves the existing
Ga.dual_mode()global API and is safe for 0.6.0.Long-term fix (post-0.6.0)
Make
dual_mode_valuea per-instance attribute onGa. Sincemv.pyalready readsself.Ga.dual_mode_value(instance-lookup syntax), the structural change is minimal:Ga.__init__:self.dual_mode_value = kwargs.pop('dual_mode', Ga.dual_mode_value)— snapshot the class default (or accept an explicit override) at creation time.Ga.build(): forwarddual_mode=kwarg.galgebra.interop.Cl: passdual_mode='I+'toGa.build()instead of mutating global state.galgebra.interop.kingdon.Cl: passdual_mode='Iinv+'toGa.build()instead of mutating global state... warning::save/restore block fromkingdon.Cl— no longer needed.Ga.dual_mode()class setter keeps working for backward compat.mv.pyneeds no changes.References
'Iinv+'as the correct global defaultCl(p,q,r)interface with namespace-based conventions