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
""" Conway-Sloane masses """ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.arith.all import kronecker_symbol, legendre_symbol, prime_divisors, is_prime, fundamental_discriminant from sage.symbolic.constants import pi from sage.misc.all import prod from sage.quadratic_forms.special_values import gamma__exact, zeta__exact, quadratic_L_function__exact from sage.functions.all import floor
def parity(self, allow_rescaling_flag=True): """ Returns the parity ("even" or "odd") of an integer-valued quadratic form over `ZZ`, defined up to similitude/rescaling of the form so that its Jordan component of smallest scale is unimodular. After this rescaling, we say a form is even if it only represents even numbers, and odd if it represents some odd number.
If the 'allow_rescaling_flag' is set to False, then we require that the quadratic form have a Gram matrix with coefficients in `ZZ`, and look at the unimodular Jordan block to determine its parity. This returns an error if the form is not integer-matrix, meaning that it has Jordan components at `p=2` which do not have an integer scale.
We determine the parity by looking for a 1x1 block in the 0-th Jordan component, after a possible rescaling.
INPUT:
self -- a quadratic form with base_ring `ZZ`, which we may require to have integer Gram matrix.
OUTPUT:
One of the strings: "even" or "odd"
EXAMPLES::
sage: Q = QuadraticForm(ZZ, 3, [4, -2, 0, 2, 3, 2]); Q Quadratic form in 3 variables over Integer Ring with coefficients: [ 4 -2 0 ] [ * 2 3 ] [ * * 2 ] sage: Q.parity() 'even'
::
sage: Q = QuadraticForm(ZZ, 3, [4, -2, 0, 2, 3, 1]); Q Quadratic form in 3 variables over Integer Ring with coefficients: [ 4 -2 0 ] [ * 2 3 ] [ * * 1 ] sage: Q.parity() 'even'
::
sage: Q = QuadraticForm(ZZ, 3, [4, -2, 0, 2, 2, 2]); Q Quadratic form in 3 variables over Integer Ring with coefficients: [ 4 -2 0 ] [ * 2 2 ] [ * * 2 ] sage: Q.parity() 'even'
::
sage: Q = QuadraticForm(ZZ, 3, [4, -2, 0, 2, 2, 1]); Q Quadratic form in 3 variables over Integer Ring with coefficients: [ 4 -2 0 ] [ * 2 2 ] [ * * 1 ] sage: Q.parity() 'odd'
""" ## Deal with 0-dim'l forms
## Identify the correct Jordan component to use. else: if min_scale_pow < 0: raise TypeError("Oops! If rescaling is not allowed, then we require our form to have an integral Gram matrix.") ind = scale_pow_list.index(0)
## Find the component of scale (power) zero, and then look for an odd dim'l component.
## The lattice is even if there is no component of scale (power) 0 return "even"
## Look for a 1x1 block in the 0-th Jordan component (which by ## convention of the local_normal_form routine will appear first). else:
def is_even(self, allow_rescaling_flag=True): """ Returns true iff after rescaling by some appropriate factor, the form represents no odd integers. For more details, see parity().
Requires that Q is defined over `ZZ`.
EXAMPLES::
sage: Q = QuadraticForm(ZZ, 2, [1, 0, 1]) sage: Q.is_even() False sage: Q = QuadraticForm(ZZ, 2, [1, 1, 1]) sage: Q.is_even() True
"""
def is_odd(self, allow_rescaling_flag=True): """ Returns true iff after rescaling by some appropriate factor, the form represents some odd integers. For more details, see parity().
Requires that Q is defined over `ZZ`.
EXAMPLES::
sage: Q = QuadraticForm(ZZ, 2, [1, 0, 1]) sage: Q.is_odd() True sage: Q = QuadraticForm(ZZ, 2, [1, 1, 1]) sage: Q.is_odd() False
"""
def conway_species_list_at_odd_prime(self, p): """ Returns an integer called the 'species' which determines the type of the orthogonal group over the finite field `F_p`.
This assumes that the given quadratic form is a unimodular Jordan block at an odd prime `p`. When the dimension is odd then this number is always positive, otherwise it may be positive or negative (or zero, but that is considered positive by convention).
Note: The species of a zero dim'l form is always 0+, so we interpret the return value of zero as positive here! =)
INPUT:
a positive prime number
OUTPUT:
a list of integers
EXAMPLES::
sage: Q = DiagonalQuadraticForm(ZZ, range(1,10)) sage: Q.conway_species_list_at_odd_prime(3) [6, 2, 1]
::
sage: Q = DiagonalQuadraticForm(ZZ, range(1,8)) sage: Q.conway_species_list_at_odd_prime(3) [5, 2] sage: Q.conway_species_list_at_odd_prime(5) [-6, 1]
""" ## Sanity Check: raise TypeError("Oops! We are assuming that p is an odd positive prime number.")
## Deal with the zero-dim'l form return [0]
## List the (unscaled/unimodular) Jordan blocks by their scale power
## Make a list of species (including the two zero-dim'l forms missing at either end of the list of Jordan blocks)
## Some useful variables
## Determine the species else:
## Append the species to the list
## Return the species list
def conway_species_list_at_2(self): """ Returns an integer called the 'species' which determines the type of the orthogonal group over the finite field `F_p`.
This assumes that the given quadratic form is a unimodular Jordan block at an odd prime `p`. When the dimension is odd then this number is always positive, otherwise it may be positive or negative.
Note: The species of a zero dim'l form is always 0+, so we interpret the return value of zero as positive here! =)
OUTPUT:
a list of integers
EXAMPLES::
sage: Q = DiagonalQuadraticForm(ZZ, range(1,10)) sage: Q.conway_species_list_at_2() [1, 5, 1, 1, 1, 1]
::
sage: Q = DiagonalQuadraticForm(ZZ, range(1,8)) sage: Q.conway_species_list_at_2() [1, 3, 1, 1, 1]
""" ## Some useful variables
## Deal with the zero-dim'l form return 0
## List the (unscaled/unimodular) Jordan blocks by their scale power
## Make a list of species (including the two zero-dim'l forms missing at either end of the list of Jordan blocks)
## Make the number 2*t in the C-S Table 1. else:
## Determine if the form is bound is_bound = False else:
## Determine the species else:
## Append the species to the list
## Return the species list
def conway_octane_of_this_unimodular_Jordan_block_at_2(self): """ Determines the 'octane' of this full unimodular Jordan block at the prime `p=2`. This is an invariant defined `(mod 8)`, ad.
This assumes that the form is given as a block diagonal form with unimodular blocks of size <= 2 and the 1x1 blocks are all in the upper leftmost position.
INPUT:
none
OUTPUT:
an integer 0 <= x <= 7
EXAMPLES::
sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7]) sage: Q.conway_octane_of_this_unimodular_Jordan_block_at_2() 0 sage: Q = DiagonalQuadraticForm(ZZ, [1,5,13]) sage: Q.conway_octane_of_this_unimodular_Jordan_block_at_2() 3 sage: Q = DiagonalQuadraticForm(ZZ, [3,7,13]) sage: Q.conway_octane_of_this_unimodular_Jordan_block_at_2() 7
""" ## Deal with 'even' forms else: return 4
## Deal with 'odd' forms by diagonalizing, and then computing the octane.
## Use u to diagonalize the form -- WHAT ARE THE POSSIBLE LOCAL NORMAL FORMS?
## Check for a 1x1 block and diagonalize it
## Diagonalize the 2x2 block else: B = self[ind, ind+1] if (B % 2 != 0): raise RuntimeError("Oops, we expected the mixed term to be even! ")
a = self[ind, ind] b = ZZ(B / ZZ(2)) c = self[ind+1, ind+1] tmp_disc = b * b - a * c
## Perform the diagonalization if (tmp_disc % 8 == 1): ## 2xy tmp_diag_vec[ind] = 1 tmp_diag_vec[ind+1] = -1 ind += 2 elif(tmp_disc % 8 == 5): ## 2x^2 + 2xy + 2y^2 tmp_diag_vec[0] = 3*u tmp_diag_vec[ind] = -u tmp_diag_vec[ind+1] = -u ind += 2 u = tmp_diag_vec[0] else: raise RuntimeError("Oops! This should not happen -- the odd 2x2 blocks have disc 1 or 5 (mod 8).")
## Compute the octane else: raise RuntimeError("Oops! The diagonal elements should all be odd... =(")
## Return its value
def conway_diagonal_factor(self, p): """ Computes the diagonal factor of Conway's `p`-mass.
INPUT:
`p` -- a prime number > 0
OUTPUT:
a rational number > 0
EXAMPLES::
sage: Q = DiagonalQuadraticForm(ZZ, range(1,6)) sage: Q.conway_diagonal_factor(3) 81/256
""" ## Get the species list at p else:
## Evaluate the diagonal factor else:
## Return the diagonal factor
def conway_cross_product_doubled_power(self, p): """ Computes twice the power of p which evaluates the 'cross product' term in Conway's mass formula.
INPUT:
`p` -- a prime number > 0
OUTPUT:
a rational number
EXAMPLES::
sage: Q = DiagonalQuadraticForm(ZZ, range(1,8)) sage: Q.conway_cross_product_doubled_power(2) 18 sage: Q.conway_cross_product_doubled_power(3) 10 sage: Q.conway_cross_product_doubled_power(5) 6 sage: Q.conway_cross_product_doubled_power(7) 6 sage: Q.conway_cross_product_doubled_power(11) 0 sage: Q.conway_cross_product_doubled_power(13) 0
"""
def conway_type_factor(self): """ This is a special factor only present in the mass formula when `p=2`.
INPUT:
none
OUTPUT:
a rational number
EXAMPLES::
sage: Q = DiagonalQuadraticForm(ZZ, range(1,8)) sage: Q.conway_type_factor() 4
"""
def conway_p_mass(self, p): """ Computes Conway's `p`-mass.
INPUT:
`p` -- a prime number > 0
OUTPUT:
a rational number > 0
EXAMPLES::
sage: Q = DiagonalQuadraticForm(ZZ, range(1, 6)) sage: Q.conway_p_mass(2) 16/3 sage: Q.conway_p_mass(3) 729/256
""" ## Compute the first two factors of the p-mass
## Multiply by the 'type factor' when p = 2
## Return the result
def conway_standard_p_mass(self, p): """ Computes the standard (generic) Conway-Sloane `p`-mass.
INPUT:
`p` -- a prime number > 0
OUTPUT:
a rational number > 0
EXAMPLES::
sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) sage: Q.conway_standard_p_mass(2) 2/3
""" ## Some useful variables else:
## Compute the inverse of the generic p-mass #d = self.det() ## Note: No normalizing power of 2 is needed since the power is even. #if not ((p == 2) or (d % p == 0)):
## Return the standard p-mass
def conway_standard_mass(self): """ Returns the infinite product of the standard mass factors.
INPUT:
none
OUTPUT:
a rational number > 0
EXAMPLES::
sage: Q = QuadraticForm(ZZ, 3, [2, -2, 0, 3, -5, 4]) sage: Q.conway_standard_mass() 1/6
::
sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) sage: Q.conway_standard_mass() 1/6
""" else:
## DIAGNOSTIC #print "n = ", n #print "s = ", s #print "Gamma Factor = \n", prod([gamma__exact(j / ZZ(2)) for j in range(1, n+1)]) #print "Zeta Factor = \n", prod([zeta__exact(2*k) for k in range(1, s)]) #print "Pi Factor = \n", pi**((-1) * n * (n+1) / ZZ(4))
* prod([gamma__exact(j / ZZ(2)) for j in range(1, n+1)]) \ * prod([zeta__exact(2*k) for k in range(1, s)])
def conway_mass(self): """ Compute the mass by using the Conway-Sloane mass formula.
INPUT:
none
OUTPUT:
a rational number > 0
EXAMPLES::
sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) sage: Q.conway_mass() 1/48
sage: Q = DiagonalQuadraticForm(ZZ, [7,1,1]) sage: Q.conway_mass() 3/16
sage: Q = QuadraticForm(ZZ, 3, [7, 2, 2, 2, 0, 2]) + DiagonalQuadraticForm(ZZ, [1]) sage: Q.conway_mass() 3/32
""" ## Try to use the cached result ## Double the form so it's integer-matrix
## Compute the standard mass
## Adjust the p-masses when p|2d
## Cache and return the (simplified) result
## ========================================================
#def conway_generic_mass(self): # """ # Computes the generic mass given as # 2 \pi^{-n(n+1)/4} \prod_{j=1}^{n} \Gamma\(\tfrac{j}{2}\) # \zeta(2) \cdots \zeta(2s-2) \zeta_{D}(s) # where $n = 2s$ or $2s-1$ depending on the parity of $n$, # and $D = (-1)^{s} d$. We interpret the symbol $\(\frac{D}{p}\)$ # as 0 if $p\mid 2d$. # (Conway and Sloane, Mass formula paper, p??) # # This is possibly equal to # 2^{-td} * \tau(G) *[\prod_{i=1}^{t} \zeta(1-2i) ]* L(1-t, \chi) # where $\dim(Q) = n = 2t$ or $2t+1$, and the last factor is omitted # when $n$ is odd. # (GHY, Prop 7.4 and 7.5, p121) # """ # RR = RealField(200) # n = self.dim() # if n % 2 == 0: # s = n / 2 # else: # s = (n-1) / 2 # # ## Form the generic zeta product # ans = 2 * RR(pi)^(-n * (n+1) / 4) # for j in range(1,n+1): # ans *= gamma(RR(j/2)) # for j in range(2, 2*s, 2): ## j = 2, ..., 2s-2 # ans *= zeta(RR(j)) # # ## Extra L-factor for even dimensional forms -- DO THIS!!! # raise NotImplementedError, "This routine is not finished yet... =(" # # ## Return the answer # return ans
#def conway_p_mass_adjustment(self, p): # """ # Computes the adjustment to give the p-mass from the generic mass. # """ # pass
######################################################################## |