Karim BELABAS on Mon, 7 Jun 1999 15:13:15 +0200 (MET DST)


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: rank=8, torsion group=Z/2Z*Z/2Z


[Igor:]
>> On Mon, Apr 26, 1999 at 10:52:55AM -0400, Andrej Dujella wrote:
>>> I found three examples of elliptic cuves over Q
>>> with torsion group isomorphic to Z/2Z * Z/2Z
>>> and with rank = 8.
>>> This improves my previous examples with rank = 7
>>> (see A. Dujella: Diophantine triples and construction of
>>> high-rank elliptic curves over Q with three non-trivial
>>> 2-torsion points, Rocky Mountain J. Math., to appear).
>>> 
>>> These elliptic curves are
>>> 
>>>            y^2=x*[x+(b-a)(d-c)]*[x+(c-a)(d-b)],
>>> 
>>> where (a,b,c,d)=
>>> (32/91, 60/91, 1878240/1324801, 15343900/12215287),
>>> (17/448, 2145/448, 23460/7, 2352/7921) and
>>> (559/1380, 252/115, 24264935/2979076, 16454108/1703535).
[...]
>> 
>> So PARI thinks the torsion groups are isomorphic to Z/2Z,
>> contrary to what Dr. Dujella's findings.
>> 
>> I looked at it many times, and I believe I set it up correctly.  So
>> looks like it's a PARI bug.
[...]
> On the other hand, if I use the integral model
> and reduce the curves globally, it works fine:
[...]
> So the bug is definitely related to handling non-integral
> coefficients.

Here's a tentative (brute force) patch. In effect, it switches to an integral
model [not a minimal one, hence it'll be much faster than ellglobalred, which
requires factoring the discriminant].

The patch "fixes" the same problem in Lutz-Nagell (which raised an error, not
a wrong result). Here a minimal model would definitely help, but this
approach is hopelessly slow anyway...

Finally, it replaces "precision loss in truncation" messages in the routine
by something more helpful.

Karim.

*** src/modules/elliptic.c.orig	Thu Jun  3 15:59:26 1999
--- src/modules/elliptic.c	Mon Jun  7 15:09:41 1999
***************
*** 2694,2699 ****
--- 2694,2712 ----
    avma=av; return gzero;
  }
  
