+ sage: set_random_seed()
+ sage: n = ZZ.random_element(1,5)
+ sage: B = RealSymmetricEJA._denormalized_basis(n,QQ)
+ sage: all( M.is_symmetric() for M in B)
+ True
+
+ """
+ # The basis of symmetric matrices, as matrices, in their R^(n-by-n)
+ # coordinates.
+ S = []
+ for i in xrange(n):
+ for j in xrange(i+1):
+ Eij = matrix(field, n, lambda k,l: k==i and l==j)
+ if i == j:
+ Sij = Eij
+ else:
+ Sij = Eij + Eij.transpose()
+ S.append(Sij)
+ return S
+
+
+ @staticmethod
+ def _max_test_case_size():
+ return 4 # Dimension 10
+
+
+ def __init__(self, n, field=QQ, **kwargs):
+ basis = self._denormalized_basis(n, field)
+ super(RealSymmetricEJA, self).__init__(field, basis, n, **kwargs)
+
+
+class ComplexMatrixEuclideanJordanAlgebra(MatrixEuclideanJordanAlgebra):
+ @staticmethod
+ def real_embed(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]]``.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import \
+ ....: ComplexMatrixEuclideanJordanAlgebra
+
+ 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: ComplexMatrixEuclideanJordanAlgebra.real_embed(M)
+ [ 4 -2| 1 2]
+ [ 2 4|-2 1]
+ [-----+-----]
+ [ 0 -1| 6 0]
+ [ 1 0| 0 6]
+
+ TESTS:
+
+ Embedding is a homomorphism (isomorphism, in fact)::
+
+ sage: set_random_seed()
+ sage: n_max = ComplexMatrixEuclideanJordanAlgebra._max_test_case_size()
+ sage: n = ZZ.random_element(n_max)
+ sage: F = QuadraticField(-1, 'i')
+ sage: X = random_matrix(F, n)
+ sage: Y = random_matrix(F, n)
+ sage: Xe = ComplexMatrixEuclideanJordanAlgebra.real_embed(X)
+ sage: Ye = ComplexMatrixEuclideanJordanAlgebra.real_embed(Y)
+ sage: XYe = ComplexMatrixEuclideanJordanAlgebra.real_embed(X*Y)
+ sage: Xe*Ye == XYe
+ True
+
+ """
+ n = M.nrows()
+ if M.ncols() != n:
+ raise ValueError("the matrix 'M' must be square")
+
+ # We don't need any adjoined elements...
+ field = M.base_ring().base_ring()
+
+ blocks = []
+ for z in M.list():
+ a = z.list()[0] # real part, I guess
+ b = z.list()[1] # imag part, I guess
+ blocks.append(matrix(field, 2, [[a,b],[-b,a]]))
+
+ return matrix.block(field, n, blocks)
+
+
+ @staticmethod
+ def real_unembed(M):
+ """
+ The inverse of _embed_complex_matrix().
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import \
+ ....: ComplexMatrixEuclideanJordanAlgebra
+
+ EXAMPLES::
+
+ sage: A = matrix(QQ,[ [ 1, 2, 3, 4],
+ ....: [-2, 1, -4, 3],
+ ....: [ 9, 10, 11, 12],
+ ....: [-10, 9, -12, 11] ])
+ sage: ComplexMatrixEuclideanJordanAlgebra.real_unembed(A)
+ [ 2*i + 1 4*i + 3]
+ [ 10*i + 9 12*i + 11]
+
+ TESTS:
+
+ Unembedding is the inverse of embedding::
+
+ sage: set_random_seed()
+ sage: F = QuadraticField(-1, 'i')
+ sage: M = random_matrix(F, 3)
+ sage: Me = ComplexMatrixEuclideanJordanAlgebra.real_embed(M)
+ sage: ComplexMatrixEuclideanJordanAlgebra.real_unembed(Me) == M
+ True