def class_nr_pos_def_qf(D): r""" Compute the class number of positive definite quadratic forms. For fundamental discriminants this is the class number of Q(sqrt(D)), otherwise it is computed using: Cohen 'A course in Computational Algebraic Number Theory', p. 233 """ if D>0: return 0 D4 = D % 4 if D4 == 3 or D4==2: return 0 K = QuadraticField(D) if is_fundamental_discriminant(D): return K.class_number() else: D0 = K.discriminant() Df = ZZ(D).divide_knowing_divisible_by(D0) if not is_square(Df): raise ArithmeticError("Did not get a discrimimant * square! D={0} disc(D)={1}".format(D,D0)) D2 = sqrt(Df) h0 = QuadraticField(D0).class_number() w0 = _get_w(D0) w = _get_w(D) #print "w,w0=",w,w0 #print "h0=",h0 h = 1 for p in prime_divisors(D2): h = QQ(h)*(1-kronecker(D0,p)/QQ(p)) #print "h=",h #print "fak=", h=QQ(h*h0*D2*w)/QQ(w0) return h
def lpp_table(self): """generate the large putative primes table""" output_str = r"${Delta_K}$ & $\Q(\sqrt{{{D}}})$ & {large_putative_primes}\\" latex_output = [] for D in range(-self.range, self.range + 1): if Integer(D).is_squarefree(): if not D in CLASS_NUMBER_ONE_DISCS: if D != 1: K = QuadraticField(D) Delta_K = K.discriminant() candidates = get_isogeny_primes(K, aux_prime_count=25, bound=2000, loop_curves=False) candidates = [ c for c in candidates if c not in EC_Q_ISOGENY_PRIMES ] candidates = [c for c in candidates if c > 71] candidates.sort() large_putative_primes = ", ".join(map(str, candidates)) output_here = output_str.format( Delta_K=Delta_K, D=D, large_putative_primes=large_putative_primes, ) latex_output.append(output_here) for one_line in latex_output: print(one_line)
def class_nr_pos_def_qf(D): r""" Compute the class number of positive definite quadratic forms. For fundamental discriminants this is the class number of Q(sqrt(D)), otherwise it is computed using: Cohen 'A course in Computational Algebraic Number Theory', p. 233 """ if D>0: return 0 D4 = D % 4 if D4 == 3 or D4==2: return 0 K = QuadraticField(D) if is_fundamental_discriminant(D): return K.class_number() else: D0 = K.discriminant() Df = ZZ(D).divide_knowing_divisible_by(D0) if not is_square(Df): raise ArithmeticError,"DId not get a discrinimant * square! D={0} disc(D)={1}".format(D,D0) D2 = sqrt(Df) h0 = QuadraticField(D0).class_number() w0 = _get_w(D0) w = _get_w(D) #print "w,w0=",w,w0 #print "h0=",h0 h = 1 for p in prime_divisors(D2): h = QQ(h)*(1-kronecker(D0,p)/QQ(p)) #print "h=",h #print "fak=", h=QQ(h*h0*D2*w)/QQ(w0) return h
def test_interval(D): K = QuadraticField(D) if not K.discriminant() in CLASS_NUMBER_ONE_DISCS: superset, _ = get_isogeny_primes(K, **TEST_SETTINGS) # test that there are not too many primes left over todo = set(superset).difference(EC_Q_ISOGENY_PRIMES) assert len(todo) == 0 or max(todo) <= 109 assert len(todo) <= 2 or max(todo) <= 31
def oezman_sieve(p, N): """If p is unramified in Q(sqrt(-N)) this always returns True. Otherwise returns True iff p is in S_N or . Only makes sense if p ramifies in K""" M = QuadraticField(-N) if p.divides(M.discriminant()): return True pp = (M * p).factor()[0][0] C_M = M.class_group() if C_M(pp).order() == 1: return True return False
def dimension_cuspforms_sqrt5(k1, k2): ''' Return the dimension of hilbert cusp forms of weight (k1, k2) where k1 > 2 and k2 > 2. cf. K. Takase, on the trace formula of the Hecke operators and the special values of the second L-functions attached to the Hilbert modular forms. manuscripta math. 55, 137 -- 170 (1986). ''' k = (k1, k2) F = QuadraticField(5) rho = (1 + F.gen()) / ZZ(2) a = c_km2_1_rho(k, rho) return (ZZ((k1 - 1) * (k2 - 1)) / ZZ(60) + ZZ(c_km2_1_01(k)) / ZZ(4) + ZZ(c_km2_1_11(k)) / ZZ(3) + ZZ(a + F(a).galois_conjugate()) / ZZ(5))
def test_get_dirichlet_character(): K = QuadraticField(-31) chi = get_dirichlet_character(K) assert (3 * K).is_prime() assert chi(3) == -1 assert not (5 * K).is_prime() assert chi(5) == 1 assert (73 * K).is_prime() assert chi(73) == -1
def main(): for D in square_free_D: K = QuadraticField(D) if not K.discriminant() in CLASS_NUMBER_ONE_DISCS: superset, _ = get_isogeny_primes( K, bound=1000, ice_filter=True, appendix_bound=1000, norm_bound=50, auto_stop_strategy=True, repeat_bound=4, ) possible_new_isog_primes = superset - EC_Q_ISOGENY_PRIMES possible_new_isog_primes_list = list(possible_new_isog_primes) possible_new_isog_primes_list.sort() if possible_new_isog_primes_list: print(f"D = {D} possible isogenies = {possible_new_isog_primes_list}")
def test_interval(self): R = 100 for D in range(-R, R + 1): if Integer(D).is_squarefree(): if not D in CLASS_NUMBER_ONE_DISCS: if D != 1: K = QuadraticField(D) superset = get_isogeny_primes(K, AUX_PRIME_COUNT) self.assertTrue( set(superset).issuperset(EC_Q_ISOGENY_PRIMES))
def c_km2_1_sqrt2(k): K = QuadraticField(2) a = K.gen() k1, k2 = k k1 = k1 % 8 k2 = k2 % 8 k = (k1, k2) if k in [(0, 0), (2, 2), (4, 4), (6, 6), (0, 6), (6, 0), (2, 4), (4, 2)]: return 1 if k in [(3, 7), (7, 3)]: return 2 if k in [(0, 7), (2, 3), (3, 0), (3, 6), (4, 3), (6, 7), (7, 2), (7, 4)]: return a if k1 in [1, 5] or k2 in [1, 5]: return 0 if k in [(0, 3), (2, 7), (3, 2), (3, 4), (4, 7), (6, 3), (7, 0), (7, 6)]: return -a if k in [(3, 3), (7, 7)]: return -2 else: return -1
def oezman_sieve(p, N): """Returns True iff p is in S_N. Only makes sense if p ramifies in K""" M = QuadraticField(-N) h_M = M.class_number() H = M.hilbert_class_field("b") primes_above_p = M.primes_above(p) primes_tot_split_in_hcf = [] for P in primes_above_p: if len(H.primes_above(P)) == h_M: primes_tot_split_in_hcf.append(P) if not primes_tot_split_in_hcf: return False f = R(hilbert_class_polynomial(M.discriminant())) B = NumberField(f, name="t") assert B.degree() == h_M possible_nus = B.primes_above(p) for nu in possible_nus: if nu.residue_class_degree() == 1: return True return False
def quadratic_number_field(): """ Return a quadratic extension of QQ. EXAMPLES: sage: sage.rings.tests.quadratic_number_field() Number Field in a with defining polynomial x^2 - 61099 """ from sage.all import ZZ, QuadraticField while True: d = ZZ.random_element(x=-10**5, y=10**5) if not d.is_square(): return QuadraticField(d, 'a')
def test_from_literature(D, extra_isogeny, appendix_bound, potenial_isogenies): K = QuadraticField(D) upperbound = potenial_isogenies.union(EC_Q_ISOGENY_PRIMES).union( {extra_isogeny}) superset, _ = get_isogeny_primes(K, appendix_bound=appendix_bound, **TEST_SETTINGS) assert set(EC_Q_ISOGENY_PRIMES).difference(superset) == set() assert extra_isogeny in superset assert set( superset.difference(upperbound)) == set(), "We got worse at filtering" assert set( upperbound.difference(superset)) == set(), "We got better at filtering"
def dlmv_table(self): """generate the dlmv table""" output_str = ( r"${Delta_K}$ & $\Q(\sqrt{{{D}}})$ & ${rem} \times 10^{{{exp_at_10}}}$\\" ) for D in range(-self.range, self.range + 1): if Integer(D).is_squarefree(): if not D in CLASS_NUMBER_ONE_DISCS: if D != 1: K = QuadraticField(D) Delta_K = K.discriminant() dlmv_bound = RR(DLMV(K)) log_dlmv_bound = dlmv_bound.log10() exp_at_10 = int(log_dlmv_bound) rem = log_dlmv_bound - exp_at_10 rem = 10**rem rem = rem.numerical_approx(digits=3) output_here = output_str.format(Delta_K=Delta_K, D=D, rem=rem, exp_at_10=exp_at_10) print(output_here)
def compare_formulas_1(D, k): DG = DirichletGroup(abs(D)) chi = DG(kronecker_character(D)) d1 = dimension_new_cusp_forms(chi, k) #if D>0: # lvals=sage.lfunctions.all.lcalc.twist_values(1,2,D) #else: # lvals=sage.lfunctions.all.lcalc.twist_values(1,D,0) #s1=RR(sum([sqrt(abs(lv[0]))*lv[1]*2**len(prime_factors(D/lv[0])) for lv in lvals if lv[0].divides(D) and Zmod(lv[0])(abs(D/lv[0])).is_square()])) #d2=RR(1/pi*s1) d2 = 0 for d in divisors(D): if is_fundamental_discriminant(-d): K = QuadraticField(-d) DD = old_div(ZZ(D), ZZ(d)) ep = euler_phi((chi * DG(kronecker_character(-d))).conductor()) #ep=euler_phi(squarefree_part(abs(D*d))) print("ep=", ep, D, d) ids = [a for a in K.ideals_of_bdd_norm(-DD)[-DD]] eulers1 = [] for a in ids: e = a.euler_phi() if e != 1 and ep == 1: if K(-1).mod(a) != K(1).mod(a): e = old_div(e, (2 * ep)) else: e = old_div(e, ep) eulers1.append(e) print(eulers1, ep) s = sum(eulers1) if ep == 1 and not (d.divides(DD) or abs(DD) == 1): continue print(d, s) if len(eulers1) > 0: d2 += s * K.class_number() return d1 - d2
def cli_handler(args): if not Integer(args.D).is_squarefree(): msg = "Your D is not squarefree. Please choose a " "squarefree D. Exiting." print(msg) return if args.D in CLASS_NUMBER_ONE_DISCS: msg = ( "Your D yields an imaginary quadratic field of class " "number one. These fields have infinitely many isogeny primes. " "Exiting." ) print(msg) return K = QuadraticField(args.D) if args.dlmv: dlmv_bound = DLMV(K) print( "DLMV bound for {} is:\n\n{}\n\nwhich is approximately {}".format( K, dlmv_bound, RR(dlmv_bound) ) ) else: if args.rigorous: bound = None print("Checking all Type 2 primes up to conjectural bound") else: bound = args.bound print("WARNING: Only checking Type 2 primes up to {}.\n".format(bound)) print( ( "To check all, run with '--rigorous', but be advised that " "this will take ages and require loads of memory" ) ) superset = get_isogeny_primes(K, args.aux_prime_count, bound, args.loop_curves) print("superset = {}".format(superset))
def works_method_of_appendix(p, K): """This implements the method of the appendix, returns True if that method is able to remove p as an isogeny prime for K.""" if QuadraticField(-p).class_number() <= K.degree(): return False if p in SMALL_GONALITIES: return False chi = get_dirichlet_character(K) if K.degree() == 2 and chi(p) == -1: return False logger.debug("Testing whether torsion is same") if is_torsion_same(p, K, chi): logger.debug("Torsion is same test passed") logger.debug("Testing whether rank is same") if is_rank_of_twist_zero(p, chi): return True return False
def test_73_Box(self): K = QuadraticField(-31) superset = get_isogeny_primes(K, AUX_PRIME_COUNT) self.assertTrue(set(superset).issuperset(EC_Q_ISOGENY_PRIMES)) self.assertIn(73, superset)
def test_103(self): K = QuadraticField(5 * 577) superset = get_isogeny_primes(K, AUX_PRIME_COUNT) self.assertTrue(set(superset).issuperset(EC_Q_ISOGENY_PRIMES)) self.assertIn(103, superset)
def test_73(self): K = QuadraticField(-127) superset = get_isogeny_primes(K, AUX_PRIME_COUNT, loop_curves=True) self.assertTrue(set(superset).issuperset(EC_Q_ISOGENY_PRIMES)) self.assertIn(73, superset)
def test_191(self): K = QuadraticField(61 * 229 * 145757) superset = get_isogeny_primes(K, AUX_PRIME_COUNT) self.assertTrue(set(superset).issuperset(EC_Q_ISOGENY_PRIMES)) self.assertIn(191, superset)
def test_is_rank_of_twist_zero(): p = 73 K = QuadraticField(-31) chi = get_dirichlet_character(K) assert not is_rank_of_twist_zero(p, chi)
def test_311(self): K = QuadraticField(11 * 17 * 9011 * 23629) superset = get_isogeny_primes(K, AUX_PRIME_COUNT) self.assertTrue(set(superset).issuperset(EC_Q_ISOGENY_PRIMES)) self.assertIn(311, superset)
def _test(self): from sage.all import QuadraticField, loads, dumps K = QuadraticField(-1, 'i') if loads(dumps(K.maximal_order())) is not K.maximal_order(): raise Exception("#24934 has not been fixed")
# -*- coding: utf-8; mode: sage -*- from itertools import takewhile from pickle import Pickler from os.path import join from sage.all import (ZZ, FreeModule, PolynomialRing, QuadraticField, TermOrder, cached_method, flatten, gcd, load, QQ, cached_function, PowerSeriesRing, O) from sage.libs.singular.function import singular_function K = QuadraticField(5) Monomial_Wts = (6, 5, 2) R = PolynomialRing(K, names='g6, g5, g2', order=TermOrder('wdegrevlex', Monomial_Wts)) g6, g5, g2 = R.gens() DATA_DIR = "/home/sho/work/rust/hilbert_sqrt5/data/brackets" smodule = singular_function("module") sideal = singular_function("ideal") squotient = singular_function("quotient") smres = singular_function("mres") slist = singular_function("list") sintersect = singular_function("intersect") ssyz = singular_function("syz") def diag_res(f): R_el = PolynomialRing(QQ, "E4, E6") E4, E6 = R_el.gens() Delta = (E4**3 - E6**2) / 1728 d = {g2: E4, g5: 0, g6: 2 * Delta} return f.subs(d)
[email protected]. ==================================================================== """ import pytest from sage.all import EllipticCurve_from_j, GF, QQ, QuadraticField from sage.rings.polynomial.polynomial_ring import polygen from sage.schemes.elliptic_curves.constructor import EllipticCurve from sage_code.frobenius_polynomials import ( semi_stable_frobenius_polynomial, isogeny_character_values_12, ) K = QuadraticField(-127, "D") D = K.gen(0) j = 20 * (3 * (-26670989 - 15471309 * D) / 2**26)**3 # this is one of the curves from the Gonzaléz, Lario, and Quer article E = EllipticCurve_from_j(j) def test_semi_stable_frobenius_polynomial(): # test that we indeed have a 73 isogeny mod p for p in 2, 3, 5, 7, 11, 19: for pp, e in (p * K).factor(): f = semi_stable_frobenius_polynomial(E, pp) assert not f.change_ring(GF(73)).is_irreducible()
def test_works_method_of_appendix(D, p, works): K = QuadraticField(D) result = works_method_of_appendix(p, K) assert result == works