+ /* one can do much better by factoring denom(D) (see ellglobalred) */
+ static GEN
+ ellintegralmodel(GEN e)
+ {
+   GEN a = cgetg(6,t_VEC), v;
+   long i;
+ 
+   for (i=1; i<6; i++) a[i]=e[i];
+   a = denom(a); if (gcmp1(a)) return NULL;
+   v = cgetg(5,t_VEC);
+   v[1]=linv(a); v[2]=v[3]=v[4]=zero; return v;
+ }
+ 
  /* Using Lutz-Nagell */
  
  /* p is a polynomial of degree exactly 3 with integral coefficients
***************
*** 2747,2767 ****
  GEN
  torsellnagelllutz(GEN e)
  {
!   GEN d,ld,pol,p1,lr,v,w,w2,w3;
    long i,j,nlr,t,t2,k,k2,av=avma;
  
    checkell(e);
!   for (i=1; i<=5; i++)
!     if (typ(e[i]) != t_INT) err(talker, "not an integral model in torsell");
    pol = RHSpol(e);
    lr=ratroot(pol); nlr=lg(lr)-1;
!   v=cgetg(17,t_VEC); p1=cgetg(2,t_VEC); p1[1]=zero; v[1]=(long)p1;
    for (t=1,i=1; i<=nlr; i++)
    {
      p1=cgetg(3,t_VEC);
      p1[1] = lr[i];
      p1[2] = lmul2n(gneg(ellLHS0(e,(GEN)lr[i])), -1);
!     v[++t]=(long)p1;
    }
    ld = factor(gmul2n(absi((GEN)e[12]), 4));
    p1 = (GEN)ld[2]; k = lg(p1);
--- 2760,2780 ----
  GEN
  torsellnagelllutz(GEN e)
  {
!   GEN d,ld,pol,p1,lr,r,v,w,w2,w3;
    long i,j,nlr,t,t2,k,k2,av=avma;
  
    checkell(e);
!   v = ellintegralmodel(e);
!   if (v) e = coordch(e,v);
    pol = RHSpol(e);
    lr=ratroot(pol); nlr=lg(lr)-1;
!   r=cgetg(17,t_VEC); p1=cgetg(2,t_VEC); p1[1]=zero; r[1]=(long)p1;
    for (t=1,i=1; i<=nlr; i++)
    {
      p1=cgetg(3,t_VEC);
      p1[1] = lr[i];
      p1[2] = lmul2n(gneg(ellLHS0(e,(GEN)lr[i])), -1);
!     r[++t]=(long)p1;
    }
    ld = factor(gmul2n(absi((GEN)e[12]), 4));
    p1 = (GEN)ld[2]; k = lg(p1);
***************
*** 2776,2788 ****
        p1[1] = lr[i];
        p1[2] = lmul2n(gsub(d,ellLHS0(e,(GEN)lr[i])), -1);
  
!       if (is_new_torsion(e,v,p1,t2))
        {
          GEN p2 = cgetg(3,t_VEC);
          p2[1] = p1[1];
          p2[2] = lsub((GEN)p1[2],d);
! 	v[++t]=(long)p1;
!         v[++t]=(long)p2;
        }
      }
    }
--- 2789,2801 ----
        p1[1] = lr[i];
        p1[2] = lmul2n(gsub(d,ellLHS0(e,(GEN)lr[i])), -1);
  
!       if (is_new_torsion(e,r,p1,t2))
        {
          GEN p2 = cgetg(3,t_VEC);
          p2[1] = p1[1];
          p2[2] = lsub((GEN)p1[2],d);
! 	r[++t]=(long)p1;
!         r[++t]=(long)p2;
        }
      }
    }
***************
*** 2799,2808 ****
    {
      w2=cgetg(2,t_VEC); w2[1]=lstoi(t);
      for (k=2; k<=t; k++)
!       if (itos(orderell(e,(GEN)v[k])) == t) break;
      if (k>t) err(bugparier,"torsell (bug1)");
  
!     w3=cgetg(2,t_VEC); w3[1]=v[k];
    }
    else
    {
--- 2812,2821 ----
    {
      w2=cgetg(2,t_VEC); w2[1]=lstoi(t);
      for (k=2; k<=t; k++)
!       if (itos(orderell(e,(GEN)r[k])) == t) break;
      if (k>t) err(bugparier,"torsell (bug1)");
  
!     w3=cgetg(2,t_VEC); w3[1]=r[k];
    }
    else
    {
***************
*** 2810,2821 ****
      t2 = t>>1;
      w2=cgetg(3,t_VEC); w2[1]=lstoi(t2); w2[2]=(long)gdeux;
      for (k=2; k<=t; k++)
!       if (itos(orderell(e,(GEN)v[k])) == t2) break;
      if (k>t) err(bugparier,"torsell (bug3)");
  
!     p1 = powell(e,(GEN)v[k],stoi(t>>2));
!     k2 = (lg(p1)==3 && gegal((GEN)v[2],p1))? 3: 2;
!     w3=cgetg(3,t_VEC); w3[1]=v[k]; w3[2]=v[k2];
    }
    w=cgetg(4,t_VEC);
    w[1] = lstoi(t);
--- 2823,2839 ----
      t2 = t>>1;
      w2=cgetg(3,t_VEC); w2[1]=lstoi(t2); w2[2]=(long)gdeux;
      for (k=2; k<=t; k++)
!       if (itos(orderell(e,(GEN)r[k])) == t2) break;
      if (k>t) err(bugparier,"torsell (bug3)");
  
!     p1 = powell(e,(GEN)r[k],stoi(t>>2));
!     k2 = (lg(p1)==3 && gegal((GEN)r[2],p1))? 3: 2;
!     w3=cgetg(3,t_VEC); w3[1]=r[k]; w3[2]=r[k2];
!   }
!   if (v)
!   {
!     v[1] = linv((GEN)v[1]);
!     w3 = pointch(w3,v);
    }
    w=cgetg(4,t_VEC);
    w[1] = lstoi(t);
***************
*** 2849,2863 ****
    return b;
  }
  
  /* Input the curve, a point, and an integer n, returns a point of order n
     on the curve, or 0 if the point p is not a proper point. */
  static GEN
  torspnt(GEN e, GEN q, long n)
  {
    GEN p = cgetg(3,t_VEC);
!   p[1] = lmul2n(ground(gmul2n((GEN)q[1],2)),-2);
!   p[2] = lmul2n(ground(gmul2n((GEN)q[2],3)),-3);
!   return (oncurve(e,p) && gcmp0(gimag(p))
        && lg(powell(e,p,stoi(n))) == 2
        && itos(orderell(e,p)) == n)? greal(p): NULL;
  }
--- 2867,2891 ----
    return b;
  }
  
+ static GEN
+ _round(GEN x)
+ {
+   long e;
+   x = grndtoi(x,&e);
+   if (e >= 0)
+     err(talker, "ellinit data not accurate enough. Increase precision");
+   return x;
+ }
+ 
  /* Input the curve, a point, and an integer n, returns a point of order n
     on the curve, or 0 if the point p is not a proper point. */
  static GEN
  torspnt(GEN e, GEN q, long n)
  {
    GEN p = cgetg(3,t_VEC);
!   p[1] = lmul2n(_round(gmul2n((GEN)q[1],2)),-2);
!   p[2] = lmul2n(_round(gmul2n((GEN)q[2],3)),-3);
!   return (gcmp0(gimag(p)) && oncurve(e,p)
        && lg(powell(e,p,stoi(n))) == 2
        && itos(orderell(e,p)) == n)? greal(p): NULL;
  }
