]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/euclidean_jordan_algebra.py
eja: add composition (multiplication) for morphisms.
[sage.d.git] / mjo / eja / euclidean_jordan_algebra.py
index 72e167e6811912c3b19a71b27432d052800d3051..d459ebe97540abe88f1aef603e29ec994bd1cb74 100644 (file)
@@ -16,8 +16,10 @@ from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra_morphi
 
 class FiniteDimensionalEuclideanJordanAlgebraMorphism(FiniteDimensionalAlgebraMorphism):
     """
-    A very thin wrapper around FiniteDimensionalAlgebraMorphism that
-    does only two things:
+    A linear map between two finite-dimensional EJAs.
+
+    This is a very thin wrapper around FiniteDimensionalAlgebraMorphism
+    that does only a few things:
 
       1. Avoids the ``unitary`` and ``check`` arguments to the constructor
          that will always be ``False``. This is necessary because these
@@ -28,11 +30,54 @@ class FiniteDimensionalEuclideanJordanAlgebraMorphism(FiniteDimensionalAlgebraMo
       2. Inputs and outputs the underlying matrix with respect to COLUMN
          vectors, unlike the parent class.
 
+      3. Allows us to add, multiply (compose), and invert morphisms in
+         the obvious way.
+
     If this seems a bit heavyweight, it is. I would have been happy to
     use a the ring morphism that underlies the finite-dimensional
     algebra morphism, but they don't seem to be callable on elements of
-    our EJA.
+    our EJA, and you can't add/multiply/invert them.
     """
+
+    def __add__(self, other):
+        """
+        Add two EJA morphisms in the obvious way.
+
+        EXAMPLES::
+
+            sage: J = RealSymmetricEJA(3)
+            sage: x = J.zero()
+            sage: y = J.one()
+            sage: x.operator() + y.operator()
+            Morphism from Euclidean Jordan algebra of degree 6 over Rational
+            Field to Euclidean Jordan algebra of degree 6 over Rational Field
+            given by matrix
+            [1 0 0 0 0 0]
+            [0 1 0 0 0 0]
+            [0 0 1 0 0 0]
+            [0 0 0 1 0 0]
+            [0 0 0 0 1 0]
+            [0 0 0 0 0 1]
+
+        TESTS::
+
+            sage: set_random_seed()
+            sage: J = random_eja()
+            sage: x = J.random_element()
+            sage: y = J.random_element()
+            sage: (x.operator() + y.operator()) in J.Hom(J)
+            True
+
+        """
+        P = self.parent()
+        if not other in P:
+            raise ValueError("summands must live in the same space")
+
+        return FiniteDimensionalEuclideanJordanAlgebraMorphism(
+                  P,
+                  self.matrix() + other.matrix() )
+
+
     def __init__(self, parent, f):
         FiniteDimensionalAlgebraMorphism.__init__(self,
                                                   parent,
@@ -41,6 +86,82 @@ class FiniteDimensionalEuclideanJordanAlgebraMorphism(FiniteDimensionalAlgebraMo
                                                   check=False)
 
 
+    def __invert__(self):
+        """
+        EXAMPLES::
+
+            sage: J = RealSymmetricEJA(2)
+            sage: x = J.linear_combination(zip(range(len(J.gens())), J.gens()))
+            sage: x.is_invertible()
+            True
+            sage: ~x.operator()
+            Morphism from Euclidean Jordan algebra of degree 3 over Rational
+            Field to Euclidean Jordan algebra of degree 3 over Rational Field
+            given by matrix
+            [-3/2    2 -1/2]
+            [   1    0    0]
+            [-1/2    0  1/2]
+            sage: x.operator_matrix().inverse()
+            [-3/2    2 -1/2]
+            [   1    0    0]
+            [-1/2    0  1/2]
+
+        TESTS::
+
+            sage: set_random_seed()
+            sage: J = random_eja()
+            sage: x = J.random_element()
+            sage: not x.is_invertible() or (
+            ....:   (~x.operator()).matrix() == x.operator_matrix().inverse() )
+            True
+
+        """
+        A = self.matrix()
+        if not A.is_invertible():
+            raise ValueError("morphism is not invertible")
+
+        P = self.parent()
+        return FiniteDimensionalEuclideanJordanAlgebraMorphism(self.parent(),
+                                                                A.inverse())
+
+    def __mul__(self, other):
+        """
+        Compose two EJA morphisms using multiplicative notation.
+
+        EXAMPLES::
+
+            sage: J = RealSymmetricEJA(3)
+            sage: x = J.zero()
+            sage: y = J.one()
+            sage: x.operator() * y.operator()
+            Morphism from Euclidean Jordan algebra of degree 6 over Rational
+            Field to Euclidean Jordan algebra of degree 6 over Rational Field
+            given by matrix
+            [0 0 0 0 0 0]
+            [0 0 0 0 0 0]
+            [0 0 0 0 0 0]
+            [0 0 0 0 0 0]
+            [0 0 0 0 0 0]
+            [0 0 0 0 0 0]
+
+        TESTS::
+
+            sage: set_random_seed()
+            sage: J = random_eja()
+            sage: x = J.random_element()
+            sage: y = J.random_element()
+            sage: (x.operator() * y.operator()) in J.Hom(J)
+            True
+
+        """
+        if not other.codomain() is self.domain():
+            raise ValueError("(co)domains must agree for composition")
+
+        return FiniteDimensionalEuclideanJordanAlgebraMorphism(
+                  self.parent(),
+                  self.matrix()*other.matrix() )
+
+
     def _repr_(self):
         """
         We override only the representation that is shown to the user,