]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/eja/euclidean_jordan_algebra.py
eja: add ComplexHermitianSimpleEJA to random_eja().
[sage.d.git] / mjo / eja / euclidean_jordan_algebra.py
index fdaccba58a8b99a2f5222054358969ce3e731882..6bc53a172f5bd72ccc3cec7315bb908425160f57 100644 (file)
@@ -652,9 +652,9 @@ def 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)
+    n = ZZ.random_element(1,5).abs()
+    constructor = choice([eja_rn, eja_ln, eja_sn, ComplexHermitianSimpleEJA])
+    return constructor(n, field=QQ)
 
 
 
@@ -709,7 +709,7 @@ def _multiplication_table_from_matrix_basis(basis):
     S = [ vec2mat(b) for b in W.basis() ]
 
     Qs = []
-    for s in 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:
@@ -718,10 +718,10 @@ def _multiplication_table_from_matrix_basis(basis):
         # constructor uses ROW vectors and not COLUMN vectors. That's
         # why we're computing rows here and not columns.
         Q_rows = []
-        for t in basis:
+        for t in S:
             this_row = mat2vec((s*t + t*s)/2)
             Q_rows.append(W.coordinates(this_row))
-        Q = matrix(field,Q_rows)
+        Q = matrix(field, W.dimension(), Q_rows)
         Qs.append(Q)
 
     return Qs
@@ -758,7 +758,48 @@ def _embed_complex_matrix(M):
         a = z.real()
         b = z.imag()
         blocks.append(matrix(field, 2, [[a,-b],[b,a]]))
-    return block_matrix(field, n, blocks)
+
+    # We can drop the imaginaries here.
+    return block_matrix(field.base_ring(), n, blocks)
+
+
+def _unembed_complex_matrix(M):
+    """
+    The inverse of _embed_complex_matrix().
+
+    EXAMPLES::
+
+        sage: A = matrix(QQ,[ [ 1,  2,   3,  4],
+        ....:                 [-2,  1,  -4,  3],
+        ....:                 [ 9,  10, 11, 12],
+        ....:                 [-10, 9, -12, 11] ])
+        sage: _unembed_complex_matrix(A)
+        [  -2*i + 1   -4*i + 3]
+        [ -10*i + 9 -12*i + 11]
+    """
+    n = ZZ(M.nrows())
+    if M.ncols() != n:
+        raise ArgumentError("the matrix 'M' must be square")
+    if not n.mod(2).is_zero():
+        raise ArgumentError("the matrix 'M' must be a complex embedding")
+
+    F = QuadraticField(-1, 'i')
+    i = F.gen()
+
+    # Go top-left to bottom-right (reading order), converting every
+    # 2-by-2 block we see to a single complex element.
+    elements = []
+    for k in xrange(n/2):
+        for j in xrange(n/2):
+            submat = M[2*k:2*k+2,2*j:2*j+2]
+            if submat[0,0] != submat[1,1]:
+                raise ArgumentError('bad real submatrix')
+            if submat[0,1] != -submat[1,0]:
+                raise ArgumentError('bad imag submatrix')
+            z = submat[0,0] + submat[1,0]*i
+            elements.append(z)
+
+    return matrix(F, n/2, elements)
 
 
 def RealSymmetricSimpleEJA(n):
@@ -769,14 +810,23 @@ def RealSymmetricSimpleEJA(n):
     """
     pass
 
-def ComplexHermitianSimpleEJA(n):
+def ComplexHermitianSimpleEJA(n, field=QQ):
     """
     The rank-n simple EJA consisting of complex Hermitian n-by-n
     matrices over the real numbers, the usual symmetric Jordan product,
     and the real-part-of-trace inner product. It has dimension `n^2 over
     the reals.
     """
-    pass
+    F = QuadraticField(-1, 'i')
+    i = F.gen()
+    S = _real_symmetric_basis(n, field=F)
+    T = []
+    for s in S:
+        T.append(s)
+        T.append(i*s)
+    embed_T = [ _embed_complex_matrix(t) for t in T ]
+    Qs = _multiplication_table_from_matrix_basis(embed_T)
+    return FiniteDimensionalEuclideanJordanAlgebra(field, Qs, rank=n)
 
 def QuaternionHermitianSimpleEJA(n):
     """