X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Feja%2Feja_algebra.py;h=6b5b090fbefc4a51bfbedaf5a64d997ec7cfad64;hb=d6c744ecba0a22fdd76cb17e663594d323d1bb38;hp=f2d7ba70c82ae38375d3496521eef14463566897;hpb=2e4211deee2c4556f2c2b4dccc857106ce6bc89a;p=sage.d.git diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index f2d7ba7..6b5b090 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -32,22 +32,25 @@ for these simple algebras: * :class:`RealSymmetricEJA` * :class:`ComplexHermitianEJA` * :class:`QuaternionHermitianEJA` + * :class:`OctonionHermitianEJA` -Missing from this list is the algebra of three-by-three octononion -Hermitian matrices, as there is (as of yet) no implementation of the -octonions in SageMath. In addition to these, we provide two other -example constructions, +In addition to these, we provide two other example constructions, + * :class:`JordanSpinEJA` * :class:`HadamardEJA` + * :class:`AlbertEJA` * :class:`TrivialEJA` The Jordan spin algebra is a bilinear form algebra where the bilinear form is the identity. The Hadamard EJA is simply a Cartesian product -of one-dimensional spin algebras. And last but not least, the trivial -EJA is exactly what you think. Cartesian products of these are also -supported using the usual ``cartesian_product()`` function; as a -result, we support (up to isomorphism) all Euclidean Jordan algebras -that don't involve octonions. +of one-dimensional spin algebras. The Albert EJA is simply a special +case of the :class:`OctonionHermitianEJA` where the matrices are +three-by-three and the resulting space has dimension 27. And +last/least, the trivial EJA is exactly what you think it is; it could +also be obtained by constructing a dimension-zero instance of any of +the other algebras. Cartesian products of these are also supported +using the usual ``cartesian_product()`` function; as a result, we +support (up to isomorphism) all Euclidean Jordan algebras. SETUP:: @@ -59,8 +62,6 @@ EXAMPLES:: Euclidean Jordan algebra of dimension... """ -from itertools import repeat - from sage.algebras.quatalg.quaternion_algebra import QuaternionAlgebra from sage.categories.magmatic_algebras import MagmaticAlgebras from sage.categories.sets_cat import cartesian_product @@ -1543,7 +1544,7 @@ class FiniteDimensionalEJA(CombinatorialFreeModule): class RationalBasisEJA(FiniteDimensionalEJA): r""" - New class for algebras whose supplied basis elements have all rational entries. + Algebras whose supplied basis elements have all rational entries. SETUP:: @@ -1574,7 +1575,11 @@ class RationalBasisEJA(FiniteDimensionalEJA): if check_field: # Abuse the check_field parameter to check that the entries of # out basis (in ambient coordinates) are in the field QQ. - if not all( all(b_i in QQ for b_i in b.list()) for b in basis ): + # Use _all2list to get the vector coordinates of octonion + # entries and not the octonions themselves (which are not + # rational). + if not all( all(b_i in QQ for b_i in _all2list(b)) + for b in basis ): raise TypeError("basis not rational") super().__init__(basis, @@ -1831,7 +1836,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, RationalBasisEJA, MatrixEJA): +class RealSymmetricEJA(RationalBasisEJA, ConcreteEJA, MatrixEJA): """ The rank-n simple EJA consisting of real symmetric n-by-n matrices, the usual symmetric Jordan product, and the trace inner @@ -2113,7 +2118,7 @@ class ComplexMatrixEJA(RealEmbeddedMatrixEJA): return matrix(F, n/d, elements) -class ComplexHermitianEJA(ConcreteEJA, RationalBasisEJA, ComplexMatrixEJA): +class ComplexHermitianEJA(RationalBasisEJA, ConcreteEJA, ComplexMatrixEJA): """ The rank-n simple EJA consisting of complex Hermitian n-by-n matrices over the real numbers, the usual symmetric Jordan product, @@ -2415,8 +2420,8 @@ class QuaternionMatrixEJA(RealEmbeddedMatrixEJA): return matrix(Q, n/d, elements) -class QuaternionHermitianEJA(ConcreteEJA, - RationalBasisEJA, +class QuaternionHermitianEJA(RationalBasisEJA, + ConcreteEJA, QuaternionMatrixEJA): r""" The rank-n simple EJA consisting of self-adjoint n-by-n quaternion @@ -2585,7 +2590,7 @@ class QuaternionHermitianEJA(ConcreteEJA, n = ZZ.random_element(cls._max_random_instance_size() + 1) return cls(n, **kwargs) -class OctonionHermitianEJA(FiniteDimensionalEJA, MatrixEJA): +class OctonionHermitianEJA(RationalBasisEJA, ConcreteEJA, MatrixEJA): r""" SETUP:: @@ -2668,7 +2673,23 @@ class OctonionHermitianEJA(FiniteDimensionalEJA, MatrixEJA): sage: J.rank.clear_cache() # long time sage: J.rank() # long time 2 + """ + @staticmethod + def _max_random_instance_size(): + r""" + The maximum rank of a random QuaternionHermitianEJA. + """ + return 1 # Dimension 1 + + @classmethod + def random_instance(cls, **kwargs): + """ + Return a random instance of this type of algebra. + """ + n = ZZ.random_element(cls._max_random_instance_size() + 1) + return cls(n, **kwargs) + def __init__(self, n, field=AA, **kwargs): if n > 3: # Otherwise we don't get an EJA. @@ -2755,7 +2776,29 @@ class OctonionHermitianEJA(FiniteDimensionalEJA, MatrixEJA): """ return (X*Y).trace().real().coefficient(0) -class HadamardEJA(ConcreteEJA, RationalBasisEJA): + +class AlbertEJA(OctonionHermitianEJA): + r""" + The Albert algebra is the algebra of three-by-three Hermitian + matrices whose entries are octonions. + + SETUP:: + + sage: from mjo.eja.eja_algebra import AlbertEJA + + EXAMPLES:: + + sage: AlbertEJA(field=QQ, orthonormalize=False) + Euclidean Jordan algebra of dimension 27 over Rational Field + sage: AlbertEJA() # long time + Euclidean Jordan algebra of dimension 27 over Algebraic Real Field + + """ + def __init__(self, *args, **kwargs): + super().__init__(3, *args, **kwargs) + + +class HadamardEJA(RationalBasisEJA, ConcreteEJA): """ Return the Euclidean Jordan Algebra corresponding to the set `R^n` under the Hadamard product. @@ -2847,7 +2890,7 @@ class HadamardEJA(ConcreteEJA, RationalBasisEJA): return cls(n, **kwargs) -class BilinearFormEJA(ConcreteEJA, RationalBasisEJA): +class BilinearFormEJA(RationalBasisEJA, ConcreteEJA): 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 = @@ -3095,7 +3138,7 @@ class JordanSpinEJA(BilinearFormEJA): return cls(n, **kwargs) -class TrivialEJA(ConcreteEJA, RationalBasisEJA): +class TrivialEJA(RationalBasisEJA, ConcreteEJA): """ The trivial Euclidean Jordan algebra consisting of only a zero element. @@ -3642,7 +3685,9 @@ class RationalBasisCartesianProductEJA(CartesianProductEJA, SETUP:: - sage: from mjo.eja.eja_algebra import (JordanSpinEJA, + sage: from mjo.eja.eja_algebra import (HadamardEJA, + ....: JordanSpinEJA, + ....: OctonionHermitianEJA, ....: RealSymmetricEJA) EXAMPLES: @@ -3659,15 +3704,32 @@ class RationalBasisCartesianProductEJA(CartesianProductEJA, sage: J.rank() 5 + TESTS: + + The ``cartesian_product()`` function only uses the first factor to + decide where the result will live; thus we have to be careful to + check that all factors do indeed have a `_rational_algebra` member + before we try to access it:: + + sage: J1 = OctonionHermitianEJA(1) # no rational basis + sage: J2 = HadamardEJA(2) + sage: cartesian_product([J1,J2]) + Euclidean Jordan algebra of dimension 1 over Algebraic Real Field + (+) Euclidean Jordan algebra of dimension 2 over Algebraic Real Field + sage: cartesian_product([J2,J1]) + Euclidean Jordan algebra of dimension 2 over Algebraic Real Field + (+) Euclidean Jordan algebra of dimension 1 over Algebraic Real Field + """ def __init__(self, algebras, **kwargs): CartesianProductEJA.__init__(self, algebras, **kwargs) self._rational_algebra = None if self.vector_space().base_field() is not QQ: - self._rational_algebra = cartesian_product([ - r._rational_algebra for r in algebras - ]) + if all( hasattr(r, "_rational_algebra") for r in algebras ): + self._rational_algebra = cartesian_product([ + r._rational_algebra for r in algebras + ]) RationalBasisEJA.CartesianProduct = RationalBasisCartesianProductEJA