]> gitweb.michael.orlitzky.com - sage.d.git/commitdiff
mjo.eja.eja_operator: fix exponentiation master
authorMichael Orlitzky <michael@orlitzky.com>
Wed, 1 Oct 2025 15:58:08 +0000 (11:58 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Wed, 1 Oct 2025 15:58:08 +0000 (11:58 -0400)
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

index b8e953bceea64c0d12be852f911df5bebc821155..d8ae802491474c91f8e674fc37a4b01b44b9e642 100644 (file)
@@ -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::