Schneller Algo + Berechnung des Vereinfachten Bruhat-Graphen

This commit is contained in:
Florian Stecker
2016-08-29 15:19:49 +02:00
parent d47c3cb45b
commit bb91e24b8a
5 changed files with 208 additions and 138 deletions

View File

@@ -20,15 +20,15 @@ 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)
void print_thickening(int rank, int order, const signed char *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");
if(thickening[i] == HEAD_MARKER)
fprintf(f, "\e[41mx\e[39m\e[49m");
else if(thickening[i] < 0 && thickening[i] > -10)
fprintf(f, "\e[47m\e[30m%d\e[40m\e[m", -thickening[i]);
fprintf(f, "\e[47m\e[30m%d\e[39m\e[49m", -thickening[i]);
else if(thickening[i] <= -10)
fprintf(f, "\e[47m\e[30m+\e[40m\e[m");
fprintf(f, "\e[47m\e[30m+\e[39m\e[49m");
else if(thickening[i] > 0 && thickening[i] < 10)
fprintf(f, "%d", thickening[i]);
else if(thickening[i] >= 10)
@@ -44,10 +44,10 @@ void print_thickening(int rank, int order, const int *thickening, int is_fat, in
if(conflict)
fprintf(f, " C");
fprintf(f, "\n");
fprintf(f, "\e[K\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)
void print_balanced_thickening(int rank, int order, const signed char *thickening, const int *left_invariant, const int *right_invariant, const char *alphabet, FILE *f)
{
for(int i = 0; i < order; i++) {
if(thickening[i])
@@ -309,13 +309,11 @@ void prepare_graph(semisimple_type_t type, node_t *graph, edgelist_t **edgelists
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;
signed char *level;
long count;
int is_fat, is_slim;
int current_level, head, current;
int i;
int conflict;
edgelist_t *edge;
queue_t queue;
@@ -323,120 +321,79 @@ void enumerate_balanced_thickenings(semisimple_type_t type, node_t *graph, const
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));
level = (signed char*)malloc(order*sizeof(int));
thickenings_count = fat_count = slim_count = balanced_count = 0;
count = 0;
memset(level, 0, order*sizeof(int));
current_level = 1;
head = order - 1;
level[head] = 1000;
level[head] = HEAD_MARKER;
while(current_level > 0) {
// calculate transitive closure
conflict = 0;
// calculate transitive closure; that is, fill current_level in every spot which must be marked with the current hat (but was not already before), and -current_level in every opposite spot (including opposite to the head)
is_slim = 1;
queue_init(&queue);
level[graph[head].opposite] = -current_level;
queue_put(&queue, head);
for(int i = head + 1; level[i] != 1000 && i < order; i++) {
if(level[graph[i].opposite] == 0) {
for(int i = head + 1; level[i] != HEAD_MARKER && i < order; i++) { // everything which is right to the head and empty will not get marked in this or higher levels, so we can mark its opposite
if(level[i] == current_level) {
is_slim = 0;
break;
} if(level[i] == 0) {
level[i] = -current_level;
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(is_slim) {
while((current = queue_get(&queue)) != -1) {
edge = graph[current].bruhat_lower;
while(edge) {
if(level[edge->to] < 0) {
is_slim = 0;
break;
} else if(level[edge->to] == 0) {
level[edge->to] = current_level;
level[graph[edge->to].opposite] = -current_level;
queue_put(&queue, edge->to);
}
edge = edge->next;
}
}
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;
}
// now we have something, check if it is a balanced thickening
if(is_slim) {
is_fat = 1;
for(int i = 0; i < order; i++) {
if(level[i] == 0) {
is_fat = 0;
break;
}
if(level[edge->to] == 0) {
level[edge->to] = current_level;
queue_put(&queue, edge->to);
}
edge = edge->next;
}
if(is_fat) {
// ERROR(count >= MAX_THICKENINGS, "Too many balanced thickenings! Increase MAX_THICKENINGS\n");
if(count % 10000000 == 0)
print_thickening(rank, order, level, 0, 0, 0, alphabet, stderr);
// fwrite(level, sizeof(signed char), order, outfile);
count++;
}
}
/*
// 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) {
if(level[i] != 0)
is_slim = 0;
} else {
if(level[i] == 0)
is_fat = 0;
}
}
// count
thickenings_count++;
if(is_fat)
fat_count++;
if(is_slim)
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));
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++) {
left_invariant[j] = 1;
right_invariant[j] = 1;
}
for(int i = 0; i < order; i++) {
for(int j = 0; j < rank; j++) {
if(level[i] == 0 && level[graph[i].left[j]] != 0 || level[i] != 0 && level[graph[i].left[j]] == 0)
left_invariant[j] = 0;
if(level[i] == 0 && level[graph[i].right[j]] != 0 || level[i] != 0 && level[graph[i].right[j]] == 0)
right_invariant[j] = 0;
}
}
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", but only if it is slim, as otherwise there is no point in adding even more
if(!conflict) {
if(is_slim) {
for(i = head - 1; i >= 0; i--)
if(level[i] == 0)
break;
if(i >= 0) {
head = i;
level[head] = 1000;
level[head] = HEAD_MARKER;
current_level++;
// print_thickening(rank, order, level, 0, 0, 0, alphabet, stderr);
ERROR(current_level >= HEAD_MARKER, "HEAD_MARKER to small!\n");
continue;
}
}
@@ -449,31 +406,25 @@ void enumerate_balanced_thickenings(semisimple_type_t type, node_t *graph, const
if(i >= 0) { // if this was successful, just move head
level[head] = 0;
head = i;
level[head] = 1000;
level[head] = HEAD_MARKER;
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] != 1000);
} while(head < order && level[head] != HEAD_MARKER);
}
}
// clean up
for(int i = 0; i < order; i++)
if(level[i] >= current_level && level[i] != 1000 || level[i] <= -current_level)
if(level[i] >= current_level && level[i] != HEAD_MARKER || level[i] <= -current_level)
level[i] = 0;
// print_thickening(rank, order, level, 0, 0, 0, alphabet, stderr);
}
fprintf(stderr, "\n");
fprintf(stderr, "Found %ld thickenings, %ld fat, %ld slim, %ld balanced\n\n", thickenings_count, fat_count, slim_count, balanced_count);
fprintf(stderr, "Found %ld balanced thickenings\n\n", count);
free(level);
free(left_invariant);
free(right_invariant);
}