import sympy as sym
from sympy import poly
a = sym.Symbol('a')
b = sym.Symbol('b')
c = sym.Symbol('c')
d = sym.Symbol('d')
e = sym.Symbol('e')
def make_T(Fpair): #Subfunction for the group builder
def T(L):
return Fpair[0][0](Fpair[1][0](L))
return T
#Takes in a specific set of maps and genereates the group G_k using those maps as a base.
#The 120 benchmark is an optimization made with foresight that this group only gets that big,
#removing the constraint has no effect other than making group generation longer
def Build_Group(S, base):
G = []
out = set()
i = 0
for x in S:
out.add(tuple(x[1]))
G.append(x)
while i < len(G) and len(G) < 120:
for f in G:
T = make_T([G[i], f])
res = T(base)
if not(tuple(res) in out):
out.add(tuple(res))
G.append([T, res])
T = make_T([f, G[i]])
res = T(base)
if not(tuple(res) in out):
out.add(tuple(res))
G.append([T, res])
i += 1
return G
def genXk(k): #Generates the set G_k will act upon
X_k = set()
for m in range(1,k):
for n in range(1,k):
for l in range(1,k):
for p in [t for t in range(0,k) if t not in [m,n,l]]:
for q in [t for t in range(0,k) if t not in [m,n,l, (m+n+l - p) %k]]:
X_k.add((m,n,l,p,q))
return X_k
#Takes in G_k and an integer k >= 2 and determines the orbits of the action of G_k on X_k
def genorbits(G, k):
X_k = genXk(k)
Y = genXk(k)
orbits = set()
while len(Y) > 0:
for x in X_k:
if not(x in Y):
continue
orbitx = set()
for f in G:
y = tuple([l % k for l in f[0](list(x))])
if(y != x and not(y in orbitx)):
orbitx.add(y)
Y.discard(y)
orbitx.add(x)
orbits.add(tuple(orbitx))
Y.discard(x)
return orbits
#Handler for large scale orbit generation
def orbit_lists(G, n, m):
for k in range(n, m+1):
print(f"Generating orbit file for k = {k}...")
O = genorbits(G, k)
with open("Orbits_k=" + str(k) + ".txt", mode = "w") as file:
if len(O) == 1:
file.write(f"The 1 orbit of the action of G_k on X_k for k = {k} is,\n\n")
else:
file.write(f"The {len(O)} orbits of the action of G_k on X_k for k = {k} are,\n\n")
for orb in O:
file.write(f"The orbit generated by {orb[len(orb)-1]} is listed below and is of size {len(orb)}\n")
for x in orb:
file.write(str(x) + "\n")
file.write("\n")
return 1
#main
def main():
def T_1(L):
NL = [L[1] - L[3], L[0] - L[3], L[2] - L[3], -L[3], L[4] - L[3]]
return NL
def T_2(L):
NL = [L[0], L[0] - L[3], L[0] - L[4], L[0] - L[1], L[0] - L[2]]
return NL
def T_6(L):
NL = [L[3] - L[0], L[1], L[2], L[3], L[1] + L[2] - L[4]]
return NL
def T_8(L):
NL = [L[0], L[2], L[1], L[4], L[3]]
return NL
def T_16(L):
return T_1(T_6(L))
base = [a, b, c, d, e]
S = [[T_2, T_2(base)], [T_16, T_16(base)], [T_8, T_8(base)]]
G = Build_Group(S, base)
print("This program will generate orbit files for the action of G_k on X_k for all integers k >=2 in a user given range.\nThese files will be saved as 'orbit_k=i.txt' as they are generated.\nWarning: This code may take exceedingly long to run on some machines for large values of k")
n = int(input("Enter a starting integer n (this number must be >= 2): "))
m = int(input("Enter a finishing integer m (only one file will be generated if m = n): "))
orbit_lists(G, n, m)
main()