edited weyl.c to use indices

This commit is contained in:
Florian Stecker 2017-02-21 12:01:47 +01:00
parent cc3e5952b1
commit 98f055d026
2 changed files with 67 additions and 63 deletions

View File

@ -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:");

125
weyl.c
View File

@ -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;
}