return tuple( self.random_element() for idx in range(count) )
+ def _rank_computation(self):
+ r"""
+ Compute the rank of this algebra using highly suspicious voodoo.
+
+ ALGORITHM:
+
+ We first compute the basis representation of the operator L_x
+ using polynomial indeterminates are placeholders for the
+ coordinates of "x", which is arbitrary. We then use that
+ matrix to compute the (polynomial) entries of x^0, x^1, ...,
+ x^d,... for increasing values of "d", starting at zero. The
+ idea is that. If we also add "coefficient variables" a_0,
+ a_1,... to the ring, we can form the linear combination
+ a_0*x^0 + ... + a_d*x^d = 0, and ask what dimension the
+ solution space has as an affine variety. When "d" is smaller
+ than the rank, we expect that dimension to be the number of
+ coordinates of "x", since we can set *those* to whatever we
+ want, but linear independence forces the coefficients a_i to
+ be zero. Eventually, when "d" passes the rank, the dimension
+ of the solution space begins to grow, because we can *still*
+ set the coordinates of "x" arbitrarily, but now there are some
+ coefficients that make the sum zero as well. So, when the
+ dimension of the variety jumps, we return the corresponding
+ "d" as the rank of the algebra. This appears to work.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (HadamardEJA,
+ ....: JordanSpinEJA,
+ ....: RealSymmetricEJA,
+ ....: ComplexHermitianEJA,
+ ....: QuaternionHermitianEJA)
+
+ EXAMPLES::
+
+ sage: J = HadamardEJA(5)
+ sage: J._rank_computation() == J.rank()
+ True
+ sage: J = JordanSpinEJA(5)
+ sage: J._rank_computation() == J.rank()
+ True
+ sage: J = RealSymmetricEJA(4)
+ sage: J._rank_computation() == J.rank()
+ True
+ sage: J = ComplexHermitianEJA(3)
+ sage: J._rank_computation() == J.rank()
+ True
+ sage: J = QuaternionHermitianEJA(2)
+ sage: J._rank_computation() == J.rank()
+ True
+
+ """
+ n = self.dimension()
+ var_names = [ "X" + str(z) for z in range(1,n+1) ]
+ d = 0
+ ideal_dim = len(var_names)
+ def L_x_i_j(i,j):
+ # From a result in my book, these are the entries of the
+ # basis representation of L_x.
+ return sum( vars[d+k]*self.monomial(k).operator().matrix()[i,j]
+ for k in range(n) )
+
+ while ideal_dim == len(var_names):
+ coeff_names = [ "a" + str(z) for z in range(d) ]
+ R = PolynomialRing(self.base_ring(), coeff_names + var_names)
+ vars = R.gens()
+ L_x = matrix(R, n, n, L_x_i_j)
+ x_powers = [ vars[k]*(L_x**k)*self.one().to_vector()
+ for k in range(d) ]
+ eqs = [ sum(x_powers[k][j] for k in range(d)) for j in range(n) ]
+ ideal_dim = R.ideal(eqs).dimension()
+ d += 1
+
+ # Subtract one because we increment one too many times, and
+ # subtract another one because "d" is one greater than the
+ # answer anyway; when d=3, we go up to x^2.
+ return d-2
+
def rank(self):
"""
Return the rank of this EJA.