+ @staticmethod
+ def _denormalized_basis(A):
+ """
+ Returns a basis for the space of complex Hermitian n-by-n matrices.
+
+ Why do we embed these? Basically, because all of numerical linear
+ algebra assumes that you're working with vectors consisting of `n`
+ entries from a field and scalars from the same field. There's no way
+ to tell SageMath that (for example) the vectors contain complex
+ numbers, while the scalar field is real.
+
+ SETUP::
+
+ sage: from mjo.hurwitz import (ComplexMatrixAlgebra,
+ ....: QuaternionMatrixAlgebra,
+ ....: OctonionMatrixAlgebra)
+ sage: from mjo.eja.eja_algebra import MatrixEJA
+
+ TESTS::
+
+ sage: set_random_seed()
+ sage: n = ZZ.random_element(1,5)
+ sage: A = MatrixSpace(QQ, n)
+ sage: B = MatrixEJA._denormalized_basis(A)
+ sage: all( M.is_hermitian() for M in B)
+ True
+
+ ::
+
+ sage: set_random_seed()
+ sage: n = ZZ.random_element(1,5)
+ sage: A = ComplexMatrixAlgebra(n, scalars=QQ)
+ sage: B = MatrixEJA._denormalized_basis(A)
+ sage: all( M.is_hermitian() for M in B)
+ True
+
+ ::
+
+ sage: set_random_seed()
+ sage: n = ZZ.random_element(1,5)
+ sage: A = QuaternionMatrixAlgebra(n, scalars=QQ)
+ sage: B = MatrixEJA._denormalized_basis(A)
+ sage: all( M.is_hermitian() for M in B )
+ True
+
+ ::
+
+ sage: set_random_seed()
+ sage: n = ZZ.random_element(1,5)
+ sage: A = OctonionMatrixAlgebra(n, scalars=QQ)
+ sage: B = MatrixEJA._denormalized_basis(A)
+ sage: all( M.is_hermitian() for M in B )
+ True
+
+ """
+ # These work for real MatrixSpace, whose monomials only have
+ # two coordinates (because the last one would always be "1").
+ es = A.base_ring().gens()
+ gen = lambda A,m: A.monomial(m[:2])
+
+ if hasattr(A, 'entry_algebra_gens'):
+ # We've got a MatrixAlgebra, and its monomials will have
+ # three coordinates.
+ es = A.entry_algebra_gens()
+ gen = lambda A,m: A.monomial(m)
+
+ basis = []
+ for i in range(A.nrows()):
+ for j in range(i+1):
+ if i == j:
+ E_ii = gen(A, (i,j,es[0]))
+ basis.append(E_ii)
+ else:
+ for e in es:
+ E_ij = gen(A, (i,j,e))
+ E_ij += E_ij.conjugate_transpose()
+ basis.append(E_ij)
+
+ return tuple( basis )
+