This page provides the SageMath script which confirms the computational parts of the arXiv preprint Transitive sets of derangements in primitive actions of PSL2(q). You can
from itertools import product
# Corollary 3.3
for q in [z for z in range(5, 21, 2) if is_prime_power(z)]:
F = GF(q)
S = {r + 1/r for r in F if r != 0}
S.add(F.zero())
for a, b, c, d in product(F, repeat=4):
if a*d - b*c == 1:
if all(a*r + d/r in S and -c*r + b/r in S for r in F if r != 0):
assert ((a == d == 0 or b == c == 0) or
(q == 9 and F(2) in {a*r + d/r for r in F if r != 0}))
print('Corollary 3.3 confirmed')
# Corollary 3.6
for q in [z for z in range(3, 21, 2) if is_prime_power(z)]:
F = GF(q^2)
S = {r + 1/r for r in F if r^(q+1) == 1}
S.add(F.zero())
for a, b in product(F, repeat=2):
if a^(q+1) + b^(q+1) == 1:
if all(a*r + a^(q+1)/r in S and b*r + b^(q+1)/r in S for
r in F if r^(q+1) == 1):
assert a == 0 or b == 0
print('Corollary 3.6 confirmed')
def gener(L):
# Compute matrix group generated by the matrices in L
S = {matrix(z, immutable=True) for z in L}
flag = True
while flag:
C = S.copy()
flag = False
for x in L:
for y in S:
xy = matrix(x*y, immutable=True)
if xy not in C:
C.add(xy)
flag = True
S = C.copy()
return S
catal = [1, 2, 5, 14, 42]
# Hbar = A_4 (Case (d))
F.<i> = QuadraticField(-1)
S.<a, b, c, d, A, B, C, D> = F[]
I = matrix(S, 2, [i, 0, 0, -i])
J = matrix(S, 2, [0, 1, -1, 0])
K = I*J
W = (-matrix.identity(S, 2) + I + J + K)/2
H = gener([I, W])
x = matrix(2, [a, b, c, d])
y = matrix(2, [A, B, C, D])
T = {z.trace() for z in H} - {-2, 2}
assert prod(A - t for t in T) == A^3 - A
txy = x.trace()*y.trace() - (x*y).trace()
det = x.det()
for m in [0, 1]:
s = sum((h*y).trace()*(h*x).trace()^(2*m+1) for h in H)
assert 2*s == len(H)*catal[m]*txy*det^m
print('Case A_4 confirmed')
# Hbar = S_4 (Case (e))
N.<i> = QuadraticField(-1)
_x = N['dummy'].0
F.<rho> = NumberField(_x^2 - 2)
S.<a, b, c, d, A, B, C, D> = F[]
I = matrix(S, 2, [i, 0, 0, -i])
J = matrix(S, 2, [0, 1, -1, 0])
K = I*J
W = (-matrix.identity(S, 2) + I + J + K)/2
H = gener([(J + K)/rho, W])
x = matrix(2, [a, b, c, d])
y = matrix(2, [A, B, C, D])
T = {z.trace() for z in H} - {-2, 2}
assert prod(A - t for t in T) == A^5 + (-3)*A^3 + 2*A
txy = x.trace()*y.trace() - (x*y).trace()
det = x.det()
for m in [0, 1, 2]:
s = sum((h*y).trace()*(h*x).trace()^(2*m+1) for h in H)
assert 2*s == len(H)*catal[m]*txy*det^m
print('Case S_4 confirmed')
# Hbar = A_5 (Case (f))
N.<i> = QuadraticField(-1)
_x = N['dummy'].0
F.<sig> = NumberField(_x^2 + _x - 1)
S.<a, b, c, d, A, B, C, D> = F[]
I = matrix(S, 2, [i, 0, 0, -i])
J = matrix(S, 2, [0, 1, -1, 0])
K = I*J
W = (-matrix.identity(S, 2) + I + J + K)/2
H = gener([I/2 + J*sig/2 + K*(sig+1)/2, W])
x = matrix(2, [a, b, c, d])
y = matrix(2, [A, B, C, D])
T = {z.trace() for z in H} - {-2, 2}
assert prod(A - t for t in T) == A^7 + (-4)*A^5 + 4*A^3 - A
txy = x.trace()*y.trace() - (x*y).trace()
det = x.det()
for m in [0, 1, 2, 3, 4]:
s = sum((h*y).trace()*(h*x).trace()^(2*m+1) for h in H)
assert 2*s == len(H)*catal[m]*txy*det^m
print('Case A_5 confirmed')
print('Finished, all claims confirmed!')