enumerate-balanced-ideals/D2n.c

134 lines
3.5 KiB
C

#include "thickenings.h"
#include "weyl.h"
#include "queue.h"
#include <strings.h>
#include <stdio.h>
#include <inttypes.h>
int main(int argc, const char *argv[])
{
if(argc < 2) {
fprintf(stderr, "Rank argument required.\n");
return 1;
}
int rank = atoi(argv[1]);
if(rank <= 0 || rank > 1000) {
fprintf(stderr, "Rank must be a small positive integer.\n");
return 1;
}
if(rank % 2) {
fprintf(stderr, "Rank must be even.\n"); // opposition involution not trivial otherwise
return 1;
}
doublequotient_t *dq = (doublequotient_t*)malloc(sizeof(doublequotient_t));
simple_type_t type;
type.series = 'D';
type.rank = rank;
dq->type.n = 1;
dq->type.factors = &type;
dq->left_invariance = (1<<rank) - 2;
dq->right_invariance = 0;
dq->group = 0;
dq->grouplists = 0;
dq->groupletters = 0;
dq->count = 1 << (rank - 1);
dq->cosets = (doublecoset_t*)malloc(dq->count*sizeof(doublecoset_t));
dq->lists = (doublecoset_list_t*)malloc(2*dq->count*rank*sizeof(doublecoset_list_t)); // conservative estimate
int nlists = 0;
int *bitmask = malloc((1<<(rank-1)) * sizeof(int));
int *bitmask_reverse = malloc((1<<rank) * sizeof(int));
int index = 0;
LOG("Prepare.\n");
for(int i = 0; i < dq->count; i++) {
dq->cosets[i].index = i;
dq->cosets[i].bruhat_lower = (doublecoset_list_t*)0;
dq->cosets[i].bruhat_higher = (doublecoset_list_t*)0;
dq->cosets[i].min = (weylgroup_element_t*)0;
dq->cosets[i].max = (weylgroup_element_t*)0;
}
LOG("Create bitmasks.\n");
for(uint64_t i = 0; i < (1 << rank); i++) {
if(__builtin_popcountll(i) % 2 == 1)
bitmask_reverse[i] = -1;
else {
bitmask[index] = i;
bitmask_reverse[i] = index++;
}
}
LOG("Generate bruhat order.\n");
for(int i = 0; i < dq->count; i++) {
for(int j = 0; j < rank - 1; j++) {
if(!(bitmask[i] & BIT(j)) && (bitmask[i] & BIT(j+1))) {
int lowerind = bitmask_reverse[bitmask[i] ^ (BIT(j) | BIT(j+1))];
dq->lists[nlists].next = dq->cosets[i].bruhat_lower;
dq->cosets[i].bruhat_lower = &dq->lists[nlists];
dq->cosets[i].bruhat_lower->to = &dq->cosets[lowerind];
nlists++;
}
}
if((bitmask[i] & BIT(0)) && (bitmask[i] & BIT(1))) {
int lowerind = bitmask_reverse[bitmask[i] & ~(BIT(0) | BIT(1))];
dq->lists[nlists].next = dq->cosets[i].bruhat_lower;
dq->cosets[i].bruhat_lower = &dq->lists[nlists];
dq->cosets[i].bruhat_lower->to = &dq->cosets[lowerind];
nlists++;
}
}
LOG("Revert bruhat order.\n");
for(int i = 0; i < dq->count; i++) {
for(doublecoset_list_t *cur = dq->cosets[i].bruhat_lower; cur; cur = cur->next) {
dq->lists[nlists].next = cur->to->bruhat_higher;
cur->to->bruhat_higher = &dq->lists[nlists];
cur->to->bruhat_higher->to = &dq->cosets[i];
nlists++;
}
}
LOG("Find opposites.\n");
for(int i = 0; i < dq->count; i++) {
int oppind = bitmask_reverse[~bitmask[i] & ((1<<rank) - 1)];
dq->cosets[i].opposite = &dq->cosets[oppind];
}
/*
printf("\n");
printf("digraph test123 {\n");
for(int i = 0; i < dq->count; i++) {
for(doublecoset_list_t *cur = dq->cosets[i].bruhat_lower; cur; cur = cur->next) {
printf("\"0x%02x\" -> \"0x%02x\";\n", bitmask[i], bitmask[cur->to->index]);
}
}
printf("}\n\n");
printf("Opposites:\n");
for(int i = 0; i < dq->count; i++)
printf("0x%02x <-> %d 0x%02x\n", bitmask[i], dq->cosets[i].opposite->index, bitmask[dq->cosets[i].opposite->index]);
printf("\n");
*/
long count = enumerate_balanced_thickenings(dq, 0, 0);
printf("Found %ld balanced ideals.\n", count);
free(bitmask);
free(bitmask_reverse);
free(dq->lists);
free(dq->cosets);
free(dq);
return 0;
}