- The natural representation of an element in the subalgebra is
- the same as its natural representation in the superalgebra::
-
- sage: set_random_seed()
- sage: A = random_eja().random_element().subalgebra_generated_by()
- sage: y = A.random_element()
- sage: actual = y.natural_representation()
- sage: expected = y.superalgebra_element().natural_representation()
- sage: actual == expected
- True
-
- The left-multiplication-by operator for elements in the subalgebra
- works like it does in the superalgebra, even if we orthonormalize
- our basis::
-
- sage: set_random_seed()
- sage: x = random_eja(AA).random_element()
- sage: A = x.subalgebra_generated_by(orthonormalize_basis=True)
- sage: y = A.random_element()
- sage: y.operator()(A.one()) == y
- True
-
- """
-
- def superalgebra_element(self):
- """
- Return the object in our algebra's superalgebra that corresponds
- to myself.
-
- SETUP::
-
- sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
- ....: random_eja)
-
- EXAMPLES::
-
- sage: J = RealSymmetricEJA(3)
- sage: x = sum(J.gens())
- sage: x
- e0 + e1 + e2 + e3 + e4 + e5
- sage: A = x.subalgebra_generated_by()
- sage: A(x)
- f1
- sage: A(x).superalgebra_element()
- e0 + e1 + e2 + e3 + e4 + e5
-
- TESTS:
-
- We can convert back and forth faithfully::
-
- sage: set_random_seed()
- sage: J = random_eja()
- sage: x = J.random_element()
- sage: A = x.subalgebra_generated_by()
- sage: A(x).superalgebra_element() == x
- True
- sage: y = A.random_element()
- sage: A(y.superalgebra_element()) == y
- True
-
- """
- return self.parent().superalgebra().linear_combination(
- zip(self.parent()._superalgebra_basis, self.to_vector()) )
-
-
-
-
-class FiniteDimensionalEuclideanJordanElementSubalgebra(FiniteDimensionalEuclideanJordanAlgebra):
- """
- The subalgebra of an EJA generated by a single element.
-
- SETUP::
-
- sage: from mjo.eja.eja_algebra import (ComplexHermitianEJA,
- ....: JordanSpinEJA)
-
- TESTS:
-
- Ensure that our generator names don't conflict with the superalgebra::
-
- sage: J = JordanSpinEJA(3)
- sage: J.one().subalgebra_generated_by().gens()
- (f0,)
- sage: J = JordanSpinEJA(3, prefix='f')
- sage: J.one().subalgebra_generated_by().gens()
- (g0,)
- sage: J = JordanSpinEJA(3, prefix='b')
- sage: J.one().subalgebra_generated_by().gens()
- (c0,)
-
- Ensure that we can find subalgebras of subalgebras::
-
- sage: A = ComplexHermitianEJA(3).one().subalgebra_generated_by()
- sage: B = A.one().subalgebra_generated_by()
- sage: B.dimension()
- 1
-
- """
- def __init__(self, elt, orthonormalize_basis):
- self._superalgebra = elt.parent()
- category = self._superalgebra.category().Associative()
- V = self._superalgebra.vector_space()
- field = self._superalgebra.base_ring()
-
- # A half-assed attempt to ensure that we don't collide with
- # the superalgebra's prefix (ignoring the fact that there
- # could be super-superelgrbas in scope). If possible, we
- # try to "increment" the parent algebra's prefix, although
- # this idea goes out the window fast because some prefixen
- # are off-limits.
- prefixen = [ 'f', 'g', 'h', 'a', 'b', 'c', 'd' ]
- try:
- prefix = prefixen[prefixen.index(self._superalgebra.prefix()) + 1]
- except ValueError:
- prefix = prefixen[0]
-
- # This list is guaranteed to contain all independent powers,
- # because it's the maximal set of powers that could possibly
- # be independent (by a dimension argument).
- powers = [ elt**k for k in range(V.dimension()) ]
- power_vectors = [ p.to_vector() for p in powers ]
- P = matrix(field, power_vectors)
-
- if orthonormalize_basis == False:
- # In this case, we just need to figure out which elements
- # of the "powers" list are redundant... First compute the
- # vector subspace spanned by the powers of the given
- # element.
-
- # Figure out which powers form a linearly-independent set.
- ind_rows = P.pivot_rows()
-
- # Pick those out of the list of all powers.
- superalgebra_basis = tuple(map(powers.__getitem__, ind_rows))
-
- # If our superalgebra is a subalgebra of something else, then
- # these vectors won't have the right coordinates for
- # V.span_of_basis() unless we use V.from_vector() on them.
- basis_vectors = map(power_vectors.__getitem__, ind_rows)