bridge/class-master/depend/pari/src/basemath/ellisog.c
/* Given an elliptic curve E and a polynomial kerp whose roots give the
 * x-coordinates of a subgroup G of E, return the curve E/G and,
 * if only_image is zero, the isogeny pi:E -> E/G. Variables vx and vy are
 * used to describe the isogeny (and are ignored if only_image is zero). */
Given an elliptic curve E and a polynomial kerp whose roots give the
x-coordinates of a subgroup G of E, return the curve E/G and,
if only_image is zero, the isogeny pi:E -> E/G. Variables vx and vy are
used to describe the isogeny (and are ignored if only_image is zero).
Given an elliptic curve E and a polynomial kerp whose roots give the x - coordinates of a subgroup G of E return the curve E / G and if only_image is zero the isogeny pi : E - > E / G . Variables vx and vy are used to describe the isogeny ( and are ignored if only_image is zero ) .
static GEN
isogeny_from_kernel_poly(GEN E, GEN kerp, long only_image, long vx, long vy)
{
  long m;
  GEN b2 = ell_get_b2(E), b4 = ell_get_b4(E), b6 = ell_get_b6(E);
  GEN p1, p2, p3, x, y, f, g, two_tors, EE, t, w;
  GEN kerh = two_torsion_part(E, kerp);
  GEN kerq = RgX_divrem(kerp, kerh, ONLY_DIVIDES);
  if (!kerq) pari_err_BUG("isogeny_from_kernel_poly");
  m = degpol(kerq);
  kerp = RgX_normalize(kerp);
  kerq = RgX_normalize(kerq);
  kerh = RgX_normalize(kerh);
  switch(degpol(kerh))
  {
  case 0:
    two_tors = only_image? mkvec2(gen_0, gen_0):
      mkvec5(gen_0, gen_0, pol_0(vx), pol_0(vx), pol_1(vx));
    break;
  case 1:
    two_tors = contrib_weierstrass_pt(E, kerh, only_image,vx,vy);
    break;
  case 3:
    two_tors = contrib_full_tors(E, kerh, only_image,vx,vy);
    break;
  default:
    two_tors = NULL;
    pari_err_DOMAIN("isogeny_from_kernel_poly", "kernel polynomial",
                    "does not define a subgroup of", E, kerp);
  }
  first_three_power_sums(kerq,&p1,&p2,&p3);
  x = pol_x(vx);
  y = pol_x(vy);
  t = gadd(gmulsg(6L, p2), gadd(gmul(b2, p1), gmulsg(m, b4)));
  w = gadd(gmulsg(10L, p3),
           gadd(gmul(gmulsg(2L, b2), p2),
                gadd(gmul(gmulsg(3L, b4), p1), gmulsg(m, b6))));
  EE = make_velu_curve(E, gadd(t, gel(two_tors, 1)),
                          gadd(w, gel(two_tors, 2)));
  if (only_image) return EE;
  f = isog_abscissa(E, kerp, kerq, x, two_tors);
  g = isog_ordinate(E, kerp, kerq, x, y, two_tors, f);
  return mkvec2(EE, mkvec3(f,g,kerp));
}
static GEN isogeny_from_kernel_poly ( GEN E , GEN kerp , long only_image , long vx , long vy ) { long m ; GEN b2 = ell_get_b2 ( E ) , b4 = ell_get_b4 ( E ) , b6 = ell_get_b6 ( E ) ; GEN p1 , p2 , p3 , x , y , f , g , two_tors , EE , t , w ; GEN kerh = two_torsion_part ( E , kerp ) ; GEN kerq = RgX_divrem ( kerp , kerh , ONLY_DIVIDES ) ; if ( ! kerq ) pari_err_BUG ( " " ) ; m = degpol ( kerq ) ; kerp = RgX_normalize ( kerp ) ; kerq = RgX_normalize ( kerq ) ; kerh = RgX_normalize ( kerh ) ; switch ( degpol ( kerh ) ) { case 0 : two_tors = only_image ? mkvec2 ( gen_0 , gen_0 ) : mkvec5 ( gen_0 , gen_0 , pol_0 ( vx ) , pol_0 ( vx ) , pol_1 ( vx ) ) ; break ; case 1 : two_tors = contrib_weierstrass_pt ( E , kerh , only_image , vx , vy ) ; break ; case 3 : two_tors = contrib_full_tors ( E , kerh , only_image , vx , vy ) ; break ; default : two_tors = NULL ; pari_err_DOMAIN ( " " , " " , " " , E , kerp ) ; } first_three_power_sums ( kerq , & p1 , & p2 , & p3 ) ; x = pol_x ( vx ) ; y = pol_x ( vy ) ; t = gadd ( gmulsg ( 6L , p2 ) , gadd ( gmul ( b2 , p1 ) , gmulsg ( m , b4 ) ) ) ; w = gadd ( gmulsg ( 10L , p3 ) , gadd ( gmul ( gmulsg ( 2L , b2 ) , p2 ) , gadd ( gmul ( gmulsg ( 3L , b4 ) , p1 ) , gmulsg ( m , b6 ) ) ) ) ; EE = make_velu_curve ( E , gadd ( t , gel ( two_tors , 1 ) ) , gadd ( w , gel ( two_tors , 2 ) ) ) ; if ( only_image ) return EE ; f = isog_abscissa ( E , kerp , kerq , x , two_tors ) ; g = isog_ordinate ( E , kerp , kerq , x , y , two_tors , f ) ; return mkvec2 ( EE , mkvec3 ( f , g , kerp ) ) ; }
Given an elliptic curve E and a polynomial kerp whose roots give the
 x-coordinates of a subgroup G of E, return the curve E/G and,
 if only_image is zero, the isogeny pi:E -> E/G.
Given an elliptic curve E and a polynomial kerp whose roots give the x - coordinates of a subgroup G of E return the curve E / G and if only_image is zero the isogeny pi : E - > E / G .
/* isogeny degree: 2*degpol(kerp)+1-degpol(kerh) */ /* t = 6 * p2 + b2 * p1 + m * b4, */ /* w = 10 * p3 + 2 * b2 * p2 + 3 * b4 * p1 + m * b6, */