]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/eja_operator.py
eja: rename RealCartesianProductEJA -> HadamardEJA.
[sage.d.git] / mjo / eja / eja_operator.py
index 781d987518af32043ef11ccbb1533f9ad4f3b6ef..ee33dbf53b36fd9851d31169d5699041f460328e 100644 (file)
@@ -117,13 +117,13 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
             sage: from mjo.eja.eja_operator import FiniteDimensionalEuclideanJordanAlgebraOperator
             sage: from mjo.eja.eja_algebra import (
             ....:   JordanSpinEJA,
-            ....:   RealCartesianProductEJA,
+            ....:   HadamardEJA,
             ....:   RealSymmetricEJA)
 
         EXAMPLES::
 
             sage: J1 = JordanSpinEJA(3)
-            sage: J2 = RealCartesianProductEJA(2)
+            sage: J2 = HadamardEJA(2)
             sage: J3 = RealSymmetricEJA(1)
             sage: mat1 = matrix(QQ, [[1,2,3],
             ....:                    [4,5,6]])
@@ -383,13 +383,64 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
         return (self + (-other))
 
 
+    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, random_eja
+            sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
+            ....:                                  TrivialEJA,
+            ....:                                  random_eja)
 
         EXAMPLES::
 
@@ -404,6 +455,12 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
             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::
@@ -413,11 +470,11 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
             sage: J.one().operator().is_invertible()
             True
 
-        The zero operator is never invertible::
+        The zero operator is never invertible in a nontrivial algebra::
 
             sage: set_random_seed()
             sage: J = random_eja()
-            sage: J.zero().operator().is_invertible()
+            sage: not J.is_trivial() and J.zero().operator().is_invertible()
             False
 
         """
@@ -474,6 +531,11 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
         Return the spectral decomposition of this operator as a list of
         (eigenvalue, orthogonal projector) pairs.
 
+        This is the unique spectral decomposition, up to the order of
+        the projection operators, with distinct eigenvalues. So, the
+        projections are generally onto subspaces of dimension greater
+        than one.
+
         SETUP::
 
             sage: from mjo.eja.eja_algebra import RealSymmetricEJA
@@ -497,15 +559,9 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
             True
             sage: P1^2 == P1
             True
-            sage: c0 = P0(A.one())
-            sage: c1 = P1(A.one())
-            sage: c0.inner_product(c1) == 0
-            True
-            sage: c0 + c1 == A.one()
-            True
-            sage: c0.is_idempotent()
+            sage: P0*P1 == A.zero().operator()
             True
-            sage: c1.is_idempotent()
+            sage: P1*P0 == A.zero().operator()
             True
 
         """
@@ -526,4 +582,4 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
                    self.codomain(),
                    mat)
             projectors.append(Pi)
-        return zip(eigenvalues, projectors)
+        return list(zip(eigenvalues, projectors))