Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved ozman sieve #95

Merged
merged 3 commits into from Jan 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions helper_scripts/bash_sage_init.sh
Expand Up @@ -7,5 +7,8 @@ if [ ! -f ${SAGE_BIN_DIR}/sage-env-config ]; then
SAGE_BIN_DIR=$(sage -sh -c 'echo $SAGE_VENV')/bin
fi
source ${SAGE_BIN_DIR}/sage-env-config
if [ ! -f ${SAGE_BIN_DIR}/sage-env ]; then
SAGE_BIN_DIR=$(sage -sh -c 'echo $SAGE_VENV')/bin
fi
source ${SAGE_BIN_DIR}/sage-env
export PATH=$(dirname -- ${HELPER_DIR})/venv/bin:$SAGE_BIN_DIR:${PATH}
2 changes: 1 addition & 1 deletion isogeny_primes.py
Expand Up @@ -61,7 +61,7 @@ def DLMV(K):
delta_K = log(2) / (r_K + 1)
C_1_K = r_K ** (r_K + 1) * delta_K ** (-(r_K - 1)) / 2
C_2_K = exp(24 * C_1_K * R_K)
CHEB_DEN_BOUND = (4 * log(Delta_K ** h_K) + 5 * h_K + 5) ** 2
CHEB_DEN_BOUND = (4 * log(Delta_K**h_K) + 5 * h_K + 5) ** 2
C_0 = ((CHEB_DEN_BOUND ** (12 * h_K)) * C_2_K + CHEB_DEN_BOUND ** (6 * h_K)) ** 4

