bridge/class-master/depend/pari/src/basemath/ellsea.c
/*Returns the trace modulo ell^k when ell is an Elkies prime */
Returns the trace modulo ell^k when ell is an Elkies prime
Returns the trace modulo ell^k when ell is an Elkies prime
static GEN
find_trace_Elkies_power(GEN a4, GEN a6, ulong ell, long *pt_k, struct meqn *MEQN, GEN g, GEN tr, GEN q, GEN T, GEN p, long smallfact, pari_timer *ti)
{
  pari_sp ltop = avma, btop;
  GEN tmp, Eba4, Eba6, Eca4, Eca6, Ib, kpoly;
  long k = *pt_k;
  ulong lambda, ellk = upowuu(ell, k), pellk = umodiu(q, ellk);
  long cnt;
  if (DEBUGLEVEL) { err_printf("mod %ld", ell); }
  Eba4 = a4;
  Eba6 = a6;
  tmp = find_isogenous(a4,a6, ell, MEQN, g, T, p);
  if (!tmp) { avma = ltop; return NULL; }
  Eca4 =  gel(tmp, 1);
  Eca6 =  gel(tmp, 2);
  kpoly = gel(tmp, 3);
  Ib = pol_x(0);
  lambda = tr ? find_eigen_value_oneroot(a4, a6, ell, tr, kpoly, T, p):
                find_eigen_value_power(a4, a6, ell, 1, 1, kpoly, T, p);
  if (DEBUGLEVEL>1) err_printf(" [%ld ms]", timer_delay(ti));
  if (smallfact && smallfact%(long)ell!=0)
  {
    ulong pell = pellk%ell;
    ulong ap = Fl_add(lambda, Fl_div(pell, lambda, ell), ell);
    if (Fl_sub(pell, ap, ell)==ell-1) { avma = ltop; return mkvecsmall(ap); }
    if (smallfact < 0 && Fl_add(pell, ap, ell)==ell-1) { avma = ltop; return mkvecsmall(ap); }
  }
  btop = avma;
  for (cnt = 2; cnt <= k; cnt++)
  {
    GEN tmp = find_kernel_power(Eba4, Eba6, Eca4, Eca6, ell, MEQN, kpoly, Ib, T, p);
    if (!tmp) { k = cnt-1; break; }
    if (DEBUGLEVEL) err_printf(", %Ps", powuu(ell, cnt));
    lambda = find_eigen_value_power(a4, a6, ell, cnt, lambda, gel(tmp,3), T, p);
    Eba4 = Eca4;
    Eba6 = Eca6;
    Eca4 = gel(tmp,1);
    Eca6 = gel(tmp,2);
    kpoly = gel(tmp,4);
    Ib = gel(tmp, 5);
    if (gc_needed(btop, 1))
    {
      if(DEBUGMEM>1) pari_warn(warnmem,"find_trace_Elkies_power");
      gerepileall(btop, 6, &Eba4, &Eba6, &Eca4, &Eca6, &kpoly, &Ib);
    }
    if (DEBUGLEVEL>1) err_printf(" [%ld ms]", timer_delay(ti));
  }
  avma = ltop;
  ellk = upowuu(ell, k);
  pellk = umodiu(q, ellk);
  *pt_k = k;
  return mkvecsmall(Fl_add(lambda, Fl_div(pellk, lambda, ellk), ellk));
}
static GEN find_trace_Elkies_power ( GEN a4 , GEN a6 , ulong ell , long * pt_k , struct meqn * MEQN , GEN g , GEN tr , GEN q , GEN T , GEN p , long smallfact , pari_timer * ti ) { pari_sp ltop = avma , btop ; GEN tmp , Eba4 , Eba6 , Eca4 , Eca6 , Ib , kpoly ; long k = * pt_k ; ulong lambda , ellk = upowuu ( ell , k ) , pellk = umodiu ( q , ellk ) ; long cnt ; if ( DEBUGLEVEL ) { err_printf ( " " , ell ) ; } Eba4 = a4 ; Eba6 = a6 ; tmp = find_isogenous ( a4 , a6 , ell , MEQN , g , T , p ) ; if ( ! tmp ) { avma = ltop ; return NULL ; } Eca4 = gel ( tmp , 1 ) ; Eca6 = gel ( tmp , 2 ) ; kpoly = gel ( tmp , 3 ) ; Ib = pol_x ( 0 ) ; lambda = tr ? find_eigen_value_oneroot ( a4 , a6 , ell , tr , kpoly , T , p ) : find_eigen_value_power ( a4 , a6 , ell , 1 , 1 , kpoly , T , p ) ; if ( DEBUGLEVEL > 1 ) err_printf ( " " , timer_delay ( ti ) ) ; if ( smallfact && smallfact % ( long ) ell != 0 ) { ulong pell = pellk % ell ; ulong ap = Fl_add ( lambda , Fl_div ( pell , lambda , ell ) , ell ) ; if ( Fl_sub ( pell , ap , ell ) == ell - 1 ) { avma = ltop ; return mkvecsmall ( ap ) ; } if ( smallfact < 0 && Fl_add ( pell , ap , ell ) == ell - 1 ) { avma = ltop ; return mkvecsmall ( ap ) ; } } btop = avma ; for ( cnt = 2 ; cnt <= k ; cnt ++ ) { GEN tmp = find_kernel_power ( Eba4 , Eba6 , Eca4 , Eca6 , ell , MEQN , kpoly , Ib , T , p ) ; if ( ! tmp ) { k = cnt - 1 ; break ; } if ( DEBUGLEVEL ) err_printf ( " " , powuu ( ell , cnt ) ) ; lambda = find_eigen_value_power ( a4 , a6 , ell , cnt , lambda , gel ( tmp , 3 ) , T , p ) ; Eba4 = Eca4 ; Eba6 = Eca6 ; Eca4 = gel ( tmp , 1 ) ; Eca6 = gel ( tmp , 2 ) ; kpoly = gel ( tmp , 4 ) ; Ib = gel ( tmp , 5 ) ; if ( gc_needed ( btop , 1 ) ) { if ( DEBUGMEM > 1 ) pari_warn ( warnmem , " " ) ; gerepileall ( btop , 6 , & Eba4 , & Eba6 , & Eca4 , & Eca6 , & kpoly , & Ib ) ; } if ( DEBUGLEVEL > 1 ) err_printf ( " " , timer_delay ( ti ) ) ; } avma = ltop ; ellk = upowuu ( ell , k ) ; pellk = umodiu ( q , ellk ) ; * pt_k = k ; return mkvecsmall ( Fl_add ( lambda , Fl_div ( pellk , lambda , ellk ) , ellk ) ) ; }
Returns the trace modulo ell^k when ell is an Elkies prime
Returns the trace modulo ell^k when ell is an Elkies prime