]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/euclidean_jordan_algebra.py
eja: add a comment about row/column vectors to eja_sn().
[sage.d.git] / mjo / eja / euclidean_jordan_algebra.py
index 1281a029a8f5c4557d9d35ee50342caecdc51054..c47f4003690905278904327e63ddaf7dcf9e0b44 100644 (file)
@@ -127,7 +127,44 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
 
 
         def characteristic_polynomial(self):
-            return self.matrix().characteristic_polynomial()
+            """
+            Return my characteristic polynomial (if I'm a regular
+            element).
+
+            Eventually this should be implemented in terms of the parent
+            algebra's characteristic polynomial that works for ALL
+            elements.
+            """
+            if self.is_regular():
+                return self.minimal_polynomial()
+            else:
+                raise NotImplementedError('irregular element')
+
+
+        def det(self):
+            """
+            Return my determinant, the product of my eigenvalues.
+
+            EXAMPLES::
+
+                sage: J = eja_ln(2)
+                sage: e0,e1 = J.gens()
+                sage: x = e0 + e1
+                sage: x.det()
+                0
+                sage: J = eja_ln(3)
+                sage: e0,e1,e2 = J.gens()
+                sage: x = e0 + e1 + e2
+                sage: x.det()
+                -1
+
+            """
+            cs = self.characteristic_polynomial().coefficients(sparse=False)
+            r = len(cs) - 1
+            if r >= 0:
+                return cs[0] * (-1)**r
+            else:
+                raise ValueError('charpoly had no coefficients')
 
 
         def is_nilpotent(self):
@@ -451,6 +488,25 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
             return self.parent().linear_combination(zip(c_coordinates, basis))
 
 
+        def trace(self):
+            """
+            Return my trace, the sum of my eigenvalues.
+
+            EXAMPLES::
+
+                sage: J = eja_ln(3)
+                sage: e0,e1,e2 = J.gens()
+                sage: x = e0 + e1 + e2
+                sage: x.trace()
+                2
+
+            """
+            cs = self.characteristic_polynomial().coefficients(sparse=False)
+            if len(cs) >= 2:
+                return -1*cs[-2]
+            else:
+                raise ValueError('charpoly had fewer than 2 coefficients')
+
 
 def eja_rn(dimension, field=QQ):
     """
@@ -540,3 +596,65 @@ def eja_ln(dimension, field=QQ):
     # ambient dimension).
     rank = min(dimension,2)
     return FiniteDimensionalEuclideanJordanAlgebra(field,Qs,rank=rank)
+
+
+def eja_sn(dimension, field=QQ):
+    """
+    Return the simple Jordan algebra of ``dimension``-by-``dimension``
+    symmetric matrices over ``field``.
+
+    EXAMPLES::
+
+        sage: J = eja_sn(2)
+        sage: e0, e1, e2 = J.gens()
+        sage: e0*e0
+        e0
+        sage: e1*e1
+        e0 + e2
+        sage: e2*e2
+        e2
+
+    """
+    Qs = []
+
+    # In S^2, for example, we nominally have four coordinates even
+    # though the space is of dimension three only. The vector space V
+    # is supposed to hold the entire long vector, and the subspace W
+    # of V will be spanned by the vectors that arise from symmetric
+    # matrices. Thus for S^2, dim(V) == 4 and dim(W) == 3.
+    V = VectorSpace(field, dimension**2)
+
+    # The basis of symmetric matrices, as matrices, in their R^(n-by-n)
+    # coordinates.
+    S = []
+
+    for i in xrange(dimension):
+        for j in xrange(i+1):
+            Eij = matrix(field, dimension, lambda k,l: k==i and l==j)
+            if i == j:
+                Sij = Eij
+            else:
+                Sij = Eij + Eij.transpose()
+            S.append(Sij)
+
+    def mat2vec(m):
+        return vector(field, m.list())
+
+    W = V.span( mat2vec(s) for s in S )
+
+    for s in S:
+        # Brute force the multiplication-by-s matrix by looping
+        # through all elements of the basis and doing the computation
+        # to find out what the corresponding row should be. BEWARE:
+        # these multiplication tables won't be symmetric! It therefore
+        # becomes REALLY IMPORTANT that the underlying algebra
+        # constructor uses ROW vectors and not COLUMN vectors. That's
+        # why we're computing rows here and not columns.
+        Q_rows = []
+        for t in S:
+            this_row = mat2vec((s*t + t*s)/2)
+            Q_rows.append(W.coordinates(this_row))
+        Q = matrix(field,Q_rows)
+        Qs.append(Q)
+
+    return FiniteDimensionalEuclideanJordanAlgebra(field,Qs,rank=dimension)