From 707c1ace788819d3d0542e61dab0134eabea2159 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 2 Dec 2020 07:21:34 -0500 Subject: [PATCH] eja: don't pass in a full multiplication table unless necessary. --- mjo/eja/TODO | 7 ++--- mjo/eja/eja_algebra.py | 55 ++++++++++++++++++++++++++------------- mjo/eja/eja_subalgebra.py | 20 ++++++++++---- 3 files changed, 54 insertions(+), 28 deletions(-) diff --git a/mjo/eja/TODO b/mjo/eja/TODO index cbe1d95..2752dc4 100644 --- a/mjo/eja/TODO +++ b/mjo/eja/TODO @@ -46,12 +46,9 @@ 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 11. Figure out if CombinatorialFreeModule's use of IndexedGenerators can be used to replace the matrix_basis(). -12. Don't pass in an n-by-n multiplication/i-p table since only the - lower-left half is used. +12. Move the "field" argument to a keyword after basis, jp, and ip. -13. Move the "field" argument to a keyword after basis, jp, and ip. - -14. Instead of storing the multiplication and inner-product tables in +13. Instead of storing the multiplication and inner-product tables in RationalBasisEuclideanJordanAlgebra, why not just create the algebra over QQ in the constructor and save that? They're globally unique, so we won't wind up with multiple copies. diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index 107adcc..bab1002 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -1197,11 +1197,19 @@ class RationalBasisEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebr # the given basis. W = V.span_of_basis( vector_basis ) - # TODO: use symmetry - self._deortho_multiplication_table = [ [0 for j in range(n)] - for i in range(n) ] - self._deortho_inner_product_table = [ [0 for j in range(n)] - for i in range(n) ] + if check_axioms: + # If the superclass constructor is going to verify the + # symmetry of this table, it has better at least be + # square... + self._deortho_multiplication_table = [ [0 for j in range(n)] + for i in range(n) ] + self._deortho_inner_product_table = [ [0 for j in range(n)] + for i in range(n) ] + else: + self._deortho_multiplication_table = [ [0 for j in range(i+1)] + for i in range(n) ] + self._deortho_inner_product_table = [ [0 for j in range(i+1)] + for i in range(n) ] # Note: the Jordan and inner-products are defined in terms # of the ambient basis. It's important that their arguments @@ -1224,12 +1232,14 @@ class RationalBasisEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebr # table is in terms of vectors elt = _mat2vec(elt) - # TODO: use symmetry elt = W.coordinate_vector(elt) self._deortho_multiplication_table[i][j] = elt - self._deortho_multiplication_table[j][i] = elt self._deortho_inner_product_table[i][j] = ip - self._deortho_inner_product_table[j][i] = ip + if check_axioms: + # The tables are square if we're verifying that they + # are commutative. + self._deortho_multiplication_table[j][i] = elt + self._deortho_inner_product_table[j][i] = ip if self._deortho_multiplication_table is not None: self._deortho_multiplication_table = tuple(map(tuple, self._deortho_multiplication_table)) @@ -1268,9 +1278,15 @@ class RationalBasisEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebr self._deortho_matrix = matrix( U.coordinate_vector(q) for q in vector_basis ) - # TODO: use symmetry - mult_table = [ [0 for j in range(n)] for i in range(n) ] - ip_table = [ [0 for j in range(n)] for i in range(n) ] + # If the superclass constructor is going to verify the + # symmetry of this table, it has better at least be + # square... + if check_axioms: + mult_table = [ [0 for j in range(n)] for i in range(n) ] + ip_table = [ [0 for j in range(n)] for i in range(n) ] + else: + mult_table = [ [0 for j in range(i+1)] for i in range(n) ] + ip_table = [ [0 for j in range(i+1)] for i in range(n) ] # Note: the Jordan and inner-products are defined in terms # of the ambient basis. It's important that their arguments @@ -1293,12 +1309,14 @@ class RationalBasisEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebr # table is in terms of vectors elt = _mat2vec(elt) - # TODO: use symmetry elt = W.coordinate_vector(elt) mult_table[i][j] = elt - mult_table[j][i] = elt ip_table[i][j] = ip - ip_table[j][i] = ip + if check_axioms: + # The tables are square if we're verifying that they + # are commutative. + mult_table[j][i] = elt + ip_table[j][i] = ip if basis_is_matrices: for m in basis: @@ -2609,21 +2627,22 @@ class DirectSumEJA(FiniteDimensionalEuclideanJordanAlgebra): n2 = J2.dimension() n = n1+n2 V = VectorSpace(field, n) - mult_table = [ [ V.zero() for j in range(n) ] + mult_table = [ [ V.zero() for j in range(i+1) ] for i in range(n) ] for i in range(n1): - for j in range(n1): + for j in range(i+1): p = (J1.monomial(i)*J1.monomial(j)).to_vector() mult_table[i][j] = V(p.list() + [field.zero()]*n2) for i in range(n2): - for j in range(n2): + for j in range(i+1): p = (J2.monomial(i)*J2.monomial(j)).to_vector() mult_table[n1+i][n1+j] = V([field.zero()]*n1 + p.list()) # TODO: build the IP table here from the two constituent IP # matrices (it'll be block diagonal, I think). - ip_table = None + ip_table = [ [ field.zero() for j in range(i+1) ] + for i in range(n) ] super(DirectSumEJA, self).__init__(field, mult_table, ip_table, diff --git a/mjo/eja/eja_subalgebra.py b/mjo/eja/eja_subalgebra.py index 6eca475..fb0f26c 100644 --- a/mjo/eja/eja_subalgebra.py +++ b/mjo/eja/eja_subalgebra.py @@ -176,13 +176,21 @@ class FiniteDimensionalEuclideanJordanSubalgebra(FiniteDimensionalEuclideanJorda W = V.span_of_basis( V.from_vector(b.to_vector()) for b in basis ) n = len(basis) - mult_table = [[W.zero() for i in range(n)] for j in range(n)] - ip_table = [ [ self._superalgebra.inner_product(basis[i],basis[j]) - for i in range(n) ] - for j in range(n) ] + if check_axioms: + # The tables are square if we're verifying that they + # are commutative. + mult_table = [[W.zero() for j in range(n)] for i in range(n)] + ip_table = [ [ self._superalgebra.inner_product(basis[i],basis[j]) + for j in range(n) ] + for i in range(n) ] + else: + mult_table = [[W.zero() for j in range(i+1)] for i in range(n)] + ip_table = [ [ self._superalgebra.inner_product(basis[i],basis[j]) + for j in range(i+1) ] + for i in range(n) ] for i in range(n): - for j in range(n): + for j in range(i+1): product = basis[i]*basis[j] # product.to_vector() might live in a vector subspace # if our parent algebra is already a subalgebra. We @@ -190,6 +198,8 @@ class FiniteDimensionalEuclideanJordanSubalgebra(FiniteDimensionalEuclideanJorda # that case. product_vector = V.from_vector(product.to_vector()) mult_table[i][j] = W.coordinate_vector(product_vector) + if check_axioms: + mult_table[j][i] = mult_table[i][j] matrix_basis = tuple( b.to_matrix() for b in basis ) -- 2.44.2