]> gitweb.michael.orlitzky.com - sage.d.git/commitdiff
eja: special subalgebra handling for Cartesian product EJAs.
authorMichael Orlitzky <michael@orlitzky.com>
Sat, 4 Feb 2023 16:26:55 +0000 (11:26 -0500)
committerMichael Orlitzky <michael@orlitzky.com>
Sat, 4 Feb 2023 16:26:55 +0000 (11:26 -0500)
The matrix representation of an element in a Cartesian product EJA
will be an ordered tupe of matrices. When we move into a subalgebra,
the same element (considered as an element of the subalgebra) no
longer lives in a "Cartesian product EJA," since we give the
subalgebra its own basis. However, if we ever want to convert back,
then we need to know that the element originally came from a Cartesian
product EJA, because scalar fucking scaling doesn't fucking work on
ordered pairs!

mjo/eja/eja_algebra.py
mjo/eja/eja_element.py
mjo/eja/eja_subalgebra.py

index d3eac4f6d3bfbad50f6bbc4b371aaa9d39f8859b..92a7df167a4596504c712cf2117e79568cf7eda9 100644 (file)
@@ -3416,6 +3416,34 @@ class CartesianProductEJA(FiniteDimensionalEJA):
         return FiniteDimensionalEJAOperator(Ji,self,Ei.matrix())
 
 
+    def subalgebra(self, basis, **kwargs):
+        r"""
+        Create a subalgebra of this algebra from the given basis.
+
+        Only overridden to allow us to use a special Cartesian product
+        subalgebra class.
+
+        SETUP::
+
+            sage: from mjo.eja.eja_algebra import (HadamardEJA,
+            ....:                                  QuaternionHermitianEJA)
+
+        EXAMPLES:
+
+        Subalgebras of Cartesian product EJAs have a different class
+        than those of non-Cartesian-product EJAs::
+
+            sage: J1 = HadamardEJA(2,field=QQ,orthonormalize=False)
+            sage: J2 = QuaternionHermitianEJA(0,field=QQ,orthonormalize=False)
+            sage: J = cartesian_product([J1,J2])
+            sage: K1 = J1.subalgebra((J1.one(),), orthonormalize=False)
+            sage: K = J.subalgebra((J.one(),), orthonormalize=False)
+            sage: K1.__class__ is K.__class__
+            False
+
+        """
+        from mjo.eja.eja_subalgebra import FiniteDimensionalCartesianProductEJASubalgebra
+        return FiniteDimensionalCartesianProductEJASubalgebra(self, basis, **kwargs)
 
 FiniteDimensionalEJA.CartesianProduct = CartesianProductEJA
 
index 235047a153f0594bf450987ae2988a5873d92f36..df14666d85df17d8005432ecad777b4a8d0f9076 100644 (file)
@@ -1722,7 +1722,31 @@ class FiniteDimensionalEJAElement(IndexedFreeModuleElement):
         return self.trace_inner_product(self).sqrt()
 
 
-class CartesianProductEJAElement(FiniteDimensionalEJAElement):
+class CartesianProductParentEJAElement(FiniteDimensionalEJAElement):
+    r"""
+    An intermediate class for elements that have a Cartesian
+    product as their parent algebra.
+
+    This is needed because the ``to_matrix`` method (which gives you a
+    representation from the superalgebra) needs to do special stuff
+    for Cartesian products. Specifically, an EJA subalgebra of a
+    Cartesian product EJA will not itself be a Cartesian product (it
+    has its own basis) -- but we want ``to_matrix()`` to be able to
+    give us a Cartesian product representation.
+    """
+    def to_matrix(self):
+        # An override is necessary to call our custom _scale().
+        B = self.parent().matrix_basis()
+        W = self.parent().matrix_space()
+
+        # Aaaaand linear combinations don't work in Cartesian
+        # product spaces, even though they provide a method with
+        # that name. This is hidden in a subclass because the
+        # _scale() function is slow.
+        pairs = zip(B, self.to_vector())
+        return W.sum( _scale(b, alpha) for (b,alpha) in pairs )
+
+class CartesianProductEJAElement(CartesianProductParentEJAElement):
     def det(self):
         r"""
         Compute the determinant of this product-element using the
@@ -1734,15 +1758,3 @@ class CartesianProductEJAElement(FiniteDimensionalEJAElement):
         """
         from sage.misc.misc_c import prod
         return prod( f.det() for f in self.cartesian_factors() )
-
-    def to_matrix(self):
-        # An override is necessary to call our custom _scale().
-        B = self.parent().matrix_basis()
-        W = self.parent().matrix_space()
-
-        # Aaaaand linear combinations don't work in Cartesian
-        # product spaces, even though they provide a method with
-        # that name. This is hidden behind an "if" because the
-        # _scale() function is slow.
-        pairs = zip(B, self.to_vector())
-        return W.sum( _scale(b, alpha) for (b,alpha) in pairs )
index ca8efa1fd410b8f5f3f6d177b62779b1a24ccaf5..c9abada53cf3fbd3803601fa0e7b430a0b506fd1 100644 (file)
@@ -2,7 +2,8 @@ from sage.matrix.constructor import matrix
 from sage.misc.cachefunc import cached_method
 
 from mjo.eja.eja_algebra import FiniteDimensionalEJA
-from mjo.eja.eja_element import FiniteDimensionalEJAElement
+from mjo.eja.eja_element import (FiniteDimensionalEJAElement,
+                                 CartesianProductParentEJAElement)
 
 class FiniteDimensionalEJASubalgebraElement(FiniteDimensionalEJAElement):
     """
@@ -265,3 +266,41 @@ class FiniteDimensionalEJASubalgebra(FiniteDimensionalEJA):
 
 
     Element = FiniteDimensionalEJASubalgebraElement
+
+
+
+class FiniteDimensionalCartesianProductEJASubalgebraElement(FiniteDimensionalEJASubalgebraElement, CartesianProductParentEJAElement):
+    r"""
+    The class for elements that both belong to a subalgebra and
+    have a Cartesian product algebra as their parent. By inheriting
+    :class:`CartesianProductParentEJAElement` in addition to
+    :class:`FiniteDimensionalEJASubalgebraElement`, we allow the
+    ``to_matrix()`` method to be overridden with the version that
+    works on Cartesian products.
+
+    SETUP::
+
+        sage: from mjo.eja.eja_algebra import (HadamardEJA,
+        ....:                                  RealSymmetricEJA)
+
+    TESTS:
+
+    This used to fail when ``subalgebra_idempotent()`` tried to
+    embed the subalgebra element back into the original EJA::
+
+        sage: J1 = HadamardEJA(0, field=QQ, orthonormalize=False)
+        sage: J2 = RealSymmetricEJA(2, field=QQ, orthonormalize=False)
+        sage: J = cartesian_product([J1,J2])
+        sage: J.one().subalgebra_idempotent() == J.one()
+        True
+
+    """
+    pass
+
+class FiniteDimensionalCartesianProductEJASubalgebra(FiniteDimensionalEJASubalgebra):
+    r"""
+    Subalgebras whose parents are Cartesian products. Exists only
+    to specify a special element class that will (in addition)
+    inherit from ``CartesianProductParentEJAElement``.
+    """
+    Element = FiniteDimensionalCartesianProductEJASubalgebraElement