Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/ext/pari/simon/ellQ.gp
8820 views
1
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
2
\\ Copyright (C) 2008 Denis Simon
3
\\
4
\\ Distributed under the terms of the GNU General Public License (GPL)
5
\\
6
\\ This code is distributed in the hope that it will be useful,
7
\\ but WITHOUT ANY WARRANTY; without even the implied warranty of
8
\\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9
\\ General Public License for more details.
10
\\
11
\\ The full text of the GPL is available at:
12
\\
13
\\ http://www.gnu.org/licenses/
14
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
15
16
\\
17
\\ Auteur:
18
\\ Denis SIMON -> [email protected]
19
\\ adresse du fichier:
20
\\ www.math.unicaen.fr/~simon/ellQ.gp
21
\\
22
\\ *********************************************
23
\\ * VERSION 29/04/2008 *
24
\\ *********************************************
25
\\
26
\\ Programme de calcul du rang des courbes elliptiques sur Q.
27
\\ langage: GP
28
\\ pour l'utiliser, lancer gp, puis taper
29
\\ \r ellQ.gp
30
\\
31
\\ Ce programme utilise le module de resolution des formes quadratiques
32
\\ situe a l'adresse
33
\\ www.math.unicaen.fr/~simon/qfsolve.gp
34
\\ Il faut donc aussi taper:
35
\\ \r qfsolve.gp
36
\\
37
\\ Explications succintes :
38
\\ La fonction ellrank() accepte toutes les courbes sous la forme
39
\\ [a1,a2,a3,a4,a6]
40
\\ Les coefficients peuvent etre entiers ou non.
41
\\ L'algorithme utilise est celui de la 2-descente.
42
\\ La 2-torsion peut etre quelconque.
43
\\ Il suffit de taper :
44
\\
45
\\ gp > ell = [a1,a2,a3,a4,a6];
46
\\ gp > ellrank(ell)
47
\\
48
\\ Retourne un vecteur [r,s,vec]
49
\\ ou r est le rang probable (c'est toujours une minoration du rang),
50
\\ s est le 2-rang du groupe de Selmer,
51
\\ vec est une liste de points independants dans E(Q)/2E(Q).
52
\\
53
\\ Courbes de la forme: k*y^2 = x^3+A*x^2+B*x+C
54
\\ sans 2-torsion, A,B,C entiers.
55
\\ gp > bnf = bnfinit(x^3+A*x^2+B*x+C);
56
\\ gp > ell = ellinit([0,A,0,B,C],1);
57
\\ gp > rank = ell2descent_gen(ell,bnf,k);
58
\\
59
\\ Courbes avec #E[2](Q) >= 2:
60
\\ ell doit etre sous la forme
61
\\ y^2 = x^3 + A*^2 + B*x
62
\\ avec A et B entiers.
63
\\ gp > ell = [0,A,0,B,0]
64
\\ gp > ell2descent_viaisog(ell)
65
\\ = algorithme de la 2-descente par isogenies
66
\\ Attention A et B doivent etre entiers
67
\\
68
\\ Courbes avec #E[2](Q) = 4: y^2 = (x-e1)*(x-e2)*(x-e3)
69
\\ gp > ell2descent_complete(e1,e2,e3)
70
\\ = algorithme de la 2-descente complete
71
\\ Attention: les ei doivent etre entiers.
72
\\
73
\\
74
\\ On peut avoir plus ou moins de details de calculs avec
75
\\ DEBUGLEVEL_ell = 0;
76
\\ DEBUGLEVEL_ell = 1; 2; 3;...
77
\\
78
\\
79
\\
80
81
{
82
\\
83
\\ Variables globales usuelles
84
\\
85
86
DEBUGLEVEL_ell = 1; \\ pour avoir plus ou moins de details
87
LIM1 = 5; \\ limite des points triviaux sur les quartiques
88
LIM3 = 50; \\ limite des points sur les quartiques ELS
89
LIMTRIV = 50; \\ limite des points triviaux sur la courbe elliptique
90
91
\\
92
\\ Variables globales techniques
93
\\
94
95
MAXPROB = 20;
96
LIMBIGPRIME = 30; \\ pour distinguer un petit nombre premier d'un grand
97
\\ utilise un test probabiliste pour les grands
98
\\ si LIMBIGPRIME = 0, n'utilise aucun test probabiliste
99
ELLREDGENFLAG = 1;\\ pour reduire les genereteurs a la fin de l'algorithme
100
}
101
102
\\
103
\\ Programmes
104
\\
105
106
\\
107
\\ Fonctions communes ell.gp et ellQ.gp
108
\\
109
{
110
ellinverturst(urst) =
111
local(u = urst[1], r = urst[2], s = urst[3], t = urst[4]);
112
[1/u,-r/u^2,-s/u,(r*s-t)/u^3];
113
}
114
{
115
ellchangecurveinverse(ell,v) = ellchangecurve(ell,ellinverturst(v));
116
}
117
{
118
ellchangepointinverse(pt,v) = ellchangepoint(pt,ellinverturst(v));
119
}
120
{
121
ellcomposeurst(urst1,urst2) =
122
local(u1 = urst1[1], r1 = urst1[2], s1 = urst1[3], t1 = urst1[4],
123
u2 = urst2[1], r2 = urst2[2], s2 = urst2[3], t2 = urst2[4]);
124
[u1*u2,u1^2*r2+r1,u1*s2+s1,u1^3*t2+s1*u1^2*r2+t1];
125
}
126
{
127
ellinverturst(urst) =
128
local(u = urst[1], r = urst[2], s = urst[3], t = urst[4]);
129
[1/u,-r/u^2,-s/u,(r*s-t)/u^3];
130
}
131
{
132
ellchangecurveinverse(ell,v) = ellchangecurve(ell,ellinverturst(v));
133
}
134
{
135
ellchangepointinverse(pt,v) = ellchangepoint(pt,ellinverturst(v));
136
}
137
{
138
ellcomposeurst(urst1,urst2) =
139
local(u1 = urst1[1], r1 = urst1[2], s1 = urst1[3], t1 = urst1[4],
140
u2 = urst2[1], r2 = urst2[2], s2 = urst2[3], t2 = urst2[4]);
141
[u1*u2,u1^2*r2+r1,u1*s2+s1,u1^3*t2+s1*u1^2*r2+t1];
142
}
143
{
144
polratroots(pol) =
145
local(f,ans);
146
f = factor(pol)[,1];
147
ans = [];
148
for( j = 1, #f,
149
if( poldegree(f[j]) == 1,
150
ans = concat(ans,[-polcoeff(f[j],0)/polcoeff(f[j],1)])));
151
return(ans);
152
}
153
if( DEBUGLEVEL_ell >= 4, print("mysubst"));
154
{
155
mysubst(polsu,subsx) =
156
if( type(lift(polsu)) == "t_POL",
157
return(simplify(subst(lift(polsu),variable(lift(polsu)),subsx)))
158
, return(simplify(lift(polsu))));
159
}
160
if( DEBUGLEVEL_ell >= 4, print("degre"));
161
{
162
degre(idegre) =
163
local(ideg,jdeg);
164
165
ideg = idegre; jdeg = 0;
166
while( ideg >>= 1, jdeg++);
167
return(jdeg);
168
}
169
if( DEBUGLEVEL_ell >= 4, print("nfissquare"));
170
{
171
nfissquare(nf, a) = #nfsqrt(nf,a) > 0;
172
}
173
if( DEBUGLEVEL_ell >= 4, print("nfsqrt"));
174
{
175
nfsqrt( nf, a) =
176
\\ si a est un carre, renvoie [sqrt(a)], sinon [].
177
local(alift,ta,res,pfact,r1,py);
178
179
if( DEBUGLEVEL_ell >= 5, print("entree dans nfsqrt ",a));
180
if( a==0 || a==1,
181
if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt"));
182
return([a]));
183
184
alift = lift(a);
185
ta = type(a);
186
if( !poldegree(alift), alift = polcoeff(alift,0));
187
188
if( type(alift) != "t_POL",
189
if( issquare(alift),
190
if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt"));
191
return([sqrtrat(alift)])));
192
193
if( poldegree(nf.pol) <= 1,
194
if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt"));
195
return([]));
196
if( ta == "t_POL", a = Mod(a,nf.pol));
197
198
\\ tous les plgements reels doivent etre >0
199
\\
200
r1 = nf.sign[1];
201
for( i = 1, r1,
202
py = mysubst(alift,nf.roots[i]);
203
if( sign(py) < 0,
204
if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt"));
205
return([])));
206
\\ factorisation sur K du polynome X^2-a :
207
if( variable(nf.pol) == x,
208
py = subst(nf.pol,x,y);
209
pfact = lift(factornf(x^2-mysubst(alift,Mod(y,py)),py)[1,1])
210
,
211
pfact = lift(factornf(x^2-a,nf.pol)[1,1]));
212
if( poldegree(pfact) == 2,
213
if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt"));
214
return([]));
215
if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt"));
216
return([subst(polcoeff(pfact,0),y,Mod(variable(nf.pol),nf.pol))]);
217
}
218
if( DEBUGLEVEL_ell >= 4, print("sqrtrat"));
219
{
220
sqrtrat(a) =
221
sqrtint(numerator(a))/sqrtint(denominator(a));
222
}
223
\\
224
\\ Fonctions propres a ellQ.gp
225
\\
226
227
if( DEBUGLEVEL_ell >= 4, print("ellhalf"));
228
{
229
ellhalf(ell,P)=
230
\\ renvoie tous les points Q sur ell tels que 2Q = P.
231
local(pol2,ratroots,half,x2,y2,P2);
232
233
if(#ell < 13, ell=ellinit(ell,1));
234
235
pol2 = Pol([4,ell.b2,2*ell.b4,ell.b6]); \\ polynome de 2-division
236
237
if( P == [0],
238
ratroots = polratroots(pol2);
239
half = vector(#ratroots,i,[ratroots[i],ellordinate(ell,ratroots[i])[1]]);
240
half = concat( [[0]], half);
241
return(half)
242
);
243
244
x2=Pol([1,0,-ell.b4,-2*ell.b6,-ell.b8]); \\ x(2P) = x2/pol2
245
246
half = [];
247
ratroots = polratroots(x2-P[1]*pol2);
248
if( #ratroots == 0, return(half));
249
for( i = 1, #ratroots,
250
y2 = ellordinate(ell,ratroots[i]);
251
for( j = 1, #y2,
252
P2 = [ratroots[i],y2[j]];
253
if( ellpow(ell,P2,2) == P, half = concat(half,[P2]))
254
)
255
);
256
return(half);
257
}
258
if( DEBUGLEVEL_ell >= 4, print("elltors2"));
259
{
260
elltors2(ell)=
261
\\ Calcule le sous-groupe de 2-torsion de la courbe elliptique ell.
262
local(pol2,ratroots,tors2);
263
264
if( DEBUGLEVEL_ell >= 4, print("calcul de la 2-torsion"));
265
if(#ell < 13, ell=ellinit(ell,1));
266
tors2 = ellhalf(ell,[0]);
267
if( #tors2 == 1,
268
tors2 = [1, [], []],
269
if( #tors2 == 2,
270
tors2 = [2, [2], [tors2[2]]]
271
, tors2 = [4, [2,2], [tors2[2],tors2[3]]]
272
));
273
if( DEBUGLEVEL_ell >= 4, print("E[2] = ",tors2));
274
return(tors2);
275
}
276
if( DEBUGLEVEL_ell >= 4, print("elltorseven"));
277
{
278
elltorseven(ell)=
279
\\ Calcule le 2-Sylow sous-groupe de torsion de la courbe elliptique ell.
280
local(torseven,P2);
281
282
if( DEBUGLEVEL_ell >= 4, print("calcul de la 2^n-torsion"));
283
if(#ell < 13, ell=ellinit(ell,1));
284
torseven = elltors2(ell);
285
286
while( torseven[1] != 1,
287
P2 = ellhalf(ell,torseven[3][1]);
288
if( #P2 > 0,
289
torseven[1] *= 2;
290
torseven[2][1] *= 2;
291
torseven[3][1] = P2[1];
292
next
293
);
294
if( #torseven[3] == 1, break());
295
296
P2 = ellhalf(ell,torseven[3][2]);
297
if( #P2 > 0,
298
torseven[1] *= 2;
299
torseven[2][2] *= 2;
300
torseven[3][2] = P2[1];
301
next
302
);
303
P2 = ellhalf(ell,elladd(ell,torseven[3][1],torseven[3][2]));
304
if( #P2 > 0,
305
torseven[1] *= 2;
306
torseven[2][1] *= 2;
307
torseven[3][1] = P2[1];
308
next
309
);
310
break()
311
);
312
313
if( DEBUGLEVEL_ell >= 4, print("E[2^n] = ",torseven));
314
return(torseven);
315
}
316
if( DEBUGLEVEL_ell >= 4, print("polratroots"));
317
{
318
polratroots(pol) =
319
local(f,ans);
320
f = factor(pol)[,1];
321
ans=[];
322
for( j = 1, #f,
323
if( poldegree(f[j]) == 1,
324
ans = concat(ans,[-polcoeff(f[j],0)/polcoeff(f[j],1)])));
325
return(ans);
326
}
327
if( DEBUGLEVEL_ell >= 4, print("ratpoint"));
328
{
329
ratpoint(pol,lim=1,singlepoint=1,tryhard=0) =
330
\\ Recherche de points sur y^2=pol(x).
331
\\ Les coeff de pol sont entiers.
332
\\ Si singlepoint >= 1, cherche un seul point, sinon plusieurs.
333
\\ Si tryhard == 1, on essaye une autre strategie quand pol est imprimitif.
334
335
local(listpoints,point1,odd,deg4,pol16,tab16,pol9,tab9,pol5,tab5,pol0,vecz,vecx,lead,zz,xx,x16,x9,x5,evpol,ix,iz,K,factK,e,cont,ind,p,sol,factpol,r,M,U);
336
337
if( DEBUGLEVEL_ell >= 4, print("entree dans ratpoint avec pol = ",pol); print("lim = ",lim););
338
if( !singlepoint, listpoints = []);
339
point1 = [];
340
341
\\ cas triviaux
342
if( issquare(pollead(pol)),
343
point1 = [ 1, sqrtrat(pollead(pol)), 0];
344
if( DEBUGLEVEL_ell >= 3, print("solution triviale: a est un carre"));
345
if( singlepoint,
346
if( DEBUGLEVEL_ell >= 4, print("fin de ratpoint"));
347
return(point1));
348
listpoints = concat(listpoints,[point1]));
349
if( issquare(polcoeff(pol,0)),
350
point1 = [ 0, sqrtrat(polcoeff(pol,0)) ];
351
if( DEBUGLEVEL_ell >= 3, print("solution triviale: e est un carre"));
352
if( singlepoint,
353
if( DEBUGLEVEL_ell >= 4, print("fin de ratpoint"));
354
return(point1));
355
listpoints = concat(listpoints,[point1]));
356
odd = poldegree(pol)%2;
357
deg4 = poldegree(pol) == 4;
358
359
\\ initialisation du crible modulo 16, 9 et 5
360
if( deg4,
361
pol16 = (Vec(pol)*Mod(1,16))~;
362
tab16 = matrix(16,16);
363
for(xx = 0, 16-1,
364
for(zz = 0, 16-1,
365
tab16[xx+1,zz+1] = !issquare([xx^4,xx^3*zz,xx^2*zz^2,xx*zz^3,zz^4]*pol16)));
366
pol9 = (Vec(pol)~)*Mod(1,9);
367
tab9 = matrix(9,9);
368
for(xx = 0, 9-1,
369
for(zz = 0, 9-1,
370
tab9[xx+1,zz+1] = !issquare([xx^4,xx^3*zz,xx^2*zz^2,xx*zz^3,zz^4]*pol9)));
371
pol5 = (Vec(pol)~)*Mod(1,5);
372
tab5 = matrix(5,5);
373
for(xx = 0, 5-1,
374
for(zz = 0, 5-1,
375
tab5[xx+1,zz+1] = !issquare([xx^4,xx^3*zz,xx^2*zz^2,xx*zz^3,zz^4]*pol5)))
376
);
377
378
lead = pollead(pol);
379
pol0 = polcoeff(pol,0);
380
381
if( odd,
382
vecz = vector(lim,i,i^2);
383
,
384
\\ si le degre de pol est pair, il faut que le coeff dominant soit
385
\\ un carre mod zz.
386
vecz = vector(lim);
387
zz = 0;
388
for( i = 1, lim,
389
zz++; while( !issquare(Mod(lead,zz)),zz++); vecz[i] = zz
390
));
391
\\ le coeff constant doit etre un carre mod xx.
392
vecx = vector(lim);
393
xx = 0;
394
for( i = 1, lim,
395
xx++; while( !issquare(Mod(pol0,xx)),xx++); vecx[i] = xx);
396
397
if( DEBUGLEVEL_ell >= 4, print("xmax = ",vecx[lim]));
398
if( DEBUGLEVEL_ell >= 4, print("zmax = ",vecz[lim]));
399
400
if( DEBUGLEVEL_ell >= 5, print("vecx = ",vecx));
401
if( DEBUGLEVEL_ell >= 5, print("vecz = ",vecz));
402
403
\\ boucle sur x = xx/zz
404
for( somme = 2, 2*lim,
405
for( ix = max(1,somme-lim), min(lim,somme-1),
406
xx = vecx[ix]; iz = somme-ix; zz = vecz[iz];
407
if( gcd(zz,xx) > 1, next);
408
if( odd && !issquare(lead*Mod(xx,zz)), next);
409
for( eps = 1, 2, if( eps == 2, zz = -zz);
410
if( deg4 &&
411
(tab16[xx%16+1,zz%16+1] || tab9[xx%9+1,zz%9+1] || tab5[xx%5+1,zz%5+1])
412
, next);
413
evpol = subst(pol,variable(pol),xx/zz);
414
if( issquare(evpol),
415
point1 = [xx/zz,sqrtrat(evpol)];
416
if( singlepoint, break(3));
417
listpoints = concat(listpoints,[point1])
418
))));
419
420
if( point1 != [],
421
if( DEBUGLEVEL_ell >= 3, print("point trouve par ratpoint = ",point1));
422
if( DEBUGLEVEL_ell >= 4, print("sortie de ratpoint "));
423
if( singlepoint, return(point1), return(listpoints))
424
);
425
426
\\
427
\\ Essaye une autre strategie quand pol a un content non trivial
428
\\
429
430
if( !odd && tryhard,
431
if( DEBUGLEVEL_ell >= 4, print(" Autre strategie dans ratpoint **********"));
432
K = content(pol);
433
if( K != 1,
434
pol /= K;
435
factK = factor(K);
436
e = factK[,2]\2;
437
cont = factorback(factK[,1],e);
438
K /= cont^2;
439
if(K != 1,
440
e = factK[,2]%2;
441
ind = #e; while( !e[ind], ind--);
442
p = factK[ind,1];
443
if( valuation( pollead(pol), p) == 1 ||
444
( valuation( pollead(pol), p) >= 2 && valuation( polcoeff(pol,poldegree(pol)-1), p) == 0),
445
if( DEBUGLEVEL_ell >= 4, print(" utilise une racine de pol mod p = ",p));
446
sol = ratpoint(K/p^2*subst(polrecip(pol),variable(pol),p*variable(pol)),lim,singlepoint,1);
447
if( #sol > 0,
448
point1 = [ 1/(sol[1]*p),
449
sol[2]*cont*p/(p*sol[1])^(poldegree(pol)/2) ];
450
if( DEBUGLEVEL_ell >= 4, print("sortie de ratpoint ",point1));
451
return(point1)
452
)
453
);
454
factpol = factormod(pol,p)[,1];
455
for( i = 1, #factpol,
456
if( poldegree(factpol[i]) !=1, next);
457
if( DEBUGLEVEL_ell >= 4, print(" utilise une racine de pol mod p = ",p));
458
r = -centerlift(polcoeff(factpol[i],0));
459
if( valuation(subst(pol,variable(pol),r),p) > 2, next);
460
M = [p,r;0,1];
461
U = redquartique(subst(K*pol,variable(pol),p*variable(pol)+r));
462
if( content(U[1]) != p, next);
463
sol = ratpoint(K/p^2*U[1],lim,singlepoint,1);
464
if( #sol > 0,
465
M = (M*U[2])*[sol[1], #sol == 2]~;
466
point1 = [ M[1]/M[2], sol[2]*cont*p/M[2]^(poldegree(pol)/2) ];
467
if( DEBUGLEVEL_ell >= 4, print("sortie de ratpoint ",point1));
468
return(point1)
469
)
470
)
471
)
472
)
473
);
474
475
return([]);
476
}
477
if( DEBUGLEVEL_ell >= 5, print("psquare"));
478
{
479
psquare( a, p) =
480
local(ap,v);
481
482
if( DEBUGLEVEL_ell >= 5, print("entree dans psquare ",[a,p]));
483
\\ a est un entier
484
\\ renvoie 1 si a est un carre dans Zp 0 sinon
485
if( a == 0,
486
if( DEBUGLEVEL_ell >= 5, print("fin de psquare 1"));
487
return(1));
488
\\
489
v = valuation(a,p);
490
if( v%2,
491
if( DEBUGLEVEL_ell >= 5, print("fin de psquare 0"));
492
return(0));
493
if( p == 2,
494
ap = (a>>v)%8-1,
495
ap = kronecker(a/p^v,p)-1
496
);
497
if( DEBUGLEVEL_ell >= 5, print("fin de psquare ", !ap));
498
return(!ap);
499
}
500
if( DEBUGLEVEL_ell >= 4, print("lemma6"));
501
{
502
lemma6(pol, p, nu, xx) =
503
local(gx,gpx,lambda,mu);
504
505
\\ pour les p <> 2
506
gx = subst( pol, variable(pol), xx);
507
if( psquare(gx,p), return(1));
508
gpx = subst( pol', variable(pol), xx);
509
lambda = valuation(gx,p); mu = valuation(gpx,p);
510
511
if( lambda > 2*mu, return(1));
512
\\ if( (lambda >= mu+nu) && (nu > mu), return(1));
513
if( (lambda >= 2*nu) && (mu >= nu), return(0));
514
return(-1);
515
}
516
if( DEBUGLEVEL_ell >= 4, print("lemma7"));
517
{
518
lemma7( pol, nu, xx) =
519
local(gx,gpx,lambda,mu,q);
520
521
\\ pour p = 2
522
gx = subst( pol, variable(pol), xx);
523
if( psquare(gx,2), return(1));
524
gpx = subst( pol', variable(pol), xx);
525
lambda = valuation(gx,2); mu = valuation(gpx,2);
526
if( lambda > 2*mu, return(1));
527
if( nu > mu,
528
if( lambda%2, return(-1));
529
q = mu+nu-lambda;
530
if( q == 1, return(1));
531
if( q == 2 && (gx>>lambda)%4 == 1, return(1));
532
return(-1));
533
q = lambda-2*nu;
534
if( q >= 0, return(0));
535
if( q == -2 && (gx>>lambda)%4 == 1, return(0));
536
return(-1);
537
}
538
if( DEBUGLEVEL_ell >= 4, print("zpsoluble"));
539
{
540
zpsoluble(pol, p, nu, pnu, x0, pnup) =
541
local(result,pol2,fact,x1);
542
543
if( DEBUGLEVEL_ell >= 5, print("entree dans zpsoluble ",[pol,p,x0,nu]));
544
if( p == 2,
545
result = lemma7(pol,nu,x0),
546
result = lemma6(pol,p,nu,x0));
547
if( result == +1,
548
if( DEBUGLEVEL_ell >= 5, print("fin de zpsoluble 1 lemma"));
549
return(1));
550
if( result == -1,
551
if( DEBUGLEVEL_ell >= 5, print("fin de zpsoluble 0 lemma"));
552
return(0));
553
pnup = pnu*p;
554
nu++;
555
if( p< LIMBIGPRIME || !LIMBIGPRIME,
556
for( i = 0, p-1,
557
if( zpsoluble(pol,p,nu,pnup,x0+pnu*i),
558
if( DEBUGLEVEL_ell >= 5, print("fin de zpsoluble"));
559
return(1)))
560
,
561
pol2 = subst(pol,variable(pol),x0+pnu*variable(pol));
562
pol2 /= content(pol2);
563
pol2 = pol2*Mod(1,p);
564
if( !poldegree(pol2), return(0));
565
fact = factormod(pol2,p)[,1];
566
for( i = 1, #fact,
567
x1 = -centerlift(polcoeff(fact[i],0));
568
if( zpsoluble(pol,p,nu,pnup,x0+pnu*x1),
569
if( DEBUGLEVEL_ell >= 5, print("fin de zpsoluble"));
570
return(1)));
571
for( i = 1, MAXPROB,
572
x1 = random(p);
573
if( zpsoluble(pol,p,nu,pnup,x0+pnu*x1),
574
if( DEBUGLEVEL_ell >= 5, print("fin de zpsoluble"));
575
return(1)))
576
);
577
if( DEBUGLEVEL_ell >= 2,
578
if( p >= LIMBIGPRIME,
579
print("******* test probabiliste en p = ",p,"*******")));
580
if( DEBUGLEVEL_ell >= 5, print("fin de zpsoluble"));
581
return(0);
582
}
583
if( DEBUGLEVEL_ell >= 4, print("qpsoluble"));
584
{
585
qpsoluble(pol, p) =
586
if( DEBUGLEVEL_ell >= 5, print("entree dans qpsoluble ",p); print("pol = ",pol));
587
if( psquare(pollead(pol),p),
588
if( DEBUGLEVEL_ell >= 5, print("fin de qpsoluble 1"));
589
return(1));
590
if( psquare(polcoeff(pol,0),p),
591
if( DEBUGLEVEL_ell >= 5, print("fin de qpsoluble 1"));
592
return(1));
593
if( zpsoluble(pol,p,0,1,0),
594
if( DEBUGLEVEL_ell >= 5, print("fin de qpsoluble 1"));
595
return(1));
596
if( zpsoluble(polrecip(pol),p,1,p,0),
597
if( DEBUGLEVEL_ell >= 5, print("fin de qpsoluble 1"));
598
return(1));
599
if( DEBUGLEVEL_ell >= 5, print("fin de qpsoluble 0"));
600
return(0);
601
}
602
if( DEBUGLEVEL_ell >= 4, print("locallysoluble"));
603
{
604
locallysoluble(pol) =
605
\\ teste l'existence locale de solutions de y^2 = pol(x,z)
606
local(plist,disc0,p,c,vc);
607
608
if( DEBUGLEVEL_ell >= 4, print("entree dans locallysoluble :",pol));
609
610
\\ place reelle
611
if( !(poldegree(pol)%2) && sign(pollead(pol)) < 0
612
&& sign(polcoeff(pol,0)) < 0 && polsturm(pol) == 0,
613
if( DEBUGLEVEL_ell >= 3, print(" non ELS a l'infini"));
614
if( DEBUGLEVEL_ell >= 4, print("fin de locallysoluble"));
615
return(0));
616
617
\\
618
\\ places finies de plist */
619
\\
620
pol *= denominator(content(pol))^2;
621
c = content(pol);
622
623
disc0 = poldisc(pol);
624
plist = factor (abs(2*disc0));
625
if( DEBUGLEVEL_ell >= 4, print("liste de premiers = ",plist));
626
for( i = 1, #plist[,1],
627
p = plist[i,1];
628
if( DEBUGLEVEL_ell >= 4, print("p = ",p));
629
vc = valuation(c,p);
630
if( vc >= 2,
631
pol /= p^(2*(vc\2));
632
plist[i,2] -= 2*(vc\2)*(2*poldegree(pol)-2)
633
);
634
if( poldegree(pol) == 4 && p != 2 && plist[i,2] < 2, next);
635
if( !qpsoluble(pol,p),
636
if( DEBUGLEVEL_ell >= 3, print(" non ELS en ",p));
637
if( DEBUGLEVEL_ell >= 4, print("fin de locallysoluble"));
638
return(0)));
639
640
if( DEBUGLEVEL_ell >= 2, print(" quartique ELS"));
641
if( DEBUGLEVEL_ell >= 4, print("fin de locallysoluble"));
642
return(1);
643
}
644
if( DEBUGLEVEL_ell >= 4, print("redquartique"));
645
{
646
redquartique(pol) =
647
\\ reduction d'une quartique.
648
\\ ou plus generalement d'un polynome de degre deg.
649
local(prec,prec0,d,disc2,test,normderiv,disc2v,r,q,M);
650
651
if( DEBUGLEVEL_ell >= 4, print("entree dans redquartique"));
652
if( DEBUGLEVEL_ell >= 3, print(" reduction de la quartique ",pol));
653
654
\\ choix de la precision des calculs.
655
prec = prec0 = default(realprecision);
656
d = poldegree(pol);
657
disc2 = poldisc(pol)^2;
658
test = 0;
659
while( test == 0,
660
if( DEBUGLEVEL_ell >= 4, print(" precision = ",prec));
661
r = polroots(pol);
662
normderiv = vector( d, i, norm(subst(pol',variable(pol),r[i])));
663
disc2v = prod( i = 1, d, normderiv[i]) * pollead(pol)^(2*d-4);
664
test = abs(disc2v-disc2) < 10^(-prec\2);
665
if( !test, default(realprecision, prec *= 2))
666
);
667
668
\\ On n'utilise plus
669
\\ q = Vec(sum( i = 1, d, norm(x-r[i])));
670
\\ mais la normalisation de Cremona-Stoll
671
q = Vec(sum( i = 1, d, norm(x-r[i]) / normderiv[i]^(1/(d-2))));
672
M = QfbReduce([q[1],q[2]/2;q[2]/2,q[3]]);
673
pol = subst(pol,variable(pol),Pol(M[1,])/Pol(M[2,]))*Pol(M[2,])^poldegree(pol);
674
675
if( prec != prec0, default(realprecision,prec0));
676
677
if( DEBUGLEVEL_ell >= 3, print(" quartique reduite = ",pol));
678
if( DEBUGLEVEL_ell >= 4, print("sortie de redquartique"));
679
680
return([pol,M]);
681
}
682
if( DEBUGLEVEL_ell >= 4, print("reducemodsquares"));
683
{
684
reducemodsquares(delta,d) =
685
\\ reduction du coefficient de x^d dans ( delta modulo les carres )
686
local(deg,xx,z,qd,Qd,reduc);
687
688
deg = poldegree(delta.mod);
689
xx = Mod(x,delta.mod);
690
z = subst(Pol(vector(deg,i,eval(Str("a"i)))),x,xx);
691
qd = polcoeff(lift(delta*z^2),d,x);
692
Qd = simplify(matrix(deg,deg,i,j,deriv(deriv(qd,eval(Str("a"i))),eval(Str("a"j)))/2));
693
694
reduc = IndefiniteLLL(Qd);
695
if( #reduc == 2, reduc = reduc[2][,1]);
696
697
return(delta*subst(Pol(reduc),x,xx)^2);
698
}
699
if( DEBUGLEVEL_ell >= 4, print("ellsort"));
700
{
701
ellsort(listpts) =
702
\\ tri des points listpts sur une courbe elliptique
703
\\ suivant la hauteur naive.
704
local(n,v,aux,ord);
705
706
v = vector(n = #listpts);
707
for( i = 1, n,
708
if( listpts[i] == [0], v[i] = [0,0,0]; next);
709
aux = denominator(listpts[i][2])/denominator(listpts[i][1]);
710
v[i] = vecsort(abs([listpts[i][1]*aux^2, listpts[i][2]*aux^3,aux]),,4);
711
);
712
ord = vecsort(v,,3);
713
return(vector(n,i,listpts[ord[i]]));
714
}
715
if( DEBUGLEVEL_ell >= 4, print("ellredgen"));
716
{
717
ellredgen(ell,listgen,K=1) =
718
\\ reduction des generateurs de listgen
719
\\ sur la courbe ell = [a1,a2,a3,a4,a6]
720
\\ ou K*y^2 = x^3 + a2*x^2 + a4*x + a6 (lorsque a1 = a3 = 0);
721
local(d,sqrtK,urst,M,U,limgoodrelations,listgen2);
722
723
if( DEBUGLEVEL_ell >= 3, print("Reduction des generateurs ",listgen));
724
if( DEBUGLEVEL_ell >= 5, print("ell=",ell));
725
d = #listgen;
726
if( d == 0, return([]));
727
728
if( #ell < 19, ell = ellinit(ell));
729
if( K != 1,
730
if( ell.a1 != 0 || ell.a3 != 0, error(" ellredgen : a1*a3 != 0"));
731
ell[2] *= K; ell[4] *= K^2; ell[5] *= K^3;
732
ell[6] *= K; ell[7] *= K^2; ell[8] *= K^3; ell[9] *= K^4;
733
ell[10] *= K^2; ell[11] *= K^3; ell[12] *= K^6;
734
sqrtK = sqrt(K);
735
ell[14] *= K;
736
ell[15] /= sqrtK; ell[16] /= sqrtK;
737
ell[17] *= sqrtK; ell[18] *= sqrtK;
738
ell[19] /= K;
739
740
for( i = 1, d,
741
for( j = 1, #listgen[i],
742
listgen[i][j] *= K^j))
743
);
744
745
ell = ellminimalmodel(ell,&urst);
746
listgen = ellchangepoint(listgen,urst);
747
748
\\ Recherche des relations entre les points de listgen
749
\\ par recherche du noyau de la matrice des hauteurs
750
751
M = ellheightmatrix(ell,listgen);
752
if( DEBUGLEVEL_ell >= 4, print("matrice des hauteurs = ",M));
753
M = round( M*10^(default(realprecision)-10) );
754
U = qflll(M,4);
755
U = concat(U[1],U[2]);
756
757
/* BEGIN patch to work with PARI 2.4.4 */
758
/* AUTHORS: John Cremona, Jeroen Demeyer (Sage Trac #11130) */
759
if( DEBUGLEVEL_ell >= 4, print(" change of basis proposed by LLL = ",U));
760
\\ The columns of U that have very small coefficients (coeff < 20)
761
\\ are either exact relations or reductions. These are the ones we
762
\\ want to keep, the other ones are irrelevant.
763
keep = 0;
764
for( i = 1, d,
765
if( vecmax(abs(U[,i])) < 20, keep += 1<<(i-1))
766
);
767
U = vecextract(U, keep);
768
/* END patch from Sage Ticket #11130 to work with PARI 2.4.4 */
769
770
U = completebasis(U);
771
if( DEBUGLEVEL_ell >= 4, print("changement de base = ",U));
772
773
listgen2 = vector(d);
774
for( i = 1, d,
775
listgen2[i] = [0];
776
for( j = 1, d,
777
listgen2[i] = elladd(ell,listgen2[i],ellpow(ell,listgen[j],U[j,i]))));
778
listgen = listgen2;
779
780
\\ Tri des points d'ordre infini
781
782
listgen2 = [];
783
for( i = 1, d,
784
if( !ellorder(ell,listgen[i]),
785
listgen2 = concat(listgen2,[listgen[i]])));
786
listgen = listgen2;
787
if( DEBUGLEVEL_ell >= 3, print("points d'ordre infini = ",listgen));
788
d = #listgen;
789
if( d == 0, return([]));
790
791
\\ Reduction des points d'ordre infini
792
793
if( d > 1,
794
M = ellheightmatrix(ell,listgen);
795
if( DEBUGLEVEL_ell >= 4, print("matrice des hauteurs = ",M));
796
U = qflllgram(M);
797
if( DEBUGLEVEL_ell >= 4, print("changement de base = ",U));
798
799
listgen2 = vector(d);
800
for( i = 1, d,
801
listgen2[i] = [0];
802
for( j = 1, d,
803
listgen2[i] = elladd(ell,listgen2[i],ellpow(ell,listgen[j],U[j,i]))));
804
listgen = listgen2
805
);
806
807
listgen = ellsort(listgen);
808
if( DEBUGLEVEL_ell >= 4, print("generateurs tries = ",listgen));
809
810
listgen = ellchangepointinverse(listgen,urst);
811
if( K != 1,
812
for( i = 1, d,
813
for( j = 1, 2,
814
listgen[i][j] /= K^j)));
815
816
\\ on ne garde que les points (x,y) avec y >= 0
817
818
if( ell.a1 == 0 && ell.a3 == 0,
819
for( i = 1, d,
820
if( #listgen[i] == 2,
821
listgen[i][2] = abs(listgen[i][2]))));
822
823
if( DEBUGLEVEL_ell >= 2, print("generateurs reduits = ",listgen));
824
return(listgen);
825
}
826
if( DEBUGLEVEL_ell >= 4, print("ell2descent_gen"));
827
{
828
ell2descent_gen(ell,ext,K=1,help=[],redflag=0) =
829
\\ si ell= K*y^2=P(x), alors ext est le buchinitfu de l'extension.
830
\\ theta est une racine de P.
831
\\ dans la suite ext est note L = Q(theta).
832
\\ help est une liste de points deja connus sur ell.
833
\\ ell est de la forme K*y^2=x^3+A*x^2+B*x+C */
834
\\ ie ell=[0,A,0,B,C], avec A,B et C entiers */
835
\\
836
\\ si redflag != 0, on utilise la reduction modulo les carres.
837
\\
838
839
local(A,B,C,S,SLprod,SLlist,aux,oddclass,LS2gen,fact,trouve,i,polrel,ttheta,polprime,KS2gen,LS2genunit,normLS2gen,normcoord,LS2coordtilda,LS2,listgen,listpoints,listpointstriv,listpointsmwr,list,m1,m2,lastloc,maskwhile,iwhile,zc,j,iaux,liftzc,den,ispointtriv,point,found,idealfactorzc,idealzc,baseidealzc,q2,sol,q1,param,pol,redq,q0,pointxx,point2,v,rang);
840
841
if( DEBUGLEVEL_ell >= 4, print("entree dans ell2descent_gen"));
842
843
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
844
\\ construction de L(S,2) \\
845
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
846
847
if( #ell < 13, ell = ellinit(ell,1));
848
849
if( ell.a1 != 0 || ell.a3 != 0,
850
error(" ell2descent_gen : la courbe n'est pas sous la forme [0,a,0,b,c]"));
851
if( denominator(ell.a2) > 1 || denominator(ell.a4) > 1 || denominator(ell.a6) >1,
852
error(" ell2descent_gen : coefficients non entiers"));
853
854
A = ell.a2; if( DEBUGLEVEL_ell >= 2, print("A = ",A));
855
B = ell.a4; if( DEBUGLEVEL_ell >= 2, print("B = ",B));
856
C = ell.a6; if( DEBUGLEVEL_ell >= 2, print("C = ",C));
857
858
polrel = Pol([1,A,B,C]);
859
if( !ext,
860
if( DEBUGLEVEL_ell >= 2, print("bnfinit(",polrel,")"));
861
ext = bnfinit(polrel,1));
862
863
S = -abs(K*ext.index);
864
SLprod = idealmul(ext,K,idealadd(ext,ext.pol',ext.index));
865
SLlist = idealfactor(ext,SLprod)[,1]~;
866
aux = []; SLprod = 1;
867
for( i = 1, #SLlist,
868
if( !(K%SLlist[i][1]) || valuation(ext.index,SLlist[i][1]),
869
SLprod = idealmul(ext,SLprod,SLlist[i]);
870
aux = concat(aux,[SLlist[i]])));
871
SLlist = aux;
872
oddclass = 0;
873
while( !oddclass,
874
\\ Constructoin de S:
875
if( DEBUGLEVEL_ell >= 4, print("SLlist = ",SLlist));
876
\\ Construction des S-unites
877
LS2gen = bnfsunit(ext,SLlist);
878
if( DEBUGLEVEL_ell >= 4, print("LS2gen = ",LS2gen));
879
\\ on ajoute la partie paire du groupe de classes.
880
oddclass = LS2gen[5][1]%2;
881
if( !oddclass,
882
if( DEBUGLEVEL_ell >= 3, print("Groupe de classes pair"));
883
if( DEBUGLEVEL_ell >= 4, print(LS2gen[5]));
884
S *= LS2gen[5][3][1][1,1];
885
SLprod = idealmul(ext,SLprod,LS2gen[5][3][1]);
886
fact = idealfactor(ext,LS2gen[5][3][1])[,1];
887
trouve = 0; i = 0;
888
while( !trouve,
889
i++; trouve = 1;
890
for( j = 1, #SLlist,
891
if( SLlist[j] == fact[i], trouve = 0; break)));
892
SLlist = concat(SLlist,[fact[i]]))
893
);
894
895
if( DEBUGLEVEL_ell >= 4, print("S = ",S));
896
897
ttheta = Mod(x,polrel); \\ ttheta est la racine de P(x)
898
polprime = Mod(polrel',polrel);
899
900
KS2gen = factor(S)[,1]~;
901
902
if( DEBUGLEVEL_ell >= 3, print("#KS2gen = ",#KS2gen));
903
if( DEBUGLEVEL_ell >= 3, print("KS2gen = ",KS2gen));
904
905
LS2genunit = ext.tufu;
906
LS2genunit = concat(LS2gen[1],LS2genunit);
907
908
LS2genunit = subst(LS2genunit,x,ttheta);
909
LS2genunit = LS2genunit*Mod(1,polrel);
910
if( DEBUGLEVEL_ell >= 3, print("#LS2genunit = ",#LS2genunit));
911
if( DEBUGLEVEL_ell >= 3, print("LS2genunit = ",LS2genunit));
912
913
\\ dans LS2gen, on ne garde que ceux dont la norme
914
\\ est un carre.
915
916
normLS2gen = norm(LS2genunit);
917
if( DEBUGLEVEL_ell >= 4, print("normLS2gen = ",normLS2gen));
918
919
\\ matrice de l'application norme
920
921
normcoord = matrix(#KS2gen,#normLS2gen);
922
for( j = 1, #normLS2gen,
923
normcoord[1,j] = (sign(normLS2gen[j]) < 0);
924
for( i = 2, #KS2gen,
925
normcoord[i,j] = valuation(normLS2gen[j],KS2gen[i])));
926
if( DEBUGLEVEL_ell >= 4, print("normcoord = ",normcoord));
927
928
\\ construction du noyau de la norme
929
930
LS2coordtilda = lift(matker(normcoord*Mod(1,2)));
931
if( DEBUGLEVEL_ell >= 4, print("LS2coordtilda = ",LS2coordtilda));
932
LS2 = vector(#LS2coordtilda[1,],i,0);
933
for( i = 1, #LS2coordtilda[1,],
934
aux = 1;
935
for( j = 1, #LS2coordtilda[,i],
936
if( sign(LS2coordtilda[j,i]),
937
aux *= LS2genunit[j]));
938
LS2[i] = aux
939
);
940
if( DEBUGLEVEL_ell >= 3, print("LS2 = ",LS2));
941
if( DEBUGLEVEL_ell >= 3, print("norm(LS2) = ",norm(LS2)));
942
943
\\ Reduction des generateurs de LS2
944
945
if( redflag,
946
for( i = 1, #LS2,
947
LS2[i] = reducemodsquares(LS2[i],2)));
948
949
\\ Fin de la construction de LS2
950
951
listgen = LS2;
952
if( DEBUGLEVEL_ell >= 2, print("LS2gen = ",listgen));
953
if( DEBUGLEVEL_ell >= 2, print("#LS2gen = ",#listgen));
954
listpoints = [];
955
956
if( DEBUGLEVEL_ell >= 3, print("(A,B,C) = ",[A,B,C]));
957
958
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
959
\\ Recherche de points triviaux. \\
960
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
961
962
if( DEBUGLEVEL_ell >= 2, print("Recherche de points triviaux sur la courbe"));
963
listpointstriv = ratpoint(K^3*subst(polrel,x,x/K),LIMTRIV,0,0);
964
for( i = 1, #listpointstriv,
965
if( #listpointstriv[i] == 3,
966
listpointstriv[i] = [0]
967
, for( j = 1, 2, listpointstriv[i][j] /= K^j))
968
);
969
listpointstriv = concat(help,listpointstriv);
970
if( DEBUGLEVEL_ell >= 1, print("Points triviaux sur la courbe = ",listpointstriv));
971
972
973
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
974
\\ parcours de L(S,2) \\
975
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
976
977
listpointsmwr = [];
978
list = [ 6, ell.disc, 0 ];
979
m1 = 0; m2 = 0; lastloc = -1;
980
maskwhile = 1<<#listgen;
981
iwhile = 1;
982
while( iwhile < maskwhile,
983
if( DEBUGLEVEL_ell >= 4, print("iwhile = ",iwhile); print("listgen = ",listgen));
984
zc = Mod(1,polrel); j = 1; iaux = iwhile;
985
while( iaux,
986
if( iaux%2, zc *= listgen[j]);
987
iaux >>= 1; j++);
988
if( DEBUGLEVEL_ell >= 2, print(); print("zc = ",zc));
989
liftzc = lift(zc);
990
if( redflag,
991
zc = reducemodsquares(zc,2);
992
liftzc = lift(zc);
993
den = denominator(content(liftzc))^2;
994
zc *= den; liftzc *= den;
995
if( DEBUGLEVEL_ell >= 2, print("zcred = ",zc))
996
);
997
998
\\ Est-ce un point trivial ?
999
ispointtriv = 0;
1000
for( i = 1, #listpointstriv,
1001
point = listpointstriv[i];
1002
if( #point == 2,
1003
if( nfissquare(ext.nf,K*(point[1]-x)*liftzc),
1004
if( DEBUGLEVEL_ell >= 2, print(" vient du point trivial ",point));
1005
listpointsmwr = concat(listpointsmwr,[point]);
1006
m1++;
1007
if( degre(iwhile) > lastloc, m2++);
1008
found = (ispointtriv = 1);
1009
break
1010
)));
1011
1012
\\ Ce n'est pas un point trivial
1013
if( !ispointtriv,
1014
\\ Il faut resoudre une forme quadratique
1015
\\ q2 = matrix(3,3,i,j,trace(zc*ttheta^(i+j-2)/polprime));
1016
\\if( DEBUGLEVEL_ell >= 4, print("q2 = ",q2));
1017
idealfactorzc = idealfactor(ext,zc);
1018
idealfactorzc[,2] *= -1;
1019
idealfactorzc[,2] \= 2;
1020
idealzc = idealfactorback(ext,idealfactorzc);
1021
if( idealzc == 1, idealzc = matid(3));
1022
baseidealzc = vector(3,i,nfbasistoalg(ext,idealzc[,i]));
1023
q2 = matrix(3,3,i,j,trace(zc*baseidealzc[i]*baseidealzc[j]/polprime));
1024
if( DEBUGLEVEL_ell >= 4, print("q2 = ",q2));
1025
\\ q2 *= ext.index;
1026
\\ if( DEBUGLEVEL_ell >= 4, print("q2 = ",q2));
1027
if( DEBUGLEVEL_ell >= 4, print("q2/content(q2) = ",q2/content(q2)));
1028
sol = Qfsolve(q2/content(q2));
1029
if( DEBUGLEVEL_ell >= 4,print("sol = ",sol));
1030
if( type(sol) == "t_INT",
1031
if( DEBUGLEVEL_ell >= 3, print("non ELS en ",sol));
1032
iwhile++; next
1033
);
1034
1035
\\ \\\\\\\\\\\
1036
\\ Construction de la quartique
1037
\\ \\\\\\\\\\\
1038
q1 = -matrix(3,3,i,j,trace(zc*baseidealzc[i]*baseidealzc[j]*(ttheta+A)/polprime));
1039
param = Qfparam(q2,sol)*[x^2,x,1]~;
1040
param /= content(param);
1041
pol = param~*q1*param;
1042
if( DEBUGLEVEL_ell >= 2, print(" quartique: ",K,"*Y^2 = ",pol));
1043
redq = redquartique(pol);
1044
if( DEBUGLEVEL_ell >= 2, print(" reduite: ",K,"*Y^2 = ",redq[1]));
1045
pol = redq[1];
1046
den = denominator(content(K*pol));
1047
pol *= den^2;
1048
1049
\\ \\\\\\\\\\\
1050
\\ Recherche de points sur la quartique
1051
\\ \\\\\\\\\\\
1052
1053
point = ratpoint(K*pol,LIM1,1,0);
1054
if( point != [],
1055
m1++;
1056
if( #point == 2, point = concat(point,[1]));
1057
point = concat(redq[2]*[point[1],point[3]]~,[point[2]/den]~);
1058
param = subst(param,x,x/y)*y^2;
1059
param = subst(subst(param,x,point[1]),y,point[2]);
1060
if( DEBUGLEVEL_ell >= 2, print(" point sur la quartique = ",point));
1061
param *= K/point[3];
1062
if( DEBUGLEVEL_ell >= 3, print("reconstruction du point sur la courbe"));
1063
q0 = matrix(3,3,i,j,trace(zc*baseidealzc[i]*baseidealzc[j]*(ttheta^2+A*ttheta+B)/polprime));
1064
pointxx = param~*q0*param/K;
1065
point2 = [ pointxx, sqrtrat(subst(x^3+A*x^2+B*x+C,x,pointxx)/K)];
1066
if( DEBUGLEVEL_ell >= 1, print("point sur la courbe = ",point2));
1067
listpointsmwr = concat(listpointsmwr,[point2]);
1068
if( degre(iwhile) > lastloc, m2++);
1069
found = 1
1070
,
1071
if( locallysoluble(K*pol),
1072
if( degre(iwhile) > lastloc, m2++; lastloc = degre(iwhile));
1073
point = ratpoint(K*pol,LIM3,1,1);
1074
if( #point > 0,
1075
m1++;
1076
if( #point == 2, point = concat(point,[1]));
1077
point = concat(redq[2]*[point[1],point[3]]~,[point[2]/den]~);
1078
param = subst(param,x,x/y)*y^2;
1079
param = subst(subst(param,x,point[1]),y,point[2]);
1080
if( DEBUGLEVEL_ell >= 3, print(" point sur la quartique = ",point));
1081
param *= K/point[3];
1082
if( DEBUGLEVEL_ell >= 3, print("reconstruction du point sur la courbe"));
1083
q0 = matrix(3,3,i,j,trace(zc*baseidealzc[i]*baseidealzc[j]*(ttheta^2+A*ttheta+B)/polprime));
1084
pointxx = param~*q0*param/K;
1085
point2 = [ pointxx, sqrtrat(subst(x^3+A*x^2+B*x+C,x,pointxx)/K)];
1086
if( DEBUGLEVEL_ell >= 1, print("point sur la courbe = ",point2));
1087
listpointsmwr = concat(listpointsmwr,[point2]);
1088
found = 1
1089
)
1090
)
1091
)
1092
);
1093
if( found || ispointtriv,
1094
found = 0; lastloc = -1;
1095
v = 0; iaux = (iwhile>>1);
1096
while( iaux, iaux >>= 1; v++);
1097
maskwhile >>= 1;
1098
listgen = vecextract(listgen,1<<#listgen-1<<v-1);
1099
iwhile = 1<<v
1100
, iwhile ++
1101
)
1102
);
1103
1104
if( DEBUGLEVEL_ell >= 2,
1105
print();
1106
print("rang des points trouves = ",m1);
1107
print("rang du groupe de Selmer = ",m2));
1108
if( DEBUGLEVEL_ell >= 1,
1109
print("#S(E/Q)[2] = ",1<<m2));
1110
if( m1 == m2,
1111
if( DEBUGLEVEL_ell >= 1,
1112
print("#E(Q)/2E(Q) = ",1<<m1);
1113
print("#III(E/Q)[2] = 1");
1114
print("rang(E/Q) = ",m1));
1115
rang = m1
1116
,
1117
if( DEBUGLEVEL_ell >= 1,
1118
print("#E(Q)/2E(Q) >= ",1<<m1);
1119
print("#III(E/Q)[2] <= ",1<<(m2-m1));
1120
print("rang(E/Q) >= ",m1));
1121
rang = m1;
1122
if( (m2-m1)%2,
1123
if( DEBUGLEVEL_ell >= 1,
1124
print(" III devrait etre un carre, donc ");
1125
if( m2-m1 > 1,
1126
print("#E(Q)/2E(Q) >= ",1<<(m1+1));
1127
print("#III(E/Q)[2] <= ",1<<(m2-m1-1));
1128
print("rang(E/Q) >= ",m1+1)
1129
,
1130
print("#E(Q)/2E(Q) = ",1<<(m1+1));
1131
print("#III(E/Q)[2] = 1");
1132
print("rang(E/Q) = ",m1+1)));
1133
rang = m1+1
1134
)
1135
);
1136
if( DEBUGLEVEL_ell >= 1, print("listpointsmwr = ",listpointsmwr));
1137
for( i = 1, #listpointsmwr,
1138
if( subst(polrel,x,listpointsmwr[i][1])-K*listpointsmwr[i][2]^2,
1139
error(" ell2descent_gen : MAUVAIS POINT = ",listpointsmwr[i])));
1140
if( #listpointsmwr >= 2,
1141
listpointsmwr = ellredgen(ell,listpointsmwr,K));
1142
if( DEBUGLEVEL_ell >= 4, print("fin de ell2descent_gen"));
1143
return([rang,m2,listpointsmwr]);
1144
}
1145
if( DEBUGLEVEL_ell >= 4, print("ellrank"));
1146
{
1147
ellrank(ell,help=[]) =
1148
\\ Algorithme de la 2-descente sur la courbe elliptique ell.
1149
\\ help est une liste de points connus sur ell.
1150
local(urst,urst1,den,eqell,tors2,bnf,rang,time1);
1151
1152
if( DEBUGLEVEL_ell >= 3, print("entree dans ellrank"));
1153
if( #ell < 13, ell = ellinit(ell,1));
1154
1155
\\ supprime les coefficients a1 et a3
1156
urst = [1,0,0,0];
1157
if( ell.a1 != 0 || ell.a3 != 0,
1158
urst1 = [1,0,-ell.a1/2,-ell.a3/2];
1159
ell = ellchangecurve(ell,urst1);
1160
urst = ellcomposeurst(urst,urst1)
1161
);
1162
1163
\\ supprime les denominateurs
1164
while( (den = denominator([ell.a2,ell.a4,ell.a6])) > 1,
1165
den = factor(den); den[,2] = vectorv(#den[,2],i,1);
1166
den = factorback(den);
1167
urst1 = [1/den,0,0,0];
1168
ell = ellchangecurve(ell,urst1);
1169
urst = ellcomposeurst(urst,urst1)
1170
);
1171
1172
help = ellchangepoint(help,urst);
1173
eqell = Pol([1,ell.a2,ell.a4,ell.a6]);
1174
if( DEBUGLEVEL_ell >= 1, print("courbe elliptique : Y^2 = ",eqell));
1175
1176
\\ choix de l'algorithme suivant la 2-torsion
1177
1178
tors2 = ellhalf(ell,[0]);
1179
if( DEBUGLEVEL_ell >= 1, print("E[2] = ",tors2));
1180
1181
if( #tors2 == 1, \\ cas 1: 2-torsion triviale
1182
if( DEBUGLEVEL_ell >= 3, print1("bnfinit "));
1183
if( DEBUGLEVEL_ell >= 4, gettime());
1184
bnf = bnfinit(eqell,1);
1185
if( DEBUGLEVEL_ell >= 4, time1 = gettime());
1186
if( DEBUGLEVEL_ell >= 3, print("ok"));
1187
rang = ell2descent_gen(ell,bnf,1,help);
1188
if( DEBUGLEVEL_ell >= 4, print("temps dans bnfinit = ",time1));
1189
if( DEBUGLEVEL_ell >= 4, print("temps pour le reste = ",gettime()));
1190
,
1191
if( #tors2 >= 2, \\ cas 2: 2-torsion >= Z/2Z
1192
if( ell.a6 != 0,
1193
urst1 = [1,tors2[2][1],0,0];
1194
ell = ellchangecurve(ell,urst1);
1195
urst = ellcomposeurst(urst,urst1)
1196
);
1197
eqell = Pol([1,ell.a2,ell.a4,ell.a6]);
1198
if( DEBUGLEVEL_ell >= 1, print("courbe elliptique : Y^2 = ",eqell));
1199
1200
rang = ell2descent_viaisog(ell,help)
1201
, \\ cas 3: 2-torsion = Z/2Z*Z/2Z
1202
\\ rang = ell2descent_complete(tors2[2][1],tors2[3][2],tors2[4][3])
1203
));
1204
1205
rang[3] = ellchangepointinverse(rang[3],urst);
1206
if( DEBUGLEVEL_ell >= 3, print("fin de ellrank"));
1207
1208
return(rang);
1209
}
1210
if( DEBUGLEVEL_ell >= 4, print("ell2descent_complete"));
1211
{
1212
ell2descent_complete(e1,e2,e3) =
1213
\\ calcul du rang d'une courbe elliptique
1214
\\ par la methode de 2-descente complete.
1215
\\ Y^2 = (x-e1)*(x-e2)*(x-e3);
1216
\\ en suivant la methode decrite par J.Silverman
1217
\\ renvoie [r,s,v] avec
1218
\\ r est une borne inferieure du rang de E(Q)
1219
\\ s est le rang du 2-groupe de Selmer
1220
\\ v est un systeme de points independants dans E(Q)/2E(Q)
1221
1222
\\ e1, e2 et e3 sont des entiers.
1223
1224
local(d32,d31,d21,G1,G2,vect1,vect2,selmer,rang,listepoints,b1,b2,q1,q2,sol1,param1,param1x,sol2,quart,point,z1,solx,soly,strange);
1225
1226
if( DEBUGLEVEL_ell >= 2, print("Algorithme de la 2-descente complete"));
1227
1228
\\ calcul des groupes G1 et G2
1229
1230
d32 = e3-e2; d31 = e3-e1; d21 = e2-e1;
1231
G1 = factor(-abs(d31*d21))[,1];
1232
G2 = factor(-abs(d32*d21))[,1];
1233
1234
if( DEBUGLEVEL_ell >= 3, print("G1 = ",G1));
1235
if( DEBUGLEVEL_ell >= 3, print("G2 = ",G2));
1236
1237
\\ parcours de G1*G2
1238
1239
vect1 = vector(#G1,i,[0,1]);
1240
vect2 = vector(#G2,i,[0,1]);
1241
selmer = 0;
1242
rang = 0;
1243
listepoints = [];
1244
1245
forvec( X = vect1,
1246
b1 = prod( i = 1, #G1, G1[i]^X[i]);
1247
forvec( Y = vect2,
1248
b2 = prod( i = 1, #G2, G2[i]^Y[i]);
1249
1250
if( DEBUGLEVEL_ell >= 3, print("[b1,b2] = ",lift([b1,b2])));
1251
1252
\\ points triviaux provenant de la 2-torsion
1253
1254
if( b1==1 && b2==1,
1255
if( DEBUGLEVEL_ell >= 4, print(" point trivial [0]"));
1256
selmer++; rang++; next);
1257
if( issquare(-d21*b2) && issquare(d31*d21*b1),
1258
if( DEBUGLEVEL_ell >= 3, print(" point trivial [e1,0]"));
1259
selmer++; rang++; listepoints = concat(listepoints,[[e1,0]]); next);
1260
if( issquare(d21*b1) && issquare(-d32*d21*b2),
1261
if( DEBUGLEVEL_ell >= 3, print(" point trivial [e2,0]"));
1262
selmer++; rang++; listepoints = concat(listepoints,[[e2,0]]); next);
1263
if( issquare(d31*b1) && issquare(d32*b2),
1264
if( DEBUGLEVEL_ell >= 3, print(" point trivial [e3,0]"));
1265
selmer++; rang++; listepoints = concat(listepoints,[[e3,0]]); next);
1266
1267
\\ il faut resoudre 2 equations quadratiques:
1268
\\ (1) b1*z1^2-b2*z2^2 = e2-e1
1269
\\ (2) b1*z1^2-b1*b2*z3^2 = e3-e1
1270
\\ on aura alors (x,y) = (b1*z1^2+e1,b1*b2*z1*z2*z3)
1271
1272
q1 = matdiagonal([b1,-b2,-d21]);
1273
if( DEBUGLEVEL_ell >= 3, print(" q1 = ",q1));
1274
q2 = matdiagonal([b1,-b1*b2,-d31]);
1275
if( DEBUGLEVEL_ell >= 3, print(" q2 = ",q2));
1276
1277
\\ solution de la premiere forme quadratique
1278
1279
sol1 = Qfsolve(q1);
1280
if( type(sol1) == "t_INT",
1281
if( DEBUGLEVEL_ell >= 3, print(" q1 non ELS en ",sol1));
1282
next);
1283
if( DEBUGLEVEL_ell >= 3, print(" sol part de q1 = ",sol1));
1284
param1 = Qfparam(q1,sol1,1);
1285
if( DEBUGLEVEL_ell >= 3, print(" param de q1 = ",param1));
1286
param1x = param1*[x^2,x,1]~;
1287
1288
sol2 = Qfsolve(q2);
1289
if( type(sol2) == "t_INT",
1290
if( DEBUGLEVEL_ell >= 3, print(" q2 non ELS en ",sol2));
1291
next);
1292
1293
quart = b1*b2*(b1*param1x[1]^2-d31*param1x[3]^2);
1294
if( DEBUGLEVEL_ell >= 3, print(" quart = ",quart));
1295
1296
\\ la quartique est-elle localement soluble ?
1297
1298
if( !locallysoluble(quart),
1299
if( DEBUGLEVEL_ell >= 3, print(" quartique non ELS "));
1300
next);
1301
if( DEBUGLEVEL_ell >= 2, print(" y^2 = ",quart));
1302
selmer++;
1303
1304
\\ recherche de points sur la quartique.
1305
1306
point = ratpoint(quart,LIM3,1);
1307
if( point != [],
1308
if( DEBUGLEVEL_ell >= 2, print("point trouve sur la quartique !!"));
1309
if( DEBUGLEVEL_ell >= 3, print(point));
1310
if( #point == 2,
1311
z1 = subst(param1x[1],x,point[1])/subst(param1x[3],x,point[1])
1312
, z1 = param1[1,1]/param1[3,1]);
1313
solx = b1*z1^2+e1;
1314
soly = sqrtrat((solx-e1)*(solx-e2)*(solx-e3));
1315
listepoints = concat(listepoints,[[solx,soly]]);
1316
if( DEBUGLEVEL_ell >= 1, print("point sur la courbe elliptique = ",[solx,soly]));
1317
rang++
1318
,
1319
if( DEBUGLEVEL_ell >= 2, print("aucun point trouve sur la quartique"))
1320
)
1321
)
1322
);
1323
1324
\\ fin
1325
1326
if( DEBUGLEVEL_ell >= 1,
1327
print("#S^(2) = ",selmer));
1328
if( rang > selmer/2, rang = selmer);
1329
if( DEBUGLEVEL_ell >= 1,
1330
strange = rang != selmer;
1331
if( strange,
1332
print("#E[K]/2E[K]>= ",rang)
1333
, print("#E[K]/2E[K] = ",rang));
1334
print("#E[2] = 4");
1335
);
1336
rang = ceil(log(rang)/log(2))-2;
1337
selmer = valuation(selmer,2);
1338
if( DEBUGLEVEL_ell >= 1,
1339
if( strange,
1340
print(selmer-2," >= rang >= ",rang)
1341
, print("rang = ",rang));
1342
if( rang, print("points = ",listepoints));
1343
);
1344
ell = ellinit([0,-(e1+e2+e3),0,e1*e2+e2*e3+e3*e1,-e1*e2*e3]);
1345
if( ELLREDGENFLAG, listepoints = ellredgen(ell,listepoints));
1346
listepoints = concat(ellsort(elltorseven(ell)[3]),listepoints);
1347
1348
return([rang,selmer,listepoints]);
1349
}
1350
if( DEBUGLEVEL_ell >= 4, print("ellcount"));
1351
{
1352
ellcount( c, d, KS2gen, listpointstriv=[]) =
1353
local(found,listgen,listpointscount,m1,m2,lastloc,mask,i,d1,iaux,j,triv,pol,point,deuxpoints,v);
1354
1355
if( DEBUGLEVEL_ell >= 4, print("entree dans ellcount ",[c,d]));
1356
if( DEBUGLEVEL_ell >= 4, print("KS2gen = ",KS2gen));
1357
if( DEBUGLEVEL_ell >= 4, print("listpointstriv = ",listpointstriv));
1358
1359
found = 0;
1360
listgen = KS2gen;
1361
listpointscount = [];
1362
1363
m1 = m2 = 0; lastloc = -1;
1364
1365
mask = 1 << #KS2gen;
1366
i = 1;
1367
while( i < mask,
1368
d1 = 1; iaux = i; j = 1;
1369
while( iaux,
1370
if( iaux%2, d1 *= listgen[j]);
1371
iaux >>= 1; j++);
1372
if( DEBUGLEVEL_ell >= 2, print("d1 = ",d1));
1373
triv = 0;
1374
for( j = 1, #listpointstriv,
1375
if( listpointstriv[j][1] && issquare(d1*listpointstriv[j][1]),
1376
listpointscount = concat(listpointscount,[listpointstriv[j]]);
1377
if( DEBUGLEVEL_ell >= 2, print("point trivial"));
1378
triv = 1; m1++;
1379
if( degre(i) > lastloc, m2++);
1380
found = 1; lastloc = -1; break));
1381
if( !triv,
1382
pol = Pol([d1,0,c,0,d/d1]);
1383
if( DEBUGLEVEL_ell >= 3, print("quartique = y^2 = ",pol));
1384
point = ratpoint(pol,LIM1,1);
1385
if( point != [],
1386
if( DEBUGLEVEL_ell >= 2, print("point sur la quartique"));
1387
if( DEBUGLEVEL_ell >= 3, print(point));
1388
m1++;
1389
listpointscount = concat(listpointscount,[d1*point[1]*point]);
1390
if( degre(i) > lastloc, m2++);
1391
found = 1; lastloc = -1
1392
,
1393
if( locallysoluble(pol),
1394
if( degre(i) > lastloc, m2++; lastloc = degre(i));
1395
point = ratpoint(pol,LIM3,1);
1396
if( point != [],
1397
if( DEBUGLEVEL_ell >= 2, print("point sur la quartique"));
1398
if( DEBUGLEVEL_ell >= 3, print(point));
1399
m1++;
1400
listpointscount = concat(listpointscount,[d1*point[1]*point]);
1401
if( degre(i) > lastloc, m2++);
1402
found = 1; lastloc = -1
1403
,
1404
if( DEBUGLEVEL_ell >= 2, print(" pas de point trouve sur la quartique"))
1405
))));
1406
if( found,
1407
found = 0;
1408
v = 0; iaux = (i>>1);
1409
while( iaux, iaux >>= 1; v++);
1410
mask >>= 1;
1411
listgen = vecextract(listgen,(1<<#listgen)-(1<<v)-1);
1412
i = (1<<v)
1413
, i++)
1414
);
1415
1416
for( i = 1, #listpointscount,
1417
if( #listpointscount[i] > 1,
1418
if( subst(x^3+c*x^2+d*x,x,listpointscount[i][1])-listpointscount[i][2]^2 != 0,
1419
error(" ellcount : MAUVAIS POINT "))));
1420
if( DEBUGLEVEL_ell >= 4, print("fin de ellcount"));
1421
return([listpointscount,[m1,m2]]);
1422
}
1423
if( DEBUGLEVEL_ell >= 4, print("ell2descent_viaisog"));
1424
{
1425
ell2descent_viaisog(ell,help=[]) =
1426
\\ Calcul du rang des courbes elliptiques avec 2-torsion
1427
\\ par la methode des 2-isogenies.
1428
\\
1429
\\ ell = [a1,a2,a3,a4,a6]
1430
\\ y^2+a1xy+a3y=x^3+a2x^2+a4x+a6
1431
\\
1432
\\ ell doit etre sous la forme
1433
\\ y^2=x^3+ax^2+bx -> ell = [0,a,0,b,0]
1434
\\ avec a et b entiers.
1435
local(i,P,Pfact,tors,listpointstriv,apinit,bpinit,plist,KS2prod,oddclass,KS2gen,listpoints,pointgen,n1,n2,certain,np1,np2,listpoints2,aux1,aux2,certainp,rang,strange);
1436
1437
if( DEBUGLEVEL_ell >= 2, print("Algorithme de la 2-descente par isogenies"));
1438
if( #ell < 13, ell = ellinit(ell,1));
1439
1440
if( ell.disc == 0,
1441
error(" ell2descent_viaisog : courbe singuliere !!"));
1442
if( ell.a1 != 0 || ell.a3 != 0 || ell.a6 != 0,
1443
error(" ell2descent_viaisog : la courbe n'est pas sous la forme [0,a,0,b,0]"));
1444
if( denominator(ell.a2) > 1 || denominator(ell.a4) > 1,
1445
error(" ell2descent_viaisog : coefficients non entiers"));
1446
1447
P = Pol([1,ell.a2,ell.a4]);
1448
Pfact = factor(P)[,1];
1449
tors = #Pfact;
1450
listpointstriv = concat(help,elltorseven(ell)[3]);
1451
1452
apinit = -2*ell.a2; bpinit = ell.a2^2-4*ell.a4;
1453
1454
plist = factor(6*ell.disc)[,1];
1455
1456
if( DEBUGLEVEL_ell >= 3, print(" Recherche de points triviaux sur la courbe"));
1457
P *= x;
1458
if( DEBUGLEVEL_ell >= 3, print("Y^2 = ",P));
1459
listpointstriv = concat( listpointstriv, ratpoint(P,LIMTRIV,0));
1460
if( DEBUGLEVEL_ell >= 1, print("points triviaux sur E(Q) = ",listpointstriv); print());
1461
1462
KS2prod = -abs(ell.a4);
1463
if( bpinit < 0, KS2prod = -KS2prod);
1464
KS2gen = factor(KS2prod)[,1];
1465
1466
if( DEBUGLEVEL_ell >= 2,
1467
print("#K(b,2)gen = ",#KS2gen);
1468
print("K(b,2)gen = ",KS2gen));
1469
1470
listpoints = ellcount(ell.a2,ell.a4,KS2gen,listpointstriv);
1471
pointgen = listpoints[1];
1472
if( DEBUGLEVEL_ell >= 1, print("points sur E(Q) = ",pointgen); print());
1473
n1 = listpoints[2][1]; n2 = listpoints[2][2];
1474
1475
certain = (n1 == n2);
1476
if( DEBUGLEVEL_ell >= 1,
1477
if( certain,
1478
print("[E(Q):phi'(E'(Q))] = ",1<<n1);
1479
print("#S^(phi')(E'/Q) = ",1<<n2);
1480
print("#III(E'/Q)[phi'] = 1"); print()
1481
,
1482
print("[E(Q):phi'(E'(Q))] >= ",1<<n1);
1483
print("#S^(phi')(E'/Q) = ",1<<n2);
1484
print("#III(E'/Q)[phi'] <= ",1<<(n2-n1)); print())
1485
);
1486
1487
KS2prod = -abs(bpinit);
1488
if( ell.a4 < 0, KS2prod = -KS2prod);
1489
KS2gen = factor(KS2prod)[,1];
1490
1491
if( DEBUGLEVEL_ell >= 2,
1492
print("#K(a^2-4b,2)gen = ",#KS2gen);
1493
print("K(a^2-4b,2)gen = ",KS2gen));
1494
1495
P = Pol([1,apinit,bpinit]);
1496
listpointstriv = elltorseven([0,apinit,0,bpinit,0])[3];
1497
1498
if( DEBUGLEVEL_ell >= 3, print(" Recherche de points triviaux sur la courbe"));
1499
P *= x;
1500
if( DEBUGLEVEL_ell >= 3, print("Y^2 = ",P));
1501
listpointstriv = concat( listpointstriv, ratpoint(P,LIMTRIV,0));
1502
if( DEBUGLEVEL_ell >= 1, print("points triviaux sur E'(Q) = ",listpointstriv); print());
1503
1504
listpoints = ellcount(apinit,bpinit,KS2gen,listpointstriv);
1505
if( DEBUGLEVEL_ell >= 1, print("points sur E'(Q) = ",listpoints[1]));
1506
np1 = listpoints[2][1]; np2 = listpoints[2][2];
1507
listpoints2 = vector(#listpoints[1],i,0);
1508
for( i = 1, #listpoints[1],
1509
listpoints2[i] = [0,0];
1510
aux1 = listpoints[1][i][1]^2;
1511
if( aux1 != 0,
1512
aux2 = listpoints[1][i][2];
1513
listpoints2[i][1] = aux2^2/aux1/4;
1514
listpoints2[i][2] = aux2*(bpinit-aux1)/aux1/8
1515
, listpoints2[i] = listpoints[1][i]));
1516
if( DEBUGLEVEL_ell >= 1, print("points sur E(Q) = ",listpoints2); print());
1517
pointgen = concat(pointgen,listpoints2);
1518
1519
certainp = (np1 == np2);
1520
if( DEBUGLEVEL_ell >= 1,
1521
if( certainp,
1522
print("[E'(Q):phi(E(Q))] = ",1<<np1);
1523
print("#S^(phi)(E/Q) = ",1<<np2);
1524
print("#III(E/Q)[phi] = 1"); print()
1525
,
1526
print("[E'(Q):phi(E(Q))] >= ",1<<np1);
1527
print("#S^(phi)(E/Q) = ",1<<np2);
1528
print("#III(E/Q)[phi] <= ",1<<(np2-np1)); print());
1529
1530
if( !certain && (np2 > np1), print1(1<<(np2-np1)," <= "));
1531
print1("#III(E/Q)[2] ");
1532
if( certain && certainp, print1(" "), print1("<"));
1533
print("= ",1<<(n2+np2-n1-np1));
1534
1535
print("#E(Q)[2] = ",1<<tors);
1536
);
1537
rang = n1+np1-2;
1538
if( DEBUGLEVEL_ell >= 1,
1539
if( certain && certainp,
1540
print("#E(Q)/2E(Q) = ",(1<<(rang+tors)));
1541
print("rang = ",rang); print()
1542
,
1543
print("#E(Q)/2E(Q) >= ",(1<<(rang+tors))); print();
1544
print(rang," <= rang <= ",n2+np2-2); print()
1545
));
1546
1547
strange = (n2+np2-n1-np1)%2;
1548
if( strange,
1549
if( DEBUGLEVEL_ell >= 1,
1550
print(" !!! III doit etre un carre !!!"); print("donc"));
1551
if( certain,
1552
np1++;
1553
certainp = (np1 == np2);
1554
if( DEBUGLEVEL_ell >= 1,
1555
if( certainp,
1556
print("[E'(Q):phi(E(Q))] = ",1<<np1);
1557
print("#S^(phi)(E/Q) = ",1<<np2);
1558
print("#III(E/Q)[phi] = 1"); print()
1559
,
1560
print("[E'(Q):phi(E(Q))] >= ",1<<np1);
1561
print("#S^(phi)(E/Q) = ",1<<np2);
1562
print("#III(E/Q)[phi] <= ",1<<(np2-np1)); print())
1563
)
1564
,
1565
if( certainp,
1566
n1++;
1567
certain = (n1 == n2);
1568
if( DEBUGLEVEL_ell >= 1,
1569
if( certain,
1570
print("[E(Q):phi'(E'(Q))] = ",1<<n1);
1571
print("#S^(phi')(E'/Q) = ",1<<n2);
1572
print("#III(E'/Q)[phi'] = 1"); print()
1573
,
1574
print("[E(Q):phi'(E'(Q))] >= ",1<<n1);
1575
print("#S^(phi')(E'/Q) = ",1<<n2);
1576
print("#III(E'/Q)[phi'] <= ",1<<(n2-n1)); print())
1577
)
1578
, n1++)
1579
);
1580
1581
if( DEBUGLEVEL_ell >= 1,
1582
print("#S^(2)(E/Q) = ",1<<(n2+np2-1));
1583
if( !certain && (np2 > np1), print1(1<<(np2-np1)," <= "));
1584
print1("#III(E/Q)[2] ");
1585
if( certain && certainp, print1(" "), print1("<"));
1586
print("= ",1<<(n2+np2-n1-np1));
1587
print("#E(Q)[2] = ",1<<tors);
1588
);
1589
rang = n1+np1-2;
1590
if( DEBUGLEVEL_ell >= 1,
1591
if( certain && certainp,
1592
print("#E(Q)/2E(Q) = ",(1<<(rang+tors))); print();
1593
print("rang = ",rang); print()
1594
,
1595
print("#E(Q)/2E(Q) >= ",(1<<(rang+tors))); print();
1596
print(rang," <= rang <= ",n2+np2-2); print())
1597
));
1598
1599
\\ fin de strange
1600
1601
if( ELLREDGENFLAG, pointgen = ellredgen(ell,pointgen));
1602
pointgen = concat(ellsort(elltorseven(ell)[3]),pointgen);
1603
if( DEBUGLEVEL_ell >= 1, print("points = ",pointgen));
1604
if( DEBUGLEVEL_ell >= 3, print("fin de ell2descent_viaisog"));
1605
return([rang,n2+np2-2+tors,pointgen]);
1606
}
1607
1608
1609
1610