Generate + Process

This commit is contained in:
Florian Stecker
2016-07-26 10:09:34 +02:00
parent eb7f469171
commit a17c6fb06e
5 changed files with 400 additions and 169 deletions

View File

@@ -6,30 +6,11 @@
#include <malloc.h>
#include <memory.h>
#include "thickenings.h"
#include "coxeter.h"
#include "queue.h"
#define DEBUG(msg, ...) do{fprintf(stderr, msg, ##__VA_ARGS__); }while(0)
#define MAX_THICKENINGS 10000
typedef struct _edgelist {
int to;
struct _edgelist *next;
} edgelist_t;
typedef struct {
int *word;
int wordlength;
int *left;
int *right;
int opposite;
edgelist_t *bruhat_lower;
edgelist_t *bruhat_higher;
int is_hyperplane_reflection; // boolean value
} node_t;
static char *alphabetize(int *word, int len, const char *alphabet, char *buffer)
char *alphabetize(int *word, int len, const char *alphabet, char *buffer)
{
int i = 0;
for(i = 0; i < len; i++)
@@ -39,30 +20,30 @@ static char *alphabetize(int *word, int len, const char *alphabet, char *buffer)
return buffer;
}
static void print_balanced_thickening(int rank, int order, const int *thickening, const int *left_invariant, const int *right_invariant, const char *alphabet)
void print_balanced_thickening(int rank, int order, const int *thickening, const int *left_invariant, const int *right_invariant, const char *alphabet, FILE *f)
{
for(int i = 0; i < order; i++) {
if(thickening[i])
printf("x");
fprintf(f, "x");
else
printf("0");
fprintf(f, "0");
}
printf(" left: ");
fprintf(f, " left: ");
for(int j = 0; j < rank; j++)
if(left_invariant[j])
printf("%c", alphabet[j]);
fprintf(f, "%c", alphabet[j]);
else
printf(" ");
fprintf(f, " ");
printf(" right: ");
fprintf(f, " right: ");
for(int j = 0; j < rank; j++)
if(right_invariant[j])
printf("%c", alphabet[j]);
fprintf(f, "%c", alphabet[j]);
else
printf(" ");
fprintf(f, " ");
printf("\n");
fprintf(f, "\n");
}
static int compare_wordlength(const void *a, const void *b, void *gr)
@@ -74,72 +55,34 @@ static int compare_wordlength(const void *a, const void *b, void *gr)
return graph[i].wordlength - graph[j].wordlength;
}
int main(int argc, const char *argv[])
void prepare_graph(semisimple_type_t type, node_t *graph, edgelist_t **edgelists_pointer, int **words_pointer) // the edgelists_pointer and words_pointer arguments are just for freeing afterwards
{
queue_t queue;
// heap stuff
node_t *graph, *graph_unsorted;
int *graph_data;
int *wordlength_order, *reverse_wordlength_order, *seen, *level;
int *words;
edgelist_t *edgelists;
int *left, *right;
int *left_invariant, *right_invariant;
edgelist_t *edge, *previous;
int rank, order;
semisimple_type_t type;
int edgelist_count, hyperplane_count, max_wordlength;
int current, head, i, current_level;
int is_fat, is_slim;
int thickenings_count, fat_count, slim_count, balanced_count;
edgelist_t *edge, *previous;
int edgelist_count, max_wordlength, hyperplane_count;
int current;
int *balanced_thickenings;
int *graph_data;
node_t *graph_unsorted;
int *wordlength_order, *reverse_wordlength_order, *seen, *words;
edgelist_t *edgelists;
char *string_buffer1, *string_buffer2;
const char *alphabet = "abcdefghijklmnopqrstuvwxyz";
ERROR(argc < 2, "Too few arguments!\n");
type.n = argc - 1;
type.factors = (simple_type_t*)malloc((argc-1)*sizeof(simple_type_t));
for(int i = 0; i < argc - 1; i++) {
type.factors[i].series = argv[i+1][0];
type.factors[i].rank = argv[i+1][1] - '0';
ERROR(argv[i+1][0] < 'A' || argv[i+1][0] > 'I' || argv[i+1][1] < '1' || argv[i+1][1] > '9', "Arguments must be Xn with X out of A-I and n out of 0-9\n");
}
// initialize
rank = coxeter_rank(type);
order = coxeter_order(type);
ERROR(strlen(alphabet) < rank, "The alphabet has too few letters\n");
// DEBUG("The group has rank %d and order %d\n", rank, order);
graph = (node_t*)malloc(order*sizeof(node_t));
graph_unsorted = (node_t*)malloc(order*sizeof(node_t));
graph_data = (int*)malloc(order*rank*sizeof(int));
graph_unsorted = (node_t*)malloc(order*sizeof(node_t));
wordlength_order = (int*)malloc(order*sizeof(int));
reverse_wordlength_order = (int*)malloc(order*sizeof(int));
seen = (int*)malloc(order*sizeof(int));
level = (int*)malloc(order*sizeof(int));
left = (int*)malloc(order*rank*sizeof(int));
right = (int*)malloc(order*rank*sizeof(int));
left_invariant = (int*)malloc(rank*sizeof(int));
right_invariant = (int*)malloc(rank*sizeof(int));
balanced_thickenings = (int*)malloc(MAX_THICKENINGS*order*sizeof(int));
// DEBUG("Generate Cayley graph\n");
generate_coxeter_graph(type, graph_data);
for(int i = 0; i < order; i++) {
graph_unsorted[i].left = &left[i*rank];
graph_unsorted[i].right = &right[i*rank];
for(int j = 0; j < rank; j++)
graph_unsorted[i].left[j] = graph_data[i*rank + j];
graph_unsorted[i].left = graph[i].left;
graph_unsorted[i].right = graph[i].right;
graph_unsorted[i].word = 0;
graph_unsorted[i].wordlength = INT_MAX;
graph_unsorted[i].bruhat_lower = 0;
@@ -147,7 +90,15 @@ int main(int argc, const char *argv[])
graph_unsorted[i].is_hyperplane_reflection = 0;
}
// DEBUG("Find wordlengths\n");
// get coxeter graph
generate_coxeter_graph(type, graph_data);
for(int i = 0; i < order; i++)
for(int j = 0; j < rank; j++)
graph_unsorted[i].left[j] = graph_data[i*rank + j];
// find wordlengths
graph_unsorted[0].wordlength = 0;
queue_init(&queue);
@@ -167,10 +118,7 @@ int main(int argc, const char *argv[])
if(graph_unsorted[i].wordlength > max_wordlength)
max_wordlength = graph_unsorted[i].wordlength;
string_buffer1 = (char*)malloc((max_wordlength+1)*sizeof(char));
string_buffer2 = (char*)malloc((max_wordlength+1)*sizeof(char));
// DEBUG("Sort by wordlength\n");
// sort by wordlength
for(int i = 0; i < order; i++)
wordlength_order[i] = i;
@@ -183,7 +131,7 @@ int main(int argc, const char *argv[])
graph[i].left[j] = reverse_wordlength_order[graph[i].left[j]]; // rewrite references
}
// DEBUG("Find words\n");
// find words
words = (int*)malloc(order*max_wordlength*sizeof(int));
memset(words, 0, order*max_wordlength*sizeof(int));
@@ -202,7 +150,7 @@ int main(int argc, const char *argv[])
}
}
// DEBUG("Generate right edges\n");
// generate right edges
for(int i = 0; i < order; i++) {
for(int j = 0; j < rank; j++) {
@@ -214,7 +162,7 @@ int main(int argc, const char *argv[])
}
}
// DEBUG("Find opposites\n");
// find opposites
node_t *longest = &graph[order-1];
for(int i = 0; i < order; i++) {
@@ -224,7 +172,7 @@ int main(int argc, const char *argv[])
graph[i].opposite = current;
}
// DEBUG("Enumerate hyperplanes\n"); // every right edge is a reflection along a hyperplane; calculate what this reflection does to the identity
// enumerate hyperplanes
hyperplane_count = 0;
for(int i = 0; i < order; i++) {
@@ -245,10 +193,10 @@ int main(int argc, const char *argv[])
}
}
// DEBUG("The Weyl chambers are bounded by %d hyperplanes\n", hyperplane_count);
// DEBUG("Generate folding order\n");
// generate folding order
edgelists = (edgelist_t*)malloc(order*hyperplane_count*sizeof(edgelist_t));
edgelist_count = 0;
for(int i = 0; i < order; i++) {
if(graph[i].is_hyperplane_reflection) {
for(int j = 0; j < order; j++) {
@@ -270,7 +218,7 @@ int main(int argc, const char *argv[])
}
}
// DEBUG("Remove redundant edges\n");
// remove redundant edges
for(int i = 0; i < order; i++) {
memset(seen, 0, order*sizeof(int));
@@ -280,7 +228,7 @@ int main(int argc, const char *argv[])
previous = (edgelist_t*)0;
while(edge) {
if(seen[edge->to] && graph[i].wordlength - graph[edge->to].wordlength == len) {
// printf("deleting from %d to %d\n", i, edge->to);
// fprintf(stderr, "deleting from %d to %d\n", i, edge->to);
if(previous)
previous->next = edge->next;
else
@@ -308,7 +256,7 @@ int main(int argc, const char *argv[])
}
}
// DEBUG("Reverse folding order\n");
// reverse folding order
for(int i = 0; i < order; i++) {
edge = graph[i].bruhat_lower;
@@ -321,21 +269,35 @@ int main(int argc, const char *argv[])
}
}
printf("Rank: %d\t\tOrder: %d\t\tHyperplanes: %d\n", rank, order, hyperplane_count);
printf("\n");
printf("Group elements: \n");
for(int i = 0, wl = 0; i < order; i++) {
if(i == 0) {
printf("1");
} else if(graph[i].wordlength > wl) {
printf("\n%s ", alphabetize(graph[i].word, graph[i].wordlength, alphabet, string_buffer1));
wl = graph[i].wordlength;
} else
printf("%s ", alphabetize(graph[i].word, graph[i].wordlength, alphabet, string_buffer1));
}
printf("\n\n");
*edgelists_pointer = edgelists;
*words_pointer = words;
// DEBUG("Enumerate thickenings\n");
free(graph_data);
free(graph_unsorted);
free(wordlength_order);
free(reverse_wordlength_order);
free(seen);
}
void enumerate_balanced_thickenings(semisimple_type_t type, node_t *graph, const char *alphabet, FILE *outfile)
{
int rank, order;
int *level;
int *left_invariant, *right_invariant;
long thickenings_count, fat_count, slim_count, balanced_count;
int is_fat, is_slim;
int current_level, head, current;
int i;
edgelist_t *edge;
queue_t queue;
rank = coxeter_rank(type);
order = coxeter_order(type);
level = (int*)malloc(order*sizeof(int));
left_invariant = (int*)malloc(rank*sizeof(int));
right_invariant = (int*)malloc(rank*sizeof(int));
thickenings_count = fat_count = slim_count = balanced_count = 0;
memset(level, 0, order*sizeof(int));
@@ -357,6 +319,8 @@ int main(int argc, const char *argv[])
}
}
// we have a thickening, do something with it!
is_fat = is_slim = 1;
for(int i = 0; i < order; i++) {
if(level[graph[i].opposite] != 0) {
@@ -376,10 +340,12 @@ int main(int argc, const char *argv[])
slim_count++;
if(is_slim && is_fat) {
ERROR(balanced_count >= MAX_THICKENINGS, "Too many balanced thickenings! Increase MAX_THICKENINGS\n");
memcpy(&balanced_thickenings[balanced_count*order], level, order*sizeof(int));
//memcpy(&balanced_thickenings[balanced_count*order], level, order*sizeof(int));
fwrite(level, sizeof(int), order, outfile);
balanced_count++;
}
// print out the thickening
if(is_fat && is_slim) {
// check for invariances
for(int j = 0; j < rank; j++) {
@@ -394,9 +360,12 @@ int main(int argc, const char *argv[])
right_invariant[j] = 0;
}
}
print_balanced_thickening(rank, order, level, left_invariant, right_invariant, alphabet);
print_balanced_thickening(rank, order, level, left_invariant, right_invariant, alphabet, stderr);
}
// now find the next one!
// try to find empty spot to the left of "head"
for(i = head - 1; i >= 0; i--)
if(level[i] == 0)
@@ -433,58 +402,10 @@ int main(int argc, const char *argv[])
level[i] = 0;
}
printf("\n");
printf("Found %d thickenings, %d fat, %d slim, %d balanced\n\n", thickenings_count, fat_count, slim_count, balanced_count);
fprintf(stderr, "\n");
fprintf(stderr, "Found %ld thickenings, %ld fat, %ld slim, %ld balanced\n\n", thickenings_count, fat_count, slim_count, balanced_count);
/*
for(int i = 0; i < balanced_count; i++) {
// figure out invariances
for(int j = 0; j < rank; j++) {
left_invariant[j] = 1;
right_invariant[j] = 1;
}
int *current_thickening = balanced_thickenings + i*order;
for(int k = 0; k < order; k++) {
for(int j = 0; j < rank; j++) {
if(current_thickening[k] == 0 && current_thickening[graph[k].left[j]] != 0 || current_thickening[k] != 0 && current_thickening[graph[k].left[j]] == 0)
left_invariant[j] = 0;
if(current_thickening[k] == 0 && current_thickening[graph[k].right[j]] != 0 || current_thickening[k] != 0 && current_thickening[graph[k].right[j]] == 0)
right_invariant[j] = 0;
}
}
printf("left: ");
for(int k = 0; k < rank; k++)
printf("%c", left_invariant[k] ? alphabet[k] : ' ');
printf(" right: ");
for(int k = 0; k < rank; k++)
printf("%c", right_invariant[k] ? alphabet[k] : ' ');
printf("\n");
}
*/
free(edgelists);
free(words);
free(string_buffer1);
free(string_buffer2);
free(graph);
free(graph_unsorted);
free(graph_data);
free(wordlength_order);
free(reverse_wordlength_order);
free(seen);
free(level);
free(left);
free(right);
free(left_invariant);
free(right_invariant);
free(type.factors);
free(balanced_thickenings);
return 0;
}