def hecke_polynomial_in_T_variable(self, q, var='x', basis=None, verbose=True): r""" The function hecke_polynomial returns a polynomial whose coefficients are power series in the variable `w`, which represents an element in the disc of radius `1/p`. This function instead uses the more standard variable `T`, which represents an element in the disc of radius `1`. EXAMPLES:: sage: MM = FamiliesOfOMS(11, 0, sign=-1, p=3, prec_cap=[4, 4], base_coeffs=ZpCA(3, 8)) sage: HP = MM.hecke_polynomial_in_T_variable(3, verbose=False); HP (1 + O(3^8))*x^2 + (2 + 2*3 + 3^2 + O(3^4) + (2 + 2*3 + O(3^3))*T + O(3^2)*T^2 + (1 + O(3))*T^3 + O(T^4))*x + 1 + 2*3 + 3^2 + O(3^4) + O(3^3)*T + (2 + 3 + O(3^2))*T^2 + (1 + O(3))*T^3 + O(T^4) """ HPw = self.hecke_polynomial(q, var, basis, verbose) from sage.rings.power_series_ring import PowerSeriesRing from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing v_prec = self.precision_cap()[1] RT = PowerSeriesRing(self.base_ring().base_ring(), 'T', default_prec=v_prec) R = PolynomialRing(RT, var) poly_coeffs = [] for c in HPw.padded_list(): prec = c.prec() cL = c.padded_list() length = len(cL) cL = [cL[i] >> i for i in range(length)] j = 0 while j < length: if cL[j].precision_absolute() <= 0: break j += 1 poly_coeffs.append(RT(cL, j)) poly_coeffs[-1] = RT.one() return R(poly_coeffs)
def _compute_acting_matrix(self, g, M): r""" INPUT: - ``g`` -- an instance of :class:`sage.matrices.matrix_integer_2x2.Matrix_integer_2x2` or :class:`sage.matrix.matrix_generic_dense.Matrix_generic_dense` - ``M`` -- a positive integer giving the precision at which ``g`` should act. OUTPUT: - """ #tim = verbose("Starting") a, b, c, d = self._adjuster(g) # if g.parent().base_ring().is_exact(): # self._check_mat(a, b, c, d) #k = self._k base_ring = self.domain().base_ring() #cdef Matrix B = matrix(base_ring,M,M) B = matrix(base_ring, M, M) # if M == 0: return B.change_ring(self.codomain().base_ring()) R = PowerSeriesRing(base_ring, 'y', default_prec = M) y = R.gen() #tim = verbose("Checked, made R",tim) # special case for small precision, large weight scale = (b+d*y)/(a+c*y) #t = (a+c*y)**k # will already have precision M t = R.one() #cdef long row, col # #tim = verbose("Made matrix",tim) for col in range(M): for row in range(M): #B.set_unsafe(row, col, t[row]) B[row, col] = t[row] t *= scale #verbose("Finished loop",tim) # the change_ring here is annoying, but otherwise we have to change ring each time we multiply B = B.change_ring(self.codomain().base_ring()) #if self._character is not None: # B *= self._character(a) if self._dettwist is not None: B *= (a*d - b*c) ** (self._dettwist) return B
def q_expansion(self, n): r""" Return the `q`-expansion of ``self`` at the cusp at infinity. INPUT: - ``n`` (integer): number of terms to calculate OUTPUT: - a power series over `\ZZ` in the variable `q`, with a *relative* precision of `1 + O(q^n)`. ALGORITHM: Calculates eta to (n/m) terms, where m is the smallest integer dividing self.level() such that self.r(m) != 0. Then multiplies. EXAMPLES:: sage: EtaProduct(36, {6:6, 2:-6}).q_expansion(10) q + 6*q^3 + 27*q^5 + 92*q^7 + 279*q^9 + O(q^11) sage: R.<q> = ZZ[[]] sage: EtaProduct(2,{2:24,1:-24}).q_expansion(100) == delta_qexp(101)(q^2)/delta_qexp(101)(q) True """ R, q = PowerSeriesRing(ZZ, 'q').objgen() pr = R.one().O(n) if not self._rdict: # if self.is_one(): return pr # self.r(d) should always be nonzero since we filtered out the 0s eta_n = max(n // d for d in self._rdict) # if self.r(d) eta = qexp_eta(R, eta_n) for d in self._rdict: rd = self._rdict[d] if rd: pr *= eta(q ** d) ** ZZ(rd) return pr * q**(self._sumDR // 24)