diff --git a/Makefile b/Makefile index 37d9b50..0b94379 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ HEADERS=coxeter.h thickenings.h queue.h -OPTIONS=-O0 -g -std=gnu99 +OPTIONS=-O3 -g -std=gnu99 all: generate process diff --git a/process.c b/process.c index 9c68df8..a17be77 100644 --- a/process.c +++ b/process.c @@ -95,17 +95,23 @@ int main(int argc, const char *argv[]) // finally do stuff + int counter = 0; + while(fread(level, sizeof(int), order, infile) == order) { + if((counter++) % 100000 == 0) + print_thickening(rank, order, level, 0, 0, 0, alphabet, stdout); + continue; + for(int j = 0; j < rank; j++) { left_invariant[j] = 1; right_invariant[j] = 1; } for(int j = 0; j < order; j++) { for(int k = 0; k < rank; k++) { - if(level[j] == 0 && level[graph[j].left[k]] != 0 || level[j] != 0 && level[graph[j].left[k]] == 0) + if(level[j] > 0 && level[graph[j].left[k]] < 0 || level[j] < 0 && level[graph[j].left[k]] > 0) left_invariant[k] = 0; - if(level[j] == 0 && level[graph[j].right[k]] != 0 || level[j] != 0 && level[graph[j].right[k]] == 0) + if(level[j] > 0 && level[graph[j].right[k]] < 0 || level[j] < 0 && level[graph[j].right[k]] > 0) right_invariant[k] = 0; } } @@ -113,7 +119,7 @@ int main(int argc, const char *argv[]) ngens = 0; memset(generators, 0, order*sizeof(int)); for(int j = 0; j < order; j++) { - if(level[j] == -1 && generators[j] == 0) { // ignore the generator, if it is equivalent to one already seen + if(level[j] == 1000 && generators[j] == 0) { // ignore the generator, if it is equivalent to one already seen ngens++; queue_init(&queue); queue_put(&queue, j); diff --git a/thickenings.c b/thickenings.c index 9f0530a..bc9d13c 100644 --- a/thickenings.c +++ b/thickenings.c @@ -20,6 +20,33 @@ char *alphabetize(int *word, int len, const char *alphabet, char *buffer) return buffer; } +void print_thickening(int rank, int order, const int *thickening, int is_fat, int is_slim, int conflict, const char *alphabet, FILE *f) +{ + for(int i = 0; i < order; i++) { + if(thickening[i] == 1000) + fprintf(f, "\e[41mx\e[40m\e[m"); + else if(thickening[i] < 0 && thickening[i] > -10) + fprintf(f, "\e[47m\e[30m%d\e[40m\e[m", -thickening[i]); + else if(thickening[i] <= -10) + fprintf(f, "\e[47m\e[30m+\e[40m\e[m"); + else if(thickening[i] > 0 && thickening[i] < 10) + fprintf(f, "%d", thickening[i]); + else if(thickening[i] >= 10) + fprintf(f, "+"); + else + fprintf(f, " "); + } + + if(is_fat) + fprintf(f, " F"); + if(is_slim) + fprintf(f, " S"); + if(conflict) + fprintf(f, " C"); + + fprintf(f, "\n"); +} + 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++) { @@ -288,6 +315,7 @@ void enumerate_balanced_thickenings(semisimple_type_t type, node_t *graph, const int is_fat, is_slim; int current_level, head, current; int i; + int conflict; edgelist_t *edge; queue_t queue; @@ -303,14 +331,31 @@ void enumerate_balanced_thickenings(semisimple_type_t type, node_t *graph, const memset(level, 0, order*sizeof(int)); current_level = 1; head = order - 1; - level[head] = -1; + level[head] = 1000; while(current_level > 0) { // calculate transitive closure + conflict = 0; queue_init(&queue); queue_put(&queue, head); + for(int i = head + 1; level[i] != 1000 && i < order; i++) { + if(level[graph[i].opposite] == 0) { + level[graph[i].opposite] = current_level; + queue_put(&queue, graph[i].opposite); + } + } while((current = queue_get(&queue)) != -1) { + if(level[current] < 0 || level[graph[current].opposite] > 0) { // conflict, can not be slim + conflict = 1; + break; + } + if(level[graph[current].opposite] == 0) + level[graph[current].opposite] = - current_level; edge = graph[current].bruhat_lower; while(edge) { + if(level[edge->to] < 0) { + conflict = 1; + break; + } if(level[edge->to] == 0) { level[edge->to] = current_level; queue_put(&queue, edge->to); @@ -319,8 +364,8 @@ void enumerate_balanced_thickenings(semisimple_type_t type, node_t *graph, const } } + /* // 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) { @@ -344,7 +389,9 @@ void enumerate_balanced_thickenings(semisimple_type_t type, node_t *graph, const fwrite(level, sizeof(int), order, outfile); balanced_count++; } + */ + /* // print out the thickening if(is_fat && is_slim) { // check for invariances @@ -362,44 +409,65 @@ void enumerate_balanced_thickenings(semisimple_type_t type, node_t *graph, const } print_balanced_thickening(rank, order, level, left_invariant, right_invariant, alphabet, stderr); } + */ + is_fat = 1; + for(int i = 0; i < order; i++) { + if(level[i] == 0) + is_fat = 0; + } + + if(is_fat && !conflict) { + // ERROR(balanced_count >= MAX_THICKENINGS, "Too many balanced thickenings! Increase MAX_THICKENINGS\n"); + fwrite(level, sizeof(int), order, outfile); + balanced_count++; + } + + // print_thickening(rank, order, level, is_fat, !conflict, conflict, 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) - break; - if(i >= 0) { - head = i; - level[head] = -1; - current_level++; - continue; + // try to find empty spot to the left of "head", but only if it is slim, as otherwise there is no point in adding even more + if(!conflict) { + for(i = head - 1; i >= 0; i--) + if(level[i] == 0) + break; + if(i >= 0) { + head = i; + level[head] = 1000; + current_level++; + // print_thickening(rank, order, level, 0, 0, 0, alphabet, stderr); + continue; + } } // if none was found, try to move "head" to the left while(current_level > 0) { for(i = head - 1; i >= 0; i--) - if(level[i] == 0 || level[i] >= current_level) + if(level[i] == 0 || level[i] >= current_level || level[i] <= -current_level) break; if(i >= 0) { // if this was successful, just move head level[head] = 0; head = i; - level[head] = -1; + level[head] = 1000; break; } else { // if moving the head is not possible, take the next head to the right current_level--; level[head] = 0; do { head++; - } while(head < order && level[head] != -1); + } while(head < order && level[head] != 1000); } } // clean up - for(int i = 0; i < head; i++) - if(level[i] >= current_level) + for(int i = 0; i < order; i++) + if(level[i] >= current_level && level[i] != 1000 || level[i] <= -current_level) level[i] = 0; + + + // print_thickening(rank, order, level, 0, 0, 0, alphabet, stderr); + } fprintf(stderr, "\n"); diff --git a/thickenings.h b/thickenings.h index 89d387f..36f6922 100644 --- a/thickenings.h +++ b/thickenings.h @@ -5,7 +5,7 @@ #define DEBUG(msg, ...) do{fprintf(stderr, msg, ##__VA_ARGS__); }while(0) -#define MAX_THICKENINGS 1000000 +#define MAX_THICKENINGS 10000000 typedef struct _edgelist { int to; @@ -25,6 +25,7 @@ typedef struct { char *alphabetize(int *word, int len, const char *alphabet, char *buffer); void print_balanced_thickening(int rank, int order, const int *thickening, const int *left_invariant, const int *right_invariant, const char *alphabet, FILE *f); +void print_thickening(int rank, int order, const int *thickening, int fat, int slim, int conflict, const char *alphabet, FILE *f); static int compare_wordlength(const void *a, const void *b, void *gr); void prepare_graph(semisimple_type_t type, node_t *graph, edgelist_t **edgelists_pointer, int **words_pointer); void enumerate_balanced_thickenings(semisimple_type_t type, node_t *graph, const char *alphabet, FILE *outfile);