- # If we're going to orthonormalize the basis anyway, we
- # might as well just do Gram-Schmidt on the whole list of
- # powers. The redundant ones will get zero'd out. If this
- # looks like a roundabout way to orthonormalize, it is.
- # But converting everything from algebra elements to vectors
- # to matrices and then back again turns out to be about
- # as fast as reimplementing our own Gram-Schmidt that
- # works in an EJA.
- G,_ = P.gram_schmidt(orthonormal=True)
- basis_vectors = [ g for g in G.rows() if not g.is_zero() ]
- superalgebra_basis = [ self._superalgebra.from_vector(b)
- for b in basis_vectors ]
-
- W = V.span_of_basis( V.from_vector(v) for v in basis_vectors )
-
- fdeja = super(FiniteDimensionalEuclideanJordanElementSubalgebra, self)
- fdeja.__init__(self._superalgebra,
- superalgebra_basis,
- category=category,
- check=False)
+ # Echelonize the matrix ourselves, because otherwise the
+ # call to P.pivot_rows() below can choose a non-optimal
+ # row-reduction algorithm. In particular, scaling can
+ # 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
+ if superalgebra.base_ring() is not QQ:
+ algo = "scaled_partial_pivoting"
+ P.echelonize(algorithm=algo)
+
+ # In this case, we just need to figure out which elements
+ # of the "powers" list are redundant... First compute the
+ # vector subspace spanned by the powers of the given
+ # element.
+
+ # Figure out which powers form a linearly-independent set.
+ ind_rows = P.pivot_rows()
+
+ # Pick those out of the list of all powers.
+ basis = tuple(map(powers.__getitem__, ind_rows))
+
+
+ super().__init__(superalgebra,
+ basis,
+ associative=True,
+ **kwargs)