aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano.tronto@gmail.com>2019-07-30 16:25:26 +0200
committerSebastiano Tronto <sebastiano.tronto@gmail.com>2019-07-30 16:25:26 +0200
commitcf6c4f80c1eb5f77d14816bcc6323e01c35d94ce (patch)
tree93764201f104cedff0e6dd19c46dab1bfd1df120
parent3062ce67bb0240a47841bfb954ca79a2d8d64768 (diff)
downloadkummer-degrees-cf6c4f80c1eb5f77d14816bcc6323e01c35d94ce.tar.gz
kummer-degrees-cf6c4f80c1eb5f77d14816bcc6323e01c35d94ce.zip
Using results of PST-2 to compute parameters over Q4 directly
-rw-r--r--.kummer_degree.sage.swpbin0 -> 53248 bytes
-rw-r--r--.parameters_Q4_new.sage.swpbin0 -> 12288 bytes
-rw-r--r--kummer_degree.sage195
-rw-r--r--parameters_Q4_new.sage60
-rw-r--r--parameters_Q4_old.sage123
5 files changed, 254 insertions, 124 deletions
diff --git a/.kummer_degree.sage.swp b/.kummer_degree.sage.swp
new file mode 100644
index 0000000..befa4d7
--- /dev/null
+++ b/.kummer_degree.sage.swp
Binary files differ
diff --git a/.parameters_Q4_new.sage.swp b/.parameters_Q4_new.sage.swp
new file mode 100644
index 0000000..c4d2710
--- /dev/null
+++ b/.parameters_Q4_new.sage.swp
Binary files differ
diff --git a/kummer_degree.sage b/kummer_degree.sage
index 5800559..6f3dab9 100644
--- a/kummer_degree.sage
+++ b/kummer_degree.sage
@@ -275,127 +275,67 @@ def l_adic_failure_from_data( B, l, tablel, M, N ):
275 275
276 return l^(r*n-tablel[m-1][0][n-1]) 276 return l^(r*n-tablel[m-1][0][n-1])
277 277
278# Computes the l-divisibility parameters of G over Q4, given a good basis b 278# Returns the l-dvisibility parameters of G over Q, given a good basis gb of G,
279# as a list of pairs (di,hi).
280def parameters_Q( gb, l ):
281 ret = []
282 for i in range( len( gb ) ):
283 for j in gb[i]:
284 ret.append( (i,0) )
285 return ret
286
287# Computes the l-divisibility parameters of G over Q4, given a good basis gb
279# over Q for G. Returns a list of pairs (di,hi). 288# over Q for G. Returns a list of pairs (di,hi).
280# If l is odd it just uses the good basis given to compute the parameters. 289# If l is odd it just uses the good basis given to compute the parameters.
290# If l=2, it uses the results of PST-2.
281def parameters_Q4( gb, l ): 291def parameters_Q4( gb, l ):
282 # Converts from "good basis format" to simple list
283 b = []
284 for x in gb:
285 b += x
286 ret = []
287
288 if l != 2: 292 if l != 2:
289 for i in range( len( gb ) ): 293 return parameters_Q( gb, l )
290 for j in gb[i]:
291 ret.append( (i,0) )
292 return ret
293 else: 294 else:
294 R.<y> = PolynomialRing( QQ ) 295 # Converts from "good basis format" to simple list
295 pol = R(y^2+1) 296 b = []
296 Q4.<eye> = NumberField( pol ) # I already use i for other things 297 for x in gb:
297 298 b += x
298 # Factorize basis elements over Q4 and so on. 299
299 d = [] 300 M = exponent_matrix( b )
300 B = []
301 h = []
302 ideals_list = set()
303 M = [] # Exponent matrix of the Bi's
304
305 # Pre-process to find all ideals appearing in the factorization and fix
306 # a chosen generator for each of them. This is important in order to
307 # compute the "sign" (h-parameter) of an element with respect to it Bi.
308 for g in b:
309 factorization_list = list( Q4.ideal(g).factor() )
310 ideals_list |= set( [ x[0] for x in factorization_list ] )
311 ideals_list = list( ideals_list )
312 # Chooses a generator of each principal ideal in the list
313 irreducibles_list = [ J.gens_reduced()[0] for J in ideals_list ]
314 301
315 # Compute the Q4-parameters of the given basis b. Also computes the 302 # Thanks to my terrible notation, the elements of b are what are called
316 # exponent matrix of the Bi's 303 # g_i in the article, while the elements of bb will be the b_i's.
317 for g in b: 304 bb = [ abs(b[i]) ^ (2^(-divisibility(M[i],2))) for i in range(len(b)) ]
318 factorization_list = list( Q4.ideal(g).factor() )
319 exps = [ x[1] for x in factorization_list ]
320 d.append( divisibility( exps, l ) )
321 Bg = 1
322 for j in range(len(factorization_list)):
323 a = 0
324 for i in range( len( ideals_list ) ):
325 if ideals_list[i] == factorization_list[j][0]:
326 a = irreducibles_list[i]
327 break
328 Bg *= a ^ (exps[j]/(l^d[-1]))
329 B.append(Bg)
330 u = g / (Bg^(l^d[-1]))
331 if not u.is_unit():
332 print "Error: g is not the right power of the computed Bg."
333 print "g:", g, ", Bg:", Bg, ", exponent:", l^d[-1]
334 if u == 1:
335 h.append( 0 )
336 elif u == -1:
337 h.append( 1 )
338 else:
339 h.append( 2 )
340 305
341 # Make the exponent matrix M (for now as a list of rows) 306 # Computing a combination of bb elements of the form 2 * square.
342 for g in B: 307 MM = exponent_matrix( bb + [2] ).change_ring( GF( 2 ) )
343 row = [0] * len(ideals_list)
344 for i in range(len(ideals_list)):
345 I = ideals_list[i]
346 ee = 1
347 while (I^ee).divides(g):
348 ee += 1
349 row[i] = ee-1
350 M.append(row)
351 308
352 # If the Bi's are not strongly independent, apply the algorithm (only 309 for a in MM.kernel().basis():
353 # once) to produce a new basis. The new basis has maximal parameters. 310 if a[-1] != 0:
354 coeffs = find_combination( matrix(M), l ) 311 # the vector a[0:-1] gives the coefficients for a combination
355 if coeffs != []: 312 # of the b_i's of the form 2 * square
313
314 # Basis elements that actually appear in the combination
315 c = [ b[i] for i in range(len(a[0:-1])) if a[i] != 0 ]
356 316
357 maxi = -1 317 # Return the parameters, changing only the ones fo the element
358 maxd = -1 318 # of highest divisibility that appears in the combination.
359 for i in range(len(d)): 319 ret = []
360 if d[i] > maxd and coeffs[i] != 0: 320 div_max = -1
361 maxd = d[i] 321 ind_max = -1
362 maxi = i 322 for i in range(len(b)):
323 ret.append( (divisibility(M[i],2), 1-max(0,sgn(b[i]))) )
324 if a[i] != 0 and ret[i][0] > div_max:
325 div_max = ret[i][0]
326 ind_max = i
327 d1, h1 = ret[ind_max]
328 if d1 == 1:
329 h1 = 1 - h1
330 elif d1 == 0:
331 h1 = 2
332 ret[ind_max] = ( d1+1, h1 )
363 333
364 x = [(a/coeffs[maxi]).lift() for a in coeffs] # Now a vector of int 334 return ret
365 335
366 new_element = 1 336 return parameters_Q( gb, 2 )
367 for i in range(len(d)):
368 new_element *= b[i]^( x[i] * l^(d[maxi]-d[i]) )
369
370 b[maxi] = new_element
371 337
372 # Compute new B, d and so on.
373 factorization_list = list( Q4.ideal(b[maxi]).factor() )
374 exps = [ x[1] for x in factorization_list ]
375 d[maxi] = divisibility( exps, l )
376 Bg = 1
377 338
378 for j in range(len(factorization_list)):
379 a = 0
380 for i in range( len( ideals_list ) ):
381 if ideals_list[i] == factorization_list[j][0]:
382 a = irreducibles_list[i]
383 break
384 Bg *= a ^ (exps[j]/(l^d[maxi]))
385 B[maxi] = Bg
386 M[maxi] = [ x[1] for x in list( Q4.ideal(Bg).factor() ) ]
387 u = b[maxi] / (Bg^(l^d[maxi]))
388 if not u.is_unit():
389 print "Error: new element is not the right power of B."
390 print "New el.:", b[maxi], ", B:", Bg, ", exponent:", l^d[maxi]
391 if u == 1:
392 h[maxi] = 0
393 elif u == -1:
394 h[maxi] = 1
395 else:
396 h[maxi] = 2
397
398 return [(d[i],h[i]) for i in range(len(d))]
399 339
400# Uses Theorem 18 to compute the degree of Kummer extensions. 340# Uses Theorem 18 to compute the degree of Kummer extensions.
401def compute_vl( p, n, m, r ): 341def compute_vl( p, n, m, r ):
@@ -405,6 +345,28 @@ def compute_vl( p, n, m, r ):
405 345
406 return M - m + r*n - sum( ni ) 346 return M - m + r*n - sum( ni )
407 347
348# Computes a basis for G from a set of generators.
349# Returns a pair (B,torsion) where B is a list of rational numbers and torsion
350# is true if -1 is in G and false otherwise.
351def generators_to_basis( G ):
352 (BM,BM_primes) = exponent_matrix_with_sign_and_primes( G )
353 BM = BM.echelon_form()
354 BM_primes.append(-1)
355 B = []
356 torsion = False
357
358 for r in BM.rows():
359 gr = product( [ BM_primes[i]^r[i] for i in range(len(r)) ] )
360 if gr == -1:
361 torsion = True
362 break
363 elif gr == 1:
364 break
365 else:
366 B.append(gr)
367
368 return (B,torsion)
369
408# Given any basis b of a group G computes an l-good basis for G. This is done 370# Given any basis b of a group G computes an l-good basis for G. This is done
409# using the algorithm outlined in the proof of Theorem 14 of (Debry-Perucca). 371# using the algorithm outlined in the proof of Theorem 14 of (Debry-Perucca).
410def make_good_basis( b, l ): 372def make_good_basis( b, l ):
@@ -549,22 +511,7 @@ def TotalKummerFailure( G ):
549# return any value. 511# return any value.
550def total_kummer_failure( G, output ): 512def total_kummer_failure( G, output ):
551 513
552 # Computing a basis. 514 B, torsion = generators_to_basis( G )
553 (BM,BM_primes) = exponent_matrix_with_sign_and_primes( G )
554 BM = BM.echelon_form()
555 BM_primes.append(-1)
556 B = []
557 torsion = False
558
559 for r in BM.rows():
560 gr = product( [ BM_primes[i]^r[i] for i in range(len(r)) ] )
561 if gr == -1:
562 torsion = True
563 break
564 elif gr == 1:
565 break
566 else:
567 B.append(gr)
568 515
569 if len(B) == 0: 516 if len(B) == 0:
570 print "G is torsion. The extension is cyclotomic. Stopping." 517 print "G is torsion. The extension is cyclotomic. Stopping."
diff --git a/parameters_Q4_new.sage b/parameters_Q4_new.sage
new file mode 100644
index 0000000..554cc0a
--- /dev/null
+++ b/parameters_Q4_new.sage
@@ -0,0 +1,60 @@
1# Returns the l-dvisibility parameters of G over Q, given a good basis gb of G,
2# as a list of pairs (di,hi).
3def parameters_Q( gb, l ):
4 ret = []
5 for i in range( len( gb ) ):
6 for j in gb[i]:
7 ret.append( (i,0) )
8 return ret
9
10# Computes the l-divisibility parameters of G over Q4, given a good basis gb
11# over Q for G. Returns a list of pairs (di,hi).
12# If l is odd it just uses the good basis given to compute the parameters.
13# If l=2, it uses the results of PST-2.
14def parameters_Q4_new( gb, l ):
15 if l != 2:
16 return parameters_Q( gb, l )
17 else:
18 # Converts from "good basis format" to simple list
19 b = []
20 for x in gb:
21 b += x
22
23 M = exponent_matrix( b )
24
25 # Thanks to my terrible notation, the elements of b are what are called
26 # g_i in the article, while the elements of bb will be the b_i's.
27 bb = [ abs(b[i]) ^ (2^(-divisibility(M[i],2))) for i in range(len(b)) ]
28
29 # Computing a combination of bb elements of the form 2 * square.
30 MM = exponent_matrix( bb + [2] ).change_ring( GF( 2 ) )
31
32 for a in MM.kernel().basis():
33 if a[-1] != 0:
34 # the vector a[0:-1] gives the coefficients for a combination
35 # of the b_i's of the form 2 * square
36
37 # Basis elements that actually appear in the combination
38 c = [ b[i] for i in range(len(a[0:-1])) if a[i] != 0 ]
39
40 # Return the parameters, changing only the ones fo the element
41 # of highest divisibility that appears in the combination.
42 ret = []
43 div_max = -1
44 ind_max = -1
45 for i in range(len(b)):
46 ret.append( (divisibility(M[i],2), 1-max(0,sgn(b[i]))) )
47 if a[i] != 0 and ret[i][0] > div_max:
48 div_max = ret[i][0]
49 ind_max = i
50 d1, h1 = ret[ind_max]
51 if d1 == 1:
52 h1 = 1 - h1
53 elif d1 == 0:
54 h1 = 2
55 ret[ind_max] = ( d1+1, h1 )
56
57 return ret
58
59 return parameters_Q( gb, 2 )
60
diff --git a/parameters_Q4_old.sage b/parameters_Q4_old.sage
new file mode 100644
index 0000000..d96fd8c
--- /dev/null
+++ b/parameters_Q4_old.sage
@@ -0,0 +1,123 @@
1# Computes the l-divisibility parameters of G over Q4, given a good basis gb
2# over Q for G. Returns a list of pairs (di,hi).
3# If l is odd it just uses the good basis given to compute the parameters.
4def parameters_Q4( gb, l ):
5 # Converts from "good basis format" to simple list
6 b = []
7 for x in gb:
8 b += x
9 ret = []
10
11 if l != 2:
12 for i in range( len( gb ) ):
13 for j in gb[i]:
14 ret.append( (i,0) )
15 return ret
16 else:
17 R.<y> = PolynomialRing( QQ )
18 pol = R(y^2+1)
19 Q4.<eye> = NumberField( pol ) # I already use i for other things
20
21 # Factorize basis elements over Q4 and so on.
22 d = []
23 B = []
24 h = []
25 ideals_list = set()
26 M = [] # Exponent matrix of the Bi's
27
28 # Pre-process to find all ideals appearing in the factorization and fix
29 # a chosen generator for each of them. This is important in order to
30 # compute the "sign" (h-parameter) of an element with respect to it Bi.
31 for g in b:
32 factorization_list = list( Q4.ideal(g).factor() )
33 ideals_list |= set( [ x[0] for x in factorization_list ] )
34 ideals_list = list( ideals_list )
35 # Chooses a generator of each principal ideal in the list
36 irreducibles_list = [ J.gens_reduced()[0] for J in ideals_list ]
37
38 # Compute the Q4-parameters of the given basis b. Also computes the
39 # exponent matrix of the Bi's
40 for g in b:
41 factorization_list = list( Q4.ideal(g).factor() )
42 exps = [ x[1] for x in factorization_list ]
43 d.append( divisibility( exps, l ) )
44 Bg = 1
45 for j in range(len(factorization_list)):
46 a = 0
47 for i in range( len( ideals_list ) ):
48 if ideals_list[i] == factorization_list[j][0]:
49 a = irreducibles_list[i]
50 break
51 Bg *= a ^ (exps[j]/(l^d[-1]))
52 B.append(Bg)
53 u = g / (Bg^(l^d[-1]))
54 if not u.is_unit():
55 print "Error: g is not the right power of the computed Bg."
56 print "g:", g, ", Bg:", Bg, ", exponent:", l^d[-1]
57 if u == 1:
58 h.append( 0 )
59 elif u == -1:
60 h.append( 1 )
61 else:
62 h.append( 2 )
63
64 # Make the exponent matrix M (for now as a list of rows)
65 for g in B:
66 row = [0] * len(ideals_list)
67 for i in range(len(ideals_list)):
68 I = ideals_list[i]
69 ee = 1
70 while (I^ee).divides(g):
71 ee += 1
72 row[i] = ee-1
73 M.append(row)
74
75 # If the Bi's are not strongly independent, apply the algorithm (only
76 # once) to produce a new basis. The new basis has maximal parameters.
77 coeffs = find_combination( matrix(M), l )
78 if coeffs != []:
79
80 maxi = -1
81 maxd = -1
82 for i in range(len(d)):
83 if d[i] > maxd and coeffs[i] != 0:
84 maxd = d[i]
85 maxi = i
86
87 x = [(a/coeffs[maxi]).lift() for a in coeffs] # Now a vector of int
88
89 new_element = 1
90 for i in range(len(d)):
91 new_element *= b[i]^( x[i] * l^(d[maxi]-d[i]) )
92
93 b[maxi] = new_element
94
95 # Compute new B, d and so on.
96 factorization_list = list( Q4.ideal(b[maxi]).factor() )
97 exps = [ x[1] for x in factorization_list ]
98 d[maxi] = divisibility( exps, l )
99 Bg = 1
100
101 for j in range(len(factorization_list)):
102 a = 0
103 for i in range( len( ideals_list ) ):
104 if ideals_list[i] == factorization_list[j][0]:
105 a = irreducibles_list[i]
106 break
107 Bg *= a ^ (exps[j]/(l^d[maxi]))
108 B[maxi] = Bg
109 M[maxi] = [ x[1] for x in list( Q4.ideal(Bg).factor() ) ]
110 u = b[maxi] / (Bg^(l^d[maxi]))
111 if not u.is_unit():
112 print "Error: new element is not the right power of B."
113 print "New el.:", b[maxi], ", B:", Bg, ", exponent:", l^d[maxi]
114 if u == 1:
115 h[maxi] = 0
116 elif u == -1:
117 h[maxi] = 1
118 else:
119 h[maxi] = 2
120
121 return [(d[i],h[i]) for i in range(len(d))]
122
123

Generated with cgit - Back to sebastiano.tronto.net