X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Feja%2Feja_algebra.py;h=cd39704407deda564f857677a3439bb382f2bcb7;hb=1248db744b91d7d62766e4e48da234f9e9656da2;hp=ed8c85c9f60dc30c0b1f959533208b81e542b734;hpb=f69c89ed86f1e6fd4ee44f5e7df73680801ed6f2;p=sage.d.git diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index ed8c85c..cd39704 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -32,10 +32,10 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra): def __classcall_private__(cls, field, mult_table, + rank, names='e', assume_associative=False, category=None, - rank=None, natural_basis=None): n = len(mult_table) mult_table = [b.base_extend(field) for b in mult_table] @@ -56,20 +56,20 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra): return fda.__classcall__(cls, field, mult_table, + rank=rank, assume_associative=assume_associative, names=names, category=cat, - rank=rank, natural_basis=natural_basis) def __init__(self, field, mult_table, + rank, names='e', assume_associative=False, category=None, - rank=None, natural_basis=None): """ SETUP:: @@ -101,6 +101,20 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra): def _repr_(self): """ Return a string representation of ``self``. + + SETUP:: + + sage: from mjo.eja.eja_algebra import JordanSpinEJA + + TESTS: + + Ensure that it says what we think it says:: + + sage: JordanSpinEJA(2, field=QQ) + Euclidean Jordan algebra of degree 2 over Rational Field + sage: JordanSpinEJA(3, field=RDF) + Euclidean Jordan algebra of degree 3 over Real Double Field + """ fmt = "Euclidean Jordan algebra of degree {} over {}" return fmt.format(self.degree(), self.base_ring()) @@ -110,6 +124,21 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra): """ Guess a regular element. Needed to compute the basis for our characteristic polynomial coefficients. + + SETUP:: + + sage: from mjo.eja.eja_algebra import random_eja + + TESTS: + + Ensure that this hacky method succeeds for every algebra that we + know how to construct:: + + sage: set_random_seed() + sage: J = random_eja() + sage: J._a_regular_element().is_regular() + True + """ gs = self.gens() z = self.sum( (i+1)*gs[i] for i in range(len(gs)) ) @@ -218,19 +247,16 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra): @cached_method def characteristic_polynomial(self): """ + Return a characteristic polynomial that works for all elements + of this algebra. - .. WARNING:: - - This implementation doesn't guarantee that the polynomial - denominator in the coefficients is not identically zero, so - theoretically it could crash. The way that this is handled - in e.g. Faraut and Koranyi is to use a basis that guarantees - the denominator is non-zero. But, doing so requires knowledge - of at least one regular element, and we don't even know how - to do that. The trade-off is that, if we use the standard basis, - the resulting polynomial will accept the "usual" coordinates. In - other words, we don't have to do a change of basis before e.g. - computing the trace or determinant. + The resulting polynomial has `n+1` variables, where `n` is the + dimension of this algebra. The first `n` variables correspond to + the coordinates of an algebra element: when evaluated at the + coordinates of an algebra element with respect to a certain + basis, the result is a univariate polynomial (in the one + remaining variable ``t``), namely the characteristic polynomial + of that element. SETUP:: @@ -360,11 +386,61 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra): def rank(self): """ Return the rank of this EJA. + + ALGORITHM: + + The author knows of no algorithm to compute the rank of an EJA + where only the multiplication table is known. In lieu of one, we + require the rank to be specified when the algebra is created, + and simply pass along that number here. + + SETUP:: + + sage: from mjo.eja.eja_algebra import (JordanSpinEJA, + ....: RealSymmetricEJA, + ....: ComplexHermitianEJA, + ....: QuaternionHermitianEJA, + ....: random_eja) + + EXAMPLES: + + The rank of the Jordan spin algebra is always two:: + + sage: JordanSpinEJA(2).rank() + 2 + sage: JordanSpinEJA(3).rank() + 2 + sage: JordanSpinEJA(4).rank() + 2 + + The rank of the `n`-by-`n` Hermitian real, complex, or + quaternion matrices is `n`:: + + sage: RealSymmetricEJA(2).rank() + 2 + sage: ComplexHermitianEJA(2).rank() + 2 + sage: QuaternionHermitianEJA(2).rank() + 2 + sage: RealSymmetricEJA(5).rank() + 5 + sage: ComplexHermitianEJA(5).rank() + 5 + sage: QuaternionHermitianEJA(5).rank() + 5 + + TESTS: + + Ensure that every EJA that we know how to construct has a + positive integer rank:: + + sage: set_random_seed() + sage: r = random_eja().rank() + sage: r in ZZ and r > 0 + True + """ - if self._rank is None: - raise ValueError("no rank specified at genesis") - else: - return self._rank + return self._rank def vector_space(self): @@ -1388,7 +1464,17 @@ class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra): # are power-associative. # # TODO: choose generator names intelligently. - return FiniteDimensionalEuclideanJordanAlgebra(F, mats, assume_associative=True, names='f') + # + # The rank is the highest possible degree of a minimal polynomial, + # and is bounded above by the dimension. We know in this case that + # there's an element whose minimal polynomial has the same degree + # as the space's dimension, so that must be its rank too. + return FiniteDimensionalEuclideanJordanAlgebra( + F, + mats, + V.dimension(), + assume_associative=True, + names='f') def subalgebra_idempotent(self):