added index attribute, fixed F4 Cartan matrix
This commit is contained in:
commit
cc3e5952b1
193
old/process-old.c
Normal file
193
old/process-old.c
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
189
old/process.c
Normal file
189
old/process.c
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
*/
|
2
weyl.c
2
weyl.c
@ -452,7 +452,7 @@ void weyl_cartan_matrix(semisimple_type_t type, int *m)
|
|||||||
A[1][3] = A[3][1] = -1;
|
A[1][3] = A[3][1] = -1;
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
A[3][2] = -2;
|
A[2][1] = -2;
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
A[1][0] = -3;
|
A[1][0] = -3;
|
||||||
|
27
weyl.h
27
weyl.h
@ -38,8 +38,9 @@ struct _weylgroup_element {
|
|||||||
weylgroup_element_t **left;
|
weylgroup_element_t **left;
|
||||||
weylgroup_element_t **right;
|
weylgroup_element_t **right;
|
||||||
weylgroup_element_t *opposite;
|
weylgroup_element_t *opposite;
|
||||||
int is_root_reflection; // boolean value
|
int is_root_reflection; // boolean value
|
||||||
weylid_t id;
|
weylid_t id; // a unique id
|
||||||
|
int index;
|
||||||
|
|
||||||
// only set if quotient is generated
|
// only set if quotient is generated
|
||||||
doublecoset_t *coset;
|
doublecoset_t *coset;
|
||||||
@ -58,6 +59,7 @@ struct _doublecoset {
|
|||||||
doublecoset_t *opposite;
|
doublecoset_t *opposite;
|
||||||
weylgroup_element_t *max;
|
weylgroup_element_t *max;
|
||||||
weylgroup_element_t *min;
|
weylgroup_element_t *min;
|
||||||
|
int index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _doublecoset_list {
|
struct _doublecoset_list {
|
||||||
@ -69,7 +71,7 @@ struct _doublequotient {
|
|||||||
semisimple_type_t type;
|
semisimple_type_t type;
|
||||||
int left_invariance; // bitmask with rank bits
|
int left_invariance; // bitmask with rank bits
|
||||||
int right_invariance;
|
int right_invariance;
|
||||||
int count; // number of cosets
|
int count; // number of double cosets
|
||||||
doublecoset_t *cosets;
|
doublecoset_t *cosets;
|
||||||
weylgroup_element_t *group;
|
weylgroup_element_t *group;
|
||||||
doublecoset_list_t *lists; // only for memory allocation / freeing
|
doublecoset_list_t *lists; // only for memory allocation / freeing
|
||||||
@ -79,15 +81,34 @@ struct _doublequotient {
|
|||||||
|
|
||||||
/***************************** functions **************************************/
|
/***************************** functions **************************************/
|
||||||
|
|
||||||
|
/* query some basic information on root systems / Weyl groups */
|
||||||
|
|
||||||
|
// the rank
|
||||||
int weyl_rank(semisimple_type_t type);
|
int weyl_rank(semisimple_type_t type);
|
||||||
|
|
||||||
|
// the order of the weyl group
|
||||||
int weyl_order(semisimple_type_t type);
|
int weyl_order(semisimple_type_t type);
|
||||||
|
|
||||||
|
// the number of reduced positive roots
|
||||||
int weyl_positive(semisimple_type_t type);
|
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);
|
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);
|
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);
|
weylgroup_t *weyl_generate(semisimple_type_t type);
|
||||||
void weyl_destroy(weylgroup_t *group);
|
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);
|
doublequotient_t *weyl_generate_bruhat(semisimple_type_t type, int left_invariance, int right_invariance);
|
||||||
void weyl_destroy_bruhat(doublequotient_t *dq);
|
void weyl_destroy_bruhat(doublequotient_t *dq);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user