diff --git a/enumerate.c b/enumerate.c index 4756d87..aa424e1 100644 --- a/enumerate.c +++ b/enumerate.c @@ -85,6 +85,11 @@ void balanced_thickening_callback(const bitvec_t *pos, int size, void *data) for(int j = 0; j < info->rank; j++) printf("%c", right_invariance & (1 << j) ? j + 'a' : ' '); + if(info->buffer) { + printf(" set: "); + bv_print(stdout, pos, size/2); + } + /* if(info->buffer) { printf(" generators:"); diff --git a/weyl.c b/weyl.c index 5e16780..c20fa5d 100644 --- a/weyl.c +++ b/weyl.c @@ -175,7 +175,7 @@ static void generate_left_and_ids(semisimple_type_t type, weylgroup_element_t *g } // glibc search function, but with user pointer and returning index (or -1 if not found) -static int search (const void *key, const void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *, void *), void *arg) +static int search(const void *key, const void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *, void *), void *arg) { size_t l, u, idx; const void *p; @@ -503,6 +503,7 @@ weylgroup_t *weyl_generate(semisimple_type_t type) group[i].left = result->lists + 2*i*rank; group[i].right = result->lists + (2*i+1)*rank; group[i].coset = (doublecoset_t*)0; + group[i].index = i; } // the main part @@ -611,8 +612,7 @@ doublequotient_t *weyl_generate_bruhat(semisimple_type_t type, int left_invarian free(wgroup); // dissolved in result and not needed anymore - // count cosets by finding the minimum length element in every coset - LOG("Count cosets.\n"); + LOG("Count cosets.\n"); // count cosets by finding the minimum length element in every coset count = 0; for(int i = 0; i < order; i++) { @@ -634,8 +634,7 @@ doublequotient_t *weyl_generate_bruhat(semisimple_type_t type, int left_invarian } result->lists = (doublecoset_list_t*)malloc(2*count*positive*sizeof(doublecoset_list_t)); // 2 times, for bruhat lower and higher - // find minima (basically same code as above) - LOG("Find minimal length elements in cosets.\n"); + LOG("Find minimal length elements in cosets.\n"); // basically same code as above count = 0; for(int i = 0; i < order; i++) { @@ -651,7 +650,6 @@ doublequotient_t *weyl_generate_bruhat(semisimple_type_t type, int left_invarian } } - // generate quotient map LOG("Generate quotient map.\n"); for(int i = 0; i < order; i++) { @@ -663,7 +661,6 @@ doublequotient_t *weyl_generate_bruhat(semisimple_type_t type, int left_invarian } } - // find maxima LOG("Find maximal length elements.\n"); for(int i = 0; i < order; i++) { @@ -677,13 +674,58 @@ doublequotient_t *weyl_generate_bruhat(semisimple_type_t type, int left_invarian } } - // opposites LOG("Find opposites.\n"); for(int i = 0; i < count; i++) cosets[i].opposite = cosets[i].min->opposite->coset; - // bruhat order + LOG("Sort opposites.\n"); + + int *old2newindices = (int*)malloc(count*sizeof(int)); + int *new2oldindices = (int*)malloc(count*sizeof(int)); + + // give the cosets some temporary indices + for(int i = 0; i < count; i++) + cosets[i].index = i; + + // generate a nice ordering, where element j is opposite to n-j, except the self-opposite ones, which are in the middle + int j = 0; + for(int i = 0; i < count; i++) + if(i < cosets[i].opposite->index) { + old2newindices[i] = j; + old2newindices[cosets[i].opposite->index] = count-1-j; + j++; + } + for(int i = 0; i < count; i++) + if(i == cosets[i].opposite->index) + old2newindices[i] = j++; + + for(int i = 0; i < count; i++) + new2oldindices[old2newindices[i]] = i; + + // rewrite everything in the new ordering + doublecoset_t *oldcosets = (doublecoset_t*)malloc(count*sizeof(doublecoset_t)); + memcpy(oldcosets, cosets, count*sizeof(doublecoset_t)); + for(int i = 0; i < count; i++) { + cosets[i].min = oldcosets[new2oldindices[i]].min; + cosets[i].max = oldcosets[new2oldindices[i]].max; + cosets[i].opposite = cosets + old2newindices[oldcosets[new2oldindices[i]].opposite->index]; + // cosets[i].bruhat_lower = oldcosets[new2oldindices[i]].bruhat_lower; + // cosets[i].bruhat_higher = oldcosets[new2oldindices[i]].bruhat_higher; + // for(doublecoset_list_t *current = cosets[i].bruhat_lower; current; current = current -> next) + // current->to = &cosets[old2newindices[current->to->index]]; + // for(doublecoset_list_t *current = cosets[i].bruhat_higher; current; current = current -> next) + // current->to = &cosets[old2newindices[current->to->index]]; + } + for(int i = 0; i < order; i++) + group[i].coset = old2newindices[group[i].coset->index] + cosets; + for(int i = 0; i < count; i++) // do this in the end, so we can use the "index" attribute before to translate pointers to indices + cosets[i].index = i; + + free(old2newindices); + free(new2oldindices); + free(oldcosets); + LOG("Find bruhat order.\n"); int edgecount = 0; @@ -702,15 +744,13 @@ doublequotient_t *weyl_generate_bruhat(semisimple_type_t type, int left_invarian } } - // transitive reduction - LOG("Perform transitive reduction.\n"); + LOG("Perform transitive reduction.\n"); // eliminating redudant order relations - doublecoset_t *offset = &cosets[0]; doublecoset_t *origin; doublecoset_list_t *current; doublecoset_list_t *prev; queue_t queue; - int cur; + int idx; int *seen = malloc(count*sizeof(int)); for(int i = 0; i < count; i++) { memset(seen, 0, count*sizeof(int)); @@ -725,25 +765,25 @@ doublequotient_t *weyl_generate_bruhat(semisimple_type_t type, int left_invarian for(current = origin->bruhat_lower; current; current = current->next) { if(origin->min->wordlength - current->to->min->wordlength != len) { prev = current; - } else if(seen[current->to - offset]) { + } else if(seen[current->to->index]) { if(prev) prev->next = current->next; else origin->bruhat_lower = current->next; } else { prev = current; - seen[current->to - offset] = 1; - queue_put(&queue, current->to - offset); + seen[current->to->index] = 1; + queue_put(&queue, current->to->index); } } // see which nodes we can reach using only edges up to length len, mark them as seen - while((cur = queue_get(&queue)) != -1) { - current = (cur + offset)->bruhat_lower; - for(current = (cur+offset)->bruhat_lower; current; current = current->next) { - if(!seen[current->to - offset]) { - seen[current->to - offset] = 1; - queue_put(&queue, current->to - offset); + while((idx = queue_get(&queue)) != -1) { + current = cosets[idx].bruhat_lower; + for(current = cosets[idx].bruhat_lower; current; current = current->next) { + if(!seen[current->to->index]) { + seen[current->to->index] = 1; + queue_put(&queue, current->to->index); } } } @@ -752,7 +792,6 @@ doublequotient_t *weyl_generate_bruhat(semisimple_type_t type, int left_invarian free(seen); - // reverse bruhat order LOG("Revert bruhat order.\n"); for(int i = 0; i < count; i++) { @@ -764,46 +803,6 @@ doublequotient_t *weyl_generate_bruhat(semisimple_type_t type, int left_invarian } } - // sort opposites and rewrite everything - LOG("Sort opposites.\n"); - - int *old2newindices = (int*)malloc(count*sizeof(int)); - int *new2oldindices = (int*)malloc(count*sizeof(int)); - doublecoset_t *oldcosets = (doublecoset_t*)malloc(count*sizeof(doublecoset_t)); - memcpy(oldcosets, cosets, count*sizeof(doublecoset_t)); - - int j = 0; - for(int i = 0; i < count; i++) - if(&cosets[i] < cosets[i].opposite) { - old2newindices[i] = j; - old2newindices[cosets[i].opposite - cosets] = count-1-j; - j++; - } - for(int i = 0; i < count; i++) - if(i == cosets[i].opposite - cosets) - old2newindices[i] = j++; - - for(int i = 0; i < count; i++) - new2oldindices[old2newindices[i]] = i; - - for(int i = 0; i < count; i++) { - cosets[i].min = oldcosets[new2oldindices[i]].min; - cosets[i].max = oldcosets[new2oldindices[i]].max; - cosets[i].opposite = old2newindices[oldcosets[new2oldindices[i]].opposite - cosets] + cosets; - cosets[i].bruhat_lower = oldcosets[new2oldindices[i]].bruhat_lower; - cosets[i].bruhat_higher = oldcosets[new2oldindices[i]].bruhat_higher; - for(current = cosets[i].bruhat_lower; current; current = current -> next) - current->to = old2newindices[current->to - cosets] + cosets; - for(current = cosets[i].bruhat_higher; current; current = current -> next) - current->to = old2newindices[current->to - cosets] + cosets; - } - for(int i = 0; i < order; i++) - group[i].coset = old2newindices[group[i].coset - cosets] + cosets; - - free(old2newindices); - free(new2oldindices); - free(oldcosets); - return result; }