X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Feja%2Feuclidean_jordan_algebra.py;h=640048543cff7eb2e2a737f8fa49dfdb56b5991e;hb=d6e8006679a55e9d2f0da3e8400963dfdcfb3283;hp=a469bb0d7ba1302ccf30289c9b1c0c5518ed527f;hpb=8f7ecef93d07a3f969d1c944c80b75a7052a4975;p=sage.d.git diff --git a/mjo/eja/euclidean_jordan_algebra.py b/mjo/eja/euclidean_jordan_algebra.py index a469bb0..6400485 100644 --- a/mjo/eja/euclidean_jordan_algebra.py +++ b/mjo/eja/euclidean_jordan_algebra.py @@ -340,6 +340,16 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra): An element of a Euclidean Jordan algebra. """ + def __dir__(self): + """ + Oh man, I should not be doing this. This hides the "disabled" + methods ``left_matrix`` and ``matrix`` from introspection; + in particular it removes them from tab-completion. + """ + return filter(lambda s: s not in ['left_matrix', 'matrix'], + dir(self.__class__) ) + + def __init__(self, A, elt=None): """ EXAMPLES: @@ -658,8 +668,10 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra): """ Return the Jordan-multiplicative inverse of this element. - We can't use the superclass method because it relies on the - algebra being associative. + ALGORITHM: + + We appeal to the quadratic representation as in Koecher's + Theorem 12 in Chapter III, Section 5. EXAMPLES: @@ -698,34 +710,28 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra): sage: (not x.is_invertible()) or (x.inverse()*x == J.one()) True - """ - if not self.is_invertible(): - raise ValueError("element not invertible") + The inverse of the inverse is what we started with:: - if self.parent().is_associative(): - elt = FiniteDimensionalAlgebraElement(self.parent(), self) - # elt is in the right coordinates, but has the wrong class. - return self.parent()(elt.inverse().vector()) + sage: set_random_seed() + sage: J = random_eja() + sage: x = J.random_element() + sage: (not x.is_invertible()) or (x.inverse().inverse() == x) + True - # We do this a little different than the usual recursive - # call to a finite-dimensional algebra element, because we - # wind up with an inverse that lives in the subalgebra and - # we need information about the parent to convert it back. - V = self.span_of_powers() - assoc_subalg = self.subalgebra_generated_by() - # Mis-design warning: the basis used for span_of_powers() - # and subalgebra_generated_by() must be the same, and in - # the same order! - elt = assoc_subalg(V.coordinates(self.vector())) + The zero element is never invertible:: - # This will be in the subalgebra's coordinates... - fda_elt = FiniteDimensionalAlgebraElement(assoc_subalg, elt) - subalg_inverse = fda_elt.inverse() + sage: set_random_seed() + sage: J = random_eja().zero().inverse() + Traceback (most recent call last): + ... + ValueError: element is not invertible - # So we have to convert back... - basis = [ self.parent(v) for v in V.basis() ] - pairs = zip(subalg_inverse.vector(), basis) - return self.parent().linear_combination(pairs) + """ + if not self.is_invertible(): + raise ValueError("element is not invertible") + + P = self.parent() + return P(self.quadratic_representation().inverse()*self.vector()) def is_invertible(self): @@ -866,6 +872,16 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra): return self.span_of_powers().dimension() + def left_matrix(self): + """ + Our parent class defines ``left_matrix`` and ``matrix`` + methods whose names are misleading. We don't want them. + """ + raise NotImplementedError("use operator_matrix() instead") + + matrix = left_matrix + + def minimal_polynomial(self): """ Return the minimal polynomial of this element, @@ -1086,38 +1102,77 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra): sage: J = random_eja() sage: x = J.random_element() sage: y = J.random_element() + sage: Lx = x.operator_matrix() + sage: Lxx = (x*x).operator_matrix() + sage: Qx = x.quadratic_representation() + sage: Qy = y.quadratic_representation() + sage: Qxy = x.quadratic_representation(y) + sage: Qex = J.one().quadratic_representation(x) + sage: n = ZZ.random_element(10) + sage: Qxn = (x^n).quadratic_representation() Property 1: - sage: actual = x.quadratic_representation(y) - sage: expected = ( (x+y).quadratic_representation() - ....: -x.quadratic_representation() - ....: -y.quadratic_representation() ) / 2 - sage: actual == expected + sage: 2*Qxy == (x+y).quadratic_representation() - Qx - Qy True Property 2: sage: alpha = QQ.random_element() - sage: actual = (alpha*x).quadratic_representation() - sage: expected = (alpha^2)*x.quadratic_representation() - sage: actual == expected + sage: (alpha*x).quadratic_representation() == (alpha^2)*Qx + True + + Property 3: + + sage: not x.is_invertible() or ( + ....: Qx*x.inverse().vector() == x.vector() ) + True + + sage: not x.is_invertible() or ( + ....: Qx.inverse() + ....: == + ....: x.inverse().quadratic_representation() ) + True + + sage: Qxy*(J.one().vector()) == (x*y).vector() + True + + Property 4: + + sage: not x.is_invertible() or ( + ....: x.quadratic_representation(x.inverse())*Qx + ....: == Qx*x.quadratic_representation(x.inverse()) ) + True + + sage: not x.is_invertible() or ( + ....: x.quadratic_representation(x.inverse())*Qx + ....: == + ....: 2*x.operator_matrix()*Qex - Qx ) + True + + sage: 2*x.operator_matrix()*Qex - Qx == Lxx True Property 5: - sage: Qy = y.quadratic_representation() - sage: actual = J(Qy*x.vector()).quadratic_representation() - sage: expected = Qy*x.quadratic_representation()*Qy - sage: actual == expected + sage: J(Qy*x.vector()).quadratic_representation() == Qy*Qx*Qy True Property 6: - sage: k = ZZ.random_element(1,10) - sage: actual = (x^k).quadratic_representation() - sage: expected = (x.quadratic_representation())^k - sage: actual == expected + sage: Qxn == (Qx)^n + True + + Property 7: + + sage: not x.is_invertible() or ( + ....: Qx*x.inverse().operator_matrix() == Lx ) + True + + Property 8: + + sage: not x.operator_commutes_with(y) or ( + ....: J(Qx*y.vector())^n == J(Qxn*(y^n).vector()) ) True """ @@ -1211,12 +1266,11 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra): TESTS:: sage: set_random_seed() - sage: J = RealCartesianProductEJA(5) - sage: c = J.random_element().subalgebra_idempotent() - sage: c^2 == c - True - sage: J = JordanSpinEJA(5) - sage: c = J.random_element().subalgebra_idempotent() + sage: J = random_eja() + sage: x = J.random_element() + sage: while x.is_nilpotent(): + ....: x = J.random_element() + sage: c = x.subalgebra_idempotent() sage: c^2 == c True