X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;ds=sidebyside;f=mjo%2Feja%2Feja_algebra.py;h=3d49005bda1ad3c987c654b11be1ea901da5af7b;hb=0ecada5937cb3c3aa7307029f165996d83a16133;hp=5dee5d012d6c19d6fc5d79f804ad8aff2757c3d0;hpb=ea99a21239882d478c1a458a0411b1eb0588b84b;p=sage.d.git diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index 5dee5d0..3d49005 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -1200,36 +1200,29 @@ class RationalBasisEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebr V = VectorSpace(field, degree) - # If we were asked to orthonormalize, and if the orthonormal - # basis is different from the given one, then we also want to - # compute multiplication and inner-product tables for the - # deorthonormalized basis. These can be used later to - # construct a deorthonormalized copy of this algebra over QQ - # in which several operations are much faster. + # Save a copy of an algebra with the original, rational basis + # and over QQ where computations are fast. self._rational_algebra = None - if orthonormalize: - if self.base_ring() is not QQ: - # There's no point in constructing the extra algebra if this - # one is already rational. If the original basis is rational - # but normalization would make it irrational, then this whole - # constructor will just fail anyway as it tries to stick an - # irrational number into a rational algebra. - # - # Note: the same Jordan and inner-products work here, - # because they are necessarily defined with respect to - # ambient coordinates and not any particular basis. - self._rational_algebra = RationalBasisEuclideanJordanAlgebra( - basis, - jordan_product, - inner_product, - field=QQ, - orthonormalize=False, - prefix=prefix, - category=category, - check_field=False, - check_axioms=False) + if field is not QQ: + # There's no point in constructing the extra algebra if this + # one is already rational. + # + # Note: the same Jordan and inner-products work here, + # because they are necessarily defined with respect to + # ambient coordinates and not any particular basis. + self._rational_algebra = RationalBasisEuclideanJordanAlgebra( + basis, + jordan_product, + inner_product, + field=QQ, + orthonormalize=False, + prefix=prefix, + category=category, + check_field=False, + check_axioms=False) + if orthonormalize: # Compute the deorthonormalized tables before we orthonormalize # the given basis. The "check" parameter here guarantees that # the basis is linearly-independent. @@ -1365,7 +1358,7 @@ class RationalBasisEuclideanJordanAlgebra(FiniteDimensionalEuclideanJordanAlgebr Algebraic Real Field """ - if self.base_ring() is QQ or self._rational_algebra is None: + if self._rational_algebra is None: # There's no need to construct *another* algebra over the # rationals if this one is already over the # rationals. Likewise, if we never orthonormalized our @@ -1523,15 +1516,29 @@ class MatrixEuclideanJordanAlgebra: This gives the same answer as it would if we computed the trace from the unembedded (original) matrices:: + sage: set_random_seed() + sage: J = RealSymmetricEJA.random_instance() + sage: x,y = J.random_elements(2) + sage: Xe = x.to_matrix() + sage: Ye = y.to_matrix() + sage: X = J.real_unembed(Xe) + sage: Y = J.real_unembed(Ye) + sage: expected = (X*Y).trace() + sage: actual = J.trace_inner_product(Xe,Ye) + sage: actual == expected + True + + :: + sage: set_random_seed() sage: J = ComplexHermitianEJA.random_instance() sage: x,y = J.random_elements(2) sage: Xe = x.to_matrix() sage: Ye = y.to_matrix() - sage: X = ComplexHermitianEJA.real_unembed(Xe) - sage: Y = ComplexHermitianEJA.real_unembed(Ye) + sage: X = J.real_unembed(Xe) + sage: Y = J.real_unembed(Ye) sage: expected = (X*Y).trace().real() - sage: actual = ComplexHermitianEJA.trace_inner_product(Xe,Ye) + sage: actual = J.trace_inner_product(Xe,Ye) sage: actual == expected True @@ -1542,10 +1549,10 @@ class MatrixEuclideanJordanAlgebra: sage: x,y = J.random_elements(2) sage: Xe = x.to_matrix() sage: Ye = y.to_matrix() - sage: X = QuaternionHermitianEJA.real_unembed(Xe) - sage: Y = QuaternionHermitianEJA.real_unembed(Ye) + sage: X = J.real_unembed(Xe) + sage: Y = J.real_unembed(Ye) sage: expected = (X*Y).trace().coefficient_tuple()[0] - sage: actual = QuaternionHermitianEJA.trace_inner_product(Xe,Ye) + sage: actual = J.trace_inner_product(Xe,Ye) sage: actual == expected True @@ -1556,12 +1563,12 @@ class MatrixEuclideanJordanAlgebra: try: # Works in QQ, AA, RDF, et cetera. - return tr.real() / cls.dimension_over_reals() + 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] / cls.dimension_over_reals() + return tr.coefficient_tuple()[0] class RealMatrixEuclideanJordanAlgebra(MatrixEuclideanJordanAlgebra): @@ -1803,11 +1810,19 @@ class ComplexMatrixEuclideanJordanAlgebra(MatrixEuclideanJordanAlgebra): field = M.base_ring() R = PolynomialRing(field, 'z') z = R.gen() + + # Sage doesn't know how to adjoin the complex "i" (the root of + # x^2 + 1) to a field in a general way. Here, we just enumerate + # all of the cases that I have cared to support so far. if field is AA: # Sage doesn't know how to embed AA into QQbar, i.e. how # to adjoin sqrt(-1) to AA. F = QQbar + elif not field.is_exact(): + # RDF or RR + F = field.complex_field() else: + # Works for QQ and... maybe some other fields. F = field.extension(z**2 + 1, 'I', embedding=CLF(-1).sqrt()) i = F.gen()