davidloeffler

Sage script for endomorphisms (v2)

May 23rd, 2021 (edited)
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.43 KB | None | 0 0
  1. def ordernorm(A, n):
  2.     """ Does the quadratic order A contain an element of norm n? """
  3.     K = A.number_field()
  4.     Is = K.ideals_of_bdd_norm(n)[n]
  5.     for I in Is:
  6.         if not I.is_principal(): continue
  7.         g = I.gens_reduced()[0]
  8.         for u in K.roots_of_unity():
  9.             if g*u in A: return True
  10.     return False
  11.    
  12. def isos_any_degree(E, n):
  13.     """ Compute all isogenies from E of degree n """
  14.     factors = flatten(list([p]*e for (p, e) in n.factor()))
  15.     isos = E.isogenies_prime_degree(factors[0])
  16.     for f in factors[1:]:
  17.         new_isos = []
  18.         for h in isos:
  19.             EE = h.codomain()
  20.             for j in EE.isogenies_prime_degree(f):
  21.                 new_isos.append(j*h)
  22.         isos = new_isos
  23.     return isos
  24.  
  25. def has_endo(E, n):
  26.     """ Does E have an endomorphism of degree n? """
  27.     H = isos_any_degree(E, n)
  28.     for h in H:
  29.         if h.codomain().is_isomorphic(E):
  30.             return True
  31.     return False
  32.  
  33. def endomorphism_conductor(E):
  34.     """ Compute the conductor of the order which is the endomorphism ring of E. """
  35.     A0 = E.frobenius_order()
  36.     K = A0.number_field()
  37.     if K.degree() != 2: raise ValueError
  38.  
  39.     if K.disc() % 4:
  40.         t = (K(K.disc()).sqrt() + 1)/2
  41.     else:
  42.         t = K(K.disc()/4).sqrt()
  43.  
  44.     c0 = ZZ((A0.discriminant() / K.discriminant()).sqrt())
  45.     assert A0 == K.order([c0*t])
  46.  
  47.     ords = [K.order([c*t]) for c in c0.divisors()]
  48.    
  49.     auts = len(E.automorphisms())
  50.     ords = [A for A in ords if len(list(u for u in K.roots_of_unity() if u in A)) == auts]
  51.        
  52.     for n in [2..100]:
  53.         if len(ords) == 1:
  54.             break
  55.         if len(ords) == 0:
  56.             raise ArithmeticError
  57.         #print("Testing n = %s, candidate orders %s" % (n, [A.discriminant() for A in ords]))
  58.         if all(ordernorm(A, n) for A in ords):
  59.             #print("n = %s won't help: all have norm n" % n)
  60.             continue
  61.         elif all (not ordernorm(A, n) for A in ords):
  62.             #print("n = %s won't help: none have norm n" % n)
  63.             continue
  64.         if has_endo(E, n):
  65.             ords = [A for A in ords if ordernorm(A, n)]
  66.         else:
  67.             ords = [A for A in ords if not ordernorm(A, n)]
  68.     else:
  69.         raise ArithmeticError("Can't distinguish orders of conductors %s and %s" % (ords[0].discriminant(), ords[1].discriminant()))
  70.     return (ords[0].discriminant() / K.discriminant()).sqrt()
Add Comment
Please, Sign In to add comment