X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Feja%2Feja_algebra.py;h=aef11acd1dbb6dc60b4765be1790f2fb71c5a1be;hb=ff77756eb6b57897d27656a69562663782f64d92;hp=e16fd97c4f0e55591728dc8204da3d941529380c;hpb=28d86108d78f1ea5a93d9cc8d69bad9cc8cd74fd;p=sage.d.git diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index e16fd97..aef11ac 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -1656,7 +1656,7 @@ class RationalBasisEJA(FiniteDimensionalEJA): subs_dict = { X[i]: BX[i] for i in range(len(X)) } return tuple( a_i.subs(subs_dict) for a_i in a ) -class ConcreteEJA(RationalBasisEJA): +class ConcreteEJA(FiniteDimensionalEJA): r""" A class for the Euclidean Jordan algebras that we know by name. @@ -1733,11 +1733,9 @@ class MatrixEJA: def trace_inner_product(X,Y): r""" A trace inner-product for matrices that aren't embedded in the - reals. + reals. It takes MATRICES as arguments, not EJA elements. """ - # We take the norm (absolute value) because Octonions() isn't - # smart enough yet to coerce its one() into the base field. - return (X*Y).trace().abs() + return (X*Y).trace().real() class RealEmbeddedMatrixEJA(MatrixEJA): @staticmethod @@ -1833,7 +1831,7 @@ class RealEmbeddedMatrixEJA(MatrixEJA): # as a REAL matrix will be 2*a = 2*Re(z_1). And so forth. return (X*Y).trace()/cls.dimension_over_reals() -class RealSymmetricEJA(ConcreteEJA, MatrixEJA): +class RealSymmetricEJA(ConcreteEJA, RationalBasisEJA, MatrixEJA): """ The rank-n simple EJA consisting of real symmetric n-by-n matrices, the usual symmetric Jordan product, and the trace inner @@ -2115,7 +2113,7 @@ class ComplexMatrixEJA(RealEmbeddedMatrixEJA): return matrix(F, n/d, elements) -class ComplexHermitianEJA(ConcreteEJA, ComplexMatrixEJA): +class ComplexHermitianEJA(ConcreteEJA, RationalBasisEJA, ComplexMatrixEJA): """ The rank-n simple EJA consisting of complex Hermitian n-by-n matrices over the real numbers, the usual symmetric Jordan product, @@ -2417,7 +2415,9 @@ class QuaternionMatrixEJA(RealEmbeddedMatrixEJA): return matrix(Q, n/d, elements) -class QuaternionHermitianEJA(ConcreteEJA, QuaternionMatrixEJA): +class QuaternionHermitianEJA(ConcreteEJA, + RationalBasisEJA, + QuaternionMatrixEJA): r""" The rank-n simple EJA consisting of self-adjoint n-by-n quaternion matrices, the usual symmetric Jordan product, and the @@ -2586,7 +2586,89 @@ class QuaternionHermitianEJA(ConcreteEJA, QuaternionMatrixEJA): return cls(n, **kwargs) class OctonionHermitianEJA(FiniteDimensionalEJA, MatrixEJA): + r""" + SETUP:: + + sage: from mjo.eja.eja_algebra import (FiniteDimensionalEJA, + ....: OctonionHermitianEJA) + + EXAMPLES: + + The 3-by-3 algebra satisfies the axioms of an EJA:: + + sage: OctonionHermitianEJA(3, # long time + ....: field=QQ, # long time + ....: orthonormalize=False, # long time + ....: check_axioms=True) # long time + Euclidean Jordan algebra of dimension 27 over Rational Field + + After a change-of-basis, the 2-by-2 algebra has the same + multiplication table as the ten-dimensional Jordan spin algebra:: + + sage: b = OctonionHermitianEJA._denormalized_basis(2,QQ) + sage: basis = (b[0] + b[9],) + b[1:9] + (b[0] - b[9],) + sage: jp = OctonionHermitianEJA.jordan_product + sage: ip = OctonionHermitianEJA.trace_inner_product + sage: J = FiniteDimensionalEJA(basis, + ....: jp, + ....: ip, + ....: field=QQ, + ....: orthonormalize=False) + sage: J.multiplication_table() + +----++----+----+----+----+----+----+----+----+----+----+ + | * || b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7 | b8 | b9 | + +====++====+====+====+====+====+====+====+====+====+====+ + | b0 || b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7 | b8 | b9 | + +----++----+----+----+----+----+----+----+----+----+----+ + | b1 || b1 | b0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + +----++----+----+----+----+----+----+----+----+----+----+ + | b2 || b2 | 0 | b0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + +----++----+----+----+----+----+----+----+----+----+----+ + | b3 || b3 | 0 | 0 | b0 | 0 | 0 | 0 | 0 | 0 | 0 | + +----++----+----+----+----+----+----+----+----+----+----+ + | b4 || b4 | 0 | 0 | 0 | b0 | 0 | 0 | 0 | 0 | 0 | + +----++----+----+----+----+----+----+----+----+----+----+ + | b5 || b5 | 0 | 0 | 0 | 0 | b0 | 0 | 0 | 0 | 0 | + +----++----+----+----+----+----+----+----+----+----+----+ + | b6 || b6 | 0 | 0 | 0 | 0 | 0 | b0 | 0 | 0 | 0 | + +----++----+----+----+----+----+----+----+----+----+----+ + | b7 || b7 | 0 | 0 | 0 | 0 | 0 | 0 | b0 | 0 | 0 | + +----++----+----+----+----+----+----+----+----+----+----+ + | b8 || b8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | b0 | 0 | + +----++----+----+----+----+----+----+----+----+----+----+ + | b9 || b9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | b0 | + +----++----+----+----+----+----+----+----+----+----+----+ + + TESTS: + We can actually construct the 27-dimensional Albert algebra, + and we get the right unit element if we recompute it:: + + sage: J = OctonionHermitianEJA(3, # long time + ....: field=QQ, # long time + ....: orthonormalize=False) # long time + sage: J.one.clear_cache() # long time + sage: J.one() # long time + b0 + b9 + b26 + sage: J.one().to_matrix() # long time + +----+----+----+ + | e0 | 0 | 0 | + +----+----+----+ + | 0 | e0 | 0 | + +----+----+----+ + | 0 | 0 | e0 | + +----+----+----+ + + The 2-by-2 algebra is isomorphic to the ten-dimensional Jordan + spin algebra, but just to be sure, we recompute its rank:: + + sage: J = OctonionHermitianEJA(2, # long time + ....: field=QQ, # long time + ....: orthonormalize=False) # long time + sage: J.rank.clear_cache() # long time + sage: J.rank() # long time + 2 + """ def __init__(self, n, field=AA, **kwargs): if n > 3: # Otherwise we don't get an EJA. @@ -2599,6 +2681,7 @@ class OctonionHermitianEJA(FiniteDimensionalEJA, MatrixEJA): super().__init__(self._denormalized_basis(n,field), self.jordan_product, self.trace_inner_product, + field=field, **kwargs) # TODO: this could be factored out somehow, but is left here @@ -2621,7 +2704,7 @@ class OctonionHermitianEJA(FiniteDimensionalEJA, MatrixEJA): EXAMPLES:: - sage: B = OctonionHermitianEJA._denormalized_basis(3) + sage: B = OctonionHermitianEJA._denormalized_basis(3,QQ) sage: all( M.is_hermitian() for M in B ) True sage: len(B) @@ -2629,7 +2712,7 @@ class OctonionHermitianEJA(FiniteDimensionalEJA, MatrixEJA): """ from mjo.octonions import OctonionMatrixAlgebra - MS = OctonionMatrixAlgebra(n, field=field) + MS = OctonionMatrixAlgebra(n, scalars=field) es = MS.entry_algebra().gens() basis = [] @@ -2641,13 +2724,38 @@ class OctonionHermitianEJA(FiniteDimensionalEJA, MatrixEJA): else: for e in es: E_ij = MS.monomial( (i,j,e) ) - E_ij += MS.monomial( (j,i,e.conjugate()) ) + ec = e.conjugate() + # If the conjugate has a negative sign in front + # of it, (j,i,ec) won't be a monomial! + if (j,i,ec) in MS.indices(): + E_ij += MS.monomial( (j,i,ec) ) + else: + E_ij -= MS.monomial( (j,i,-ec) ) basis.append(E_ij) return tuple( basis ) + @staticmethod + def trace_inner_product(X,Y): + r""" + The octonions don't know that the reals are embedded in them, + so we have to take the e0 component ourselves. + + SETUP:: + + sage: from mjo.eja.eja_algebra import OctonionHermitianEJA + + TESTS:: + + sage: J = OctonionHermitianEJA(2,field=QQ,orthonormalize=False) + sage: I = J.one().to_matrix() + sage: J.trace_inner_product(I, -I) + -2 + + """ + return (X*Y).trace().real().coefficient(0) -class HadamardEJA(ConcreteEJA): +class HadamardEJA(ConcreteEJA, RationalBasisEJA): """ Return the Euclidean Jordan Algebra corresponding to the set `R^n` under the Hadamard product. @@ -2739,7 +2847,7 @@ class HadamardEJA(ConcreteEJA): return cls(n, **kwargs) -class BilinearFormEJA(ConcreteEJA): +class BilinearFormEJA(ConcreteEJA, RationalBasisEJA): r""" The rank-2 simple EJA consisting of real vectors ``x=(x0, x_bar)`` with the half-trace inner product and jordan product ``x*y = @@ -2987,7 +3095,7 @@ class JordanSpinEJA(BilinearFormEJA): return cls(n, **kwargs) -class TrivialEJA(ConcreteEJA): +class TrivialEJA(ConcreteEJA, RationalBasisEJA): """ The trivial Euclidean Jordan algebra consisting of only a zero element.