From 02bb28968221a0f077b49205e2746abd8c5450d9 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sat, 4 Feb 2023 11:26:55 -0500 Subject: [PATCH] eja: special subalgebra handling for Cartesian product EJAs. 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 | 28 ++++++++++++++++++++++++++ mjo/eja/eja_element.py | 38 +++++++++++++++++++++++------------- mjo/eja/eja_subalgebra.py | 41 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 93 insertions(+), 14 deletions(-) diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index d3eac4f..92a7df1 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -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 diff --git a/mjo/eja/eja_element.py b/mjo/eja/eja_element.py index 235047a..df14666 100644 --- a/mjo/eja/eja_element.py +++ b/mjo/eja/eja_element.py @@ -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 ) diff --git a/mjo/eja/eja_subalgebra.py b/mjo/eja/eja_subalgebra.py index ca8efa1..c9abada 100644 --- a/mjo/eja/eja_subalgebra.py +++ b/mjo/eja/eja_subalgebra.py @@ -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 -- 2.44.2