]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/euclidean_jordan_algebra.py
eja: fix the basis order for Sn.
[sage.d.git] / mjo / eja / euclidean_jordan_algebra.py
index 2404af03d7f249fec64caab63e9954aca91af7ab..802171fb0c4cc029c43d4fb4b17004d76bb938ed 100644 (file)
@@ -384,6 +384,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
             Squaring in the subalgebra should be the same thing as
             squaring in the superalgebra::
 
+                sage: set_random_seed()
                 sage: J = eja_ln(5)
                 sage: x = J.random_element()
                 sage: u = x.subalgebra_generated_by().random_element()
@@ -596,3 +597,104 @@ 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())
+
+    def vec2mat(v):
+        return matrix(field, dimension, v.list())
+
+    W = V.span( mat2vec(s) for s in S )
+
+    # Taking the span above reorders our basis (thanks, jerk!) so we
+    # need to put our "matrix basis" in the same order as the
+    # (reordered) vector basis.
+    S = [ vec2mat(b) for b in W.basis() ]
+
+    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)
+
+
+def random_eja():
+    """
+    Return a "random" finite-dimensional Euclidean Jordan Algebra.
+
+    ALGORITHM:
+
+    For now, we choose a random natural number ``n`` (greater than zero)
+    and then give you back one of the following:
+
+      * The cartesian product of the rational numbers ``n`` times; this is
+        ``QQ^n`` with the Hadamard product.
+
+      * The Jordan spin algebra on ``QQ^n``.
+
+      * The ``n``-by-``n`` rational symmetric matrices with the symmetric
+        product.
+
+    Later this might be extended to return Cartesian products of the
+    EJAs above.
+
+    TESTS::
+
+        sage: random_eja()
+        Euclidean Jordan algebra of degree...
+
+    """
+    n = ZZ.random_element(1,10).abs()
+    constructor = choice([eja_rn, eja_ln, eja_sn])
+    return constructor(dimension=n, field=QQ)