From 3b4736dfef862300735d1a8d2137f26caa07f7c1 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 1 Oct 2025 11:58:08 -0400 Subject: [PATCH] mjo.eja.eja_operator: fix exponentiation Using exponentiation was allowing us to skip the domain/codomain check for operator composition when their dimensions agreed. To fix that, we reimplement powers directly in terms of multiplication. This also sheds light on a buggy test that needed to be fixed: isomorphisms can't necessarily be composed. --- mjo/eja/eja_operator.py | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/mjo/eja/eja_operator.py b/mjo/eja/eja_operator.py index b8e953b..d8ae802 100644 --- a/mjo/eja/eja_operator.py +++ b/mjo/eja/eja_operator.py @@ -312,7 +312,9 @@ class EJAOperator(Map): SETUP:: sage: from mjo.eja.eja_operator import EJAOperator - sage: from mjo.eja.eja_algebra import RealSymmetricEJA + sage: from mjo.eja.eja_algebra import (HadamardEJA, + ....: JordanSpinEJA, + ....: RealSymmetricEJA) TESTS: @@ -331,6 +333,20 @@ class EJAOperator(Map): Domain: Euclidean Jordan algebra of dimension 3 over... Codomain: Euclidean Jordan algebra of dimension 3 over... + TESTS: + + Exponentiation doesn't work when the domain and codomain + differ, even if their dimensions are compatible:: + + sage: J1 = HadamardEJA(3) + sage: J2 = JordanSpinEJA(3) + sage: I = J1.one().operator().matrix() + sage: L = EJAOperator(J1, J2, I) + sage: L^2 + Traceback (most recent call last): + ... + TypeError: ...domain must equal right... + """ if (n == 1): return self @@ -340,13 +356,15 @@ class EJAOperator(Map): rows = self.codomain().dimension() cols = self.domain().dimension() mat = matrix.identity(self.base_ring(), rows, cols) - else: - mat = self.matrix()**n + return EJAOperator(self.domain(), self.codomain(), mat) - return EJAOperator( - self.domain(), - self.codomain(), - mat) + # Actually multiply them for n >= 2 so that the domain and + # codomain checks in __mul__ aren't skipped (as they would be + # if we simply exponentiated the matrix). + from functools import reduce + from itertools import repeat + from operator import mul + return reduce(mul, repeat(self, n)) def _repr_(self): @@ -926,7 +944,7 @@ class EJAOperator(Map): True sage: L.inverse().is_isomorphism() True - sage: (L^2).is_isomorphism() + sage: (L.domain() != L.codomain()) or (L^2).is_isomorphism() True The identity operator is always a Jordan isomorphism:: -- 2.49.0