diff --git a/old/process-old.c b/old/process-old.c new file mode 100644 index 0000000..0dd3fb4 --- /dev/null +++ b/old/process-old.c @@ -0,0 +1,193 @@ +#include +#include +#include + +#include "thickenings.h" +#include "coxeter.h" +#include "queue.h" + +#define SWAP(t, a, b) do {t tmp = a; a = b; b = tmp;} while(0) + +char *stringify_SLn1_permutation(int *word, int wordlength, int rank, char *str) +{ + for(int i = 0; i <= rank; i++) + str[i] = '1' + i; + str[rank+1] = 0; + + for(int i = 0; i < wordlength; i++) { + char tmp = str[word[i]]; + str[word[i]] = str[word[i]+1]; + str[word[i]+1] = tmp; + } + return str; +} + + +char *stringify_Onn1_permutation(int *word, int wordlength, int rank, char *str) +{ + for(int i = 0; i <= rank*2; i++) + str[i] = '1' + i; + str[2*rank+1] = 0; + + for(int i = 0; i < wordlength; i++) { + if(word[i] == 0) + SWAP(char, str[rank-1], str[rank+1]); + else { + SWAP(char, str[rank-word[i]], str[rank-word[i]-1]); + SWAP(char, str[rank+word[i]], str[rank+word[i]+1]); + } + } + return str; +} + +int main(int argc, const char *argv[]) +{ + FILE *infile; + struct stat st; + int rank, order, hyperplanes; + semisimple_type_t type; + int n; + signed char *level; + node_t *graph; + int *left, *right; + int left_invariant, right_invariant; + int left_invariant_wanted = 0, right_invariant_wanted = 0; + + unsigned long left_invariance, right_invariance; + edgelist_t *edgelists; + int *words; + + queue_t queue; + int current; + int *seen; + int *generators; + int ngens; + + char string_buffer1[1000]; + const char *alphabet = "abcdefghijklmnopqrstuvwxyz"; + + // parse arguments + + if(argc < 2) + infile = stdin; + else { + if(strcmp(argv[1], "-") == 0) + infile = stdin; + else + infile = fopen(argv[1], "rb"); + + if(argc >= 4) { + if(strcmp(argv[2], "-") != 0) + for(int i = 0; i < strlen(argv[2]); i++) + left_invariant_wanted |= (1 << (argv[2][i] - 'a')); + if(strcmp(argv[3], "-") != 0) + for(int i = 0; i < strlen(argv[3]); i++) + right_invariant_wanted |= (1 << (argv[3][i] - 'a')); + } + } + + fread(&type.n, sizeof(int), 1, infile); // we completely trust the input data + type.factors = malloc(type.n * sizeof(simple_type_t)); + fread(type.factors, sizeof(simple_type_t), type.n, infile); + fread(&left_invariance, sizeof(simple_type_t), type.n, infile); + fread(&right_invariance, sizeof(simple_type_t), type.n, infile); + + // get graph + + rank = coxeter_rank(type); + order = coxeter_order(type); + hyperplanes = coxeter_hyperplanes(type); + ERROR(strlen(alphabet) < rank, "The alphabet has too few letters\n"); + seen = (int*)malloc(order*sizeof(int)); + generators = (int*)malloc(order*sizeof(int)); + level = (signed char*)malloc(order*sizeof(int)); + + graph = graph_alloc(type); + prepare_graph(type, graph); + + // finally do stuff + + int counter = 0; + + while(fread(level, sizeof(signed char), order, infile) == order) { + + /* + if((counter++) % 100000 == 0) + print_thickening(rank, order, level, 0, 0, 0, alphabet, stdout); + continue; + */ + + left_invariant = right_invariant = -1; // all 1s + for(int j = 0; j < order; j++) { + for(int k = 0; k < rank; k++) { + if(level[j] > 0 && level[graph[j].left[k]] < 0 || level[j] < 0 && level[graph[j].left[k]] > 0) { + left_invariant &= ~(1 << k); + } + if(level[j] > 0 && level[graph[j].right[k]] < 0 || level[j] < 0 && level[graph[j].right[k]] > 0) { + right_invariant &= ~(1 << k); + } + } + } + + if((~left_invariant & left_invariant_wanted) == 0 && (~right_invariant & right_invariant_wanted) == 0) { + ngens = 0; + memset(generators, 0, order*sizeof(int)); + for(int j = 0; j < order; j++) { + if(level[j] == HEAD_MARKER && generators[j] == 0) { // ignore the generator, if it is equivalent to one already seen + ngens++; + queue_init(&queue); + queue_put(&queue, j); + while((current = queue_get(&queue)) != -1) { + if(generators[current] == 0) { // visit everyone only once + generators[current] = ngens; + for(int k = 0; k < rank; k++) { + if(left_invariant & (1 << k)) + queue_put(&queue, graph[current].left[k]); + if(right_invariant & (1 << k)) + queue_put(&queue, graph[current].right[k]); + } + } + } + } + } + + printf("left: "); + for(int j = 0; j < rank; j++) + printf("%c", left_invariant & (1 << j) ? alphabet[j] : ' '); + printf(" right: "); + for(int j = 0; j < rank; j++) + printf("%c", right_invariant & (1 << j) ? alphabet[j] : ' '); + printf(" generators: "); + + memset(seen, 0, order*sizeof(int)); + for(int i = 0; i < order; i++) { + if(generators[i] != 0 && seen[generators[i]-1] == 0) { + seen[generators[i]-1] = 1; + // if(type.n == 1 && type.factors[0].series == 'A') + // printf("%s ", stringify_SLn1_permutation(graph[i].word, graph[i].wordlength, rank, string_buffer1)); + // else if(type.n == 1 && (type.factors[0].series == 'B' || type.factors[0].series == 'C')) + // printf("%s ", stringify_Onn1_permutation(graph[i].word, graph[i].wordlength, rank, string_buffer1)); + // else + if(i == 0) + printf("1 "); + else + printf("%s ", alphabetize(graph[i].word, graph[i].wordlength, alphabet, string_buffer1)); + } + } + + printf("\n"); + } + } + + if(infile != stdin) + fclose(infile); + + // cleanup + + graph_free(type, graph); + free(seen); + free(generators); + free(type.factors); + + return 0; +} diff --git a/old/process.c b/old/process.c new file mode 100644 index 0000000..a807283 --- /dev/null +++ b/old/process.c @@ -0,0 +1,189 @@ +#include +#include +#include + +#include "thickenings.h" +#include "weyl.h" +#include "queue.h" + +int main(int argc, const char *argv[]) +{ + FILE *infile; + semisimple_type_t type; + unsigned long left_invariance, right_invariance; // these are the invariances we have already modded out + unsigned long left_invariant, right_invariant; // these are the invariances of the thickening under consideration + int rank, cosets; + node_t *graph; + signed char *thickening; + int *seen, *generators; + queue_t queue; + int ngenerators; + int current; + + char string_buffer1[1000]; + const char *alphabet = "abcdefghijklmnopqrstuvwxyz"; + + if(argc < 2) + infile = stdin; + else + infile = fopen(argv[1], "rb"); + + // we completely trust the input data + ERROR(fread(&type.n, sizeof(int), 1, infile) == 0, "The input file seems to be empty!\n"); + type.factors = malloc(type.n * sizeof(simple_type_t)); + fread(type.factors, sizeof(simple_type_t), type.n, infile); + fread(&left_invariance, sizeof(simple_type_t), type.n, infile); + fread(&right_invariance, sizeof(simple_type_t), type.n, infile); + + rank = weyl_rank(type); + graph = graph_alloc(type); + cosets = prepare_simplified_graph(type, left_invariance, right_invariance, graph); + + thickening = (signed char*)malloc(cosets*sizeof(signed char)); + generators = (int*)malloc(cosets*sizeof(int)); + seen = (int*)malloc(cosets*sizeof(int)); + + while(fread(thickening, sizeof(signed char), cosets, infile) == cosets) { + + // determine invariances of this thickening + left_invariant = right_invariant = -1; // set all bits to 1 + for(int j = 0; j < cosets; j++) { + for(int k = 0; k < rank; k++) { + if(thickening[j] > 0 && thickening[graph[j].left[k]] < 0 || + thickening[j] < 0 && thickening[graph[j].left[k]] > 0) + left_invariant &= ~(1 << k); + if(thickening[j] > 0 && thickening[graph[j].right[k]] < 0 || + thickening[j] < 0 && thickening[graph[j].right[k]] > 0) + right_invariant &= ~(1 << k); + } + } + + // print this stuff + printf("left: "); + for(int j = 0; j < rank; j++) + printf("%c", left_invariant & (1 << j) ? alphabet[j] : ' '); + printf(" right: "); + for(int j = 0; j < rank; j++) + printf("%c", right_invariant & (1 << j) ? alphabet[j] : ' '); + printf(" generators: "); + + // find a minimal set of weyl group elements such that the union of the ideals generated by their cosets wrt the invariances determined above gives the thickening + // in the first step, mark everything which is equivalent to a "head" by a generator id + ngenerators = 0; + memset(generators, 0, cosets*sizeof(int)); + for(int j = 0; j < cosets; j++) { + if(thickening[j] == HEAD_MARKER && generators[j] == 0) { // ignore the generator, if it is equivalent to one already seen + ngenerators++; + queue_init(&queue); + queue_put(&queue, j); + while((current = queue_get(&queue)) != -1) { + if(generators[current] == 0) { // visit everyone only once + generators[current] = ngenerators; + for(int k = 0; k < rank; k++) { + if(left_invariant & (1 << k)) + queue_put(&queue, graph[current].left[k]); + if(right_invariant & (1 << k)) + queue_put(&queue, graph[current].right[k]); + } + } + } + } + } + + // in the second step, go through the list in ascending word length order and print the first appearance of each generator id + memset(seen, 0, cosets*sizeof(int)); + for(int i = 0; i < cosets; i++) { + if(generators[i] != 0 && seen[generators[i]-1] == 0) { + seen[generators[i]-1] = 1; + printf("%s ", alphabetize(graph[i].word, graph[i].wordlength, alphabet, string_buffer1)); + } + } + + printf("\n"); + } + + if(infile != stdin) + fclose(infile); + + graph_free(type, graph); + free(type.factors); + free(thickening); +} + /******************************************************************************************* + + seen = (int*)malloc(order*sizeof(int)); + generators = (int*)malloc(order*sizeof(int)); + level = (signed char*)malloc(order*sizeof(int)); + + graph = graph_alloc(type); + prepare_graph(type, graph); + + // finally do stuff + + int counter = 0; + + while(fread(level, sizeof(signed char), order, infile) == order) { + + if((~left_invariant & left_invariant_wanted) == 0 && (~right_invariant & right_invariant_wanted) == 0) { + ngens = 0; + memset(generators, 0, order*sizeof(int)); + for(int j = 0; j < order; j++) { + if(level[j] == HEAD_MARKER && generators[j] == 0) { // ignore the generator, if it is equivalent to one already seen + ngens++; + queue_init(&queue); + queue_put(&queue, j); + while((current = queue_get(&queue)) != -1) { + if(generators[current] == 0) { // visit everyone only once + generators[current] = ngens; + for(int k = 0; k < rank; k++) { + if(left_invariant & (1 << k)) + queue_put(&queue, graph[current].left[k]); + if(right_invariant & (1 << k)) + queue_put(&queue, graph[current].right[k]); + } + } + } + } + } + + printf("left: "); + for(int j = 0; j < rank; j++) + printf("%c", left_invariant & (1 << j) ? alphabet[j] : ' '); + printf(" right: "); + for(int j = 0; j < rank; j++) + printf("%c", right_invariant & (1 << j) ? alphabet[j] : ' '); + printf(" generators: "); + + memset(seen, 0, order*sizeof(int)); + for(int i = 0; i < order; i++) { + if(generators[i] != 0 && seen[generators[i]-1] == 0) { + seen[generators[i]-1] = 1; + // if(type.n == 1 && type.factors[0].series == 'A') + // printf("%s ", stringify_SLn1_permutation(graph[i].word, graph[i].wordlength, rank, string_buffer1)); + // else if(type.n == 1 && (type.factors[0].series == 'B' || type.factors[0].series == 'C')) + // printf("%s ", stringify_Onn1_permutation(graph[i].word, graph[i].wordlength, rank, string_buffer1)); + // else + if(i == 0) + printf("1 "); + else + printf("%s ", alphabetize(graph[i].word, graph[i].wordlength, alphabet, string_buffer1)); + } + } + + printf("\n"); + } + } + + if(infile != stdin) + fclose(infile); + + // cleanup + + graph_free(type, graph); + free(seen); + free(generators); + free(type.factors); + + return 0; +} +*/ diff --git a/weyl.c b/weyl.c index 7c4fbff..5e16780 100644 --- a/weyl.c +++ b/weyl.c @@ -452,7 +452,7 @@ void weyl_cartan_matrix(semisimple_type_t type, int *m) A[1][3] = A[3][1] = -1; break; case 'F': - A[3][2] = -2; + A[2][1] = -2; break; case 'G': A[1][0] = -3; diff --git a/weyl.h b/weyl.h index 55b8442..cb150bc 100644 --- a/weyl.h +++ b/weyl.h @@ -38,8 +38,9 @@ struct _weylgroup_element { weylgroup_element_t **left; weylgroup_element_t **right; weylgroup_element_t *opposite; - int is_root_reflection; // boolean value - weylid_t id; + int is_root_reflection; // boolean value + weylid_t id; // a unique id + int index; // only set if quotient is generated doublecoset_t *coset; @@ -58,6 +59,7 @@ struct _doublecoset { doublecoset_t *opposite; weylgroup_element_t *max; weylgroup_element_t *min; + int index; }; struct _doublecoset_list { @@ -69,7 +71,7 @@ struct _doublequotient { semisimple_type_t type; int left_invariance; // bitmask with rank bits int right_invariance; - int count; // number of cosets + int count; // number of double cosets doublecoset_t *cosets; weylgroup_element_t *group; doublecoset_list_t *lists; // only for memory allocation / freeing @@ -79,15 +81,34 @@ struct _doublequotient { /***************************** functions **************************************/ +/* query some basic information on root systems / Weyl groups */ + +// the rank int weyl_rank(semisimple_type_t type); + +// the order of the weyl group int weyl_order(semisimple_type_t type); + +// the number of reduced positive roots int weyl_positive(semisimple_type_t type); + +// the Cartan matrix (has rank columns and rank rows) void weyl_cartan_matrix(semisimple_type_t type, int *m); + +// the opposition involution as a map from simple roots to simple roots (indexed from 0 to rank-1) int weyl_opposition(semisimple_type_t type, int simple_root); +/* generate the Weyl group: + weyl_destroy() has to be used to free memory + */ weylgroup_t *weyl_generate(semisimple_type_t type); void weyl_destroy(weylgroup_t *group); +/* generate a double quotient of the Weyl group and its Bruhat order: + left_invariance and right_invariance are bitmaps specifying a subset of the simple roots + The Weyl group will be quotiented from the left and right by the subgroups generated by these simple root reflections + weyl_destroy_bruhat() has to be used to free memory + */ doublequotient_t *weyl_generate_bruhat(semisimple_type_t type, int left_invariance, int right_invariance); void weyl_destroy_bruhat(doublequotient_t *dq);