Path: blob/master/sage/quadratic_forms/special_values.py
4058 views
"""1Routines for computing special values of L-functions2"""34from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing5from sage.rings.arith import kronecker_symbol, bernoulli, factorial, fundamental_discriminant6from sage.rings.all import RealField7from sage.combinat.combinat import bernoulli_polynomial8from sage.rings.rational_field import QQ9from sage.rings.integer_ring import ZZ10from sage.symbolic.constants import pi11from sage.symbolic.pynac import I12from sage.rings.real_mpfr import is_RealField13from sage.misc.functional import denominator14from sage.rings.infinity import infinity151617## ---------------- The Gamma Function ------------------1819def gamma__exact(n):20"""21Evaluates the exact value of the gamma function at an integer or22half-integer argument.2324EXAMPLES::2526sage: gamma__exact(4)27628sage: gamma__exact(3)29230sage: gamma__exact(2)31132sage: gamma__exact(1)3313435sage: gamma__exact(1/2)36sqrt(pi)37sage: gamma__exact(3/2)381/2*sqrt(pi)39sage: gamma__exact(5/2)403/4*sqrt(pi)41sage: gamma__exact(7/2)4215/8*sqrt(pi)4344sage: gamma__exact(-1/2)45-2*sqrt(pi)46sage: gamma__exact(-3/2)474/3*sqrt(pi)48sage: gamma__exact(-5/2)49-8/15*sqrt(pi)50sage: gamma__exact(-7/2)5116/105*sqrt(pi)5253"""54from sage.all import sqrt55## SANITY CHECK56if (not n in QQ) or (denominator(n) > 2):57raise TypeError, "Oops! You much give an integer or half-integer argument."5859if (denominator(n) == 1):60if n <= 0:61return infinity62if n > 0:63return factorial(n-1)64else:65ans = QQ(1)66while (n != QQ(1)/2):67if (n<0):68ans *= QQ(1)/n69n = n + 170elif (n>0):71n = n - 172ans *= n7374ans *= sqrt(pi)75return ans76777879## ------------- The Riemann Zeta Function --------------8081def zeta__exact(n):82r"""83Returns the exact value of the Riemann Zeta function8485References:8687- Iwasawa's "Lectures on p-adic L-functions", p13, "Special value of `\zeta(2k)`"88- Ireland and Rosen's "A Classical Introduction to Modern Number Theory"89- Washington's "Cyclotomic Fields"9091EXAMPLES::9293sage: ## Testing the accuracy of the negative special values94sage: RR = RealField(100)95sage: for i in range(1,10):96... print "zeta(" + str(1-2*i) + "): ", RR(zeta__exact(1-2*i)) - zeta(RR(1-2*i))97zeta(-1): 0.0000000000000000000000000000098zeta(-3): 0.0000000000000000000000000000099zeta(-5): 0.00000000000000000000000000000100zeta(-7): 0.00000000000000000000000000000101zeta(-9): 0.00000000000000000000000000000102zeta(-11): 0.00000000000000000000000000000103zeta(-13): 0.00000000000000000000000000000104zeta(-15): 0.00000000000000000000000000000105zeta(-17): 0.00000000000000000000000000000106107sage: RR = RealField(100)108sage: for i in range(1,10):109... print "zeta(" + str(1-2*i) + "): ", RR(zeta__exact(1-2*i)) - zeta(RR(1-2*i))110zeta(-1): 0.00000000000000000000000000000111zeta(-3): 0.00000000000000000000000000000112zeta(-5): 0.00000000000000000000000000000113zeta(-7): 0.00000000000000000000000000000114zeta(-9): 0.00000000000000000000000000000115zeta(-11): 0.00000000000000000000000000000116zeta(-13): 0.00000000000000000000000000000117zeta(-15): 0.00000000000000000000000000000118zeta(-17): 0.00000000000000000000000000000119120"""121if n<0:122k = 1-n123return -bernoulli(k)/k124elif n>1:125if (n % 2 == 0):126return ZZ(-1)**(n/2 + 1) * ZZ(2)**(n-1) * pi**n * bernoulli(n) / factorial(n)127else:128raise TypeError, "n must be a critical value! (I.e. even > 0 or odd < 0.)"129elif n==1:130return infinity131elif n==0:132return -1/2133134## ---------- Dirichlet L-functions with quadratic characters ----------135136def QuadraticBernoulliNumber(k, d):137r"""138Compute k-th Bernoulli number for the primitive139quadratic character associated to `\chi(x) = \left(\frac{d}{x}\right)`.140141Reference: Iwasawa's "Lectures on p-adic L-functions", pp7-16.142143EXAMPLES::144145sage: ## Makes a set of odd fund discriminants < -3146sage: Fund_odd_test_set = [D for D in range(-163, -3, 4) if is_fundamental_discriminant(D)]147148sage: ## In general, we have B_{1, \chi_d} = -2h/w for odd fund disc < 0149sage: for D in Fund_odd_test_set:150... if len(BinaryQF_reduced_representatives(D)) != -QuadraticBernoulliNumber(1, D):151... print "Oops! There is an error at D = ", D152"""153## Ensure the character is primitive154d1 = fundamental_discriminant(d)155f = abs(d1)156157## Make the (usual) k-th Bernoulli polynomial158x = PolynomialRing(QQ, 'x').gen()159bp = bernoulli_polynomial(x, k)160161## Make the k-th quadratic Bernoulli number162total = sum([kronecker_symbol(d1, i) * bp(i/f) for i in range(f)])163total *= (f ** (k-1))164165return total166167168def quadratic_L_function__exact(n, d):169r"""170Returns the exact value of a quadratic twist of the Riemann Zeta function171by `\chi_d(x) = \left(\frac{d}{x}\right)`.172173References:174175- Iwasawa's "Lectures on p-adic L-functions", p16-17, "Special values of176`L(1-n, \chi)` and `L(n, \chi)`177- Ireland and Rosen's "A Classical Introduction to Modern Number Theory"178- Washington's "Cyclotomic Fields"179180EXAMPLES::181182sage: bool(quadratic_L_function__exact(1, -4) == pi/4)183True184185"""186from sage.all import SR, sqrt187if n<=0:188k = 1-n189return -QuadraticBernoulliNumber(k,d)/k190elif n>=1:191## Compute the kind of critical values (p10)192if kronecker_symbol(fundamental_discriminant(d), -1) == 1:193delta = 0194else:195delta = 1196197## Compute the positive special values (p17)198if ((n - delta) % 2 == 0):199f = abs(fundamental_discriminant(d))200if delta == 0:201GS = sqrt(f)202else:203GS = I * sqrt(f)204ans = SR(ZZ(-1)**(1+(n-delta)/2))205ans *= (2*pi/f)**n206ans *= GS ## Evaluate the Gauss sum here! =0207ans *= 1/(2 * I**delta)208ans *= QuadraticBernoulliNumber(n,d)/factorial(n)209return ans210else:211if delta == 0:212raise TypeError, "n must be a critical value!\n" + "(I.e. even > 0 or odd < 0.)"213if delta == 1:214raise TypeError, "n must be a critical value!\n" + "(I.e. odd > 0 or even <= 0.)"215216217218def quadratic_L_function__numerical(n, d, num_terms=1000):219"""220Evaluate the Dirichlet L-function (for quadratic character) numerically221(in a very naive way).222223EXAMPLES::224225sage: ## Test several values for a given character226sage: RR = RealField(100)227sage: for i in range(5):228... print "L(" + str(1+2*i) + ", (-4/.)): ", RR(quadratic_L_function__exact(1+2*i, -4)) - quadratic_L_function__numerical(RR(1+2*i),-4, 10000)229L(1, (-4/.)): 0.000049999999500000024999996962707230L(3, (-4/.)): 4.99999970000003...e-13231L(5, (-4/.)): 4.99999922759382...e-21232L(7, (-4/.)): ...e-29233L(9, (-4/.)): ...e-29234235sage: ## Testing the accuracy of the negative special values236sage: ## ---- THIS FAILS SINCE THE DIRICHLET SERIES DOESN'T CONVERGE HERE! ----237238sage: ## Test several characters agree with the exact value, to a given accuracy.239sage: for d in range(-20,0):240... if abs(RR(quadratic_L_function__numerical(1, d, 10000) - quadratic_L_function__exact(1, d))) > 0.001:241... print "Oops! We have a problem at d = ", d, " exact = ", RR(quadratic_L_function__exact(1, d)), " numerical = ", RR(quadratic_L_function__numerical(1, d))242...243244"""245## Set the correct precision if it's given (for n).246if is_RealField(n.parent()):247R = n.parent()248else:249R = RealField()250251d1 = fundamental_discriminant(d)252ans = R(0)253for i in range(1,num_terms):254ans += R(kronecker_symbol(d1,i) / R(i)**n)255return ans256257258