if self.is_trivial():
return MatrixSpace(self.base_ring(), 0)
else:
- return self._matrix_basis[0].matrix_space()
+ return self.matrix_basis()[0].parent()
@cached_method
# inappropriate for us.
return cls(**kwargs)
-# class DirectSumEJA(ConcreteEJA):
-# r"""
-# The external (orthogonal) direct sum of two other Euclidean Jordan
-# algebras. Essentially the Cartesian product of its two factors.
-# Every Euclidean Jordan algebra decomposes into an orthogonal
-# direct sum of simple Euclidean Jordan algebras, so no generality
-# is lost by providing only this construction.
-
-# SETUP::
-
-# sage: from mjo.eja.eja_algebra import (random_eja,
-# ....: HadamardEJA,
-# ....: RealSymmetricEJA,
-# ....: DirectSumEJA)
-
-# EXAMPLES::
-
-# sage: J1 = HadamardEJA(2)
-# sage: J2 = RealSymmetricEJA(3)
-# sage: J = DirectSumEJA(J1,J2)
-# sage: J.dimension()
-# 8
-# sage: J.rank()
-# 5
-
-# TESTS:
-
-# The external direct sum construction is only valid when the two factors
-# have the same base ring; an error is raised otherwise::
-
-# sage: set_random_seed()
-# sage: J1 = random_eja(field=AA)
-# sage: J2 = random_eja(field=QQ,orthonormalize=False)
-# sage: J = DirectSumEJA(J1,J2)
-# Traceback (most recent call last):
-# ...
-# ValueError: algebras must share the same base field
-
-# """
-# def __init__(self, J1, J2, **kwargs):
-# if J1.base_ring() != J2.base_ring():
-# raise ValueError("algebras must share the same base field")
-# field = J1.base_ring()
-
-# self._factors = (J1, J2)
-# n1 = J1.dimension()
-# n2 = J2.dimension()
-# n = n1+n2
-# V = VectorSpace(field, 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(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(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 = [ [ field.zero() for j in range(i+1) ]
-# for i in range(n) ]
-# super(DirectSumEJA, self).__init__(field,
-# mult_table,
-# ip_table,
-# check_axioms=False,
-# **kwargs)
-# self.rank.set_cache(J1.rank() + J2.rank())
-
-
-# def factors(self):
-# r"""
-# Return the pair of this algebra's factors.
-# SETUP::
+class DirectSumEJA(FiniteDimensionalEJA):
+ r"""
+ The external (orthogonal) direct sum of two other Euclidean Jordan
+ algebras. Essentially the Cartesian product of its two factors.
+ Every Euclidean Jordan algebra decomposes into an orthogonal
+ direct sum of simple Euclidean Jordan algebras, so no generality
+ is lost by providing only this construction.
-# sage: from mjo.eja.eja_algebra import (HadamardEJA,
-# ....: JordanSpinEJA,
-# ....: DirectSumEJA)
+ SETUP::
-# EXAMPLES::
+ sage: from mjo.eja.eja_algebra import (random_eja,
+ ....: HadamardEJA,
+ ....: RealSymmetricEJA,
+ ....: DirectSumEJA)
-# sage: J1 = HadamardEJA(2, field=QQ)
-# sage: J2 = JordanSpinEJA(3, field=QQ)
-# sage: J = DirectSumEJA(J1,J2)
-# sage: J.factors()
-# (Euclidean Jordan algebra of dimension 2 over Rational Field,
-# Euclidean Jordan algebra of dimension 3 over Rational Field)
+ EXAMPLES::
+
+ sage: J1 = HadamardEJA(2)
+ sage: J2 = RealSymmetricEJA(3)
+ sage: J = DirectSumEJA(J1,J2)
+ sage: J.dimension()
+ 8
+ sage: J.rank()
+ 5
+ sage: J.matrix_space()
+ The Cartesian product of (Full MatrixSpace of 2 by 1 dense matrices
+ over Algebraic Real Field, Full MatrixSpace of 3 by 3 dense matrices
+ over Algebraic Real Field)
+
+ TESTS:
+
+ The external direct sum construction is only valid when the two factors
+ have the same base ring; an error is raised otherwise::
+
+ sage: set_random_seed()
+ sage: J1 = random_eja(field=AA)
+ sage: J2 = random_eja(field=QQ,orthonormalize=False)
+ sage: J = DirectSumEJA(J1,J2)
+ Traceback (most recent call last):
+ ...
+ ValueError: algebras must share the same base field
+
+ """
+ def __init__(self, J1, J2, **kwargs):
+ if J1.base_ring() != J2.base_ring():
+ raise ValueError("algebras must share the same base field")
+ field = J1.base_ring()
+
+ M = J1.matrix_space().cartesian_product(J2.matrix_space())
+ self._cartprod_algebra = J1.cartesian_product(J2)
+
+ self._matrix_basis = tuple( [M((a,0)) for a in J1.matrix_basis()] +
+ [M((0,b)) for b in J2.matrix_basis()] )
+
+ n = len(self._matrix_basis)
+ self._sets = None
+ CombinatorialFreeModule.__init__(
+ self,
+ field,
+ range(n),
+ category=self._cartprod_algebra.category(),
+ bracket=False,
+ **kwargs)
+ self.rank.set_cache(J1.rank() + J2.rank())
+
+
+
+ def product(self,x,y):
+ r"""
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
+ ....: ComplexHermitianEJA,
+ ....: DirectSumEJA)
+
+ TESTS::
+
+ sage: set_random_seed()
+ sage: J1 = JordanSpinEJA(3, field=QQ)
+ sage: J2 = ComplexHermitianEJA(2, field=QQ, orthonormalize=False)
+ sage: J = DirectSumEJA(J1,J2)
+ sage: J.random_element()*J.random_element() in J
+ True
+
+ """
+ xv = self._cartprod_algebra.from_vector(x.to_vector())
+ yv = self._cartprod_algebra.from_vector(y.to_vector())
+ return self.from_vector((xv*yv).to_vector())
+
+
+ def cartesian_factors(self):
+ r"""
+ Return the pair of this algebra's factors.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (HadamardEJA,
+ ....: JordanSpinEJA,
+ ....: DirectSumEJA)
+
+ EXAMPLES::
+
+ sage: J1 = HadamardEJA(2, field=QQ)
+ sage: J2 = JordanSpinEJA(3, field=QQ)
+ sage: J = DirectSumEJA(J1,J2)
+ sage: J.cartesian_factors()
+ (Euclidean Jordan algebra of dimension 2 over Rational Field,
+ Euclidean Jordan algebra of dimension 3 over Rational Field)
+
+ """
+ return self._cartprod_algebra.cartesian_factors()
-# """
-# return self._factors
# def projections(self):
# r"""