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)
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:
# 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
+def _embed_complex_matrix(M):
+ """
+ Embed the n-by-n complex matrix ``M`` into the space of real
+ matrices of size 2n-by-2n via the map the sends each entry `z = a +
+ bi` to the block matrix ``[[a,b],[-b,a]]``.
+
+ EXAMPLES::
+
+ sage: F = QuadraticField(-1,'i')
+ sage: x1 = F(4 - 2*i)
+ sage: x2 = F(1 + 2*i)
+ sage: x3 = F(-i)
+ sage: x4 = F(6)
+ sage: M = matrix(F,2,[x1,x2,x3,x4])
+ sage: _embed_complex_matrix(M)
+ [ 4 2| 1 -2]
+ [-2 4| 2 1]
+ [-----+-----]
+ [ 0 1| 6 0]
+ [-1 0| 0 6]
+
+ """
+ n = M.nrows()
+ if M.ncols() != n:
+ raise ArgumentError("the matrix 'M' must be square")
+ field = M.base_ring()
+ blocks = []
+ for z in M.list():
+ a = z.real()
+ b = z.imag()
+ blocks.append(matrix(field, 2, [[a,-b],[b,a]]))
+
+ # 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):
"""
The rank-n simple EJA consisting of real symmetric n-by-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):
"""