Generate + Process
This commit is contained in:
parent
eb7f469171
commit
a17c6fb06e
27
Makefile
27
Makefile
@ -1,14 +1,25 @@
|
|||||||
|
HEADERS=coxeter.h thickenings.h queue.h
|
||||||
|
OPTIONS=-O0 -g -std=gnu99
|
||||||
|
|
||||||
all: thickenings
|
all: generate process
|
||||||
|
|
||||||
thickenings: thickenings.o coxeter.o
|
generate: generate.o coxeter.o thickenings.o
|
||||||
gcc -O3 -o thickenings thickenings.o coxeter.o -lgsl -lcblas
|
gcc $(OPTIONS) -o generate generate.o thickenings.o coxeter.o -lgsl -lcblas
|
||||||
|
|
||||||
thickenings.o: thickenings.c coxeter.h
|
process: process.o coxeter.o thickenings.o
|
||||||
gcc -O3 -c thickenings.c -std=gnu99
|
gcc $(OPTIONS) -o process process.o thickenings.o coxeter.o -lgsl -lcblas
|
||||||
|
|
||||||
coxeter.o: coxeter.c coxeter.h
|
generate.o: generate.c $(HEADERS)
|
||||||
gcc -O3 -c coxeter.c -std=gnu99
|
gcc $(OPTIONS) -c generate.c
|
||||||
|
|
||||||
|
process.o: process.c $(HEADERS)
|
||||||
|
gcc $(OPTIONS) -c process.c
|
||||||
|
|
||||||
|
thickenings.o: thickenings.c $(HEADERS)
|
||||||
|
gcc $(OPTIONS) -c thickenings.c
|
||||||
|
|
||||||
|
coxeter.o: coxeter.c $(HEADERS)
|
||||||
|
gcc $(OPTIONS) -c coxeter.c
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f thickenings thickenings.o coxeter.o
|
rm -f generate thickenings.o coxeter.o generate.o process.o
|
||||||
|
88
generate.c
Normal file
88
generate.c
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "coxeter.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "thickenings.h"
|
||||||
|
|
||||||
|
int main(int argc, const char *argv[])
|
||||||
|
{
|
||||||
|
semisimple_type_t type;
|
||||||
|
|
||||||
|
// heap stuff
|
||||||
|
node_t *graph;
|
||||||
|
int *left, *right;
|
||||||
|
edgelist_t *edgelists;
|
||||||
|
int *words;
|
||||||
|
|
||||||
|
int rank, order;
|
||||||
|
|
||||||
|
char string_buffer1[1000];
|
||||||
|
const char *alphabet = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
ERROR(argc < 2, "Too few arguments!\n");
|
||||||
|
|
||||||
|
type.n = argc - 1;
|
||||||
|
type.factors = (simple_type_t*)malloc((argc-1)*sizeof(simple_type_t));
|
||||||
|
for(int i = 0; i < argc - 1; i++) {
|
||||||
|
type.factors[i].series = argv[i+1][0];
|
||||||
|
type.factors[i].rank = argv[i+1][1] - '0';
|
||||||
|
ERROR(argv[i+1][0] < 'A' || argv[i+1][0] > 'I' || argv[i+1][1] < '1' || argv[i+1][1] > '9', "Arguments must be Xn with X out of A-I and n out of 0-9\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
rank = coxeter_rank(type);
|
||||||
|
order = coxeter_order(type);
|
||||||
|
|
||||||
|
ERROR(strlen(alphabet) < rank, "The alphabet has too few letters\n");
|
||||||
|
|
||||||
|
// initialize
|
||||||
|
|
||||||
|
graph = (node_t*)malloc(order*sizeof(node_t));
|
||||||
|
left = (int*)malloc(order*rank*sizeof(int));
|
||||||
|
right = (int*)malloc(order*rank*sizeof(int));
|
||||||
|
|
||||||
|
for(int i = 0; i < order; i++) {
|
||||||
|
graph[i].left = &left[rank*i];
|
||||||
|
graph[i].right = &right[rank*i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate graph
|
||||||
|
|
||||||
|
prepare_graph(type, graph, &edgelists, &words);
|
||||||
|
|
||||||
|
// print stuff
|
||||||
|
|
||||||
|
int hyperplane_count = 0;
|
||||||
|
for(int i = 0; i < order; i++)
|
||||||
|
if(graph[i].is_hyperplane_reflection)
|
||||||
|
hyperplane_count++;
|
||||||
|
|
||||||
|
fprintf(stderr, "Rank: %d\t\tOrder: %d\t\tHyperplanes: %d\n", rank, order, hyperplane_count);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr, "Group elements: \n");
|
||||||
|
for(int i = 0, wl = 0; i < order; i++) {
|
||||||
|
if(i == 0) {
|
||||||
|
fprintf(stderr, "1");
|
||||||
|
} else if(graph[i].wordlength > wl) {
|
||||||
|
fprintf(stderr, "\n%s ", alphabetize(graph[i].word, graph[i].wordlength, alphabet, string_buffer1));
|
||||||
|
wl = graph[i].wordlength;
|
||||||
|
} else
|
||||||
|
fprintf(stderr, "%s ", alphabetize(graph[i].word, graph[i].wordlength, alphabet, string_buffer1));
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n\n");
|
||||||
|
|
||||||
|
// enumerate balanced thickenings
|
||||||
|
|
||||||
|
fwrite(&type.n, sizeof(int), 1, stdout);
|
||||||
|
fwrite(type.factors, sizeof(simple_type_t), type.n, stdout);
|
||||||
|
enumerate_balanced_thickenings(type, graph, alphabet, stdout);
|
||||||
|
|
||||||
|
free(graph);
|
||||||
|
free(left);
|
||||||
|
free(right);
|
||||||
|
free(edgelists);
|
||||||
|
free(words);
|
||||||
|
free(type.factors);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
179
process.c
Normal file
179
process.c
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
#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;
|
||||||
|
semisimple_type_t type;
|
||||||
|
int n;
|
||||||
|
int *thickenings, *level;
|
||||||
|
node_t *graph;
|
||||||
|
int *left, *right;
|
||||||
|
int *left_invariant, *right_invariant;
|
||||||
|
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
|
||||||
|
infile = fopen(argv[1], "rb");
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// get graph
|
||||||
|
|
||||||
|
rank = coxeter_rank(type);
|
||||||
|
order = coxeter_order(type);
|
||||||
|
ERROR(strlen(alphabet) < rank, "The alphabet has too few letters\n");
|
||||||
|
graph = (node_t*)malloc(order*sizeof(node_t));
|
||||||
|
left = (int*)malloc(order*rank*sizeof(int));
|
||||||
|
right = (int*)malloc(order*rank*sizeof(int));
|
||||||
|
left_invariant = (int*)malloc(rank*sizeof(int));
|
||||||
|
right_invariant = (int*)malloc(rank*sizeof(int));
|
||||||
|
seen = (int*)malloc(order*sizeof(int));
|
||||||
|
generators = (int*)malloc(order*sizeof(int));
|
||||||
|
level = (int*)malloc(order*sizeof(int));
|
||||||
|
for(int i = 0; i < order; i++) {
|
||||||
|
graph[i].left = &left[i*rank];
|
||||||
|
graph[i].right = &right[i*rank];
|
||||||
|
}
|
||||||
|
prepare_graph(type, graph, &edgelists, &words);
|
||||||
|
|
||||||
|
// finally do stuff
|
||||||
|
|
||||||
|
while(fread(level, sizeof(int), order, infile) == order) {
|
||||||
|
|
||||||
|
for(int j = 0; j < rank; j++) {
|
||||||
|
left_invariant[j] = 1;
|
||||||
|
right_invariant[j] = 1;
|
||||||
|
}
|
||||||
|
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[k] = 0;
|
||||||
|
if(level[j] == 0 && level[graph[j].right[k]] != 0 || level[j] != 0 && level[graph[j].right[k]] == 0)
|
||||||
|
right_invariant[k] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngens = 0;
|
||||||
|
memset(generators, 0, order*sizeof(int));
|
||||||
|
for(int j = 0; j < order; j++) {
|
||||||
|
if(level[j] == -1 && 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[k])
|
||||||
|
queue_put(&queue, graph[current].left[k]);
|
||||||
|
if(right_invariant[k])
|
||||||
|
queue_put(&queue, graph[current].right[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("left: ");
|
||||||
|
for(int j = 0; j < rank; j++)
|
||||||
|
printf("%c", left_invariant[j] ? alphabet[j] : ' ');
|
||||||
|
printf(" right: ");
|
||||||
|
for(int j = 0; j < rank; j++)
|
||||||
|
printf("%c", right_invariant[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
|
||||||
|
|
||||||
|
free(thickenings);
|
||||||
|
free(edgelists);
|
||||||
|
free(words);
|
||||||
|
free(graph);
|
||||||
|
free(left);
|
||||||
|
free(right);
|
||||||
|
free(right_invariant);
|
||||||
|
free(left_invariant);
|
||||||
|
free(seen);
|
||||||
|
free(generators);
|
||||||
|
free(type.factors);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
243
thickenings.c
243
thickenings.c
@ -6,30 +6,11 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
|
||||||
|
#include "thickenings.h"
|
||||||
#include "coxeter.h"
|
#include "coxeter.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
|
||||||
#define DEBUG(msg, ...) do{fprintf(stderr, msg, ##__VA_ARGS__); }while(0)
|
char *alphabetize(int *word, int len, const char *alphabet, char *buffer)
|
||||||
|
|
||||||
#define MAX_THICKENINGS 10000
|
|
||||||
|
|
||||||
typedef struct _edgelist {
|
|
||||||
int to;
|
|
||||||
struct _edgelist *next;
|
|
||||||
} edgelist_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int *word;
|
|
||||||
int wordlength;
|
|
||||||
int *left;
|
|
||||||
int *right;
|
|
||||||
int opposite;
|
|
||||||
edgelist_t *bruhat_lower;
|
|
||||||
edgelist_t *bruhat_higher;
|
|
||||||
int is_hyperplane_reflection; // boolean value
|
|
||||||
} node_t;
|
|
||||||
|
|
||||||
static char *alphabetize(int *word, int len, const char *alphabet, char *buffer)
|
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(i = 0; i < len; i++)
|
for(i = 0; i < len; i++)
|
||||||
@ -39,30 +20,30 @@ static char *alphabetize(int *word, int len, const char *alphabet, char *buffer)
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_balanced_thickening(int rank, int order, const int *thickening, const int *left_invariant, const int *right_invariant, const char *alphabet)
|
void print_balanced_thickening(int rank, int order, const int *thickening, const int *left_invariant, const int *right_invariant, const char *alphabet, FILE *f)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < order; i++) {
|
for(int i = 0; i < order; i++) {
|
||||||
if(thickening[i])
|
if(thickening[i])
|
||||||
printf("x");
|
fprintf(f, "x");
|
||||||
else
|
else
|
||||||
printf("0");
|
fprintf(f, "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(" left: ");
|
fprintf(f, " left: ");
|
||||||
for(int j = 0; j < rank; j++)
|
for(int j = 0; j < rank; j++)
|
||||||
if(left_invariant[j])
|
if(left_invariant[j])
|
||||||
printf("%c", alphabet[j]);
|
fprintf(f, "%c", alphabet[j]);
|
||||||
else
|
else
|
||||||
printf(" ");
|
fprintf(f, " ");
|
||||||
|
|
||||||
printf(" right: ");
|
fprintf(f, " right: ");
|
||||||
for(int j = 0; j < rank; j++)
|
for(int j = 0; j < rank; j++)
|
||||||
if(right_invariant[j])
|
if(right_invariant[j])
|
||||||
printf("%c", alphabet[j]);
|
fprintf(f, "%c", alphabet[j]);
|
||||||
else
|
else
|
||||||
printf(" ");
|
fprintf(f, " ");
|
||||||
|
|
||||||
printf("\n");
|
fprintf(f, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int compare_wordlength(const void *a, const void *b, void *gr)
|
static int compare_wordlength(const void *a, const void *b, void *gr)
|
||||||
@ -74,72 +55,34 @@ static int compare_wordlength(const void *a, const void *b, void *gr)
|
|||||||
return graph[i].wordlength - graph[j].wordlength;
|
return graph[i].wordlength - graph[j].wordlength;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char *argv[])
|
void prepare_graph(semisimple_type_t type, node_t *graph, edgelist_t **edgelists_pointer, int **words_pointer) // the edgelists_pointer and words_pointer arguments are just for freeing afterwards
|
||||||
{
|
{
|
||||||
queue_t queue;
|
queue_t queue;
|
||||||
|
|
||||||
// heap stuff
|
|
||||||
node_t *graph, *graph_unsorted;
|
|
||||||
int *graph_data;
|
|
||||||
int *wordlength_order, *reverse_wordlength_order, *seen, *level;
|
|
||||||
int *words;
|
|
||||||
edgelist_t *edgelists;
|
|
||||||
int *left, *right;
|
|
||||||
int *left_invariant, *right_invariant;
|
|
||||||
|
|
||||||
edgelist_t *edge, *previous;
|
|
||||||
int rank, order;
|
int rank, order;
|
||||||
semisimple_type_t type;
|
edgelist_t *edge, *previous;
|
||||||
int edgelist_count, hyperplane_count, max_wordlength;
|
int edgelist_count, max_wordlength, hyperplane_count;
|
||||||
int current, head, i, current_level;
|
int current;
|
||||||
int is_fat, is_slim;
|
|
||||||
int thickenings_count, fat_count, slim_count, balanced_count;
|
|
||||||
|
|
||||||
int *balanced_thickenings;
|
int *graph_data;
|
||||||
|
node_t *graph_unsorted;
|
||||||
|
int *wordlength_order, *reverse_wordlength_order, *seen, *words;
|
||||||
|
edgelist_t *edgelists;
|
||||||
|
|
||||||
char *string_buffer1, *string_buffer2;
|
// initialize
|
||||||
|
|
||||||
const char *alphabet = "abcdefghijklmnopqrstuvwxyz";
|
|
||||||
|
|
||||||
ERROR(argc < 2, "Too few arguments!\n");
|
|
||||||
|
|
||||||
type.n = argc - 1;
|
|
||||||
type.factors = (simple_type_t*)malloc((argc-1)*sizeof(simple_type_t));
|
|
||||||
for(int i = 0; i < argc - 1; i++) {
|
|
||||||
type.factors[i].series = argv[i+1][0];
|
|
||||||
type.factors[i].rank = argv[i+1][1] - '0';
|
|
||||||
ERROR(argv[i+1][0] < 'A' || argv[i+1][0] > 'I' || argv[i+1][1] < '1' || argv[i+1][1] > '9', "Arguments must be Xn with X out of A-I and n out of 0-9\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
rank = coxeter_rank(type);
|
rank = coxeter_rank(type);
|
||||||
order = coxeter_order(type);
|
order = coxeter_order(type);
|
||||||
|
|
||||||
ERROR(strlen(alphabet) < rank, "The alphabet has too few letters\n");
|
|
||||||
|
|
||||||
// DEBUG("The group has rank %d and order %d\n", rank, order);
|
|
||||||
|
|
||||||
graph = (node_t*)malloc(order*sizeof(node_t));
|
|
||||||
graph_unsorted = (node_t*)malloc(order*sizeof(node_t));
|
|
||||||
graph_data = (int*)malloc(order*rank*sizeof(int));
|
graph_data = (int*)malloc(order*rank*sizeof(int));
|
||||||
|
graph_unsorted = (node_t*)malloc(order*sizeof(node_t));
|
||||||
wordlength_order = (int*)malloc(order*sizeof(int));
|
wordlength_order = (int*)malloc(order*sizeof(int));
|
||||||
reverse_wordlength_order = (int*)malloc(order*sizeof(int));
|
reverse_wordlength_order = (int*)malloc(order*sizeof(int));
|
||||||
seen = (int*)malloc(order*sizeof(int));
|
seen = (int*)malloc(order*sizeof(int));
|
||||||
level = (int*)malloc(order*sizeof(int));
|
|
||||||
left = (int*)malloc(order*rank*sizeof(int));
|
|
||||||
right = (int*)malloc(order*rank*sizeof(int));
|
|
||||||
left_invariant = (int*)malloc(rank*sizeof(int));
|
|
||||||
right_invariant = (int*)malloc(rank*sizeof(int));
|
|
||||||
balanced_thickenings = (int*)malloc(MAX_THICKENINGS*order*sizeof(int));
|
|
||||||
|
|
||||||
// DEBUG("Generate Cayley graph\n");
|
|
||||||
|
|
||||||
generate_coxeter_graph(type, graph_data);
|
|
||||||
|
|
||||||
for(int i = 0; i < order; i++) {
|
for(int i = 0; i < order; i++) {
|
||||||
graph_unsorted[i].left = &left[i*rank];
|
graph_unsorted[i].left = graph[i].left;
|
||||||
graph_unsorted[i].right = &right[i*rank];
|
graph_unsorted[i].right = graph[i].right;
|
||||||
for(int j = 0; j < rank; j++)
|
|
||||||
graph_unsorted[i].left[j] = graph_data[i*rank + j];
|
|
||||||
graph_unsorted[i].word = 0;
|
graph_unsorted[i].word = 0;
|
||||||
graph_unsorted[i].wordlength = INT_MAX;
|
graph_unsorted[i].wordlength = INT_MAX;
|
||||||
graph_unsorted[i].bruhat_lower = 0;
|
graph_unsorted[i].bruhat_lower = 0;
|
||||||
@ -147,7 +90,15 @@ int main(int argc, const char *argv[])
|
|||||||
graph_unsorted[i].is_hyperplane_reflection = 0;
|
graph_unsorted[i].is_hyperplane_reflection = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG("Find wordlengths\n");
|
// get coxeter graph
|
||||||
|
|
||||||
|
generate_coxeter_graph(type, graph_data);
|
||||||
|
|
||||||
|
for(int i = 0; i < order; i++)
|
||||||
|
for(int j = 0; j < rank; j++)
|
||||||
|
graph_unsorted[i].left[j] = graph_data[i*rank + j];
|
||||||
|
|
||||||
|
// find wordlengths
|
||||||
|
|
||||||
graph_unsorted[0].wordlength = 0;
|
graph_unsorted[0].wordlength = 0;
|
||||||
queue_init(&queue);
|
queue_init(&queue);
|
||||||
@ -167,10 +118,7 @@ int main(int argc, const char *argv[])
|
|||||||
if(graph_unsorted[i].wordlength > max_wordlength)
|
if(graph_unsorted[i].wordlength > max_wordlength)
|
||||||
max_wordlength = graph_unsorted[i].wordlength;
|
max_wordlength = graph_unsorted[i].wordlength;
|
||||||
|
|
||||||
string_buffer1 = (char*)malloc((max_wordlength+1)*sizeof(char));
|
// sort by wordlength
|
||||||
string_buffer2 = (char*)malloc((max_wordlength+1)*sizeof(char));
|
|
||||||
|
|
||||||
// DEBUG("Sort by wordlength\n");
|
|
||||||
|
|
||||||
for(int i = 0; i < order; i++)
|
for(int i = 0; i < order; i++)
|
||||||
wordlength_order[i] = i;
|
wordlength_order[i] = i;
|
||||||
@ -183,7 +131,7 @@ int main(int argc, const char *argv[])
|
|||||||
graph[i].left[j] = reverse_wordlength_order[graph[i].left[j]]; // rewrite references
|
graph[i].left[j] = reverse_wordlength_order[graph[i].left[j]]; // rewrite references
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG("Find words\n");
|
// find words
|
||||||
|
|
||||||
words = (int*)malloc(order*max_wordlength*sizeof(int));
|
words = (int*)malloc(order*max_wordlength*sizeof(int));
|
||||||
memset(words, 0, order*max_wordlength*sizeof(int));
|
memset(words, 0, order*max_wordlength*sizeof(int));
|
||||||
@ -202,7 +150,7 @@ int main(int argc, const char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG("Generate right edges\n");
|
// generate right edges
|
||||||
|
|
||||||
for(int i = 0; i < order; i++) {
|
for(int i = 0; i < order; i++) {
|
||||||
for(int j = 0; j < rank; j++) {
|
for(int j = 0; j < rank; j++) {
|
||||||
@ -214,7 +162,7 @@ int main(int argc, const char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG("Find opposites\n");
|
// find opposites
|
||||||
|
|
||||||
node_t *longest = &graph[order-1];
|
node_t *longest = &graph[order-1];
|
||||||
for(int i = 0; i < order; i++) {
|
for(int i = 0; i < order; i++) {
|
||||||
@ -224,7 +172,7 @@ int main(int argc, const char *argv[])
|
|||||||
graph[i].opposite = current;
|
graph[i].opposite = current;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG("Enumerate hyperplanes\n"); // every right edge is a reflection along a hyperplane; calculate what this reflection does to the identity
|
// enumerate hyperplanes
|
||||||
|
|
||||||
hyperplane_count = 0;
|
hyperplane_count = 0;
|
||||||
for(int i = 0; i < order; i++) {
|
for(int i = 0; i < order; i++) {
|
||||||
@ -245,10 +193,10 @@ int main(int argc, const char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG("The Weyl chambers are bounded by %d hyperplanes\n", hyperplane_count);
|
// generate folding order
|
||||||
// DEBUG("Generate folding order\n");
|
|
||||||
|
|
||||||
edgelists = (edgelist_t*)malloc(order*hyperplane_count*sizeof(edgelist_t));
|
edgelists = (edgelist_t*)malloc(order*hyperplane_count*sizeof(edgelist_t));
|
||||||
|
edgelist_count = 0;
|
||||||
for(int i = 0; i < order; i++) {
|
for(int i = 0; i < order; i++) {
|
||||||
if(graph[i].is_hyperplane_reflection) {
|
if(graph[i].is_hyperplane_reflection) {
|
||||||
for(int j = 0; j < order; j++) {
|
for(int j = 0; j < order; j++) {
|
||||||
@ -270,7 +218,7 @@ int main(int argc, const char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG("Remove redundant edges\n");
|
// remove redundant edges
|
||||||
|
|
||||||
for(int i = 0; i < order; i++) {
|
for(int i = 0; i < order; i++) {
|
||||||
memset(seen, 0, order*sizeof(int));
|
memset(seen, 0, order*sizeof(int));
|
||||||
@ -280,7 +228,7 @@ int main(int argc, const char *argv[])
|
|||||||
previous = (edgelist_t*)0;
|
previous = (edgelist_t*)0;
|
||||||
while(edge) {
|
while(edge) {
|
||||||
if(seen[edge->to] && graph[i].wordlength - graph[edge->to].wordlength == len) {
|
if(seen[edge->to] && graph[i].wordlength - graph[edge->to].wordlength == len) {
|
||||||
// printf("deleting from %d to %d\n", i, edge->to);
|
// fprintf(stderr, "deleting from %d to %d\n", i, edge->to);
|
||||||
if(previous)
|
if(previous)
|
||||||
previous->next = edge->next;
|
previous->next = edge->next;
|
||||||
else
|
else
|
||||||
@ -308,7 +256,7 @@ int main(int argc, const char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG("Reverse folding order\n");
|
// reverse folding order
|
||||||
|
|
||||||
for(int i = 0; i < order; i++) {
|
for(int i = 0; i < order; i++) {
|
||||||
edge = graph[i].bruhat_lower;
|
edge = graph[i].bruhat_lower;
|
||||||
@ -321,21 +269,35 @@ int main(int argc, const char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Rank: %d\t\tOrder: %d\t\tHyperplanes: %d\n", rank, order, hyperplane_count);
|
*edgelists_pointer = edgelists;
|
||||||
printf("\n");
|
*words_pointer = words;
|
||||||
printf("Group elements: \n");
|
|
||||||
for(int i = 0, wl = 0; i < order; i++) {
|
|
||||||
if(i == 0) {
|
|
||||||
printf("1");
|
|
||||||
} else if(graph[i].wordlength > wl) {
|
|
||||||
printf("\n%s ", alphabetize(graph[i].word, graph[i].wordlength, alphabet, string_buffer1));
|
|
||||||
wl = graph[i].wordlength;
|
|
||||||
} else
|
|
||||||
printf("%s ", alphabetize(graph[i].word, graph[i].wordlength, alphabet, string_buffer1));
|
|
||||||
}
|
|
||||||
printf("\n\n");
|
|
||||||
|
|
||||||
// DEBUG("Enumerate thickenings\n");
|
free(graph_data);
|
||||||
|
free(graph_unsorted);
|
||||||
|
free(wordlength_order);
|
||||||
|
free(reverse_wordlength_order);
|
||||||
|
free(seen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void enumerate_balanced_thickenings(semisimple_type_t type, node_t *graph, const char *alphabet, FILE *outfile)
|
||||||
|
{
|
||||||
|
int rank, order;
|
||||||
|
int *level;
|
||||||
|
int *left_invariant, *right_invariant;
|
||||||
|
long thickenings_count, fat_count, slim_count, balanced_count;
|
||||||
|
int is_fat, is_slim;
|
||||||
|
int current_level, head, current;
|
||||||
|
int i;
|
||||||
|
edgelist_t *edge;
|
||||||
|
|
||||||
|
queue_t queue;
|
||||||
|
|
||||||
|
rank = coxeter_rank(type);
|
||||||
|
order = coxeter_order(type);
|
||||||
|
|
||||||
|
level = (int*)malloc(order*sizeof(int));
|
||||||
|
left_invariant = (int*)malloc(rank*sizeof(int));
|
||||||
|
right_invariant = (int*)malloc(rank*sizeof(int));
|
||||||
|
|
||||||
thickenings_count = fat_count = slim_count = balanced_count = 0;
|
thickenings_count = fat_count = slim_count = balanced_count = 0;
|
||||||
memset(level, 0, order*sizeof(int));
|
memset(level, 0, order*sizeof(int));
|
||||||
@ -357,6 +319,8 @@ int main(int argc, const char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we have a thickening, do something with it!
|
||||||
|
|
||||||
is_fat = is_slim = 1;
|
is_fat = is_slim = 1;
|
||||||
for(int i = 0; i < order; i++) {
|
for(int i = 0; i < order; i++) {
|
||||||
if(level[graph[i].opposite] != 0) {
|
if(level[graph[i].opposite] != 0) {
|
||||||
@ -376,10 +340,12 @@ int main(int argc, const char *argv[])
|
|||||||
slim_count++;
|
slim_count++;
|
||||||
if(is_slim && is_fat) {
|
if(is_slim && is_fat) {
|
||||||
ERROR(balanced_count >= MAX_THICKENINGS, "Too many balanced thickenings! Increase MAX_THICKENINGS\n");
|
ERROR(balanced_count >= MAX_THICKENINGS, "Too many balanced thickenings! Increase MAX_THICKENINGS\n");
|
||||||
memcpy(&balanced_thickenings[balanced_count*order], level, order*sizeof(int));
|
//memcpy(&balanced_thickenings[balanced_count*order], level, order*sizeof(int));
|
||||||
|
fwrite(level, sizeof(int), order, outfile);
|
||||||
balanced_count++;
|
balanced_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// print out the thickening
|
||||||
if(is_fat && is_slim) {
|
if(is_fat && is_slim) {
|
||||||
// check for invariances
|
// check for invariances
|
||||||
for(int j = 0; j < rank; j++) {
|
for(int j = 0; j < rank; j++) {
|
||||||
@ -394,9 +360,12 @@ int main(int argc, const char *argv[])
|
|||||||
right_invariant[j] = 0;
|
right_invariant[j] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print_balanced_thickening(rank, order, level, left_invariant, right_invariant, alphabet);
|
print_balanced_thickening(rank, order, level, left_invariant, right_invariant, alphabet, stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// now find the next one!
|
||||||
|
|
||||||
// try to find empty spot to the left of "head"
|
// try to find empty spot to the left of "head"
|
||||||
for(i = head - 1; i >= 0; i--)
|
for(i = head - 1; i >= 0; i--)
|
||||||
if(level[i] == 0)
|
if(level[i] == 0)
|
||||||
@ -433,58 +402,10 @@ int main(int argc, const char *argv[])
|
|||||||
level[i] = 0;
|
level[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n");
|
fprintf(stderr, "\n");
|
||||||
printf("Found %d thickenings, %d fat, %d slim, %d balanced\n\n", thickenings_count, fat_count, slim_count, balanced_count);
|
fprintf(stderr, "Found %ld thickenings, %ld fat, %ld slim, %ld balanced\n\n", thickenings_count, fat_count, slim_count, balanced_count);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
for(int i = 0; i < balanced_count; i++) {
|
|
||||||
// figure out invariances
|
|
||||||
for(int j = 0; j < rank; j++) {
|
|
||||||
left_invariant[j] = 1;
|
|
||||||
right_invariant[j] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int *current_thickening = balanced_thickenings + i*order;
|
|
||||||
|
|
||||||
for(int k = 0; k < order; k++) {
|
|
||||||
for(int j = 0; j < rank; j++) {
|
|
||||||
if(current_thickening[k] == 0 && current_thickening[graph[k].left[j]] != 0 || current_thickening[k] != 0 && current_thickening[graph[k].left[j]] == 0)
|
|
||||||
left_invariant[j] = 0;
|
|
||||||
if(current_thickening[k] == 0 && current_thickening[graph[k].right[j]] != 0 || current_thickening[k] != 0 && current_thickening[graph[k].right[j]] == 0)
|
|
||||||
right_invariant[j] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("left: ");
|
|
||||||
for(int k = 0; k < rank; k++)
|
|
||||||
printf("%c", left_invariant[k] ? alphabet[k] : ' ');
|
|
||||||
printf(" right: ");
|
|
||||||
for(int k = 0; k < rank; k++)
|
|
||||||
printf("%c", right_invariant[k] ? alphabet[k] : ' ');
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
free(edgelists);
|
|
||||||
free(words);
|
|
||||||
free(string_buffer1);
|
|
||||||
free(string_buffer2);
|
|
||||||
free(graph);
|
|
||||||
free(graph_unsorted);
|
|
||||||
free(graph_data);
|
|
||||||
free(wordlength_order);
|
|
||||||
free(reverse_wordlength_order);
|
|
||||||
free(seen);
|
|
||||||
free(level);
|
free(level);
|
||||||
free(left);
|
|
||||||
free(right);
|
|
||||||
free(left_invariant);
|
free(left_invariant);
|
||||||
free(right_invariant);
|
free(right_invariant);
|
||||||
free(type.factors);
|
|
||||||
free(balanced_thickenings);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
32
thickenings.h
Normal file
32
thickenings.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef THICKENINGS_H
|
||||||
|
#define THICKENINGS_H
|
||||||
|
|
||||||
|
#include "coxeter.h"
|
||||||
|
|
||||||
|
#define DEBUG(msg, ...) do{fprintf(stderr, msg, ##__VA_ARGS__); }while(0)
|
||||||
|
|
||||||
|
#define MAX_THICKENINGS 1000000
|
||||||
|
|
||||||
|
typedef struct _edgelist {
|
||||||
|
int to;
|
||||||
|
struct _edgelist *next;
|
||||||
|
} edgelist_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int *word;
|
||||||
|
int wordlength;
|
||||||
|
int *left;
|
||||||
|
int *right;
|
||||||
|
int opposite;
|
||||||
|
edgelist_t *bruhat_lower;
|
||||||
|
edgelist_t *bruhat_higher;
|
||||||
|
int is_hyperplane_reflection; // boolean value
|
||||||
|
} node_t;
|
||||||
|
|
||||||
|
char *alphabetize(int *word, int len, const char *alphabet, char *buffer);
|
||||||
|
void print_balanced_thickening(int rank, int order, const int *thickening, const int *left_invariant, const int *right_invariant, const char *alphabet, FILE *f);
|
||||||
|
static int compare_wordlength(const void *a, const void *b, void *gr);
|
||||||
|
void prepare_graph(semisimple_type_t type, node_t *graph, edgelist_t **edgelists_pointer, int **words_pointer);
|
||||||
|
void enumerate_balanced_thickenings(semisimple_type_t type, node_t *graph, const char *alphabet, FILE *outfile);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user