I think it is probably easier to just directly generate a version of PGL
that does act on the points of ProjectiveSpace
. This code generates the collineation group of ProjectiveSpace
and PGL as a subgroup of it.
def matrix_as_permutation(projective_space,M):
points_to_process = [point for point in projective_space]
assert M.is_invertible(), "matrix must be invertible"
assert len(points_to_process[0]) == M.nrows(), "dimension of space and matrix must match"
perm = []
while(len(points_to_process)>0):
point = points_to_process[0]
cycle = [point]
points_to_process.remove(point)
next = M*point
while(next != point):
cycle.append(next)
points_to_process.remove(next)
next=M*next
perm.append(tuple(cycle))
return(perm)
def frobenius_as_permutation(projective_space):
points_to_process = [point for point in projective_space]
F = projective_space.base()
p = F.characteristic()
perm = []
while(len(points_to_process)>0):
point = points_to_process[0]
cycle = [point]
points_to_process.remove(point)
next = projective_space([x^p for x in point])
while(next != point):
cycle.append(next)
points_to_process.remove(next)
next=projective_space([x^p for x in next])
perm.append(tuple(cycle))
return(perm)
def collineation_and_projective_linear_group(n,F):
ps = ProjectiveSpace(n-1,F)
L1 = [[0 for j in range(n)] for i in range(n)]
L1[0][0]=-1
for i in range(n-1):
L1[i][i+1] = -1
L1[n-1][0]=1
M1 = matrix(F,L1)
g1 = matrix_as_permutation(ps,M1)
a = F.multiplicative_generator()
L2 = [[0 for j in range(n)] for i in range(n)]
L2[0][0] = a
for i in range(1,n):
L2[i][i] = 1
M2 = matrix(F,L2)
g2 = matrix_as_permutation(ps,M2)
g3 = frobenius_as_permutation(ps)
coll = PermutationGroup(gens=[g1,g2,g3])
pgl = coll.subgroup(gens=[g1,g2])
return((coll,pgl))
Related:
is_isomorphic
between matrix group and permutation group