X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Feja%2Feja_algebra.py;h=3f91ee3ae72c6281c9238804f146944d2c431f1e;hb=fd6618bf82173916b9a35bb3f114d31b4604f456;hp=e288c6cf4f5bbab7e27b80f239380d07762c19df;hpb=220806a8c2d8f72a164e7b0c1ba4451999e0fce5;p=sage.d.git diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index e288c6c..3f91ee3 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -1140,44 +1140,44 @@ class MatrixEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebra): Override the parent method with something that tries to compute over a faster (non-extension) field. """ - if self._basis_normalizers is None: - # We didn't normalize, so assume that the basis we started - # with had entries in a nice field. + if self._basis_normalizers is None or self.base_ring() is QQ: + # We didn't normalize, or the basis we started with had + # entries in a nice field already. Just compute the thing. return super(MatrixEuclideanJordanAlgebra, self)._charpoly_coefficients() - else: - basis = ( (b/n) for (b,n) in zip(self.natural_basis(), - self._basis_normalizers) ) - - # Do this over the rationals and convert back at the end. - # Only works because we know the entries of the basis are - # integers. The argument ``check_axioms=False`` is required - # because the trace inner-product method for this - # class is a stub and can't actually be checked. - J = MatrixEuclideanJordanAlgebra(QQ, - basis, - normalize_basis=False, - check_field=False, - check_axioms=False) - a = J._charpoly_coefficients() - - # Unfortunately, changing the basis does change the - # coefficients of the characteristic polynomial, but since - # these are really the coefficients of the "characteristic - # polynomial of" function, everything is still nice and - # unevaluated. It's therefore "obvious" how scaling the - # basis affects the coordinate variables X1, X2, et - # cetera. Scaling the first basis vector up by "n" adds a - # factor of 1/n into every "X1" term, for example. So here - # we simply undo the basis_normalizer scaling that we - # performed earlier. - # - # The a[0] access here is safe because trivial algebras - # won't have any basis normalizers and therefore won't - # make it to this "else" branch. - XS = a[0].parent().gens() - subs_dict = { XS[i]: self._basis_normalizers[i]*XS[i] - for i in range(len(XS)) } - return tuple( a_i.subs(subs_dict) for a_i in a ) + + basis = ( (b/n) for (b,n) in zip(self.natural_basis(), + self._basis_normalizers) ) + + # Do this over the rationals and convert back at the end. + # Only works because we know the entries of the basis are + # integers. The argument ``check_axioms=False`` is required + # because the trace inner-product method for this + # class is a stub and can't actually be checked. + J = MatrixEuclideanJordanAlgebra(QQ, + basis, + normalize_basis=False, + check_field=False, + check_axioms=False) + a = J._charpoly_coefficients() + + # Unfortunately, changing the basis does change the + # coefficients of the characteristic polynomial, but since + # these are really the coefficients of the "characteristic + # polynomial of" function, everything is still nice and + # unevaluated. It's therefore "obvious" how scaling the + # basis affects the coordinate variables X1, X2, et + # cetera. Scaling the first basis vector up by "n" adds a + # factor of 1/n into every "X1" term, for example. So here + # we simply undo the basis_normalizer scaling that we + # performed earlier. + # + # The a[0] access here is safe because trivial algebras + # won't have any basis normalizers and therefore won't + # make it to this "else" branch. + XS = a[0].parent().gens() + subs_dict = { XS[i]: self._basis_normalizers[i]*XS[i] + for i in range(len(XS)) } + return tuple( a_i.subs(subs_dict) for a_i in a ) @staticmethod @@ -2324,6 +2324,7 @@ class DirectSumEJA(FiniteDimensionalEuclideanJordanAlgebra): """ def __init__(self, J1, J2, field=AA, **kwargs): + self._factors = (J1, J2) n1 = J1.dimension() n2 = J2.dimension() n = n1+n2 @@ -2345,3 +2346,56 @@ class DirectSumEJA(FiniteDimensionalEuclideanJordanAlgebra): check_axioms=False, **kwargs) self.rank.set_cache(J1.rank() + J2.rank()) + + + def factors(self): + r""" + Return the pair of this algebra's factors. + + SETUP:: + + sage: from mjo.eja.eja_algebra import (HadamardEJA, + ....: JordanSpinEJA, + ....: DirectSumEJA) + + EXAMPLES:: + + sage: J1 = HadamardEJA(2,QQ) + sage: J2 = JordanSpinEJA(3,QQ) + sage: J = DirectSumEJA(J1,J2) + sage: J.factors() + (Euclidean Jordan algebra of dimension 2 over Rational Field, + Euclidean Jordan algebra of dimension 3 over Rational Field) + + """ + return self._factors + + def projections(self): + r""" + Return a pair of projections onto this algebra's factors. + + SETUP:: + + sage: from mjo.eja.eja_algebra import (JordanSpinEJA, + ....: ComplexHermitianEJA, + ....: DirectSumEJA) + + EXAMPLES:: + + sage: J1 = JordanSpinEJA(2) + sage: J2 = ComplexHermitianEJA(2) + sage: J = DirectSumEJA(J1,J2) + sage: (pi_left, pi_right) = J.projections() + sage: J.one().to_vector() + (1, 0, 1, 0, 0, 1) + sage: pi_left(J.one()).to_vector() + (1, 0) + sage: pi_right(J.one()).to_vector() + (1, 0, 0, 1) + + """ + (J1,J2) = self.factors() + n = J1.dimension() + pi_left = lambda x: J1.from_vector(x.to_vector()[:n]) + pi_right = lambda x: J2.from_vector(x.to_vector()[n:]) + return (pi_left, pi_right)