***************
*** 2885,2891 ****
  }
  
  static GEN
! tors(GEN e, long k, GEN p, GEN q)
  {
    GEN p1, r = cgetg(4,t_VEC);
    if (q)
--- 2913,2919 ----
  }
  
  static GEN
! tors(GEN e, long k, GEN p, GEN q, GEN v)
  {
    GEN p1, r = cgetg(4,t_VEC);
    if (q)
***************
*** 2897,2903 ****
      if (smaller_x((GEN)p1[1], (GEN)best[1])) q = p1;
      else if (best == np) { p = addell(e,p,q); q = np; }
      p = best_in_cycle(e,p,k);
! 
      r[1] = lstoi(2*k); p1 = cgetg(3,t_VEC); p1[1] = lstoi(k); p1[2] = deux;
      r[2] = (long)p1; p1 = cgetg(3,t_VEC); p1[1] = lcopy(p); p1[2] = lcopy(q);
      r[3] = (long)p1;
--- 2925,2936 ----
      if (smaller_x((GEN)p1[1], (GEN)best[1])) q = p1;
      else if (best == np) { p = addell(e,p,q); q = np; }
      p = best_in_cycle(e,p,k);
!     if (v) 
!     {
!       v[1] = linv((GEN)v[1]);
!       p = pointch(p,v);
!       q = pointch(q,v);
!     }
      r[1] = lstoi(2*k); p1 = cgetg(3,t_VEC); p1[1] = lstoi(k); p1[2] = deux;
      r[2] = (long)p1; p1 = cgetg(3,t_VEC); p1[1] = lcopy(p); p1[2] = lcopy(q);
      r[3] = (long)p1;
***************
*** 2907,2912 ****
--- 2940,2950 ----
      if (p)
      {
        p = best_in_cycle(e,p,k);
+       if (v) 
+       {
+         v[1] = linv((GEN)v[1]);
+         p = pointch(p,v);
+       }
        r = cgetg(4,t_VEC);
        r[1] = lstoi(k); p1 = cgetg(2,t_VEC); p1[1] = r[1];
        r[2] = (long)p1; p1 = cgetg(2,t_VEC); p1[1] = lcopy(p);
***************
*** 2921,2933 ****
  torselldoud(GEN e)
  {
    long b,i,ord,av=avma,prec, k = 1;
!   GEN w1,w22,w1j,w12,p,tor1,tor2;
  
    checkbell(e);
  
!   prec=max(MEDDEFAULTPREC,gprecision(e));
    b = torsbound(e,3);
!   if (b==1) { avma=av; return tors(e,1,NULL,NULL); }
    w22 = gmul2n((GEN)e[16],-1);
    w1 = (GEN)e[15];
    if (b % 4)
--- 2959,2974 ----
  torselldoud(GEN e)
  {
    long b,i,ord,av=avma,prec, k = 1;
!   GEN v,w1,w22,w1j,w12,p,tor1,tor2;
  
    checkbell(e);
+   v = ellintegralmodel(e);
+   if (v) e = coordch(e,v);
  
!   prec=precision((GEN)e[15]);
!   prec=max(prec,MEDDEFAULTPREC);
    b = torsbound(e,3);
!   if (b==1) { avma=av; return tors(e,1,NULL,NULL, v); }
    w22 = gmul2n((GEN)e[16],-1);
    w1 = (GEN)e[15];
    if (b % 4)
***************
*** 2948,2954 ****
        else p = NULL;
        if (p) {k = i; break; }
      }
!     return gerepileupto(av, tors(e,k,p,NULL));
    }
  
    ord = 0; tor2 = NULL;
--- 2989,2995 ----
        else p = NULL;
        if (p) {k = i; break; }
      }
!     return gerepileupto(av, tors(e,k,p,NULL, v));
    }
  
    ord = 0; tor2 = NULL;
***************
*** 3010,3016 ****
        if (!p) { p = tor1; k = 2; }
        break;
    }
!   return gerepileupto(av, tors(e,k,p,tor2));
  }
  
  GEN
--- 3051,3057 ----
        if (!p) { p = tor1; k = 2; }
        break;
    }
!   return gerepileupto(av, tors(e,k,p,tor2, v));
  }
  
  GEN
__
Karim Belabas                    email: Karim.Belabas@math.u-psud.fr
Dep. de Mathematiques, Bat. 425
Universite Paris-Sud             Tel: (00 33) 1 69 15 57 48
F-91405 Orsay (France)           Fax: (00 33) 1 69 15 60 19
--
PARI/GP Home Page: http://hasse.mathematik.tu-muenchen.de/ntsw/pari/