# TODO: make this unnecessary somehow.
from sage.misc.lazy_import import lazy_import
lazy_import('mjo.eja.eja_algebra', 'FiniteDimensionalEuclideanJordanAlgebra')
-lazy_import('mjo.eja.eja_subalgebra',
+lazy_import('mjo.eja.eja_element_subalgebra',
'FiniteDimensionalEuclideanJordanElementSubalgebra')
from mjo.eja.eja_operator import FiniteDimensionalEuclideanJordanAlgebraOperator
from mjo.eja.eja_utils import _mat2vec
return not (p(zero) == zero)
+ def is_minimal_idempotent(self):
+ """
+ Return whether or not this element is a minimal idempotent.
+
+
+ An element of a Euclidean Jordan algebra is a minimal idempotent
+ if it :meth:`is_idempotent` and if its Peirce subalgebra
+ corresponding to the eigenvalue ``1`` has dimension ``1`` (Baes,
+ Proposition 2.7.17).
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
+ ....: RealSymmetricEJA,
+ ....: random_eja)
+
+ WARNING::
+
+ This method is sloooooow.
+
+ EXAMPLES:
+
+ The spectral decomposition of a non-regular element should always
+ contain at least one non-minimal idempotent::
+
+ sage: J = RealSymmetricEJA(3, AA)
+ sage: x = sum(J.gens())
+ sage: x.is_regular()
+ False
+ sage: [ c.is_minimal_idempotent()
+ ....: for (l,c) in x.spectral_decomposition() ]
+ [False, True]
+
+ On the other hand, the spectral decomposition of a regular
+ element should always be in terms of minimal idempotents::
+
+ sage: J = JordanSpinEJA(4, AA)
+ sage: x = sum( i*J.gens()[i] for i in range(len(J.gens())) )
+ sage: x.is_regular()
+ True
+ sage: [ c.is_minimal_idempotent()
+ ....: for (l,c) in x.spectral_decomposition() ]
+ [True, True]
+
+ TESTS:
+
+ The identity element is minimal only in an EJA of rank one::
+
+ sage: set_random_seed()
+ sage: J = random_eja()
+ sage: J.rank() == 1 or not J.one().is_minimal_idempotent()
+ True
+
+ A non-idempotent cannot be a minimal idempotent::
+
+ sage: set_random_seed()
+ sage: J = JordanSpinEJA(4)
+ sage: x = J.random_element()
+ sage: (not x.is_idempotent()) and x.is_minimal_idempotent()
+ False
+
+ Proposition 2.7.19 in Baes says that an element is a minimal
+ idempotent if and only if it's idempotent with trace equal to
+ unity::
+
+ sage: set_random_seed()
+ sage: J = JordanSpinEJA(4)
+ sage: x = J.random_element()
+ sage: expected = (x.is_idempotent() and x.trace() == 1)
+ sage: actual = x.is_minimal_idempotent()
+ sage: actual == expected
+ True
+
+ """
+ if not self.is_idempotent():
+ return False
+
+ (_,_,J1) = self.parent().peirce_decomposition(self)
+ return (J1.dimension() == 1)
+
+
def is_nilpotent(self):
"""
Return whether or not some power of this element is zero.
sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
....: RealSymmetricEJA,
+ ....: TrivialEJA,
....: random_eja)
+ EXAMPLES:
+
+ Keeping in mind that the polynomial ``1`` evaluates the identity
+ element (also the zero element) of the trivial algebra, it is clear
+ that the polynomial ``1`` is the minimal polynomial of the only
+ element in a trivial algebra::
+
+ sage: J = TrivialEJA()
+ sage: J.one().minimal_polynomial()
+ 1
+ sage: J.zero().minimal_polynomial()
+ 1
+
TESTS:
The minimal polynomial of the identity and zero elements are
always the same::
sage: set_random_seed()
- sage: J = random_eja()
+ sage: J = random_eja(nontrivial=True)
sage: J.one().minimal_polynomial()
t - 1
sage: J.zero().minimal_polynomial()
sage: from mjo.eja.eja_algebra import random_eja
- TESTS::
+ TESTS:
+
+ Ensure that we can find an idempotent in a non-trivial algebra
+ where there are non-nilpotent elements::
sage: set_random_seed()
- sage: J = random_eja()
+ sage: J = random_eja(nontrivial=True)
sage: x = J.random_element()
sage: while x.is_nilpotent():
....: x = J.random_element()
True
"""
+ if self.parent().is_trivial():
+ return self
+
if self.is_nilpotent():
raise ValueError("this only works with non-nilpotent elements!")
"""
Return my trace, the sum of my eigenvalues.
+ In a trivial algebra, however you want to look at it, the trace is
+ an empty sum for which we declare the result to be zero.
+
SETUP::
sage: from mjo.eja.eja_algebra import (JordanSpinEJA,
....: RealCartesianProductEJA,
+ ....: TrivialEJA,
....: random_eja)
EXAMPLES::
+ sage: J = TrivialEJA()
+ sage: J.zero().trace()
+ 0
+
+ ::
sage: J = JordanSpinEJA(3)
sage: x = sum(J.gens())
sage: x.trace()
"""
P = self.parent()
r = P.rank()
+
+ if r == 0:
+ # Special case for the trivial algebra where
+ # the trace is an empty sum.
+ return P.base_ring().zero()
+
p = P._charpoly_coeff(r-1)
# The _charpoly_coeff function already adds the factor of
# -1 to ensure that _charpoly_coeff(r-1) is really what