X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Feja%2Feja_algebra.py;h=4609ca2a4df7a4ff762e3eef00435a70b85e8cbb;hb=e1dfaabb339864bb4bb4034ab90903e17b15f6c8;hp=a51da3e03fc753e33079fde0debdf6ee12a29b3c;hpb=9a6de831e947f663cacf56e409e99ec3aa086c62;p=sage.d.git diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index a51da3e..4609ca2 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -134,10 +134,15 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule): # long run to have the multiplication table be in terms of # algebra elements. We do this after calling the superclass # constructor so that from_vector() knows what to do. - self._multiplication_table = [ - list(map(lambda x: self.from_vector(x), ls)) - for ls in mult_table - ] + self._multiplication_table = [ [ self.vector_space().zero() + for i in range(n) ] + for j in range(n) ] + # take advantage of symmetry + for i in range(n): + for j in range(i+1): + elt = self.from_vector(mult_table[i][j]) + self._multiplication_table[i][j] = elt + self._multiplication_table[j][i] = elt if check_axioms: if not self._is_commutative(): @@ -1020,6 +1025,81 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule): Element = FiniteDimensionalEuclideanJordanAlgebraElement +class RationalBasisEuclideanJordanAlgebraNg(FiniteDimensionalEuclideanJordanAlgebra): + def __init__(self, + field, + basis, + jordan_product, + inner_product, + orthonormalize=True, + prefix='e', + category=None, + check_field=True, + check_axioms=True): + + n = len(basis) + vector_basis = basis + + from sage.structure.element import is_Matrix + basis_is_matrices = False + + degree = 0 + if n > 0: + if is_Matrix(basis[0]): + basis_is_matrices = True + vector_basis = tuple( map(_mat2vec,basis) ) + degree = basis[0].nrows()**2 + else: + degree = basis[0].degree() + + V = VectorSpace(field, degree) + + # Compute this from "Q" (obtained from Gram-Schmidt) below as + # R = Q.solve_right(A), where the rows of "Q" are the + # orthonormalized vector_basis and and the rows of "A" are the + # original vector_basis. + self._deorthonormalization_matrix = None + + if orthonormalize: + from mjo.eja.eja_utils import gram_schmidt + vector_basis = gram_schmidt(vector_basis, inner_product) + W = V.span_of_basis( vector_basis ) + if basis_is_matrices: + from mjo.eja.eja_utils import _vec2mat + basis = tuple( map(_vec2mat,vector_basis) ) + + W = V.span_of_basis( vector_basis ) + + mult_table = [ [0 for i in range(n)] for j in range(n) ] + ip_table = [ [0 for i in range(n)] for j in range(n) ] + + for i in range(n): + for j in range(i+1): + # do another mat2vec because the multiplication + # table is in terms of vectors + elt = _mat2vec(jordan_product(basis[i],basis[j])) + elt = W.coordinate_vector(elt) + mult_table[i][j] = elt + mult_table[j][i] = elt + ip = inner_product(basis[i],basis[j]) + ip_table[i][j] = ip + ip_table[j][i] = ip + + self._inner_product_matrix = matrix(field,ip_table) + + if basis_is_matrices: + for m in basis: + m.set_immutable() + else: + basis = tuple( x.column() for x in basis ) + + super().__init__(field, + mult_table, + prefix, + category, + basis, # matrix basis + check_field, + check_axioms) class RationalBasisEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebra): r""" @@ -1065,7 +1145,7 @@ class RationalBasisEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebr return superclass._charpoly_coefficients() mult_table = tuple( - map(lambda x: x.to_vector(), ls) + tuple(map(lambda x: x.to_vector(), ls)) for ls in self._multiplication_table ) @@ -2035,7 +2115,7 @@ class QuaternionHermitianEJA(QuaternionMatrixEuclideanJordanAlgebra, return cls(n, field, **kwargs) -class HadamardEJA(RationalBasisEuclideanJordanAlgebra, +class HadamardEJA(RationalBasisEuclideanJordanAlgebraNg, ConcreteEuclideanJordanAlgebra): """ Return the Euclidean Jordan Algebra corresponding to the set @@ -2078,22 +2158,17 @@ class HadamardEJA(RationalBasisEuclideanJordanAlgebra, """ def __init__(self, n, field=AA, **kwargs): V = VectorSpace(field, n) - mult_table = [ [ V.gen(i)*(i == j) for j in range(n) ] - for i in range(n) ] + basis = V.basis() - # Inner products are real numbers and not algebra - # elements, so once we turn the algebra element - # into a vector in inner_product(), we never go - # back. As a result -- contrary to what we do with - # self._multiplication_table -- we store the inner - # product table as a plain old matrix and not as - # an algebra operator. - ip_table = matrix.identity(field,n) - self._inner_product_matrix = ip_table + def jordan_product(x,y): + return V([ xi*yi for (xi,yi) in zip(x,y) ]) + def inner_product(x,y): + return x.inner_product(y) super(HadamardEJA, self).__init__(field, - mult_table, - check_axioms=False, + basis, + jordan_product, + inner_product, **kwargs) self.rank.set_cache(n)