check_axioms=True,
prefix='e'):
- # Keep track of whether or not the matrix basis consists of
- # tuples, since we need special cases for them damned near
- # everywhere. This is INDEPENDENT of whether or not the
- # algebra is a cartesian product, since a subalgebra of a
- # cartesian product will have a basis of tuples, but will not
- # in general itself be a cartesian product algebra.
- self._matrix_basis_is_cartesian = False
n = len(basis)
- if n > 0:
- if hasattr(basis[0], 'cartesian_factors'):
- self._matrix_basis_is_cartesian = True
if check_field:
if not field.is_subring(RR):
# we've specified a real embedding.
raise ValueError("scalar field is not real")
+ from mjo.eja.eja_utils import _change_ring
# If the basis given to us wasn't over the field that it's
# supposed to be over, fix that. Or, you know, crash.
- if not cartesian_product:
- # The field for a cartesian product algebra comes from one
- # of its factors and is the same for all factors, so
- # there's no need to "reapply" it on product algebras.
- if self._matrix_basis_is_cartesian:
- # OK since if n == 0, the basis does not consist of tuples.
- P = basis[0].parent()
- basis = tuple( P(tuple(b_i.change_ring(field) for b_i in b))
- for b in basis )
- else:
- basis = tuple( b.change_ring(field) for b in basis )
-
+ basis = tuple( _change_ring(b, field) for b in basis )
if check_axioms:
# Check commutativity of the Jordan and inner-products.
True
"""
- Xu = cls.real_unembed(X)
- Yu = cls.real_unembed(Y)
- tr = (Xu*Yu).trace()
-
- try:
- # Works in QQ, AA, RDF, et cetera.
- return tr.real()
- except AttributeError:
- # A quaternion doesn't have a real() method, but does
- # have coefficient_tuple() method that returns the
- # coefficients of 1, i, j, and k -- in that order.
- return tr.coefficient_tuple()[0]
+ # This does in fact compute the real part of the trace.
+ # If we compute the trace of e.g. a complex matrix M,
+ # then we do so by adding up its diagonal entries --
+ # call them z_1 through z_n. The real embedding of z_1
+ # will be a 2-by-2 REAL matrix [a, b; -b, a] whose trace
+ # as a REAL matrix will be 2*a = 2*Re(z_1). And so forth.
+ return (X*Y).trace()/cls.dimension_over_reals()
class RealMatrixEJA(MatrixEJA):
RationalBasisEJA.CartesianProduct = RationalBasisCartesianProductEJA
-random_eja = ConcreteEJA.random_instance
-
-# def random_eja(*args, **kwargs):
-# J1 = ConcreteEJA.random_instance(*args, **kwargs)
-
-# # This might make Cartesian products appear roughly as often as
-# # any other ConcreteEJA.
-# if ZZ.random_element(len(ConcreteEJA.__subclasses__()) + 1) == 0:
-# # Use random_eja() again so we can get more than two factors.
-# J2 = random_eja(*args, **kwargs)
-# J = cartesian_product([J1,J2])
-# return J
-# else:
-# return J1
+def random_eja(*args, **kwargs):
+ J1 = ConcreteEJA.random_instance(*args, **kwargs)
+
+ # This might make Cartesian products appear roughly as often as
+ # any other ConcreteEJA.
+ if ZZ.random_element(len(ConcreteEJA.__subclasses__()) + 1) == 0:
+ # Use random_eja() again so we can get more than two factors.
+ J2 = random_eja(*args, **kwargs)
+ J = cartesian_product([J1,J2])
+ return J
+ else:
+ return J1