From cf5e64b70869df65c7bb38888de54b1083e60d45 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 10 Mar 2021 13:31:53 -0500 Subject: [PATCH] eja: cache the charpoly coefficients for the AlbertEJA. --- mjo/eja/TODO | 7 +------ mjo/eja/eja_algebra.py | 8 ++++++++ mjo/eja/eja_cache.py | 42 ++++++++++++++++++++++++++++++++++++++++++ mjo/eja/eja_utils.py | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 mjo/eja/eja_cache.py diff --git a/mjo/eja/TODO b/mjo/eja/TODO index 26ff1e9..45a9ac0 100644 --- a/mjo/eja/TODO +++ b/mjo/eja/TODO @@ -1,11 +1,6 @@ 1. Add references and start citing them. -2. Pre-cache charpoly for some small algebras? - -RealSymmetricEJA(4): - -sage: F = J.base_ring() -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]*X[7] + (F(2).sqrt()/2)*X[1]*X[5]*X[6]*X[7] + (1/4)*X[3]**2*X[7]**2 - (1/2)*X[0]*X[5]*X[7]**2 + (F(2).sqrt()/2)*X[2]*X[3]*X[6]*X[8] - (1/2)*X[1]*X[4]*X[6*X[8] - (1/2)*X[1]*X[3]*X[7]*X[8] + (F(2).sqrt()/2)*X[0]*X[4]*X[7]*X[8] + (1/4)*X[1]**2*X[8]**2 - (1/2)*X[0]*X[2]*X[8]**2 - (1/2)*X[2]*X[3]**2*X[9] + (F(2).sqrt()/2)*X[1]*X[3]*X[4]*X[9] - (1/2)*X[0]*X[4]**2*X[9] - (1/2)*X[1]**2*X[5]*X[9] + X[0]*X[2]*X[5]*X[9] +2. Pre-cache charpoly for some more algebras. 3. Profile the construction of "large" matrix algebras (like the 15-dimensional QuaternionHermitianAlgebra(3)) to find out why diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index b2891e5..587d8e3 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -2281,6 +2281,14 @@ class OctonionHermitianEJA(MatrixEJA, RationalBasisEJA, ConcreteEJA): A = OctonionMatrixAlgebra(n, scalars=field) super().__init__(A, **kwargs) + if n == 3: + from mjo.eja.eja_cache import albert_eja_coeffs + a = albert_eja_coeffs(self.coordinate_polynomial_ring()) + if self._rational_algebra is None: + self._charpoly_coefficients.set_cache(a) + else: + self._rational_algebra._charpoly_coefficients.set_cache(a) + class AlbertEJA(OctonionHermitianEJA): r""" diff --git a/mjo/eja/eja_cache.py b/mjo/eja/eja_cache.py new file mode 100644 index 0000000..73405b3 --- /dev/null +++ b/mjo/eja/eja_cache.py @@ -0,0 +1,42 @@ +def albert_eja_coeffs(R): + X = R.gens() + a0 = ( X[9]*X[10]**2 + X[9]*X[11]**2 + X[9]*X[12]**2 + X[9]*X[13]**2 + + X[9]*X[14]**2 + X[9]*X[15]**2 + X[9]*X[16]**2 + X[9]*X[17]**2 - + 2*X[1]*X[10]*X[18] - 2*X[2]*X[11]*X[18] - 2*X[3]*X[12]*X[18] - + 2*X[4]*X[13]*X[18] - 2*X[5]*X[14]*X[18] - 2*X[6]*X[15]*X[18] - + 2*X[7]*X[16]*X[18] - 2*X[8]*X[17]*X[18] + X[0]*X[18]**2 + + 2*X[2]*X[10]*X[19] - 2*X[1]*X[11]*X[19] + 2*X[4]*X[12]*X[19] - + 2*X[3]*X[13]*X[19] + 2*X[6]*X[14]*X[19] - 2*X[5]*X[15]*X[19] - + 2*X[8]*X[16]*X[19] + 2*X[7]*X[17]*X[19] + X[0]*X[19]**2 + + 2*X[3]*X[10]*X[20] - 2*X[4]*X[11]*X[20] - 2*X[1]*X[12]*X[20] + + 2*X[2]*X[13]*X[20] + 2*X[7]*X[14]*X[20] + 2*X[8]*X[15]*X[20] - + 2*X[5]*X[16]*X[20] - 2*X[6]*X[17]*X[20] + X[0]*X[20]**2 + + 2*X[4]*X[10]*X[21] + 2*X[3]*X[11]*X[21] - 2*X[2]*X[12]*X[21] - + 2*X[1]*X[13]*X[21] + 2*X[8]*X[14]*X[21] - 2*X[7]*X[15]*X[21] + + 2*X[6]*X[16]*X[21] - 2*X[5]*X[17]*X[21] + X[0]*X[21]**2 + + 2*X[5]*X[10]*X[22] - 2*X[6]*X[11]*X[22] - 2*X[7]*X[12]*X[22] - + 2*X[8]*X[13]*X[22] - 2*X[1]*X[14]*X[22] + 2*X[2]*X[15]*X[22] + + 2*X[3]*X[16]*X[22] + 2*X[4]*X[17]*X[22] + X[0]*X[22]**2 + + 2*X[6]*X[10]*X[23] + 2*X[5]*X[11]*X[23] - 2*X[8]*X[12]*X[23] + + 2*X[7]*X[13]*X[23] - 2*X[2]*X[14]*X[23] - 2*X[1]*X[15]*X[23] - + 2*X[4]*X[16]*X[23] + 2*X[3]*X[17]*X[23] + X[0]*X[23]**2 + + 2*X[7]*X[10]*X[24] + 2*X[8]*X[11]*X[24] + 2*X[5]*X[12]*X[24] - + 2*X[6]*X[13]*X[24] - 2*X[3]*X[14]*X[24] + 2*X[4]*X[15]*X[24] - + 2*X[1]*X[16]*X[24] - 2*X[2]*X[17]*X[24] + X[0]*X[24]**2 + + 2*X[8]*X[10]*X[25] - 2*X[7]*X[11]*X[25] + 2*X[6]*X[12]*X[25] + + 2*X[5]*X[13]*X[25] - 2*X[4]*X[14]*X[25] - 2*X[3]*X[15]*X[25] + + 2*X[2]*X[16]*X[25] - 2*X[1]*X[17]*X[25] + X[0]*X[25]**2 + + X[1]**2*X[26] + X[2]**2*X[26] + X[3]**2*X[26] + X[4]**2*X[26] + + X[5]**2*X[26] + X[6]**2*X[26] + X[7]**2*X[26] + X[8]**2*X[26] - + X[0]*X[9]*X[26] ) + + a1 = ( -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] - X[10]**2 - X[11]**2 - + X[12]**2 - X[13]**2 - X[14]**2 - X[15]**2 - X[16]**2 - + X[17]**2 - X[18]**2 - X[19]**2 - X[20]**2 - X[21]**2 - + X[22]**2 - X[23]**2 - X[24]**2 - X[25]**2 + X[0]*X[26] + + X[9]*X[26] ) + + a2 = -X[0] - X[9] - X[26] + + return (a0,a1,a2) diff --git a/mjo/eja/eja_utils.py b/mjo/eja/eja_utils.py index 7c6c581..3942e70 100644 --- a/mjo/eja/eja_utils.py +++ b/mjo/eja/eja_utils.py @@ -2,6 +2,40 @@ from sage.functions.other import sqrt from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector +def _charpoly_sage_input(s): + r""" + Helper function that you can use on the string output from sage + to convert a charpoly coefficient into the corresponding input + to be cached. + + SETUP:: + + sage: from mjo.eja.eja_utils import _charpoly_sage_input + + EXAMPLES:: + + sage: J = JordanSpinEJA(4,QQ) + sage: J._charpoly_coefficients()[0] + X1^2 - X2^2 - X3^2 - X4^2 + sage: _charpoly_sage_input("X1^2 - X2^2 - X3^2 - X4^2") + 'X[0]**2 - X[1]**2 - X[2]**2 - X[3]**2' + + """ + import re + + exponent_out = r"\^" + exponent_in = r"**" + + digit_out = r"X([0-9]+)" + + def replace_digit(m): + # m is a match object + return "X[" + str(int(m.group(1)) - 1) + "]" + + s = re.sub(exponent_out, exponent_in, s) + return re.sub(digit_out, replace_digit, s) + + def _scale(x, alpha): r""" Scale the vector, matrix, or cartesian-product-of-those-things -- 2.43.2