Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Local Masses and Siegel Densities """ ######################################################################## ## Computes the local masses (rep'n densities of a form by itself) for a quadratic forms over ZZ ## using the papers of Pall [PSPUM VIII (1965), pp95--105] for p>2, and Watson [Mathematika ## 23, no. 1, (1976), pp 94--106] for p=2. These formulas will also work for any local field ## which is unramified at p=2. ## ## Copyright by Jonathan Hanke 2007 <jonhanke@gmail.com> ######################################################################## # python3 from __future__ import division, print_function
import copy
from sage.misc.all import prod from sage.misc.mrange import mrange from sage.functions.all import floor from sage.rings.integer_ring import ZZ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing from sage.rings.rational_field import QQ from sage.arith.all import legendre_symbol, kronecker, prime_divisors from sage.functions.all import sgn from sage.quadratic_forms.special_values import gamma__exact, zeta__exact, quadratic_L_function__exact from sage.misc.functional import squarefree_part from sage.symbolic.constants import pi from sage.matrix.matrix_space import MatrixSpace
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: m = Q.mass__by_Siegel_densities(); m 1/384 sage: m - (2^Q.dim() * factorial(Q.dim()))^(-1) 0
::
sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) sage: m = Q.mass__by_Siegel_densities(); m 1/48 sage: m - (2^Q.dim() * factorial(Q.dim()))^(-1) 0 """ ## Setup else:
## Form the generic zeta product ########################################## ########################################## #print "gp1 = ", generic_prod #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 #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 #print " NEW = ", ZZ(1) * quadratic_L_function__exact(n/2, (-1)**(n/2) * char_d) #print "gp4 = ", generic_prod
#print "generic_prod =", generic_prod
## Determine the adjustment factors ## Cancel out the generic factors #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 p_adjustment = p_adjustment / self.Kitaoka_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)
#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
def Pall_mass_density_at_odd_prime(self, p): """ Returns the local representation density of a form (for representing itself) defined over `ZZ`, at some prime `p>2`.
REFERENCES:
Pall's article "The Weight of a Genus of Positive n-ary Quadratic Forms" appearing in Proc. Symp. Pure Math. VIII (1965), pp95--105.
INPUT:
`p` -- a prime number > 2.
OUTPUT:
a rational number.
EXAMPLES::
sage: Q = QuadraticForm(ZZ, 3, [1,0,0,1,0,1]) sage: Q.Pall_mass_density_at_odd_prime(3) [(0, Quadratic form in 3 variables over Integer Ring with coefficients: [ 1 0 0 ] [ * 1 0 ] [ * * 1 ])] [(0, 3, 8)] [8/9] 8/9 8/9 """ ## Check that p is a positive prime -- unnecessary since it's done implicitly in the next step. =) raise TypeError("Oops! We need p to be a prime > 2.")
## Step 1: Obtain a p-adic (diagonal) local normal form, and ## compute the invariants for each Jordan block. #print jordan_list #print modified_jordan_list
## Step 2: Compute the list of local masses for each Jordan block #print "generic factor: ", generic_factor m = n/2 generic_factor *= (1 + legendre_symbol(((-1)**m) * d, p) * p**(-m)) #print "jordan_mass: ", generic_factor
## Step 3: Compute the local mass $\al_p$ at p. #print "M = ", M
## Return the result
def Watson_mass_at_2(self): """ Returns the local mass of the quadratic form when `p=2`, according to Watson's Theorem 1 of "The 2-adic density of a quadratic form" in Mathematika 23 (1976), pp 94--106.
INPUT:
none
OUTPUT:
a rational number
EXAMPLES::
sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) sage: Q.Watson_mass_at_2() ## WARNING: WE NEED TO CHECK THIS CAREFULLY! 384
""" ## Make a 0-dim'l quadratic form (for initialization purposes)
## Step 0: Compute Jordan blocks and bounds of the scales to keep track of
## Step 1: Compute dictionaries of the diagonal block and 2x2 block for each scale diag_dict[s] = L.extract_variables(range(i)) ## Diagonal Form dim2_dict[s+1] = L.extract_variables(range(i, L.dim())) ## Non-diagonal Form else:
#print "diag_dict = ", diag_dict #print "dim2_dict = ", dim2_dict #print "Jordan_Blocks = ", Jordan_Blocks
## Step 2: Compute three dictionaries of invariants (for n_j, m_j, nu_j) m_dict[s+1] = ZZ.one()/ZZ(2) * L.dim() else: #print " ==>", ZZ(L.dim() - 1) / ZZ(2), floor(ZZ(L.dim() - 1) / ZZ(2))
#print "n_dict = ", n_dict #print "m_dict = ", m_dict #print "nu_dict = ", nu_dict
## Step 3: Compute the e_j dictionary
eps_dict[j] = 1 else: eps_dict[j] = 1 else:
#print "eps_dict = ", eps_dict
## Step 4: Compute the quantities nu, q, P, E for the local mass at 2 sum([n_dict[r] for r in range(j+1, s_max+2)])) for j in range(s_min+1, s_max+2)])
#print "\nFinal Summary:" #print "nu =", nu #print "q = ", q #print "P = ", P #print "E = ", E
## Step 5: Compute the local mass for the prime 2.
def Kitaoka_mass_at_2(self): """ Returns the local mass of the quadratic form when `p=2`, according to Theorem 5.6.3 on pp108--9 of Kitaoka's Book "The Arithmetic of Quadratic Forms".
INPUT:
none
OUTPUT:
a rational number > 0
EXAMPLES::
sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) sage: Q.Kitaoka_mass_at_2() ## WARNING: WE NEED TO CHECK THIS CAREFULLY! 1/2
""" ## Make a 0-dim'l quadratic form (for initialization purposes)
## Step 0: Compute Jordan blocks and bounds of the scales to keep track of
## Step 1: Compute dictionaries of the diagonal block and 2x2 block for each scale diag_dict[s] = L.extract_variables(range(i)) ## Diagonal Form dim2_dict[s+1] = L.extract_variables(range(i, L.dim())) ## Non-diagonal Form else:
#print "diag_dict = ", diag_dict #print "dim2_dict = ", dim2_dict #print "Jordan_Blocks = ", Jordan_Blocks
################## START EDITING HERE ##################
## Compute q := sum of the q_j else: q += Jordan_Blocks[j][1].dim() + 1 ## When N_{j+1} is "odd", add n_j + 1
## Compute P = product of the P_j
## Compute the product E := prod_j (1 / E_j) ((diag_dict[j].dim() != 2) or (((diag_dict[j][0,0] - diag_dict[j][1,1]) % 4) != 0)):
## Deal with the complicated case: else: E *= QQ(2) / (1 - 2**(-tmp_m))
else:
## DIAGNOSTIC #print "\nFinal Summary:" #print "nu =", nu #print "q = ", q #print "P = ", P #print "E = ", E
## Compute the exponent w n_k = Jordan_Blocks[k][1].dim() w += j * n_j * (n_k + QQ(n_j + 1) / 2)
## Step 5: Compute the local mass for the prime 2.
def mass_at_two_by_counting_mod_power(self, k): """ Computes the local mass at `p=2` assuming that it's stable `(mod 2^k)`.
Note: This is **way** too slow to be useful, even when k=1!!!
TO DO: Remove this routine, or try to compile it!
INPUT:
k -- an integer >= 1
OUTPUT:
a rational number
EXAMPLES::
sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) sage: Q.mass_at_two_by_counting_mod_power(1) 4
"""
|