sage: x.inverse() == J.from_vector(x_inverse)
True
+ Trying to invert a non-invertible element throws an error:
+
+ sage: JordanSpinEJA(3).zero().inverse()
+ Traceback (most recent call last):
+ ...
+ ValueError: element is not invertible
+
TESTS:
The identity element is its own inverse::
sage: (not x.is_invertible()) or (x.inverse().inverse() == x)
True
- The zero element is never invertible::
-
- sage: set_random_seed()
- sage: J = random_eja().zero().inverse()
- Traceback (most recent call last):
- ...
- ValueError: element is not invertible
-
Proposition II.2.3 in Faraut and Korányi says that the inverse
of an element is the inverse of its left-multiplication operator
applied to the algebra's identity, when that inverse exists::
TESTS:
- The identity element is never nilpotent::
+ The identity element is never nilpotent, except in a trivial EJA::
sage: set_random_seed()
- sage: random_eja().one().is_nilpotent()
+ sage: J = random_eja()
+ sage: J.one().is_nilpotent() and not J.is_trivial()
False
The additive identity is always nilpotent::
TESTS:
The zero element should never be regular, unless the parent
- algebra has dimension one::
+ algebra has dimension less than or equal to one::
sage: set_random_seed()
sage: J = random_eja()
- sage: J.dimension() == 1 or not J.zero().is_regular()
+ sage: J.dimension() <= 1 or not J.zero().is_regular()
True
The unit element isn't regular unless the algebra happens to
sage: set_random_seed()
sage: J = random_eja()
- sage: J.dimension() == 1 or not J.one().is_regular()
+ sage: J.dimension() <= 1 or not J.one().is_regular()
True
"""
TESTS:
- The zero and unit elements are both of degree one::
+ The zero and unit elements are both of degree one in nontrivial
+ algebras::
sage: set_random_seed()
sage: J = random_eja()
- sage: J.zero().degree()
- 1
- sage: J.one().degree()
- 1
+ sage: d = J.zero().degree()
+ sage: (J.is_trivial() and d == 0) or d == 1
+ True
+ sage: d = J.one().degree()
+ sage: (J.is_trivial() and d == 0) or d == 1
+ True
Our implementation agrees with the definition::
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: A(x^2) == A(x)*A(x)
True
- By definition, the subalgebra generated by the zero element is the
- one-dimensional algebra generated by the identity element::
+ By definition, the subalgebra generated by the zero element is
+ the one-dimensional algebra generated by the identity
+ element... unless the original algebra was trivial, in which
+ case the subalgebra is trivial too::
sage: set_random_seed()
sage: A = random_eja().zero().subalgebra_generated_by()
- sage: A.dimension()
- 1
+ sage: (A.is_trivial() and A.dimension() == 0) or A.dimension() == 1
+ True
"""
return FiniteDimensionalEuclideanJordanElementSubalgebra(self, orthonormalize_basis)
"""
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