]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/euclidean_jordan_algebra.py
eja: use single-underscore method names for morphisms.
[sage.d.git] / mjo / eja / euclidean_jordan_algebra.py
index 78fa6b7c0f96725af4da2e96f09ee2d7eb5449cf..9414d2cf27fd2728ef205650b128ab37d1b83949 100644 (file)
@@ -5,7 +5,7 @@ are used in optimization, and have some additional nice methods beyond
 what can be supported in a general Jordan Algebra.
 """
 
-from sage.categories.magmatic_algebras import MagmaticAlgebras
+from sage.categories.finite_dimensional_algebras_with_basis import FiniteDimensionalAlgebrasWithBasis
 from sage.structure.element import is_Matrix
 from sage.structure.category_object import normalize_names
 
@@ -30,17 +30,16 @@ class FiniteDimensionalEuclideanJordanAlgebraMorphism(FiniteDimensionalAlgebraMo
       2. Inputs and outputs the underlying matrix with respect to COLUMN
          vectors, unlike the parent class.
 
-      3. Allows us to add morphisms in the obvious way.
-
-      4. Allows us to invert morphisms.
+      3. Allows us to add, subtract, negate, 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, and you can't add/invert them.
+    our EJA, and you can't add/multiply/etc. them.
     """
 
-    def __add__(self, other):
+    def _add_(self, other):
         """
         Add two EJA morphisms in the obvious way.
 
@@ -87,7 +86,7 @@ class FiniteDimensionalEuclideanJordanAlgebraMorphism(FiniteDimensionalAlgebraMo
                                                   check=False)
 
 
-    def __invert__(self):
+    def _invert_(self):
         """
         EXAMPLES::
 
@@ -125,6 +124,74 @@ class FiniteDimensionalEuclideanJordanAlgebraMorphism(FiniteDimensionalAlgebraMo
         return FiniteDimensionalEuclideanJordanAlgebraMorphism(self.parent(),
                                                                 A.inverse())
 
+    def _lmul_(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 _neg_(self):
+        """
+        Negate this morphism.
+
+        EXAMPLES::
+
+            sage: J = RealSymmetricEJA(2)
+            sage: x = J.one()
+            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
+            [-1  0  0]
+            [ 0 -1  0]
+            [ 0  0 -1]
+
+        TESTS::
+
+            sage: set_random_seed()
+            sage: J = random_eja()
+            sage: x = J.random_element()
+            sage: -x.operator() in J.Hom(J)
+            True
+
+        """
+        return FiniteDimensionalEuclideanJordanAlgebraMorphism(
+                  self.parent(),
+                  -self.matrix() )
+
+
     def _repr_(self):
         """
         We override only the representation that is shown to the user,
@@ -159,6 +226,36 @@ class FiniteDimensionalEuclideanJordanAlgebraMorphism(FiniteDimensionalAlgebraMo
         return "Morphism from {} to {} given by matrix\n{}".format(
             self.domain(), self.codomain(), self.matrix())
 
+
+    def __sub__(self, other):
+        """
+        Subtract one morphism from another using addition and negation.
+
+        EXAMPLES::
+
+            sage: J = RealSymmetricEJA(2)
+            sage: L1 = J.one().operator()
+            sage: L1 - L1
+            Morphism from Euclidean Jordan algebra of degree 3 over Rational
+            Field to Euclidean Jordan algebra of degree 3 over Rational
+            Field given by matrix
+            [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
+
+        """
+        return self + (-other)
+
+
     def matrix(self):
         """
         Return the matrix of this morphism with respect to a left-action
@@ -185,7 +282,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
                 raise ValueError("input is not a multiplication table")
         mult_table = tuple(mult_table)
 
-        cat = MagmaticAlgebras(field).FiniteDimensional().WithBasis()
+        cat = FiniteDimensionalAlgebrasWithBasis(field)
         cat.or_subcategory(category)
         if assume_associative:
             cat = cat.Associative()
@@ -1271,7 +1368,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
                 sage: D = (x0^2 - x_bar.inner_product(x_bar))*D
                 sage: D = D + 2*x_bar.tensor_product(x_bar)
                 sage: Q = block_matrix(2,2,[A,B,C,D])
-                sage: Q == x.quadratic_representation()
+                sage: Q == x.quadratic_representation().operator_matrix()
                 True
 
             Test all of the properties from Theorem 11.2 in Alizadeh::
@@ -1280,8 +1377,8 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
                 sage: J = random_eja()
                 sage: x = J.random_element()
                 sage: y = J.random_element()
-                sage: Lx = x.operator_matrix()
-                sage: Lxx = (x*x).operator_matrix()
+                sage: Lx = x.operator()
+                sage: Lxx = (x*x).operator()
                 sage: Qx = x.quadratic_representation()
                 sage: Qy = y.quadratic_representation()
                 sage: Qxy = x.quadratic_representation(y)
@@ -1302,17 +1399,16 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
 
             Property 3:
 
-                sage: not x.is_invertible() or (
-                ....:     Qx*x.inverse().vector() == x.vector() )
+                sage: not x.is_invertible() or ( Qx(x.inverse()) == x )
                 True
 
                 sage: not x.is_invertible() or (
-                ....:   Qx.inverse()
+                ....:   ~Qx
                 ....:   ==
                 ....:   x.inverse().quadratic_representation() )
                 True
 
-                sage: Qxy*(J.one().vector()) == (x*y).vector()
+                sage: Qxy(J.one()) == x*y
                 True
 
             Property 4:
@@ -1325,15 +1421,15 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
                 sage: not x.is_invertible() or (
                 ....:   x.quadratic_representation(x.inverse())*Qx
                 ....:   ==
-                ....:   2*x.operator_matrix()*Qex - Qx )
+                ....:   2*x.operator()*Qex - Qx )
                 True
 
-                sage: 2*x.operator_matrix()*Qex - Qx == Lxx
+                sage: 2*x.operator()*Qex - Qx == Lxx
                 True
 
             Property 5:
 
-                sage: J(Qy*x.vector()).quadratic_representation() == Qy*Qx*Qy
+                sage: Qy(x).quadratic_representation() == Qy*Qx*Qy
                 True
 
             Property 6:
@@ -1344,13 +1440,13 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
             Property 7:
 
                 sage: not x.is_invertible() or (
-                ....:   Qx*x.inverse().operator_matrix() == Lx )
+                ....:   Qx*x.inverse().operator() == Lx )
                 True
 
             Property 8:
 
                 sage: not x.operator_commutes_with(y) or (
-                ....:   J(Qx*y.vector())^n == J(Qxn*(y^n).vector()) )
+                ....:   Qx(y)^n == Qxn(y^n) )
                 True
 
             """
@@ -1359,9 +1455,9 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
             elif not other in self.parent():
                 raise TypeError("'other' must live in the same algebra")
 
-            L = self.operator_matrix()
-            M = other.operator_matrix()
-            return ( L*M + M*L - (self*other).operator_matrix() )
+            L = self.operator()
+            M = other.operator()
+            return ( L*M + M*L - (self*other).operator() )
 
 
         def span_of_powers(self):