SETUP::
sage: from mjo.eja.eja_algebra import (random_eja,
+ ....: JordanSpinEJA,
....: HadamardEJA,
- ....: RealSymmetricEJA)
+ ....: RealSymmetricEJA,
+ ....: ComplexHermitianEJA)
- EXAMPLES::
+ EXAMPLES:
+
+ The projection morphisms are Euclidean Jordan algebra
+ operators::
sage: J1 = HadamardEJA(2)
sage: J2 = RealSymmetricEJA(2)
Codomain: Euclidean Jordan algebra of dimension 3 over Algebraic
Real Field
+ The projections work the way you'd expect on the vector
+ representation of an element::
+
+ sage: J1 = JordanSpinEJA(2)
+ sage: J2 = ComplexHermitianEJA(2)
+ sage: J = cartesian_product([J1,J2])
+ sage: pi_left = J.cartesian_projection(0)
+ sage: pi_right = J.cartesian_projection(1)
+ sage: pi_left(J.one()).to_vector()
+ (1, 0)
+ sage: pi_right(J.one()).to_vector()
+ (1, 0, 0, 1)
+ sage: J.one().to_vector()
+ (1, 0, 1, 0, 0, 1)
+
TESTS:
The answer never changes::
"""
Ji = self.cartesian_factors()[i]
- # We reimplement the CombinatorialFreeModule superclass method
- # because if we don't, something gets messed up with the caching
- # and the answer changes the second time you run it. See the TESTS.
- Pi = self._module_morphism(lambda j_t: Ji.monomial(j_t[1])
- if i == j_t[0] else Ji.zero(),
- codomain=Ji)
+ # Requires the fix on Trac 31421/31422 to work!
+ Pi = super().cartesian_projection(i)
return FiniteDimensionalEJAOperator(self,Ji,Pi.matrix())
@cached_method
SETUP::
sage: from mjo.eja.eja_algebra import (random_eja,
+ ....: JordanSpinEJA,
....: HadamardEJA,
....: RealSymmetricEJA)
- EXAMPLES::
+ EXAMPLES:
+
+ The embedding morphisms are Euclidean Jordan algebra
+ operators::
sage: J1 = HadamardEJA(2)
sage: J2 = RealSymmetricEJA(2)
Algebraic Real Field (+) Euclidean Jordan algebra of
dimension 3 over Algebraic Real Field
+ The embeddings work the way you'd expect on the vector
+ representation of an element::
+
+ sage: J1 = JordanSpinEJA(3)
+ sage: J2 = RealSymmetricEJA(2)
+ sage: J = cartesian_product([J1,J2])
+ sage: iota_left = J.cartesian_embedding(0)
+ sage: iota_right = J.cartesian_embedding(1)
+ sage: iota_left(J1.zero()) == J.zero()
+ True
+ sage: iota_right(J2.zero()) == J.zero()
+ True
+ sage: J1.one().to_vector()
+ (1, 0, 0)
+ sage: iota_left(J1.one()).to_vector()
+ (1, 0, 0, 0, 0, 0)
+ sage: J2.one().to_vector()
+ (1, 0, 1)
+ sage: iota_right(J2.one()).to_vector()
+ (0, 0, 0, 1, 0, 1)
+ sage: J.one().to_vector()
+ (1, 0, 0, 1, 0, 1)
+
TESTS:
The answer never changes::
sage: E0 == E1
True
+ Composing a projection with the corresponding inclusion should
+ produce the identity map, and mismatching them should produce
+ the zero map::
+
+ sage: set_random_seed()
+ sage: J1 = random_eja()
+ sage: J2 = random_eja()
+ sage: J = cartesian_product([J1,J2])
+ sage: iota_left = J.cartesian_embedding(0)
+ sage: iota_right = J.cartesian_embedding(1)
+ sage: pi_left = J.cartesian_projection(0)
+ sage: pi_right = J.cartesian_projection(1)
+ sage: pi_left*iota_left == J1.one().operator()
+ True
+ sage: pi_right*iota_right == J2.one().operator()
+ True
+ sage: (pi_left*iota_right).is_zero()
+ True
+ sage: (pi_right*iota_left).is_zero()
+ True
+
"""
Ji = self.cartesian_factors()[i]
- # We reimplement the CombinatorialFreeModule superclass method
- # because if we don't, something gets messed up with the caching
- # and the answer changes the second time you run it. See the TESTS.
- Ei = Ji._module_morphism(lambda t: self.monomial((i, t)), codomain=self)
+ # Requires the fix on Trac 31421/31422 to work!
+ Ei = super().cartesian_embedding(i)
return FiniteDimensionalEJAOperator(Ji,self,Ei.matrix())
return sum( P(x).inner_product(P(y)) for P in projections )
-FiniteDimensionalEJA.CartesianProduct = CartesianProductEJA
-
-
-# def projections(self):
-# r"""
-# Return a pair of projections onto this algebra's factors.
-
-# SETUP::
-
-# sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
-# ....: ComplexHermitianEJA,
-# ....: DirectSumEJA)
-
-# EXAMPLES::
-
-# sage: J1 = JordanSpinEJA(2)
-# sage: J2 = ComplexHermitianEJA(2)
-# sage: J = DirectSumEJA(J1,J2)
-# sage: (pi_left, pi_right) = J.projections()
-# sage: J.one().to_vector()
-# (1, 0, 1, 0, 0, 1)
-# sage: pi_left(J.one()).to_vector()
-# (1, 0)
-# sage: pi_right(J.one()).to_vector()
-# (1, 0, 0, 1)
-
-# """
-# (J1,J2) = self.factors()
-# m = J1.dimension()
-# n = J2.dimension()
-# V_basis = self.vector_space().basis()
-# # Need to specify the dimensions explicitly so that we don't
-# # wind up with a zero-by-zero matrix when we want e.g. a
-# # zero-by-two matrix (important for composing things).
-# P1 = matrix(self.base_ring(), m, m+n, V_basis[:m])
-# P2 = matrix(self.base_ring(), n, m+n, V_basis[m:])
-# pi_left = FiniteDimensionalEJAOperator(self,J1,P1)
-# pi_right = FiniteDimensionalEJAOperator(self,J2,P2)
-# return (pi_left, pi_right)
-
-# def inclusions(self):
-# r"""
-# Return the pair of inclusion maps from our factors into us.
-
-# SETUP::
-
-# sage: from mjo.eja.eja_algebra import (random_eja,
-# ....: JordanSpinEJA,
-# ....: RealSymmetricEJA,
-# ....: DirectSumEJA)
-
-# EXAMPLES::
-
-# sage: J1 = JordanSpinEJA(3)
-# sage: J2 = RealSymmetricEJA(2)
-# sage: J = DirectSumEJA(J1,J2)
-# sage: (iota_left, iota_right) = J.inclusions()
-# sage: iota_left(J1.zero()) == J.zero()
-# True
-# sage: iota_right(J2.zero()) == J.zero()
-# True
-# sage: J1.one().to_vector()
-# (1, 0, 0)
-# sage: iota_left(J1.one()).to_vector()
-# (1, 0, 0, 0, 0, 0)
-# sage: J2.one().to_vector()
-# (1, 0, 1)
-# sage: iota_right(J2.one()).to_vector()
-# (0, 0, 0, 1, 0, 1)
-# sage: J.one().to_vector()
-# (1, 0, 0, 1, 0, 1)
-
-# TESTS:
-
-# Composing a projection with the corresponding inclusion should
-# produce the identity map, and mismatching them should produce
-# the zero map::
-
-# sage: set_random_seed()
-# sage: J1 = random_eja()
-# sage: J2 = random_eja()
-# sage: J = DirectSumEJA(J1,J2)
-# sage: (iota_left, iota_right) = J.inclusions()
-# sage: (pi_left, pi_right) = J.projections()
-# sage: pi_left*iota_left == J1.one().operator()
-# True
-# sage: pi_right*iota_right == J2.one().operator()
-# True
-# sage: (pi_left*iota_right).is_zero()
-# True
-# sage: (pi_right*iota_left).is_zero()
-# True
-
-# """
-# (J1,J2) = self.factors()
-# m = J1.dimension()
-# n = J2.dimension()
-# V_basis = self.vector_space().basis()
-# # Need to specify the dimensions explicitly so that we don't
-# # wind up with a zero-by-zero matrix when we want e.g. a
-# # two-by-zero matrix (important for composing things).
-# I1 = matrix.column(self.base_ring(), m, m+n, V_basis[:m])
-# I2 = matrix.column(self.base_ring(), n, m+n, V_basis[m:])
-# iota_left = FiniteDimensionalEJAOperator(J1,self,I1)
-# iota_right = FiniteDimensionalEJAOperator(J2,self,I2)
-# return (iota_left, iota_right)
-
-
+ Element = FiniteDimensionalEJAElement
+FiniteDimensionalEJA.CartesianProduct = CartesianProductEJA
random_eja = ConcreteEJA.random_instance