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):
"""
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):
"""