X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;ds=sidebyside;f=mjo%2Feja%2Feja_element.py;h=e30dbb13f39d06b6d49c6bfd34c829ab30d6112d;hb=e4d568e25c62d79a2dbe34b81ee4dc21edf09316;hp=6181f032e644423989cf135cd65eeafcb943585f;hpb=4c8f9aac69d1cb4097b60b10e5b198b6372ec55e;p=sage.d.git diff --git a/mjo/eja/eja_element.py b/mjo/eja/eja_element.py index 6181f03..e30dbb1 100644 --- a/mjo/eja/eja_element.py +++ b/mjo/eja/eja_element.py @@ -830,10 +830,7 @@ class FiniteDimensionalEJAElement(IndexedFreeModuleElement): ALGORITHM: - For now, we skip the messy minimal polynomial computation - and instead return the dimension of the vector space spanned - by the powers of this element. The latter is a bit more - straightforward to compute. + ......... SETUP:: @@ -881,12 +878,59 @@ class FiniteDimensionalEJAElement(IndexedFreeModuleElement): True """ - if self.is_zero() and not self.parent().is_trivial(): + n = self.parent().dimension() + + if n == 0: + # The minimal polynomial is an empty product, i.e. the + # constant polynomial "1" having degree zero. + return 0 + elif self.is_zero(): # The minimal polynomial of zero in a nontrivial algebra - # is "t"; in a trivial algebra it's "1" by convention - # (it's an empty product). + # is "t", and is of degree one. + return 1 + elif n == 1: + # If this is a nonzero element of a nontrivial algebra, it + # has degree at least one. It follows that, in an algebra + # of dimension one, the degree must be actually one. return 1 - return self.subalgebra_generated_by().dimension() + + # BEWARE: The subalgebra_generated_by() method uses the result + # of this method to construct a basis for the subalgebra. That + # means, in particular, that we cannot implement this method + # as ``self.subalgebra_generated_by().dimension()``. + + # Algorithm: keep appending (vector representations of) powers + # self as rows to a matrix and echelonizing it. When its rank + # stops increasing, we've reached a redundancy. + + # Given the special cases above, we can assume that "self" is + # nonzero, the algebra is nontrivial, and that its dimension + # is at least two. + M = matrix([(self.parent().one()).to_vector()]) + old_rank = 1 + + # Specifying the row-reduction algorithm can e.g. help over + # AA because it avoids the RecursionError that gets thrown + # when we have to look too hard for a root. + # + # Beware: QQ supports an entirely different set of "algorithm" + # keywords than do AA and RR. + algo = None + from sage.rings.all import QQ + if self.parent().base_ring() is not QQ: + algo = "scaled_partial_pivoting" + + for d in range(1,n): + M = matrix(M.rows() + [(self**d).to_vector()]) + M.echelonize(algo) + new_rank = M.rank() + if new_rank == old_rank: + return new_rank + else: + old_rank = new_rank + + return n + def left_matrix(self): @@ -1013,7 +1057,7 @@ class FiniteDimensionalEJAElement(IndexedFreeModuleElement): # in the "normal" case without us having to think about it. return self.operator().minimal_polynomial() - A = self.subalgebra_generated_by(orthonormalize_basis=False) + A = self.subalgebra_generated_by(orthonormalize=False) return A(self).operator().minimal_polynomial() @@ -1314,13 +1358,13 @@ class FiniteDimensionalEJAElement(IndexedFreeModuleElement): [(0, f2), (1, f0)] """ - A = self.subalgebra_generated_by(orthonormalize_basis=True) + A = self.subalgebra_generated_by(orthonormalize=True) result = [] for (evalue, proj) in A(self).operator().spectral_decomposition(): result.append( (evalue, proj(A.one()).superalgebra_element()) ) return result - def subalgebra_generated_by(self, orthonormalize_basis=False): + def subalgebra_generated_by(self, **kwargs): """ Return the associative subalgebra of the parent EJA generated by this element. @@ -1367,8 +1411,14 @@ class FiniteDimensionalEJAElement(IndexedFreeModuleElement): True """ - from mjo.eja.eja_element_subalgebra import FiniteDimensionalEJAElementSubalgebra - return FiniteDimensionalEJAElementSubalgebra(self, orthonormalize_basis) + from mjo.eja.eja_subalgebra import FiniteDimensionalEJASubalgebra + powers = tuple( self**k for k in range(self.degree()) ) + A = FiniteDimensionalEJASubalgebra(self.parent(), + powers, + associative=True, + **kwargs) + A.one.set_cache(A(self.parent().one())) + return A def subalgebra_idempotent(self):