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 | ||||
| 
 | ||||
| # 0 is infinity | ||||
| coxeter_matrix = [[1, 5, 5], | ||||
|                   [5, 1, 5], | ||||
|                   [5, 5, 1]] | ||||
| 
 | ||||
| import numpy as np | ||||
| import math | ||||
| from copy import copy | ||||
| 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) | ||||
| 
 | ||||
| # 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): | ||||
| 	rank = len(form) | ||||
| 	root = root_.copy() | ||||
| @ -169,29 +163,24 @@ def generate_automaton(small_roots, lex_reduced = False): | ||||
| 		graph[fr][gen] = to | ||||
| 	return graph | ||||
| 
 | ||||
| # main program | ||||
| 
 | ||||
| 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) | ||||
| graph = generate_automaton(small_roots, lex_reduced = False) | ||||
| graph_lex = generate_automaton(small_roots, lex_reduced = True) | ||||
| def enumerate_group(graph, graph_lex, max_len): | ||||
| 	rank = len(graph[0]) | ||||
| 	group = [Groupelement(0, rank, tuple())] | ||||
| 	group[0].inverse = group[0] | ||||
| 	group[0].node = group[0].lex_node = 0 | ||||
| 
 | ||||
| group = [Groupelement(0, rank, tuple())] | ||||
| group[0].inverse = group[0] | ||||
| group[0].node = group[0].lex_node = 0 | ||||
| 
 | ||||
| i = 0 | ||||
| size = 1 | ||||
| while True: | ||||
| 	i = 0 | ||||
| 	size = 1 | ||||
| 	while True: | ||||
| 		current = group[i] | ||||
| 		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 | ||||
| 
 | ||||
| 	for gen, new_lex_node in enumerate(graph_lex[current.lex_node]): | ||||
| 		if new_lex_node: | ||||
| 		for gen, new_lex_node in filter(lambda x: x[1], enumerate(graph_lex[current.lex_node])): | ||||
| 			new_element = Groupelement(size, rank, current.word + (gen,)) | ||||
| 			new_element.lex_node = new_lex_node | ||||
| 			new_element.node = graph[current.node][gen] | ||||
| @ -199,10 +188,8 @@ while True: | ||||
| 			size += 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): | ||||
| 
 | ||||
| 				# if right multiplication by k decreases length | ||||
| 				if not graph[new_element.node][k]: | ||||
| 					word = list(new_element.word) | ||||
| 					longer_suffix = group[0] | ||||
| @ -213,7 +200,6 @@ while True: | ||||
| 
 | ||||
| 						# w = w_1 t w_2, w_2 s_k = t w_2 | ||||
| 						# in the case word = [] longer_suffix could be None | ||||
| 						# found it | ||||
| 						if len(word) == 0 or shorter_suffix.right[k] == longer_suffix: | ||||
| 							# finish word | ||||
| 							while len(word) > 0: | ||||
| @ -240,8 +226,25 @@ while True: | ||||
| 						other = new_element.right[k].inverse | ||||
| 						inverse.left[k] = other | ||||
| 						other.left[k] = inverse | ||||
| 	return group | ||||
| 
 | ||||
| length = 0 | ||||
| for i in range(1,len(group)+1): | ||||
| 	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 word(w): | ||||
| 	return ''.join([chr(ord('a')+x) for x in w]) | ||||
| 
 | ||||
| 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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user