]> 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):
     """
 
 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
 
       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.
 
       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
     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,
     def __init__(self, parent, f):
         FiniteDimensionalAlgebraMorphism.__init__(self,
                                                   parent,
@@ -41,6 +86,82 @@ class FiniteDimensionalEuclideanJordanAlgebraMorphism(FiniteDimensionalAlgebraMo
                                                   check=False)
 
 
                                                   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,
     def _repr_(self):
         """
         We override only the representation that is shown to the user,