X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Feja%2Feja_algebra.py;h=6750f228451b5ec2052efc3974ddee72cd0d0c12;hb=02cbbda68c8efd79b3c9735d5eca7e7162b24840;hp=aef11acd1dbb6dc60b4765be1790f2fb71c5a1be;hpb=ff77756eb6b57897d27656a69562663782f64d92;p=sage.d.git diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index aef11ac..6750f22 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -32,22 +32,21 @@ 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:`HadamardEJA` * :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. And last but 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:: @@ -1543,7 +1542,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:: @@ -2585,7 +2584,7 @@ class QuaternionHermitianEJA(ConcreteEJA, n = ZZ.random_element(cls._max_random_instance_size() + 1) return cls(n, **kwargs) -class OctonionHermitianEJA(FiniteDimensionalEJA, MatrixEJA): +class OctonionHermitianEJA(ConcreteEJA, MatrixEJA): r""" SETUP:: @@ -2668,7 +2667,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. @@ -3380,9 +3395,17 @@ class CartesianProductEJA(FiniteDimensionalEJA): Return the space that our matrix basis lives in as a Cartesian product. + We don't simply use the ``cartesian_product()`` functor here + because it acts differently on SageMath MatrixSpaces and our + custom MatrixAlgebras, which are CombinatorialFreeModules. We + always want the result to be represented (and indexed) as + an ordered tuple. + SETUP:: - sage: from mjo.eja.eja_algebra import (HadamardEJA, + sage: from mjo.eja.eja_algebra import (ComplexHermitianEJA, + ....: HadamardEJA, + ....: OctonionHermitianEJA, ....: RealSymmetricEJA) EXAMPLES:: @@ -3395,10 +3418,44 @@ class CartesianProductEJA(FiniteDimensionalEJA): matrices over Algebraic Real Field, Full MatrixSpace of 2 by 2 dense matrices over Algebraic Real Field) + :: + + sage: J1 = ComplexHermitianEJA(1) + sage: J2 = ComplexHermitianEJA(1) + sage: J = cartesian_product([J1,J2]) + sage: J.one().to_matrix()[0] + [1 0] + [0 1] + sage: J.one().to_matrix()[1] + [1 0] + [0 1] + + :: + + sage: J1 = OctonionHermitianEJA(1) + sage: J2 = OctonionHermitianEJA(1) + sage: J = cartesian_product([J1,J2]) + sage: J.one().to_matrix()[0] + +----+ + | e0 | + +----+ + sage: J.one().to_matrix()[1] + +----+ + | e0 | + +----+ + """ - from sage.categories.cartesian_product import cartesian_product - return cartesian_product( [J.matrix_space() - for J in self.cartesian_factors()] ) + scalars = self.cartesian_factor(0).base_ring() + + # This category isn't perfect, but is good enough for what we + # need to do. + cat = MagmaticAlgebras(scalars).FiniteDimensional().WithBasis() + cat = cat.Unital().CartesianProducts() + factors = tuple( J.matrix_space() for J in self.cartesian_factors() ) + + from sage.sets.cartesian_product import CartesianProduct + return CartesianProduct(factors, cat) + @cached_method def cartesian_projection(self, i): @@ -3600,7 +3657,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: @@ -3617,15 +3676,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