+ def is_self_adjoint(self):
+ r"""
+ Return whether or not this operator is self-adjoint.
+
+ At least in Sage, the fact that the base field is real means
+ that the algebra elements have to be real as well (this is why
+ we embed the complex numbers and quaternions). As a result, the
+ matrix of this operator will contain only real entries, and it
+ suffices to check only symmetry, not conjugate symmetry.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (JordanSpinEJA)
+
+ EXAMPLES::
+
+ sage: J = JordanSpinEJA(4)
+ sage: J.one().operator().is_self_adjoint()
+ True
+
+ """
+ return self.matrix().is_symmetric()
+
+
+ def is_zero(self):
+ r"""
+ Return whether or not this map is the zero operator.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_operator import FiniteDimensionalEJAOperator
+ sage: from mjo.eja.eja_algebra import (random_eja,
+ ....: JordanSpinEJA,
+ ....: RealSymmetricEJA)
+
+ EXAMPLES::
+
+ sage: J1 = JordanSpinEJA(2)
+ sage: J2 = RealSymmetricEJA(2)
+ sage: R = J1.base_ring()
+ sage: M = matrix(R, [ [0, 0],
+ ....: [0, 0],
+ ....: [0, 0] ])
+ sage: L = FiniteDimensionalEJAOperator(J1,J2,M)
+ sage: L.is_zero()
+ True
+ sage: M = matrix(R, [ [0, 0],
+ ....: [0, 1],
+ ....: [0, 0] ])
+ sage: L = FiniteDimensionalEJAOperator(J1,J2,M)
+ sage: L.is_zero()
+ False
+
+ TESTS:
+
+ The left-multiplication-by-zero operation on a given algebra
+ is its zero map::
+
+ sage: set_random_seed()
+ sage: J = random_eja()
+ sage: J.zero().operator().is_zero()
+ True
+
+ """
+ return self.matrix().is_zero()
+
+
+ def inverse(self):
+ """
+ Return the inverse of this operator, if it exists.
+
+ The reason this method is not simply an alias for the built-in
+ :meth:`__invert__` is that the built-in inversion is a bit magic
+ since it's intended to be a unary operator. If we alias ``inverse``
+ to ``__invert__``, then we wind up having to call e.g. ``A.inverse``
+ without parentheses.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import RealSymmetricEJA, random_eja
+
+ EXAMPLES::
+
+ sage: J = RealSymmetricEJA(2)
+ sage: x = sum(J.gens())
+ sage: x.operator().inverse().matrix()
+ [3/2 -1 1/2]
+ [ -1 2 -1]
+ [1/2 -1 3/2]
+ sage: x.operator().matrix().inverse()
+ [3/2 -1 1/2]
+ [ -1 2 -1]
+ [1/2 -1 3/2]
+
+ TESTS:
+
+ The identity operator is its own inverse::
+
+ sage: set_random_seed()
+ sage: J = random_eja()
+ sage: idJ = J.one().operator()
+ sage: idJ.inverse() == idJ
+ True
+
+ The inverse of the inverse is the operator we started with::
+
+ sage: set_random_seed()
+ sage: x = random_eja().random_element()
+ sage: L = x.operator()
+ sage: not L.is_invertible() or (L.inverse().inverse() == L)
+ True
+
+ """
+ return ~self
+
+
+ def is_invertible(self):
+ """
+ Return whether or not this operator is invertible.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
+ ....: TrivialEJA,
+ ....: random_eja)
+
+ EXAMPLES::
+
+ sage: J = RealSymmetricEJA(2)
+ sage: x = sum(J.gens())
+ sage: x.operator().matrix()
+ [ 1 1/2 0]
+ [1/2 1 1/2]
+ [ 0 1/2 1]
+ sage: x.operator().matrix().is_invertible()
+ True
+ sage: x.operator().is_invertible()
+ True
+
+ The zero operator is invertible in a trivial algebra::
+
+ sage: J = TrivialEJA()
+ sage: J.zero().operator().is_invertible()
+ True
+
+ TESTS:
+
+ The identity operator is always invertible::
+
+ sage: set_random_seed()
+ sage: J = random_eja()
+ sage: J.one().operator().is_invertible()
+ True
+
+ The zero operator is never invertible in a nontrivial algebra::
+
+ sage: set_random_seed()
+ sage: J = random_eja()
+ sage: not J.is_trivial() and J.zero().operator().is_invertible()
+ False
+
+ """
+ return self.matrix().is_invertible()
+
+