From 28d86108d78f1ea5a93d9cc8d69bad9cc8cd74fd Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 3 Mar 2021 08:40:16 -0500 Subject: [PATCH] eja: begin adding OctonionHermitianEJA. --- mjo/eja/TODO | 3 ++- mjo/eja/all.py | 1 + mjo/eja/eja_algebra.py | 61 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/mjo/eja/TODO b/mjo/eja/TODO index 13b00ac..2d93ffb 100644 --- a/mjo/eja/TODO +++ b/mjo/eja/TODO @@ -19,7 +19,8 @@ sage: a0 = (1/4)*X[4]**2*X[6]**2 - (1/2)*X[2]*X[5]*X[6]**2 - (1/2)*X[3]*X[4]*X[6 6. Instead of storing a basis multiplication matrix, just make product_on_basis() a cached method and manually cache its entries. The cython cached method lookup should be faster than a - python-based matrix lookup anyway. + python-based matrix lookup anyway. NOTE: we should still be able + to recompute the table somehow. Is this worth it? 7. What the ever-loving fuck is this shit? diff --git a/mjo/eja/all.py b/mjo/eja/all.py index a3b524b..f5ef5c9 100644 --- a/mjo/eja/all.py +++ b/mjo/eja/all.py @@ -6,6 +6,7 @@ from mjo.eja.eja_algebra import (BilinearFormEJA, ComplexHermitianEJA, HadamardEJA, JordanSpinEJA, + OctonionHermitianEJA, QuaternionHermitianEJA, RealSymmetricEJA, TrivialEJA, diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index 5bf5975..e16fd97 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -2585,6 +2585,67 @@ class QuaternionHermitianEJA(ConcreteEJA, QuaternionMatrixEJA): n = ZZ.random_element(cls._max_random_instance_size() + 1) return cls(n, **kwargs) +class OctonionHermitianEJA(FiniteDimensionalEJA, MatrixEJA): + + def __init__(self, n, field=AA, **kwargs): + if n > 3: + # Otherwise we don't get an EJA. + raise ValueError("n cannot exceed 3") + + # We know this is a valid EJA, but will double-check + # if the user passes check_axioms=True. + if "check_axioms" not in kwargs: kwargs["check_axioms"] = False + + super().__init__(self._denormalized_basis(n,field), + self.jordan_product, + self.trace_inner_product, + **kwargs) + + # TODO: this could be factored out somehow, but is left here + # because the MatrixEJA is not presently a subclass of the + # FDEJA class that defines rank() and one(). + self.rank.set_cache(n) + idV = self.matrix_space().one() + self.one.set_cache(self(idV)) + + + @classmethod + def _denormalized_basis(cls, n, field): + """ + Returns a basis for the space of octonion Hermitian n-by-n + matrices. + + SETUP:: + + sage: from mjo.eja.eja_algebra import OctonionHermitianEJA + + EXAMPLES:: + + sage: B = OctonionHermitianEJA._denormalized_basis(3) + sage: all( M.is_hermitian() for M in B ) + True + sage: len(B) + 27 + + """ + from mjo.octonions import OctonionMatrixAlgebra + MS = OctonionMatrixAlgebra(n, field=field) + es = MS.entry_algebra().gens() + + basis = [] + for i in range(n): + for j in range(i+1): + if i == j: + E_ii = MS.monomial( (i,j,es[0]) ) + basis.append(E_ii) + else: + for e in es: + E_ij = MS.monomial( (i,j,e) ) + E_ij += MS.monomial( (j,i,e.conjugate()) ) + basis.append(E_ij) + + return tuple( basis ) + class HadamardEJA(ConcreteEJA): """ -- 2.44.2