add example and code to generate dot file
This commit is contained in:
parent
55f0c2d093
commit
fea1b1eb2e
67
automaton.py → coxeter_automaton.py
Executable file → Normal file
67
automaton.py → coxeter_automaton.py
Executable file → Normal file
@ -1,10 +1,4 @@
|
|||||||
#!/usr/bin/python
|
import numpy as np
|
||||||
|
|
||||||
# 0 is infinity
|
|
||||||
coxeter_matrix = [[1, 5, 5],
|
|
||||||
[5, 1, 5],
|
|
||||||
[5, 5, 1]]
|
|
||||||
|
|
||||||
import math
|
import math
|
||||||
from copy import copy
|
from copy import copy
|
||||||
from collections import deque
|
from collections import deque
|
||||||
@ -48,7 +42,7 @@ def apply_gen_to_root(form, k, root):
|
|||||||
root[k] -= 2*form_gen_root(form, k, root)
|
root[k] -= 2*form_gen_root(form, k, root)
|
||||||
|
|
||||||
# find a sequence of generators to apply to obtain a negative root, from left to right
|
# find a sequence of generators to apply to obtain a negative root, from left to right
|
||||||
# "startwidth" argument can be used to force the first entry
|
# "startwith" argument can be used to force the first entry
|
||||||
def find_word_to_negative(form, root_, startwith = None):
|
def find_word_to_negative(form, root_, startwith = None):
|
||||||
rank = len(form)
|
rank = len(form)
|
||||||
root = root_.copy()
|
root = root_.copy()
|
||||||
@ -169,29 +163,24 @@ def generate_automaton(small_roots, lex_reduced = False):
|
|||||||
graph[fr][gen] = to
|
graph[fr][gen] = to
|
||||||
return graph
|
return graph
|
||||||
|
|
||||||
# main program
|
|
||||||
|
|
||||||
form = [[-math.cos(math.pi/m) if m > 0 else -1 for m in row] for row in coxeter_matrix]
|
def enumerate_group(graph, graph_lex, max_len):
|
||||||
rank = len(coxeter_matrix)
|
rank = len(graph[0])
|
||||||
small_roots = find_small_roots(form)
|
group = [Groupelement(0, rank, tuple())]
|
||||||
graph = generate_automaton(small_roots, lex_reduced = False)
|
group[0].inverse = group[0]
|
||||||
graph_lex = generate_automaton(small_roots, lex_reduced = True)
|
group[0].node = group[0].lex_node = 0
|
||||||
|
|
||||||
group = [Groupelement(0, rank, tuple())]
|
i = 0
|
||||||
group[0].inverse = group[0]
|
size = 1
|
||||||
group[0].node = group[0].lex_node = 0
|
while True:
|
||||||
|
|
||||||
i = 0
|
|
||||||
size = 1
|
|
||||||
while True:
|
|
||||||
current = group[i]
|
current = group[i]
|
||||||
i+=1
|
i+=1
|
||||||
|
|
||||||
if current.length >= 10:
|
# break if current has the max length we have, as that's when we would start adding elements 1 longer
|
||||||
|
if current.length >= max_len:
|
||||||
break
|
break
|
||||||
|
|
||||||
for gen, new_lex_node in enumerate(graph_lex[current.lex_node]):
|
for gen, new_lex_node in filter(lambda x: x[1], enumerate(graph_lex[current.lex_node])):
|
||||||
if new_lex_node:
|
|
||||||
new_element = Groupelement(size, rank, current.word + (gen,))
|
new_element = Groupelement(size, rank, current.word + (gen,))
|
||||||
new_element.lex_node = new_lex_node
|
new_element.lex_node = new_lex_node
|
||||||
new_element.node = graph[current.node][gen]
|
new_element.node = graph[current.node][gen]
|
||||||
@ -199,10 +188,8 @@ while True:
|
|||||||
size += 1
|
size += 1
|
||||||
|
|
||||||
# w = w_1 t, w s = w_1
|
# w = w_1 t, w s = w_1
|
||||||
# right multiplication (and left in case it does the same as a right mult)
|
# right multiplication, if it decreases length
|
||||||
for k in range(rank):
|
for k in range(rank):
|
||||||
|
|
||||||
# if right multiplication by k decreases length
|
|
||||||
if not graph[new_element.node][k]:
|
if not graph[new_element.node][k]:
|
||||||
word = list(new_element.word)
|
word = list(new_element.word)
|
||||||
longer_suffix = group[0]
|
longer_suffix = group[0]
|
||||||
@ -213,7 +200,6 @@ while True:
|
|||||||
|
|
||||||
# w = w_1 t w_2, w_2 s_k = t w_2
|
# w = w_1 t w_2, w_2 s_k = t w_2
|
||||||
# in the case word = [] longer_suffix could be None
|
# in the case word = [] longer_suffix could be None
|
||||||
# found it
|
|
||||||
if len(word) == 0 or shorter_suffix.right[k] == longer_suffix:
|
if len(word) == 0 or shorter_suffix.right[k] == longer_suffix:
|
||||||
# finish word
|
# finish word
|
||||||
while len(word) > 0:
|
while len(word) > 0:
|
||||||
@ -240,8 +226,25 @@ while True:
|
|||||||
other = new_element.right[k].inverse
|
other = new_element.right[k].inverse
|
||||||
inverse.left[k] = other
|
inverse.left[k] = other
|
||||||
other.left[k] = inverse
|
other.left[k] = inverse
|
||||||
|
return group
|
||||||
|
|
||||||
length = 0
|
def word(w):
|
||||||
for i in range(1,len(group)+1):
|
return ''.join([chr(ord('a')+x) for x in w])
|
||||||
if i == len(group) or group[i].length > group[i-1].length:
|
|
||||||
print("{number:d} elements up to length {length:d}".format(number = i, length = group[i-1].length))
|
def generate_automaton_coxeter_matrix(coxeter_matrix, lex_reduced = False):
|
||||||
|
form = [[-math.cos(math.pi/m) if m > 0 else -1 for m in row] for row in coxeter_matrix]
|
||||||
|
rank = len(coxeter_matrix)
|
||||||
|
small_roots = find_small_roots(form)
|
||||||
|
return generate_automaton(small_roots, lex_reduced)
|
||||||
|
|
||||||
|
def even_graph(graph):
|
||||||
|
rank = len(graph[0])
|
||||||
|
result = []
|
||||||
|
for node in graph:
|
||||||
|
newnode = {}
|
||||||
|
for i in range(rank):
|
||||||
|
for j in range(rank):
|
||||||
|
if node[i] and graph[node[i]][j]:
|
||||||
|
newnode[(i,j)] = graph[node[i]][j]
|
||||||
|
result.append(newnode)
|
||||||
|
return result
|
48
dot_graph.py
Executable file
48
dot_graph.py
Executable file
@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
# outputs the automaton as a graphviz dot file, arranging the vertices
|
||||||
|
# in levels according to their distance from the starting vertex
|
||||||
|
# to convert to a PDF, run:
|
||||||
|
# ./dot_graph.py | dot -Tpdf > output.pdf
|
||||||
|
|
||||||
|
import coxeter_automaton
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
|
coxeter_matrix = [[1, 2, 0, 0, 0, 2],
|
||||||
|
[2, 1, 2, 0, 0, 0],
|
||||||
|
[0, 2, 1, 2, 0, 0],
|
||||||
|
[0, 0, 2, 1, 2, 0],
|
||||||
|
[0, 0, 0, 2, 1, 2],
|
||||||
|
[2, 0, 0, 0, 2, 1]]
|
||||||
|
|
||||||
|
graph = coxeter_automaton.generate_automaton_coxeter_matrix(coxeter_matrix, lex_reduced = False)
|
||||||
|
|
||||||
|
colors = {0: "red", 1: "darkgreen", 2: "blue", 3: "orange", 4: "black", 5: "gray"}
|
||||||
|
|
||||||
|
todo = deque([0])
|
||||||
|
distances = [None]*len(graph)
|
||||||
|
distances[0] = 0
|
||||||
|
|
||||||
|
while todo:
|
||||||
|
node = todo.pop()
|
||||||
|
for newnode in graph[node]:
|
||||||
|
if newnode:
|
||||||
|
if not distances[newnode] or distances[newnode] > distances[node] + 1:
|
||||||
|
distances[newnode] = distances[node] + 1
|
||||||
|
todo.appendleft(newnode)
|
||||||
|
|
||||||
|
max_distance = max(filter(None, distances))
|
||||||
|
nodes_by_distance = [[] for _ in range(max_distance+1)]
|
||||||
|
for n,d in enumerate(distances):
|
||||||
|
if d != None:
|
||||||
|
nodes_by_distance[d].append(n)
|
||||||
|
|
||||||
|
print('digraph test123 {')
|
||||||
|
for dn in nodes_by_distance:
|
||||||
|
print('{rank = same; %s}' % "; ".join([str(x) for x in dn]))
|
||||||
|
|
||||||
|
for i,node in enumerate(graph):
|
||||||
|
for edge,j in enumerate(node):
|
||||||
|
if j:
|
||||||
|
print('{i:d} -> {j:d} [color={color}];'.format(i = i, j = j, color = colors[edge]))
|
||||||
|
print('}')
|
18
example.py
Executable file
18
example.py
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import coxeter_automaton
|
||||||
|
|
||||||
|
# (2, 3, infinity) triangle group; 0 stands for infinity
|
||||||
|
coxeter_matrix = [[1, 0, 3],
|
||||||
|
[0, 1, 2],
|
||||||
|
[3, 2, 1]]
|
||||||
|
|
||||||
|
graph = coxeter_automaton.generate_automaton_coxeter_matrix(coxeter_matrix, lex_reduced = False)
|
||||||
|
graph_shortlex = coxeter_automaton.generate_automaton_coxeter_matrix(coxeter_matrix, lex_reduced = True)
|
||||||
|
|
||||||
|
print(graph)
|
||||||
|
|
||||||
|
group = coxeter_automaton.enumerate_group(graph, graph_shortlex, 10)
|
||||||
|
|
||||||
|
# for each group element g and generator a, print index of a*g
|
||||||
|
print([[l.id if l else None for l in g.left] for g in group])
|
Loading…
Reference in New Issue
Block a user