specialized routine to generate cosets for <bcd..> \ D2n
This commit is contained in:
parent
4342a1f3e5
commit
d3336bab00
133
D2n.c
Normal file
133
D2n.c
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
#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;
|
||||||
|
}
|
10
Makefile
10
Makefile
@ -7,7 +7,7 @@ SPECIAL_OPTIONS=-O3 -flto -funroll-loops -Winline
|
|||||||
OPTIONS=-m64 -march=native -mtune=native -std=gnu99 -D_GNU_SOURCE $(SPECIAL_OPTIONS)
|
OPTIONS=-m64 -march=native -mtune=native -std=gnu99 -D_GNU_SOURCE $(SPECIAL_OPTIONS)
|
||||||
NAME=enumerate-balanced-ideals
|
NAME=enumerate-balanced-ideals
|
||||||
|
|
||||||
all: enumerate graph
|
all: enumerate graph D2n
|
||||||
|
|
||||||
$(NAME).tar.bz2: $(NAME) $(HEADERS) enumerate.c weyl.c thickenings.c
|
$(NAME).tar.bz2: $(NAME) $(HEADERS) enumerate.c weyl.c thickenings.c
|
||||||
tar cjhf $(NAME).tar.bz2 $(NAME)/enumerate.c $(NAME)/weyl.c $(NAME)/thickenings.c $(NAME)/weyl.h $(NAME)/thickenings.h $(NAME)/queue.h $(NAME)/bitvec.h $(NAME)/Makefile $(NAME)/graph.c
|
tar cjhf $(NAME).tar.bz2 $(NAME)/enumerate.c $(NAME)/weyl.c $(NAME)/thickenings.c $(NAME)/weyl.h $(NAME)/thickenings.h $(NAME)/queue.h $(NAME)/bitvec.h $(NAME)/Makefile $(NAME)/graph.c
|
||||||
@ -21,12 +21,18 @@ enumerate: enumerate.o weyl.o thickenings.o
|
|||||||
graph: graph.o weyl.o
|
graph: graph.o weyl.o
|
||||||
gcc $(OPTIONS) -o graph graph.o weyl.o
|
gcc $(OPTIONS) -o graph graph.o weyl.o
|
||||||
|
|
||||||
|
D2n: D2n.o weyl.o thickenings.o
|
||||||
|
gcc $(OPTIONS) -o D2n D2n.o weyl.o thickenings.o
|
||||||
|
|
||||||
enumerate.o: enumerate.c $(HEADERS)
|
enumerate.o: enumerate.c $(HEADERS)
|
||||||
gcc $(OPTIONS) -c enumerate.c
|
gcc $(OPTIONS) -c enumerate.c
|
||||||
|
|
||||||
thickenings.o: thickenings.c $(HEADERS)
|
thickenings.o: thickenings.c $(HEADERS)
|
||||||
gcc $(OPTIONS) -c thickenings.c
|
gcc $(OPTIONS) -c thickenings.c
|
||||||
|
|
||||||
|
D2n.o: D2n.c $(HEADERS)
|
||||||
|
gcc $(OPTIONS) -c D2n.c
|
||||||
|
|
||||||
weyl.o: weyl.c $(HEADERS)
|
weyl.o: weyl.c $(HEADERS)
|
||||||
gcc $(OPTIONS) -c weyl.c
|
gcc $(OPTIONS) -c weyl.c
|
||||||
|
|
||||||
@ -34,4 +40,4 @@ graph.o: graph.c $(HEADERS)
|
|||||||
gcc $(OPTIONS) -c graph.c
|
gcc $(OPTIONS) -c graph.c
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f enumerate graph thickenings.o weyl.o enumerate.o graph.o $(NAME) $(NAME).tar.bz2
|
rm -f enumerate graph D2n thickenings.o weyl.o enumerate.o graph.o D2n.o $(NAME) $(NAME).tar.bz2
|
||||||
|
@ -110,7 +110,7 @@ static void generate_principal_ideals(doublequotient_t *dq, bitvec_t *pos, bitve
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if(is_slim[i]) {
|
if(is_slim[i] && dq->cosets[0].min) { // sometimes we don't want to define min and max
|
||||||
fprintf(stderr, " ids: [0");
|
fprintf(stderr, " ids: [0");
|
||||||
for(int j = 1; j < size; j++)
|
for(int j = 1; j < size; j++)
|
||||||
if(principal[j])
|
if(principal[j])
|
||||||
@ -160,7 +160,7 @@ long enumerate_balanced_thickenings(doublequotient_t *dq, enumeration_callback c
|
|||||||
// the algorithm only works if the opposition pairing does not stabilize any element
|
// the algorithm only works if the opposition pairing does not stabilize any element
|
||||||
// if this happens, there can be no balanced thickenings
|
// if this happens, there can be no balanced thickenings
|
||||||
for(int i = 0; i < dq->count; i++)
|
for(int i = 0; i < dq->count; i++)
|
||||||
if(dq->cosets[i].opposite->min->id == dq->cosets[i].min->id)
|
if(dq->cosets[i].opposite->index == i)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// we can only handle bitvectors up to BV_BLOCKSIZE*BV_RANK bits, but we only store half of the weyl group
|
// we can only handle bitvectors up to BV_BLOCKSIZE*BV_RANK bits, but we only store half of the weyl group
|
||||||
|
Loading…
Reference in New Issue
Block a user