# Now the Type 1 and 2 bounds
Expand Down
2 changes: 1 addition & 1 deletion latex_helper.py
Expand Up @@ -176,7 +176,7 @@ def type_2_bounds(self):
log_type_2_bound = type_2_bound.log10()
exp_at_10 = int(log_type_2_bound)
rem = log_type_2_bound - exp_at_10
rem = 10 ** rem
rem = 10**rem
rem = rem.numerical_approx(digits=3)
lmfdb_link = LMFDB_NF_URL_TRUNK.format(label)
lmfdb_link_latex = r"\href{{{the_link}}}{{{my_text}}}".format(
Expand Down
11 changes: 4 additions & 7 deletions requirements-dev.txt
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with python 3.9
# This file is autogenerated by pip-compile with python 3.10
# To update, run:
#
# pip-compile requirements-dev.in
Expand Down Expand Up @@ -73,7 +73,7 @@ pyflakes==2.5.0
# flake8
pylint==2.15.5
# via -r requirements-dev.in
pyparsing==3.0.6
pyparsing==3.0.9
# via
# -c requirements.txt
# packaging
Expand All @@ -100,16 +100,13 @@ tomli==2.0.1
# pytest
tomlkit==0.11.6
# via pylint
typing-extensions==4.0.1
typing-extensions==4.4.0
# via
# -c requirements.txt
# astroid
# black
# mypy
# pylint
vulture==2.6
# via -r requirements-dev.in
wrapt==1.13.3
wrapt==1.14.1
# via
# -c requirements.txt
# astroid
2 changes: 1 addition & 1 deletion requirements.txt
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with python 3.9
# This file is autogenerated by pip-compile with python 3.10
# To update, run:
#
# pip-compile requirements.in
Expand Down
22 changes: 11 additions & 11 deletions sage_code/character_enumeration.py
Expand Up @@ -45,15 +45,15 @@
def filter_possible_values(possible_values_list, q, residue_class_degree, prime_field):

output = []
fq = q ** residue_class_degree
fq = q**residue_class_degree
for c in possible_values_list:
if c ** 2 == prime_field(1):
if c**2 == prime_field(1):
output.append(c)
elif c ** 2 == prime_field(fq ** 2):
elif c**2 == prime_field(fq**2):
output.append(c)
else:
possible_mid_coeffs = lifts_in_hasse_range(fq, c + prime_field(fq) / c)
possible_weil_polys = [x ** 2 + a * x + fq for a in possible_mid_coeffs]
possible_weil_polys = [x**2 + a * x + fq for a in possible_mid_coeffs]

elliptic_weil_polys = [
f
Expand Down Expand Up @@ -87,13 +87,13 @@ def get_possible_vals_at_gens(gens_info, eps, embeddings, residue_field, prime_f
q = class_gp_gen.smallest_integer()
e = class_gp_gen.residue_class_degree()
filtered_values = filter_possible_values(possible_values, q, e, prime_field)
output[class_gp_gen] = list({x ** 12 for x in filtered_values})
output[class_gp_gen] = list({x**12 for x in filtered_values})

return output


def tuple_exp(tup, exp_tup):
return tuple((t ** e for t, e in zip(tup, exp_tup)))
return tuple((t**e for t, e in zip(tup, exp_tup)))


def lifts_in_hasse_range(fq, res_class):
Expand All @@ -114,13 +114,13 @@ def lifts_in_hasse_range(fq, res_class):

low_run = centered_lift

while low_run ** 2 <= fq4:
while low_run**2 <= fq4:
output.append(low_run)
low_run = low_run - p

high_run = centered_lift + p

while high_run ** 2 <= fq4:
while high_run**2 <= fq4:
output.append(high_run)
high_run = high_run + p

Expand Down Expand Up @@ -224,7 +224,7 @@ def final_filter(
# Check that these exponents correspond to the ideals in
# my_gens_ideals in the correct order
sanity_check = prod(
[Q ** a for Q, a in zip(my_gens_ideals, exponents_in_class_group)]
[Q**a for Q, a in zip(my_gens_ideals, exponents_in_class_group)]
)
assert C_K(sanity_check) == C_K(q)

Expand Down Expand Up @@ -285,7 +285,7 @@ def character_enumeration_filter(
gens_info = {}
for q in my_gens_ideals:
q_order = C_K(q).multiplicative_order()
alphas = (q ** q_order).gens_reduced()
alphas = (q**q_order).gens_reduced()
assert len(alphas) == 1
alpha = alphas[0]
gens_info[q] = (q_order, alpha)
Expand Down Expand Up @@ -314,7 +314,7 @@ def character_enumeration_filter(
# stop condition:
# 4sqrt(Nm(q)) > 2p
# Nm(q) > (p/2)**2
stop = (p ** 2 // 4) + 1
stop = (p**2 // 4) + 1
if enumeration_bound:
stop = min(stop, enumeration_bound)
aux_primes = primes_iter(K, stop)
Expand Down
6 changes: 3 additions & 3 deletions sage_code/common_utils.py
Expand Up @@ -76,12 +76,12 @@ def get_weil_polys(F):
"""
q = F.characteristic()
a = F.degree()
weil_polys = R.weil_polynomials(2, q ** a)
weil_polys = R.weil_polynomials(2, q**a)
return [f for f in weil_polys if weil_polynomial_is_elliptic(f, q, a)]


def get_ordinary_weil_polys_from_values(q, a):
weil_polys = R.weil_polynomials(2, q ** a)
weil_polys = R.weil_polynomials(2, q**a)
return [f for f in weil_polys if f[1] % q != 0]


Expand Down Expand Up @@ -129,7 +129,7 @@ def to_A(g):

def from_A(a):
assert a in A
return C_K.prod(gi ** ei for gi, ei in zip(C_K.gens(), a))
return C_K.prod(gi**ei for gi, ei in zip(C_K.gens(), a))

return A, to_A, from_A

Expand Down
4 changes: 2 additions & 2 deletions sage_code/frobenius_polynomials.py
Expand Up @@ -114,7 +114,7 @@ def semi_stable_frobenius_polynomial(
x = polygen(K)
u = uniformizer(q)
e = semistable_ramification(local_data)
L = K.extension(x ** e - t * u, "a")
L = K.extension(x**e - t * u, "a")
EL = E.change_ring(L)
qL = L.primes_above(q)[0]
Ebar = reduction(EL, qL)
Expand Down Expand Up @@ -146,4 +146,4 @@ def isogeny_character_values_12(
E: EllipticCurve_number_field, p: Integer, q: NumberFieldFractionalIdeal
):
values = isogeny_character_values(E, p, q)
return [a ** 12 for a in values]
return [a**12 for a in values]
4 changes: 2 additions & 2 deletions sage_code/generic.py
Expand Up @@ -210,7 +210,7 @@ def get_aux_primes(K, norm_bound, C_K, h_K, contains_imaginary_quadratic):


def alpha_eps_beta_bound(alpha_eps, beta, nm_q_pow_12hq):
C_mat = alpha_eps ** 2 - alpha_eps * beta.trace() + nm_q_pow_12hq
C_mat = alpha_eps**2 - alpha_eps * beta.trace() + nm_q_pow_12hq
N = ZZ(C_mat.det())
return N

Expand Down Expand Up @@ -248,7 +248,7 @@ def ABC_integers(
multiplicative_bounds = {}

nm_q = ZZ(frak_q.absolute_norm())
alphas = (frak_q ** q_class_group_order).gens_reduced()
alphas = (frak_q**q_class_group_order).gens_reduced()
assert len(alphas) == 1, "q^q_class_group_order not principal, which is very bad"
alpha = alphas[0]
output_dict = {}
Expand Down
2 changes: 1 addition & 1 deletion sage_code/type_one_primes.py
Expand Up @@ -287,7 +287,7 @@ def apply_formal_immersion_at_2(
def get_N(frob_poly, nm_q, exponent):
"""Helper method for computing Type 1 primes"""
beta = Matrix.companion(frob_poly) ** exponent
N = ZZ(1 - beta.trace() + nm_q ** exponent)
N = ZZ(1 - beta.trace() + nm_q**exponent)
return N


Expand Down
10 changes: 5 additions & 5 deletions sage_code/type_two_primes.py
Expand Up @@ -50,7 +50,7 @@

logger = logging.getLogger(__name__)

GENERIC_UPPER_BOUND = 10 ** 30
GENERIC_UPPER_BOUND = 10**30


def LLS(p):
Expand All @@ -68,7 +68,7 @@ def get_type_2_uniform_bound(ecdb_type):
else:
raise ValueError("argument must be LSS or BS")

f = BOUND_TERM ** 6 + BOUND_TERM ** 3 + 1 - x
f = BOUND_TERM**6 + BOUND_TERM**3 + 1 - x

try:
bound = find_root(f, 1000, GENERIC_UPPER_BOUND)
Expand Down Expand Up @@ -123,8 +123,8 @@ def satisfies_condition_CC(K, p):
for q in prime_range(p / 4):
for frak_q in K.primes_above(q):
f = frak_q.residue_class_degree()
if f % 2 == 1 and q ** f < p / 4:
if (q ** (2 * f) + q ** f + 1) % p != 0:
if f % 2 == 1 and q**f < p / 4:
if (q ** (2 * f) + q**f + 1) % p != 0:
if legendre_symbol(q, p) == 1: # i.e. not inert
return False
return True
Expand All @@ -141,7 +141,7 @@ def satisfies_condition_CC_uniform(possible_odd_f, p):
return False
for q in prime_range((p / 4) ^ (1 / max(possible_odd_f)) + 1):
if legendre_symbol(q, p) == 1:
if all((q ** (2 * f) + q ** f + 1) % p != 0 for f in possible_odd_f):
if all((q ** (2 * f) + q**f + 1) % p != 0 for f in possible_odd_f):
return False
return True

Expand Down
22 changes: 13 additions & 9 deletions sage_code/weeding.py
Expand Up @@ -39,6 +39,7 @@
QuadraticField,
companion_matrix,
gcd,
legendre_symbol,
oo,
parent,
prime_range,
Expand All @@ -59,16 +60,21 @@

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"""
Otherwise returns True iff p is in S_N. Only makes sense if p ramifies in K.
Also assumes that N is prime (for the time being).
"""
assert N.is_prime() and N > 2

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
if pp.is_principal():
if N % 4 == 3:
return True
if legendre_symbol(p, N) == 1:
return True
BarinderBanwait marked this conversation as resolved.
Show resolved Hide resolved

return False

Expand All @@ -77,10 +83,8 @@ def najman_trbovic_filter(unram_primes, ramified_primes):
"""Return True if a possible isogeny prime can be removed via
Theorem 2.13 of the paper of Najman-Trbovic"""

absurd_intersection = set(unram_primes).intersection(
set(ramified_primes)
)
return (len(absurd_intersection) > 0)
absurd_intersection = set(unram_primes).intersection(set(ramified_primes))
return len(absurd_intersection) > 0


def get_dirichlet_character(K):
Expand Down Expand Up @@ -119,7 +123,7 @@ def is_torsion_same(p, K, chi, B=30, uniform=False):
for q, i in frob_poly_data:
frob_pol_q = J0_min.frobenius_polynomial(q)
frob_mat = companion_matrix(frob_pol_q)
point_counts.append((frob_mat ** i).charpoly()(1))
point_counts.append((frob_mat**i).charpoly()(1))

# Recall that the rational torsion on J0(p) is entirely contained in
# the minus part (theorem of Mazur), so checking no-growth of torsion
Expand Down
24 changes: 12 additions & 12 deletions tests/fast_tests/test_character_enumeration.py
Expand Up @@ -62,10 +62,10 @@ def test_filter_possible_values(possible_values_list, q, e, prime, result):
[
(11, GF(3)(0), [0, -3, -6, 3, 6]),
# make sure we include +/-2sqrt(fq) but not +/-(2sqrt(fq)+1),
(145757 ** 2, GF(357686312646216567629137)(2 * 145757), [2 * 145757]),
(145757 ** 2, GF(357686312646216567629137)(-2 * 145757), [-2 * 145757]),
(145757 ** 2, GF(357686312646216567629137)(2 * 145757 + 1), []),
(145757 ** 2, GF(357686312646216567629137)(-2 * 145757 - 1), []),
(145757**2, GF(357686312646216567629137)(2 * 145757), [2 * 145757]),
(145757**2, GF(357686312646216567629137)(-2 * 145757), [-2 * 145757]),
(145757**2, GF(357686312646216567629137)(2 * 145757 + 1), []),
(145757**2, GF(357686312646216567629137)(-2 * 145757 - 1), []),
],
)
def test_lifts_in_hasse_range(fq, res_class, expected_range):
Expand All @@ -79,12 +79,12 @@ def test_lifts_in_hasse_range(fq, res_class, expected_range):
@pytest.mark.parametrize(
"f, q",
[
(x ** 2 - x + 1007, 13),
(x ** 2 - x + 1007, 17),
(x ** 2 - x + 1007, 19),
(x ** 2 - 11 * 17 * 9011 * 23629, 17),
(x ** 2 - 11 * 17 * 9011 * 23629, 47),
(x ** 2 - 11 * 17 * 9011 * 23629, 89),
(x**2 - x + 1007, 13),
(x**2 - x + 1007, 17),
(x**2 - x + 1007, 19),
(x**2 - 11 * 17 * 9011 * 23629, 17),
(x**2 - 11 * 17 * 9011 * 23629, 47),
(x**2 - 11 * 17 * 9011 * 23629, 89),
],
)
@pytest.mark.skip(reason="Only for profiling putative faster solution")
Expand All @@ -105,9 +105,9 @@ def test_ideal_log_relation_prime_gens(f, q):
exponents = C_K(qq).exponents()

t = qq.ideal_log_relation()
alpha_new = t * prod([(relation ** e) for relation, e in zip(relations, exponents)])
alpha_new = t * prod([(relation**e) for relation, e in zip(relations, exponents)])

sanity_check = prod([Q ** a for Q, a in zip(prime_gens, exponents)])
sanity_check = prod([Q**a for Q, a in zip(prime_gens, exponents)])
assert C_K(sanity_check) == C_K(qq)

the_principal_ideal = qq * prod([Q ** (-a) for Q, a in zip(prime_gens, exponents)])
Expand Down
4 changes: 2 additions & 2 deletions tests/fast_tests/test_common_utils.py
Expand Up @@ -36,8 +36,8 @@

x = polygen(QQ)
test_cases = [
(x ** 5 - x ** 4 + 2 * x ** 3 - 4 * x ** 2 + x - 1, 20),
(x ** 6 - 2 * x ** 5 + 6 * x ** 4 + 22 * x ** 3 + 41 * x ** 2 + 48 * x + 36, 6),
(x**5 - x**4 + 2 * x**3 - 4 * x**2 + x - 1, 20),
(x**6 - 2 * x**5 + 6 * x**4 + 22 * x**3 + 41 * x**2 + 48 * x + 36, 6),
]


Expand Down
8 changes: 4 additions & 4 deletions tests/fast_tests/test_frobenius_polynomials.py
Expand Up @@ -39,7 +39,7 @@

K = QuadraticField(-127, "D")
D = K.gen(0)
j = 20 * (3 * (-26670989 - 15471309 * D) / 2 ** 26) ** 3
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)

Expand All @@ -59,8 +59,8 @@ def test_semi_stable_frobenius_polynomial_t():
x = polygen(QQ)
K = QQ.extension(x - 1, "one")
E = EllipticCurve(K, [49, 343])
assert E.discriminant() == -(2 ** 4) * 31 * 7 ** 6
assert E.j_invariant() == K(2 ** 8 * 3 ** 3) / 31
assert E.discriminant() == -(2**4) * 31 * 7**6
assert E.j_invariant() == K(2**8 * 3**3) / 31
f1 = semi_stable_frobenius_polynomial(E, K * 7, 1)
f2 = semi_stable_frobenius_polynomial(E, K * 7, -1)(x=-x)
assert f1 == f2
Expand All @@ -72,7 +72,7 @@ def test_semi_stable_frobenius_polynomial_t():
(2, {1, 8}),
(3, {1}),
(7, {72}),
(11, {13 ** 12 % 73, 57 ** 12 % 73}),
(11, {13**12 % 73, 57**12 % 73}),
],
)
def test_isogeny_character_values_12(p, values):
Expand Down