]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/euclidean_jordan_algebra.py
eja: add algebra constructors to the global namespace.
[sage.d.git] / mjo / eja / euclidean_jordan_algebra.py
index 750b6c1c37460a704f83aeb62b66aaf4ce1ca952..70a77701b342e36eec827d3ec151b87bf67fe902 100644 (file)
@@ -28,8 +28,11 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
 
         # We need to supply something here to avoid getting the
         # default Homset of the parent FiniteDimensionalAlgebra class,
-        # which messes up e.g. equality testing.
-        parent = Hom(domain_eja, codomain_eja, VectorSpaces(F))
+        # which messes up e.g. equality testing. We use FreeModules(F)
+        # instead of VectorSpaces(F) because our characteristic polynomial
+        # algorithm will need to F to be a polynomial ring at some point.
+        # When F is a field, FreeModules(F) returns VectorSpaces(F) anyway.
+        parent = Hom(domain_eja, codomain_eja, FreeModules(F))
 
         # The Map initializer will set our parent to a homset, which
         # is explicitly NOT what we want, because these ain't algebra
@@ -143,6 +146,7 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
             return False
         return True
 
+
     def __invert__(self):
         """
         Invert this EJA operator.
@@ -348,6 +352,22 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map):
         return self._matrix
 
 
+    def minimal_polynomial(self):
+        """
+        Return the minimal polynomial of this linear operator,
+        in the variable ``t``.
+
+        EXAMPLES::
+
+            sage: J = RealSymmetricEJA(3)
+            sage: J.one().operator().minimal_polynomial()
+            t - 1
+
+        """
+        # The matrix method returns a polynomial in 'x' but want one in 't'.
+        return self.matrix().minimal_polynomial().change_variable_name('t')
+
+
 class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
     @staticmethod
     def __classcall_private__(cls,
@@ -1275,7 +1295,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
             Our parent class defines ``left_matrix`` and ``matrix``
             methods whose names are misleading. We don't want them.
             """
-            raise NotImplementedError("use operator_matrix() instead")
+            raise NotImplementedError("use operator().matrix() instead")
 
         matrix = left_matrix
 
@@ -1346,11 +1366,8 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
             # and subalgebra_generated_by() must be the same, and in
             # the same order!
             elt = assoc_subalg(V.coordinates(self.vector()))
+            return elt.operator().minimal_polynomial()
 
-            # We get back a symbolic polynomial in 'x' but want a real
-            # polynomial in 't'.
-            p_of_x = elt.operator_matrix().minimal_polynomial()
-            return p_of_x.change_variable_name('t')
 
 
         def natural_representation(self):
@@ -1419,34 +1436,11 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
 
             """
             P = self.parent()
+            fda_elt = FiniteDimensionalAlgebraElement(P, self)
             return FiniteDimensionalEuclideanJordanAlgebraOperator(
-                     P,P,
-                     self.operator_matrix() )
-
-
-
-        def operator_matrix(self):
-            """
-            Return the matrix that represents left- (or right-)
-            multiplication by this element in the parent algebra.
-
-            We implement this ourselves to work around the fact that
-            our parent class represents everything with row vectors.
-
-            EXAMPLES:
-
-            Ensure that our operator's ``matrix`` method agrees with
-            this implementation::
-
-                sage: set_random_seed()
-                sage: J = random_eja()
-                sage: x = J.random_element()
-                sage: x.operator().matrix() == x.operator_matrix()
-                True
-
-            """
-            fda_elt = FiniteDimensionalAlgebraElement(self.parent(), self)
-            return fda_elt.matrix().transpose()
+                     P,
+                     P,
+                     fda_elt.matrix().transpose() )
 
 
         def quadratic_representation(self, other=None):
@@ -1591,13 +1585,13 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
                 sage: x.subalgebra_generated_by().is_associative()
                 True
 
-            Squaring in the subalgebra should be the same thing as
-            squaring in the superalgebra::
+            Squaring in the subalgebra should work the same as in
+            the superalgebra::
 
                 sage: set_random_seed()
                 sage: x = random_eja().random_element()
                 sage: u = x.subalgebra_generated_by().random_element()
-                sage: u.operator_matrix()*u.vector() == (u**2).vector()
+                sage: u.operator()(u) == u^2
                 True
 
             """
@@ -1668,7 +1662,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
             s = 0
             minimal_dim = V.dimension()
             for i in xrange(1, V.dimension()):
-                this_dim = (u**i).operator_matrix().image().dimension()
+                this_dim = (u**i).operator().matrix().image().dimension()
                 if this_dim < minimal_dim:
                     minimal_dim = this_dim
                     s = i
@@ -1685,7 +1679,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
             # Beware, solve_right() means that we're using COLUMN vectors.
             # Our FiniteDimensionalAlgebraElement superclass uses rows.
             u_next = u**(s+1)
-            A = u_next.operator_matrix()
+            A = u_next.operator().matrix()
             c_coordinates = A.solve_right(u_next.vector())
 
             # Now c_coordinates is the idempotent we want, but it's in