edited weyl.c to use indices
This commit is contained in:
parent
cc3e5952b1
commit
98f055d026
@ -85,6 +85,11 @@ void balanced_thickening_callback(const bitvec_t *pos, int size, void *data)
|
|||||||
for(int j = 0; j < info->rank; j++)
|
for(int j = 0; j < info->rank; j++)
|
||||||
printf("%c", right_invariance & (1 << j) ? j + 'a' : ' ');
|
printf("%c", right_invariance & (1 << j) ? j + 'a' : ' ');
|
||||||
|
|
||||||
|
if(info->buffer) {
|
||||||
|
printf(" set: ");
|
||||||
|
bv_print(stdout, pos, size/2);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if(info->buffer) {
|
if(info->buffer) {
|
||||||
printf(" generators:");
|
printf(" generators:");
|
||||||
|
125
weyl.c
125
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)
|
// 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;
|
size_t l, u, idx;
|
||||||
const void *p;
|
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].left = result->lists + 2*i*rank;
|
||||||
group[i].right = result->lists + (2*i+1)*rank;
|
group[i].right = result->lists + (2*i+1)*rank;
|
||||||
group[i].coset = (doublecoset_t*)0;
|
group[i].coset = (doublecoset_t*)0;
|
||||||
|
group[i].index = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the main part
|
// 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
|
free(wgroup); // dissolved in result and not needed anymore
|
||||||
|
|
||||||
// count cosets by finding the minimum length element in every coset
|
LOG("Count cosets.\n"); // count cosets by finding the minimum length element in every coset
|
||||||
LOG("Count cosets.\n");
|
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
for(int i = 0; i < order; i++) {
|
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
|
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"); // basically same code as above
|
||||||
LOG("Find minimal length elements in cosets.\n");
|
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
for(int i = 0; i < order; i++) {
|
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");
|
LOG("Generate quotient map.\n");
|
||||||
|
|
||||||
for(int i = 0; i < order; i++) {
|
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");
|
LOG("Find maximal length elements.\n");
|
||||||
|
|
||||||
for(int i = 0; i < order; i++) {
|
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");
|
LOG("Find opposites.\n");
|
||||||
|
|
||||||
for(int i = 0; i < count; i++)
|
for(int i = 0; i < count; i++)
|
||||||
cosets[i].opposite = cosets[i].min->opposite->coset;
|
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");
|
LOG("Find bruhat order.\n");
|
||||||
|
|
||||||
int edgecount = 0;
|
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"); // eliminating redudant order relations
|
||||||
LOG("Perform transitive reduction.\n");
|
|
||||||
|
|
||||||
doublecoset_t *offset = &cosets[0];
|
|
||||||
doublecoset_t *origin;
|
doublecoset_t *origin;
|
||||||
doublecoset_list_t *current;
|
doublecoset_list_t *current;
|
||||||
doublecoset_list_t *prev;
|
doublecoset_list_t *prev;
|
||||||
queue_t queue;
|
queue_t queue;
|
||||||
int cur;
|
int idx;
|
||||||
int *seen = malloc(count*sizeof(int));
|
int *seen = malloc(count*sizeof(int));
|
||||||
for(int i = 0; i < count; i++) {
|
for(int i = 0; i < count; i++) {
|
||||||
memset(seen, 0, count*sizeof(int));
|
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) {
|
for(current = origin->bruhat_lower; current; current = current->next) {
|
||||||
if(origin->min->wordlength - current->to->min->wordlength != len) {
|
if(origin->min->wordlength - current->to->min->wordlength != len) {
|
||||||
prev = current;
|
prev = current;
|
||||||
} else if(seen[current->to - offset]) {
|
} else if(seen[current->to->index]) {
|
||||||
if(prev)
|
if(prev)
|
||||||
prev->next = current->next;
|
prev->next = current->next;
|
||||||
else
|
else
|
||||||
origin->bruhat_lower = current->next;
|
origin->bruhat_lower = current->next;
|
||||||
} else {
|
} else {
|
||||||
prev = current;
|
prev = current;
|
||||||
seen[current->to - offset] = 1;
|
seen[current->to->index] = 1;
|
||||||
queue_put(&queue, current->to - offset);
|
queue_put(&queue, current->to->index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// see which nodes we can reach using only edges up to length len, mark them as seen
|
// see which nodes we can reach using only edges up to length len, mark them as seen
|
||||||
while((cur = queue_get(&queue)) != -1) {
|
while((idx = queue_get(&queue)) != -1) {
|
||||||
current = (cur + offset)->bruhat_lower;
|
current = cosets[idx].bruhat_lower;
|
||||||
for(current = (cur+offset)->bruhat_lower; current; current = current->next) {
|
for(current = cosets[idx].bruhat_lower; current; current = current->next) {
|
||||||
if(!seen[current->to - offset]) {
|
if(!seen[current->to->index]) {
|
||||||
seen[current->to - offset] = 1;
|
seen[current->to->index] = 1;
|
||||||
queue_put(&queue, current->to - offset);
|
queue_put(&queue, current->to->index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -752,7 +792,6 @@ doublequotient_t *weyl_generate_bruhat(semisimple_type_t type, int left_invarian
|
|||||||
|
|
||||||
free(seen);
|
free(seen);
|
||||||
|
|
||||||
// reverse bruhat order
|
|
||||||
LOG("Revert bruhat order.\n");
|
LOG("Revert bruhat order.\n");
|
||||||
|
|
||||||
for(int i = 0; i < count; i++) {
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user