From e6bb7aba7677a04c3aaa4d1fdd9dd45185db2067 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 10 Mar 2021 18:04:25 -0500 Subject: [PATCH] eja: more cached charpoly coefficients. --- mjo/eja/eja_algebra.py | 15 +++++ mjo/eja/eja_cache.py | 148 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 152 insertions(+), 11 deletions(-) diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index a10e2a3..a2adbb2 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -1988,6 +1988,14 @@ class RealSymmetricEJA(MatrixEJA, RationalBasisEJA, ConcreteEJA): A = MatrixSpace(field, n) super().__init__(A, **kwargs) + from mjo.eja.eja_cache import real_symmetric_eja_coeffs + a = real_symmetric_eja_coeffs(self) + if a is not None: + if self._rational_algebra is None: + self._charpoly_coefficients.set_cache(a) + else: + self._rational_algebra._charpoly_coefficients.set_cache(a) + class ComplexHermitianEJA(MatrixEJA, RationalBasisEJA, ConcreteEJA): @@ -2070,6 +2078,13 @@ class ComplexHermitianEJA(MatrixEJA, RationalBasisEJA, ConcreteEJA): A = ComplexMatrixAlgebra(n, scalars=field) super().__init__(A, **kwargs) + from mjo.eja.eja_cache import complex_hermitian_eja_coeffs + a = complex_hermitian_eja_coeffs(self) + if a is not None: + if self._rational_algebra is None: + self._charpoly_coefficients.set_cache(a) + else: + self._rational_algebra._charpoly_coefficients.set_cache(a) @staticmethod def _max_random_instance_size(): diff --git a/mjo/eja/eja_cache.py b/mjo/eja/eja_cache.py index 8498321..b5743ec 100644 --- a/mjo/eja/eja_cache.py +++ b/mjo/eja/eja_cache.py @@ -2,20 +2,150 @@ r""" Cached characteristic polynomial coefficients for a few of the example algebras. These take a long time to compute, so it makes more sense to cache them and then only test that the cached values are -correct every once in a while. +correct every once in a while. And they're in this separate file +because they are visually horrific. The function used to turn SageMath's output into the appropriate input can be found in the eja_utils module. + +The simple algebras _not_ represented here all have rank two or less, +and are "easy" to compute even over the algebraic reals. """ -def quaternion_hermitian_eja_coeffs(J): +def real_symmetric_eja_coeffs(J): + X = J.coordinate_polynomial_ring().gens() + + if J.dimension() == 3: # n == 2 + a0 = -X[1]**2 + X[0]*X[2] + a1 = -X[0] - X[2] + return (a0,a1) + + elif J.dimension() == 6: # n == 3 + a0 = ( X[2]*X[3]**2 - 2*X[1]*X[3]*X[4] + X[0]*X[4]**2 + + X[1]**2*X[5] - X[0]*X[2]*X[5] ) + a1 = ( -X[1]**2 + X[0]*X[2] - X[3]**2 - X[4]**2 + + X[0]*X[5] + X[2]*X[5] ) + a2 = -X[0] - X[2] - X[5] + return (a0,a1,a2) + + elif J.dimension() == 10: # n == 4 + a0 = ( X[4]**2*X[6]**2 - X[2]*X[5]*X[6]**2 - + 2*X[3]*X[4]*X[6]*X[7] + 2*X[1]*X[5]*X[6]*X[7] + + X[3]**2*X[7]**2 - X[0]*X[5]*X[7]**2 + + 2*X[2]*X[3]*X[6]*X[8] - 2*X[1]*X[4]*X[6]*X[8] - + 2*X[1]*X[3]*X[7]*X[8] + 2*X[0]*X[4]*X[7]*X[8] + + X[1]**2*X[8]**2 - X[0]*X[2]*X[8]**2 - + X[2]*X[3]**2*X[9] + 2*X[1]*X[3]*X[4]*X[9] - + X[0]*X[4]**2*X[9] - X[1]**2*X[5]*X[9] + + X[0]*X[2]*X[5]*X[9] ) + + a1 = ( X[2]*X[3]**2 - 2*X[1]*X[3]*X[4] + X[0]*X[4]**2 + + X[1]**2*X[5] - X[0]*X[2]*X[5] + X[2]*X[6]**2 + + X[5]*X[6]**2 - 2*X[1]*X[6]*X[7] + X[0]*X[7]**2 + + X[5]*X[7]**2 - 2*X[3]*X[6]*X[8] - 2*X[4]*X[7]*X[8] + + X[0]*X[8]**2 + X[2]*X[8]**2 + X[1]**2*X[9] - + X[0]*X[2]*X[9] + X[3]**2*X[9] + X[4]**2*X[9] - + X[0]*X[5]*X[9] - X[2]*X[5]*X[9] ) + + a2 = ( -X[1]**2 + X[0]*X[2] - X[3]**2 - X[4]**2 + + X[0]*X[5] + X[2]*X[5] - X[6]**2 - X[7]**2 - + X[8]**2 + X[0]*X[9] + X[2]*X[9] + X[5]*X[9] ) + + a3 = -X[0] - X[2] - X[5] - X[9] + + return (a0,a1,a2,a3) + + # Don't know them + return None + + +def complex_hermitian_eja_coeffs(J): X = J.coordinate_polynomial_ring().gens() - if J.dimension() == 1: # n == 1 - a0 = -X[0] - return (a0,) + if J.dimension() == 4: # n == 2 + a0 = -X[1]**2 - X[2]**2 + X[0]*X[3] + a1 = -X[0] - X[3] + return (a0,a1) + + elif J.dimension() == 9: # n == 3 + a0 = ( X[3]*X[4]**2 + X[3]*X[5]**2 - 2*X[1]*X[4]*X[6] - + 2*X[2]*X[5]*X[6] + X[0]*X[6]**2 + 2*X[2]*X[4]*X[7] - + 2*X[1]*X[5]*X[7] + X[0]*X[7]**2 + X[1]**2*X[8] + + X[2]**2*X[8] - X[0]*X[3]*X[8] ) + + a1 = ( -X[1]**2 - X[2]**2 + X[0]*X[3] - X[4]**2 - X[5]**2 - + X[6]**2 - X[7]**2 + X[0]*X[8] + X[3]*X[8] ) + + a2 = -X[0] - X[3] - X[8] + + return (a0,a1,a2) + + elif J.dimension() == 16: # n == 4 + a0 = ( X[6]**2*X[9]**2 + X[7]**2*X[9]**2 - X[3]*X[8]*X[9]**2 + + X[6]**2*X[10]**2 + X[7]**2*X[10]**2 - X[3]*X[8]*X[10]**2 - + 2*X[4]*X[6]*X[9]*X[11] - 2*X[5]*X[7]*X[9]*X[11] + + 2*X[1]*X[8]*X[9]*X[11] - 2*X[5]*X[6]*X[10]*X[11] + + 2*X[4]*X[7]*X[10]*X[11] + 2*X[2]*X[8]*X[10]*X[11] + + X[4]**2*X[11]**2 + X[5]**2*X[11]**2 - X[0]*X[8]*X[11]**2 + + 2*X[5]*X[6]*X[9]*X[12] - 2*X[4]*X[7]*X[9]*X[12] - + 2*X[2]*X[8]*X[9]*X[12] - 2*X[4]*X[6]*X[10]*X[12] - + 2*X[5]*X[7]*X[10]*X[12] + 2*X[1]*X[8]*X[10]*X[12] + + X[4]**2*X[12]**2 + X[5]**2*X[12]**2 - X[0]*X[8]*X[12]**2 + + 2*X[3]*X[4]*X[9]*X[13] - 2*X[1]*X[6]*X[9]*X[13] + + 2*X[2]*X[7]*X[9]*X[13] + 2*X[3]*X[5]*X[10]*X[13] - + 2*X[2]*X[6]*X[10]*X[13] - 2*X[1]*X[7]*X[10]*X[13] - + 2*X[1]*X[4]*X[11]*X[13] - 2*X[2]*X[5]*X[11]*X[13] + + 2*X[0]*X[6]*X[11]*X[13] + 2*X[2]*X[4]*X[12]*X[13] - + 2*X[1]*X[5]*X[12]*X[13] + 2*X[0]*X[7]*X[12]*X[13] + + X[1]**2*X[13]**2 + X[2]**2*X[13]**2 - X[0]*X[3]*X[13]**2 - + 2*X[3]*X[5]*X[9]*X[14] + 2*X[2]*X[6]*X[9]*X[14] + + 2*X[1]*X[7]*X[9]*X[14] + 2*X[3]*X[4]*X[10]*X[14] - + 2*X[1]*X[6]*X[10]*X[14] + 2*X[2]*X[7]*X[10]*X[14] - + 2*X[2]*X[4]*X[11]*X[14] + 2*X[1]*X[5]*X[11]*X[14] - + 2*X[0]*X[7]*X[11]*X[14] - 2*X[1]*X[4]*X[12]*X[14] - + 2*X[2]*X[5]*X[12]*X[14] + 2*X[0]*X[6]*X[12]*X[14] + + X[1]**2*X[14]**2 + X[2]**2*X[14]**2 - X[0]*X[3]*X[14]**2 - + X[3]*X[4]**2*X[15] - X[3]*X[5]**2*X[15] + + 2*X[1]*X[4]*X[6]*X[15] + 2*X[2]*X[5]*X[6]*X[15] - + X[0]*X[6]**2*X[15] - 2*X[2]*X[4]*X[7]*X[15] + + 2*X[1]*X[5]*X[7]*X[15] - X[0]*X[7]**2*X[15] - + X[1]**2*X[8]*X[15] - X[2]**2*X[8]*X[15] + + X[0]*X[3]*X[8]*X[15] ) + + a1 = ( X[3]*X[4]**2 + X[3]*X[5]**2 - 2*X[1]*X[4]*X[6] - + 2*X[2]*X[5]*X[6] + X[0]*X[6]**2 + 2*X[2]*X[4]*X[7] - + 2*X[1]*X[5]*X[7] + X[0]*X[7]**2 + X[1]**2*X[8] + + X[2]**2*X[8] - X[0]*X[3]*X[8] + X[3]*X[9]**2 + + X[8]*X[9]**2 + X[3]*X[10]**2 + X[8]*X[10]**2 - + 2*X[1]*X[9]*X[11] - 2*X[2]*X[10]*X[11] + X[0]*X[11]**2 + + X[8]*X[11]**2 + 2*X[2]*X[9]*X[12] - 2*X[1]*X[10]*X[12] + + X[0]*X[12]**2 + X[8]*X[12]**2 - 2*X[4]*X[9]*X[13] - + 2*X[5]*X[10]*X[13] - 2*X[6]*X[11]*X[13] - + 2*X[7]*X[12]*X[13] + X[0]*X[13]**2 + X[3]*X[13]**2 + + 2*X[5]*X[9]*X[14] - 2*X[4]*X[10]*X[14] + + 2*X[7]*X[11]*X[14] - 2*X[6]*X[12]*X[14] + X[0]*X[14]**2 + + X[3]*X[14]**2 + X[1]**2*X[15] + X[2]**2*X[15] - + X[0]*X[3]*X[15] + X[4]**2*X[15] + X[5]**2*X[15] + + X[6]**2*X[15] + X[7]**2*X[15] - X[0]*X[8]*X[15] - + X[3]*X[8]*X[15] ) + + a2 = ( -X[1]**2 - X[2]**2 + X[0]*X[3] - X[4]**2 - X[5]**2 - + X[6]**2 - X[7]**2 + X[0]*X[8] + X[3]*X[8] - X[9]**2 - + X[10]**2 - X[11]**2 - X[12]**2 - X[13]**2 - X[14]**2 + + X[0]*X[15] + X[3]*X[15] + X[8]*X[15] ) + + a3 = -X[0] - X[3] - X[8] - X[15] + + return (a0,a1,a2,a3) + + # Don't know them + return None - elif J.dimension() == 6: # n == 2 + +def quaternion_hermitian_eja_coeffs(J): + X = J.coordinate_polynomial_ring().gens() + + if J.dimension() == 6: # n == 2 a0 = -X[1]**2 - X[2]**2 - X[3]**2 - X[4]**2 + X[0]*X[5] a1 = -X[0] - X[5] return (a0,a1) @@ -45,11 +175,7 @@ def quaternion_hermitian_eja_coeffs(J): def octonion_hermitian_eja_coeffs(J): X = J.coordinate_polynomial_ring().gens() - if J.dimension() == 1: # n == 1 - a0 = -X[0] - return (a0,) - - elif J.dimension() == 10: # n == 2 + if J.dimension() == 10: # n == 2 a0 = ( -X[1]**2 - X[2]**2 - X[3]**2 - X[4]**2 - X[5]**2 - X[6]**2 - X[7]**2 - X[8]**2 + X[0]*X[9] ) a1 = -X[0] - X[9] -- 2.43.2