From 9efefa3e54fc3e69e3f2c78457d50127a7a10131 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 26 Feb 2021 11:29:15 -0500 Subject: [PATCH] eja: start fixing Cartesian products of Cartesian products. --- mjo/eja/eja_algebra.py | 27 +++++++++++++++++++++++---- mjo/eja/eja_element.py | 8 ++++---- mjo/eja/eja_utils.py | 28 +++++++++++++++++++--------- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index cbe5c08..c1fc807 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -3220,8 +3220,11 @@ class CartesianProductEJA(CombinatorialFreeModule_CartesianProduct, # given that the first coordinate of i and j corresponds to # the factor, and the second coordinate corresponds to the # index of the generator within that factor. - factor = mon[0] - idx_in_factor = mon[1] + try: + factor = mon[0] + except TypeError: # 'int' object is not subscriptable + return mon + idx_in_factor = self._monomial_to_generator(mon[1]) offset = sum( f.dimension() for f in self.cartesian_factors()[:factor] ) @@ -3236,8 +3239,24 @@ class CartesianProductEJA(CombinatorialFreeModule_CartesianProduct, SETUP:: - sage: from mjo.eja.eja_algebra import (QuaternionHermitianEJA, - ....: RealSymmetricEJA) + sage: from mjo.eja.eja_algebra import (HadamardEJA, + ....: JordanSpinEJA, + ....: QuaternionHermitianEJA, + ....: RealSymmetricEJA,) + + EXAMPLES:: + + sage: J1 = JordanSpinEJA(2, field=QQ) + sage: J2 = RealSymmetricEJA(2, field=QQ, orthonormalize=False) + sage: J3 = HadamardEJA(1, field=QQ) + sage: K1 = cartesian_product([J1,J2]) + sage: K2 = cartesian_product([K1,J3]) + sage: list(K2.basis()) + [e(0, (0, 0)), e(0, (0, 1)), e(0, (1, 0)), e(0, (1, 1)), + e(0, (1, 2)), e(1, 0)] + sage: sage: g = K2.gens() + sage: (g[0] + 2*g[3]) * (g[1] - 4*g[2]) + e(0, (0, 1)) - 4*e(0, (1, 1)) TESTS:: diff --git a/mjo/eja/eja_element.py b/mjo/eja/eja_element.py index b5f661b..9a770ae 100644 --- a/mjo/eja/eja_element.py +++ b/mjo/eja/eja_element.py @@ -4,7 +4,7 @@ from sage.modules.free_module import VectorSpace from sage.modules.with_basis.indexed_element import IndexedFreeModuleElement from mjo.eja.eja_operator import FiniteDimensionalEJAOperator -from mjo.eja.eja_utils import _mat2vec +from mjo.eja.eja_utils import _mat2vec, _scale class FiniteDimensionalEJAElement(IndexedFreeModuleElement): """ @@ -1128,10 +1128,10 @@ class FiniteDimensionalEJAElement(IndexedFreeModuleElement): if self.parent()._matrix_basis_is_cartesian: # Aaaaand linear combinations don't work in Cartesian # product spaces, even though they provide a method - # with that name. + # with that name. This is special-cased because the + # _scale() function is slow. pairs = zip(B, self.to_vector()) - return sum( ( W(tuple(alpha*b_i for b_i in b)) - for (b,alpha) in pairs ), + return sum( ( _scale(b, alpha) for (b,alpha) in pairs ), W.zero()) else: # This is just a manual "from_vector()", but of course diff --git a/mjo/eja/eja_utils.py b/mjo/eja/eja_utils.py index 38e7576..c25b819 100644 --- a/mjo/eja/eja_utils.py +++ b/mjo/eja/eja_utils.py @@ -2,6 +2,18 @@ from sage.functions.other import sqrt from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector +def _scale(x, alpha): + r""" + Scale the vector, matrix, or cartesian-product-of-those-things + ``x`` by ``alpha``. + """ + if hasattr(x, 'cartesian_factors'): + P = x.parent() + return P(tuple( _scale(x_i, alpha) + for x_i in x.cartesian_factors() )) + else: + return x*alpha + def _all2list(x): r""" Flatten a vector, matrix, or cartesian product of those things @@ -160,18 +172,16 @@ def gram_schmidt(v, inner_product=None): R = v[0].base_ring() - # Define a scaling operation that can be used on tuples. - # Oh and our "zero" needs to belong to the right space. - scale = lambda x,alpha: x*alpha + # Our "zero" needs to belong to the right space for sum() to work. zero = v[0].parent().zero() - if hasattr(v[0], 'cartesian_factors'): - P = v[0].parent() - scale = lambda x,alpha: P(tuple( x_i*alpha - for x_i in x.cartesian_factors() )) + sc = lambda x,a: a*x + if hasattr(v[0], 'cartesian_factors'): + # Only use the slow implementation if necessary. + sc = _scale def proj(x,y): - return scale(x, (inner_product(x,y)/inner_product(x,x))) + return sc(x, (inner_product(x,y)/inner_product(x,x))) # First orthogonalize... for i in range(1,len(v)): @@ -188,6 +198,6 @@ def gram_schmidt(v, inner_product=None): # them here because then our subalgebra would have a bigger field # than the superalgebra. for i in range(len(v)): - v[i] = scale(v[i], ~norm(v[i])) + v[i] = sc(v[i], ~norm(v[i])) return v -- 2.43.2