From 09ef15bb469b45f6491c71b44dc7d50a8f2c6fe3 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 23 Aug 2019 22:09:08 -0400 Subject: [PATCH] eja: refactor and fix the fast charpoly stuff that I broke recently. --- mjo/eja/TODO | 7 ++----- mjo/eja/eja_algebra.py | 41 +++++++++++++++++++++++++---------------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/mjo/eja/TODO b/mjo/eja/TODO index 89b4d32..8497576 100644 --- a/mjo/eja/TODO +++ b/mjo/eja/TODO @@ -9,9 +9,6 @@ 5. Factor out the unit-norm basis (and operator symmetry) tests once all of the algebras pass. -6. Refactor the current ungodly fast charpoly hack (relies on the - theory to ensure that the charpolys are equal.) +6. Implement random_instance() for the main EJA class. -7. Implement random_instance() for the main EJA class. - -8. Implement random_instance() for the subalgebra class. +7. Implement random_instance() for the subalgebra class. diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index 80147df..2a5e624 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -61,9 +61,6 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule): self._rank = rank self._natural_basis = natural_basis - # TODO: HACK for the charpoly.. needs redesign badly. - self._basis_normalizers = None - if category is None: category = MagmaticAlgebras(field).FiniteDimensional() category = category.WithBasis().Unital() @@ -259,19 +256,6 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule): store the trace/determinant (a_{r-1} and a_{0} respectively) separate from the entire characteristic polynomial. """ - if self._basis_normalizers is not None: - # Must be a matrix class? - # WARNING/TODO: this whole mess is mis-designed. - n = self.natural_basis_space().nrows() - field = self.base_ring().base_ring() # yeeeeaaaahhh - J = self.__class__(n, field, False) - (_,x,_,_) = J._charpoly_matrix_system() - p = J._charpoly_coeff(i) - # p might be missing some vars, have to substitute "optionally" - pairs = zip(x.base_ring().gens(), self._basis_normalizers) - substitutions = { v: v*c for (v,c) in pairs } - return p.subs(substitutions) - (A_of_x, x, xr, detA) = self._charpoly_matrix_system() R = A_of_x.base_ring() if i >= self.rank(): @@ -908,6 +892,9 @@ class MatrixEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebra): def __init__(self, n, field=QQ, normalize_basis=True, **kwargs): S = self._denormalized_basis(n, field) + # Used in this class's fast _charpoly_coeff() override. + self._basis_normalizers = None + if n > 1 and normalize_basis: # We'll need sqrt(2) to normalize the basis, and this # winds up in the multiplication table, so the whole @@ -932,6 +919,28 @@ class MatrixEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebra): **kwargs) + @cached_method + def _charpoly_coeff(self, i): + """ + Override the parent method with something that tries to compute + over a faster (non-extension) field. + """ + if self._basis_normalizers is None: + # We didn't normalize, so assume that the basis we started + # with had entries in a nice field. + return super(MatrixEuclideanJordanAlgebra, self)._charpoly_coeff(i) + else: + n = self.natural_basis_space().nrows() + field = self.base_ring().base_ring() # yeeeeaaaahhh + J = self.__class__(n, field, False) + (_,x,_,_) = J._charpoly_matrix_system() + p = J._charpoly_coeff(i) + # p might be missing some vars, have to substitute "optionally" + pairs = zip(x.base_ring().gens(), self._basis_normalizers) + substitutions = { v: v*c for (v,c) in pairs } + return p.subs(substitutions) + + @staticmethod def multiplication_table_from_matrix_basis(basis): """ -- 2.44.2