return self.from_vector(coords)
@staticmethod
- def _max_test_case_size():
+ def _max_random_instance_size():
"""
Return an integer "size" that is an upper bound on the size of
this algebra when it is used in a random test
interpreted to be far less than the dimension) should override
with a smaller number.
"""
- return 5
+ raise NotImplementedError
def _repr_(self):
"""
Beware, this will crash for "most instances" because the
constructor below looks wrong.
"""
- if cls is TrivialEJA:
- # The TrivialEJA class doesn't take an "n" argument because
- # there's only one.
- return cls(field)
-
- n = ZZ.random_element(cls._max_test_case_size() + 1)
+ n = ZZ.random_element(cls._max_random_instance_size() + 1)
return cls(n, field, **kwargs)
@cached_method
class MatrixEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebra):
@staticmethod
- def _max_test_case_size():
+ def _max_random_instance_size():
# Play it safe, since this will be squared and the underlying
# field can have dimension 4 (quaternions) too.
return 2
The dimension of this algebra is `(n^2 + n) / 2`::
sage: set_random_seed()
- sage: n_max = RealSymmetricEJA._max_test_case_size()
+ sage: n_max = RealSymmetricEJA._max_random_instance_size()
sage: n = ZZ.random_element(1, n_max)
sage: J = RealSymmetricEJA(n)
sage: J.dimension() == (n^2 + n)/2
@staticmethod
- def _max_test_case_size():
+ def _max_random_instance_size():
return 4 # Dimension 10
Embedding is a homomorphism (isomorphism, in fact)::
sage: set_random_seed()
- sage: n_max = ComplexMatrixEuclideanJordanAlgebra._max_test_case_size()
+ sage: n_max = ComplexMatrixEuclideanJordanAlgebra._max_random_instance_size()
sage: n = ZZ.random_element(n_max)
sage: F = QuadraticField(-1, 'I')
sage: X = random_matrix(F, n)
The dimension of this algebra is `n^2`::
sage: set_random_seed()
- sage: n_max = ComplexHermitianEJA._max_test_case_size()
+ sage: n_max = ComplexHermitianEJA._max_random_instance_size()
sage: n = ZZ.random_element(1, n_max)
sage: J = ComplexHermitianEJA(n)
sage: J.dimension() == n^2
Embedding is a homomorphism (isomorphism, in fact)::
sage: set_random_seed()
- sage: n_max = QuaternionMatrixEuclideanJordanAlgebra._max_test_case_size()
+ sage: n_max = QuaternionMatrixEuclideanJordanAlgebra._max_random_instance_size()
sage: n = ZZ.random_element(n_max)
sage: Q = QuaternionAlgebra(QQ,-1,-1)
sage: X = random_matrix(Q, n)
The dimension of this algebra is `2*n^2 - n`::
sage: set_random_seed()
- sage: n_max = QuaternionHermitianEJA._max_test_case_size()
+ sage: n_max = QuaternionHermitianEJA._max_random_instance_size()
sage: n = ZZ.random_element(1, n_max)
sage: J = QuaternionHermitianEJA(n)
sage: J.dimension() == 2*(n^2) - n
**kwargs)
self.rank.set_cache(n)
+ @staticmethod
+ def _max_random_instance_size():
+ return 5
+
def inner_product(self, x, y):
"""
Faster to reimplement than to use natural representations.
**kwargs)
self.rank.set_cache(min(n,2))
+ @staticmethod
+ def _max_random_instance_size():
+ return 5
+
def inner_product(self, x, y):
r"""
Half of the trace inner product.
# largest subalgebra generated by any element.
self.rank.set_cache(0)
+ @classmethod
+ def random_instance(cls, field=AA, **kwargs):
+ # We don't take a "size" argument so the superclass method is
+ # inappropriate for us.
+ return cls(field, **kwargs)
class DirectSumEJA(FiniteDimensionalEuclideanJordanAlgebra):
r"""
"""
def __init__(self, J1, J2, field=AA, **kwargs):
+ self._factors = (J1, J2)
n1 = J1.dimension()
n2 = J2.dimension()
n = n1+n2
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::
+
+ sage: from mjo.eja.eja_algebra import (HadamardEJA,
+ ....: JordanSpinEJA,
+ ....: DirectSumEJA)
+
+ EXAMPLES::
+
+ sage: J1 = HadamardEJA(2,QQ)
+ sage: J2 = JordanSpinEJA(3,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)
+
+ """
+ return self._factors
+
+ 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()
+ n = J1.dimension()
+ pi_left = lambda x: J1.from_vector(x.to_vector()[:n])
+ pi_right = lambda x: J2.from_vector(x.to_vector()[n:])
+ 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 (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)
+
+ """
+ (J1,J2) = self.factors()
+ n = J1.dimension()
+ V_basis = self.vector_space().basis()
+ I1 = matrix.column(self.base_ring(), V_basis[:n])
+ I2 = matrix.column(self.base_ring(), V_basis[n:])
+ iota_left = lambda x: self.from_vector(I1*x.to_vector())
+ iota_right = lambda x: self.from_vector(I2*+x.to_vector())
+ return (iota_left, iota_right)
+
+ def inner_product(self, x, y):
+ r"""
+ The standard Cartesian inner-product.
+
+ We project ``x`` and ``y`` onto our factors, and add up the
+ inner-products from the subalgebras.
+
+ SETUP::
+
+
+ sage: from mjo.eja.eja_algebra import (HadamardEJA,
+ ....: QuaternionHermitianEJA,
+ ....: DirectSumEJA)
+
+ EXAMPLE::
+
+ sage: J1 = HadamardEJA(3)
+ sage: J2 = QuaternionHermitianEJA(2,QQ,normalize_basis=False)
+ sage: J = DirectSumEJA(J1,J2)
+ sage: x1 = J1.one()
+ sage: x2 = x1
+ sage: y1 = J2.one()
+ sage: y2 = y1
+ sage: x1.inner_product(x2)
+ 3
+ sage: y1.inner_product(y2)
+ 2
+ sage: J.one().inner_product(J.one())
+ 5
+
+ """
+ (pi_left, pi_right) = self.projections()
+ x1 = pi_left(x)
+ x2 = pi_right(x)
+ y1 = pi_left(y)
+ y2 = pi_right(y)
+
+ return (x1.inner_product(y1) + x2.inner_product(y2))