def basic_integral(Phi,a,j,ap,D): """ Returns `\int_{a+pZ_p} (z-{a})^j d\Phi(0-infty)` -- see formula [Pollack-Stevens, sec 9.2] INPUT: - ``Phi`` -- overconvergnt `U_p`-eigensymbol - ``a`` -- integer in [0..p-1] - ``j`` -- positive integer - ``ap`` -- Hecke eigenvalue? - ``D`` -- conductor of the quadratic twist `\chi` OUTPUT: `\int_{a+pZ_p} (z-{a})^j d\Phi(0-\infty)` EXAMPLES: """ M = Phi.num_moments() p = Phi.p() ap = ap*kronecker(D,p) ans = 0 for r in range(j+1): ans = ans+binomial(j,r)*((a-teich(a,p,M))**(j-r))*(p**r)*phi_on_Da(Phi,a,D).moment(r) return ans/ap
def eval_twisted_symbol_on_Da(self, a): # rename! should this be in modsym? """ Returns `\Phi_{\chi}(\{a/p}-{\infty})` where `Phi` is the OMS and `\chi` is a the quadratic character corresponding to self INPUT: - ``a`` -- integer in range(p) OUTPUT: The distribution `\Phi_{\chi}(\{a/p\}-\{\infty\})`. EXAMPLES: sage: from sage.modular.pollack_stevens.space import ps_modsym_from_elliptic_curve sage: E = EllipticCurve('57a') sage: p = 5 sage: prec = 4 sage: phi = ps_modsym_from_elliptic_curve(E) sage: ap = phi.Tq_eigenvalue(p,prec) sage: Phi = phi.p_stabilize_and_lift(p,ap = ap, M = prec, algorithm='stevens') sage: L = pAdicLseries(Phi) sage: L.eval_twisted_symbol_on_Da(1) (2 + 2*5 + 2*5^2 + 2*5^3 + O(5^4), 2 + 3*5 + 2*5^2 + O(5^3), 4*5 + O(5^2), 3 + O(5)) sage: from sage.modular.pollack_stevens.space import ps_modsym_from_elliptic_curve sage: E = EllipticCurve('40a4') sage: p = 7 sage: prec = 4 sage: phi = ps_modsym_from_elliptic_curve(E) sage: ap = phi.Tq_eigenvalue(p,prec) sage: Phi = phi.p_stabilize_and_lift(p,ap = ap, M = prec, algorithm='stevens') sage: L = pAdicLseries(Phi) sage: L.eval_twisted_symbol_on_Da(1) (4 + 6*7 + 3*7^2 + O(7^4), 2 + 7 + O(7^3), 4 + 6*7 + O(7^2), 6 + O(7)) """ symb = self.symb() p = symb.parent().prime() S0p = Sigma0(p) Dists = symb.parent().coefficient_module() M = Dists.precision_cap() p = Dists.prime() twisted_dist = Dists.zero_element() m_map = symb._map D = self._quadratic_twist for b in range(1, abs(D) + 1): if gcd(b, D) == 1: M1 = S0p([1, (b / abs(D)) % p**M, 0, 1]) new_dist = m_map(M1 * M2Z([a, 1, p, 0]))*M1 new_dist = new_dist.scale(kronecker(D, b)).normalize() twisted_dist = twisted_dist + new_dist #ans = ans + self.eval(M1 * M2Z[a, 1, p, 0])._right_action(M1)._lmul_(kronecker(D, b)).normalize() return twisted_dist.normalize()
def _basic_integral(self, a, j): r""" Returns `\int_{a+pZ_p} (z-{a})^j d\Phi(0-infty)` -- see formula [Pollack-Stevens, sec 9.2] INPUT: - ``a`` -- integer in range(p) - ``j`` -- integer in range(self.symb().precision_absolute()) EXAMPLES:: sage: from sage.modular.pollack_stevens.space import ps_modsym_from_elliptic_curve sage: E = EllipticCurve('57a') sage: p = 5 sage: prec = 4 sage: phi = ps_modsym_from_elliptic_curve(E) sage: phi_stabilized = phi.p_stabilize(p,M = prec+3) sage: Phi = phi_stabilized.lift(p,prec,None,algorithm = 'stevens',eigensymbol = True) sage: L = pAdicLseries(Phi) sage: L.eval_twisted_symbol_on_Da(1) (2 + 2*5 + 2*5^2 + 2*5^3 + O(5^4), 2 + 3*5 + 2*5^2 + O(5^3), 4*5 + O(5^2), 3 + O(5)) sage: L._basic_integral(1,2) 2*5^3 + O(5^4) """ symb = self.symb() M = symb.precision_absolute() if j > M: raise PrecisionError ("Too many moments requested") p = self.prime() ap = symb.Tq_eigenvalue(p) D = self._quadratic_twist ap = ap * kronecker(D, p) K = pAdicField(p, M) symb_twisted = self.eval_twisted_symbol_on_Da(a) return sum(binomial(j, r) * ((a - ZZ(K.teichmuller(a)))**(j - r)) * (p**r) * symb_twisted.moment(r) for r in range(j + 1)) / ap
def phi_on_Da(Phi,a,D): """ Returns `\Phi_{\chi}` where `\chi` is a character of conductor `D` INPUT: - ``Phi`` -- overconvergent `U_p`-eigensymbol - ``a`` -- integer in [0..p-1] - ``D`` -- conductor of the quadratic twist `\chi` OUTPUT: `\Phi_{\chi}` EXAMPLES: """ p = Phi.p() ans = Phi.zero_elt() for b in range(1,abs(D)+1): if gcd(b,D)==1: M1 = Matrix(2,2,[1,b/abs(D),0,1]) ans=ans+Phi.eval(M1*Matrix(2,2,[a,1,p,0])).act_right(M1).scale(kronecker(D,b)).normalize() return ans.normalize()
def mass__by_Siegel_densities(self, odd_algorithm="Pall", even_algorithm="Watson"): """ Gives the mass of transformations (det 1 and -1). WARNING: THIS IS BROKEN RIGHT NOW... =( Optional Arguments: - When p > 2 -- odd_algorithm = "Pall" (only one choice for now) - When p = 2 -- even_algorithm = "Kitaoka" or "Watson" REFERENCES: - Nipp's Book "Tables of Quaternary Quadratic Forms". - Papers of Pall (only for p>2) and Watson (for `p=2` -- tricky!). - Siegel, Milnor-Hussemoller, Conway-Sloane Paper IV, Kitoaka (all of which have problems...) EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1]) sage: Q.mass__by_Siegel_densities() 1/384 sage: Q.mass__by_Siegel_densities() - (2^Q.dim() * factorial(Q.dim()))^(-1) 0 :: sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) sage: Q.mass__by_Siegel_densities() 1/48 sage: Q.mass__by_Siegel_densities() - (2^Q.dim() * factorial(Q.dim()))^(-1) 0 """ ## Setup n = self.dim() s = floor((n - 1) / 2) if n % 2 != 0: char_d = squarefree_part(2 * self.det()) ## Accounts for the det as a QF else: char_d = squarefree_part(self.det()) ## Form the generic zeta product generic_prod = ZZ(2) * (pi)**(-ZZ(n) * (n + 1) / 4) ########################################## generic_prod *= (self.det())**( ZZ(n + 1) / 2) ## ***** This uses the Hessian Determinant ******** ########################################## #print "gp1 = ", generic_prod generic_prod *= prod([gamma__exact(ZZ(j) / 2) for j in range(1, n + 1)]) #print "\n---", [(ZZ(j)/2, gamma__exact(ZZ(j)/2)) for j in range(1,n+1)] #print "\n---", prod([gamma__exact(ZZ(j)/2) for j in range(1,n+1)]) #print "gp2 = ", generic_prod generic_prod *= prod([zeta__exact(ZZ(j)) for j in range(2, 2 * s + 1, 2)]) #print "\n---", [zeta__exact(ZZ(j)) for j in range(2, 2*s+1, 2)] #print "\n---", prod([zeta__exact(ZZ(j)) for j in range(2, 2*s+1, 2)]) #print "gp3 = ", generic_prod if (n % 2 == 0): generic_prod *= ZZ(1) * quadratic_L_function__exact( n / 2, (-1)**(n / 2) * char_d) #print " NEW = ", ZZ(1) * quadratic_L_function__exact(n/2, (-1)**(n/2) * char_d) #print #print "gp4 = ", generic_prod #print "generic_prod =", generic_prod ## Determine the adjustment factors adj_prod = 1 for p in prime_divisors(2 * self.det()): ## Cancel out the generic factors p_adjustment = prod([1 - ZZ(p)**(-j) for j in range(2, 2 * s + 1, 2)]) if (n % 2 == 0): p_adjustment *= ZZ(1) * (1 - kronecker( (-1)**(n / 2) * char_d, p) * ZZ(p)**(-n / 2)) #print " EXTRA = ", ZZ(1) * (1 - kronecker((-1)**(n/2) * char_d, p) * ZZ(p)**(-n/2)) #print "Factor to cancel the generic one:", p_adjustment ## Insert the new mass factors if p == 2: if even_algorithm == "Kitaoka": p_adjustment = p_adjustment / self.Kitaoka_mass_at_2() elif even_algorithm == "Watson": p_adjustment = p_adjustment / self.Watson_mass_at_2() else: raise TypeError( "There is a problem -- your even_algorithm argument is invalid. Try again. =(" ) else: if odd_algorithm == "Pall": p_adjustment = p_adjustment / self.Pall_mass_density_at_odd_prime( p) else: raise TypeError( "There is a problem -- your optional arguments are invalid. Try again. =(" ) #print "p_adjustment for p =", p, "is", p_adjustment ## Put them together (cumulatively) adj_prod *= p_adjustment #print "Cumulative adj_prod =", adj_prod ## Extra adjustment for the case of a 2-dimensional form. #if (n == 2): # generic_prod *= 2 ## Return the mass mass = generic_prod * adj_prod return mass
def mass__by_Siegel_densities(self, odd_algorithm="Pall", even_algorithm="Watson"): """ Gives the mass of transformations (det 1 and -1). WARNING: THIS IS BROKEN RIGHT NOW... =( Optional Arguments: - When p > 2 -- odd_algorithm = "Pall" (only one choice for now) - When p = 2 -- even_algorithm = "Kitaoka" or "Watson" REFERENCES: - Nipp's Book "Tables of Quaternary Quadratic Forms". - Papers of Pall (only for p>2) and Watson (for `p=2` -- tricky!). - Siegel, Milnor-Hussemoller, Conway-Sloane Paper IV, Kitoaka (all of which have problems...) EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1]) sage: Q.mass__by_Siegel_densities() 1/384 sage: Q.mass__by_Siegel_densities() - (2^Q.dim() * factorial(Q.dim()))^(-1) 0 :: sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) sage: Q.mass__by_Siegel_densities() 1/48 sage: Q.mass__by_Siegel_densities() - (2^Q.dim() * factorial(Q.dim()))^(-1) 0 """ ## Setup n = self.dim() s = (n-1) // 2 if n % 2 != 0: char_d = squarefree_part(2*self.det()) ## Accounts for the det as a QF else: char_d = squarefree_part(self.det()) ## Form the generic zeta product generic_prod = ZZ(2) * (pi)**(-ZZ(n) * (n+1) / 4) ########################################## generic_prod *= (self.det())**(ZZ(n+1)/2) ## ***** This uses the Hessian Determinant ******** ########################################## #print "gp1 = ", generic_prod generic_prod *= prod([gamma__exact(ZZ(j)/2) for j in range(1,n+1)]) #print "\n---", [(ZZ(j)/2, gamma__exact(ZZ(j)/2)) for j in range(1,n+1)] #print "\n---", prod([gamma__exact(ZZ(j)/2) for j in range(1,n+1)]) #print "gp2 = ", generic_prod generic_prod *= prod([zeta__exact(ZZ(j)) for j in range(2, 2*s+1, 2)]) #print "\n---", [zeta__exact(ZZ(j)) for j in range(2, 2*s+1, 2)] #print "\n---", prod([zeta__exact(ZZ(j)) for j in range(2, 2*s+1, 2)]) #print "gp3 = ", generic_prod if (n % 2 == 0): generic_prod *= ZZ(1) * quadratic_L_function__exact(n/2, (-1)**(n/2) * char_d) #print " NEW = ", ZZ(1) * quadratic_L_function__exact(n/2, (-1)**(n/2) * char_d) #print #print "gp4 = ", generic_prod #print "generic_prod =", generic_prod ## Determine the adjustment factors adj_prod = 1 for p in prime_divisors(2 * self.det()): ## Cancel out the generic factors p_adjustment = prod([1 - ZZ(p)**(-j) for j in range(2, 2*s+1, 2)]) if (n % 2 == 0): p_adjustment *= ZZ(1) * (1 - kronecker((-1)**(n/2) * char_d, p) * ZZ(p)**(-n/2)) #print " EXTRA = ", ZZ(1) * (1 - kronecker((-1)**(n/2) * char_d, p) * ZZ(p)**(-n/2)) #print "Factor to cancel the generic one:", p_adjustment ## Insert the new mass factors if p == 2: if even_algorithm == "Kitaoka": p_adjustment = p_adjustment / self.Kitaoka_mass_at_2() elif even_algorithm == "Watson": p_adjustment = p_adjustment / self.Watson_mass_at_2() else: raise TypeError("There is a problem -- your even_algorithm argument is invalid. Try again. =(") else: if odd_algorithm == "Pall": p_adjustment = p_adjustment / self.Pall_mass_density_at_odd_prime(p) else: raise TypeError("There is a problem -- your optional arguments are invalid. Try again. =(") #print "p_adjustment for p =", p, "is", p_adjustment ## Put them together (cumulatively) adj_prod *= p_adjustment #print "Cumulative adj_prod =", adj_prod ## Extra adjustment for the case of a 2-dimensional form. #if (n == 2): # generic_prod *= 2 ## Return the mass mass = generic_prod * adj_prod return mass