Compare commits
6 Commits
4342a1f3e5
...
old_experi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93207ff694 | ||
|
|
69564f5750 | ||
|
|
6c938f751d | ||
|
|
7fcb9f1056 | ||
|
|
69d975bac9 | ||
|
|
d3336bab00 |
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
*.o
|
||||
*.pdf
|
||||
enumerate
|
||||
idealbounds
|
||||
graph
|
||||
D2n
|
||||
dominant_weights
|
||||
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;
|
||||
}
|
||||
16
Makefile
16
Makefile
@@ -4,7 +4,7 @@ HEADERS=weyl.h thickenings.h queue.h bitvec.h
|
||||
#SPECIAL_OPTIONS=-O3 -pg -funroll-loops -fno-inline
|
||||
SPECIAL_OPTIONS=-O3 -flto -funroll-loops -Winline
|
||||
|
||||
OPTIONS=-m64 -march=native -mtune=native -std=gnu99 -D_GNU_SOURCE $(SPECIAL_OPTIONS)
|
||||
OPTIONS=-m64 -march=native -std=gnu99 -D_GNU_SOURCE $(SPECIAL_OPTIONS)
|
||||
NAME=enumerate-balanced-ideals
|
||||
|
||||
all: enumerate graph
|
||||
@@ -21,17 +21,29 @@ enumerate: enumerate.o weyl.o thickenings.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
|
||||
|
||||
dominant_weights: dominant_weights.o weyl.o thickenings.o
|
||||
gcc $(OPTIONS) -o dominant_weights dominant_weights.o weyl.o thickenings.o -lcdd
|
||||
|
||||
enumerate.o: enumerate.c $(HEADERS)
|
||||
gcc $(OPTIONS) -c enumerate.c
|
||||
|
||||
thickenings.o: thickenings.c $(HEADERS)
|
||||
gcc $(OPTIONS) -c thickenings.c
|
||||
|
||||
D2n.o: D2n.c $(HEADERS)
|
||||
gcc $(OPTIONS) -c D2n.c
|
||||
|
||||
weyl.o: weyl.c $(HEADERS)
|
||||
gcc $(OPTIONS) -c weyl.c
|
||||
|
||||
graph.o: graph.c $(HEADERS)
|
||||
gcc $(OPTIONS) -c graph.c
|
||||
|
||||
dominant_weights.o: dominant_weights.c $(HEADERS)
|
||||
gcc $(OPTIONS) -c dominant_weights.c
|
||||
|
||||
clean:
|
||||
rm -f enumerate graph thickenings.o weyl.o enumerate.o graph.o $(NAME) $(NAME).tar.bz2
|
||||
rm -f enumerate graph D2n dominant_weights thickenings.o weyl.o enumerate.o graph.o D2n.o dominant_weights.o $(NAME) $(NAME).tar.bz2
|
||||
|
||||
180
dominant_weights.c
Normal file
180
dominant_weights.c
Normal file
@@ -0,0 +1,180 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <setoper.h>
|
||||
#include <cdd.h>
|
||||
|
||||
#include "weyl.h"
|
||||
#include "thickenings.h"
|
||||
|
||||
doublequotient_t *dq;
|
||||
double *vector;
|
||||
char buf[1000], buf2[1000];
|
||||
|
||||
typedef struct {
|
||||
dd_MatrixPtr M;
|
||||
dd_LPSolutionPtr lps;
|
||||
} info_t;
|
||||
|
||||
static char* alphabetize(weylgroup_element_t *e, char *str)
|
||||
{
|
||||
if(e->wordlength == 0)
|
||||
sprintf(str, "1");
|
||||
else {
|
||||
for(int j = 0; j < e->wordlength; j++)
|
||||
str[j] = e->word[j] + 'a';
|
||||
str[e->wordlength] = 0;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
static char* print_vector(double *v, int rank, char *buf)
|
||||
{
|
||||
int written = 0;
|
||||
|
||||
for(int i = 0; i < rank; i++) {
|
||||
written += sprintf(buf+written, "%.4f", v[i]);
|
||||
if(i != rank -1) {
|
||||
sprintf(buf+written, ", ");
|
||||
written += 2;
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static char* print_vector_ptr(dd_Arow v, int rank, char *buf)
|
||||
{
|
||||
int written = 0;
|
||||
|
||||
for(int i = 0; i < rank; i++) {
|
||||
written += sprintf(buf+written, "%.4f", v[i][0]);
|
||||
if(i != rank -1) {
|
||||
sprintf(buf+written, ", ");
|
||||
written += 2;
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void balanced_thickening_callback(const bitvec_t *pos, int size, const enumeration_info_t *ei)
|
||||
{
|
||||
int bit, funcbit, sign;
|
||||
dd_rowset ImL, Lbasis;
|
||||
dd_ErrorType err = dd_NoError;
|
||||
info_t *info = (info_t*)ei->callback_data;
|
||||
int rank = weyl_rank(dq->type);
|
||||
|
||||
for(int i = 0; i < size; i++) {
|
||||
bit = i < size/2 ? bv_get_bit(pos, i) : !bv_get_bit(pos, size - 1 - i);
|
||||
sign = bit ? 1 : -1;
|
||||
info->M->matrix[i][0][0] = 0.0;
|
||||
for(int j = 0; j < rank; j++)
|
||||
info->M->matrix[i][j+1][0] = sign*vector[rank*i+j];
|
||||
// printf("0 %.2f %.2f %.2f %d %d\n", sign*vector[3*i], sign*vector[3*i+1], sign*vector[3*i+2], bit, funcbit);
|
||||
}
|
||||
|
||||
for(int i = 0; i < rank; i++) {
|
||||
info->M->matrix[i+size][0][0] = 0.0;
|
||||
for(int j = 0; j < rank; j++) {
|
||||
if(i == j)
|
||||
info->M->matrix[i+size][j+1][0] = 1.0;
|
||||
else
|
||||
info->M->matrix[i+size][j+1][0] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// dd_WriteMatrix(stdout, info->M);
|
||||
|
||||
dd_FindRelativeInterior(info->M, &ImL, &Lbasis, &(info->lps), &err);
|
||||
|
||||
if(set_card(Lbasis) != 0)
|
||||
printf("codim = %ld\n", set_card(Lbasis));
|
||||
else
|
||||
printf("weight = (%s)\n", print_vector_ptr(info->lps->sol, rank + 1, buf));
|
||||
|
||||
dd_FreeLPSolution(info->lps);
|
||||
|
||||
// printf("\n");
|
||||
}
|
||||
|
||||
static int apply_reflection(double *in, double *out, int rank, int reflection)
|
||||
{
|
||||
memcpy(out, in, rank*sizeof(double));
|
||||
/*
|
||||
out[reflection] *= -1;
|
||||
if(reflection != 0)
|
||||
out[reflection-1] += in[reflection];
|
||||
if(reflection != rank-1)
|
||||
out[reflection+1] += in[reflection];
|
||||
*/
|
||||
out[reflection] *= -1;
|
||||
if(reflection != 0)
|
||||
out[reflection] += in[reflection-1];
|
||||
if(reflection != rank-1)
|
||||
out[reflection] += in[reflection+1];
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
semisimple_type_t type;
|
||||
simple_type_t simple;
|
||||
info_t info;
|
||||
|
||||
type.n = 1;
|
||||
type.factors = &simple;
|
||||
simple.series = 'A';
|
||||
simple.rank = 3;
|
||||
|
||||
dq = weyl_generate_bruhat(type, 0, 0);
|
||||
|
||||
int order = weyl_order(type);
|
||||
int rank = weyl_rank(type);
|
||||
weylgroup_element_t *group = dq->group;
|
||||
vector = malloc(weyl_order(type)*weyl_rank(type)*sizeof(double));
|
||||
|
||||
for(int i = 0; i < rank; i++)
|
||||
vector[i] = 0.0;
|
||||
|
||||
for(int i = 0; 2*i < rank; i++) {
|
||||
for(int j = i; j < rank - i; j++) {
|
||||
vector[j] += rank - 2*i;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
vector[0] = 4.1;
|
||||
vector[1] = 6.1;
|
||||
vector[2] = 5.9;
|
||||
vector[3] = 3.9;
|
||||
*/
|
||||
|
||||
printf("regular element: (%s)\n", print_vector(vector, rank, buf));
|
||||
|
||||
for(int i = 0; i < order; i++) {
|
||||
printf("%s (%s)\n", alphabetize(&group[i], buf), print_vector(vector + rank*i, rank, buf2));
|
||||
|
||||
for(int j = 0; j < rank; j++)
|
||||
if(group[i].left[j]->wordlength > group[i].wordlength)
|
||||
apply_reflection(&vector[rank*i], &vector[rank*group[i].left[j]->index], rank, j);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
dd_set_global_constants();
|
||||
info.M = dd_CreateMatrix(order+rank, rank+1);
|
||||
info.M->representation = dd_Inequality;
|
||||
info.M->numbtype = dd_Real;
|
||||
info.M->objective = dd_LPmax;
|
||||
|
||||
enumerate_balanced_thickenings(dq, balanced_thickening_callback, &info);
|
||||
|
||||
dd_FreeMatrix(info.M);
|
||||
weyl_destroy_bruhat(dq);
|
||||
free(vector);
|
||||
|
||||
return 0;
|
||||
}
|
||||
564
enumerate.c
564
enumerate.c
@@ -9,353 +9,367 @@ char stringbuffer[100];
|
||||
char stringbuffer2[100];
|
||||
|
||||
typedef struct {
|
||||
doublequotient_t *dq;
|
||||
int rank;
|
||||
int order;
|
||||
int positive;
|
||||
int *buffer;
|
||||
int level;
|
||||
doublequotient_t *dq;
|
||||
int rank;
|
||||
int order;
|
||||
int positive;
|
||||
int *buffer;
|
||||
int level;
|
||||
} info_t;
|
||||
|
||||
static char* alphabetize(weylgroup_element_t *e, char *str)
|
||||
{
|
||||
if(e->wordlength == 0)
|
||||
sprintf(str, "1");
|
||||
else {
|
||||
for(int j = 0; j < e->wordlength; j++)
|
||||
str[j] = e->word[j] + 'a';
|
||||
str[e->wordlength] = 0;
|
||||
}
|
||||
if(e->wordlength == 0)
|
||||
sprintf(str, "1");
|
||||
else {
|
||||
for(int j = 0; j < e->wordlength; j++)
|
||||
str[j] = e->word[j] + 'a';
|
||||
str[e->wordlength] = 0;
|
||||
}
|
||||
|
||||
return str;
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
int shorten(int i, unsigned long left, unsigned long right, doublequotient_t *dq, int rank)
|
||||
{
|
||||
int shorten(int i, unsigned long left, unsigned long right, doublequotient_t *dq, int rank)
|
||||
{
|
||||
int other, shorter = i;
|
||||
do {
|
||||
i = shorter;
|
||||
for(int j = 0; j < rank; j++) {
|
||||
other = graph[shorter].left[j];
|
||||
if(left & (1 << j) &&
|
||||
graph[other].wordlength < graph[shorter].wordlength)
|
||||
shorter = other;
|
||||
other = graph[shorter].right[j];
|
||||
if(right & (1 << j) &&
|
||||
graph[other].wordlength < graph[shorter].wordlength)
|
||||
shorter = other;
|
||||
}
|
||||
i = shorter;
|
||||
for(int j = 0; j < rank; j++) {
|
||||
other = graph[shorter].left[j];
|
||||
if(left & (1 << j) &&
|
||||
graph[other].wordlength < graph[shorter].wordlength)
|
||||
shorter = other;
|
||||
other = graph[shorter].right[j];
|
||||
if(right & (1 << j) &&
|
||||
graph[other].wordlength < graph[shorter].wordlength)
|
||||
shorter = other;
|
||||
}
|
||||
} while(shorter != i);
|
||||
|
||||
return shorter;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void balanced_thickening_callback(const bitvec_t *pos, int size, const enumeration_info_t *ei)
|
||||
{
|
||||
static long totcount = 0;
|
||||
static long totcount = 0;
|
||||
|
||||
if(ei->callback_data) {
|
||||
info_t *info = (info_t*)ei->callback_data;
|
||||
if(ei->callback_data) {
|
||||
info_t *info = (info_t*)ei->callback_data;
|
||||
|
||||
unsigned long right_invariance = FIRSTBITS(info->rank);
|
||||
unsigned long left_invariance = FIRSTBITS(info->rank);
|
||||
unsigned long right_invariance = FIRSTBITS(info->rank);
|
||||
unsigned long left_invariance = FIRSTBITS(info->rank);
|
||||
|
||||
int bit1, bit2left, bit2right, left, right;
|
||||
int bit1, bit2left, bit2right, left, right;
|
||||
|
||||
for(int i = 0; i < size; i++) {
|
||||
bit1 = i < size/2 ? bv_get_bit(pos, i) : !bv_get_bit(pos, size - 1 - i);
|
||||
for(int j = 0; j < info->rank; j++) {
|
||||
left = info->dq->cosets[i].min->left[j]->coset->index;
|
||||
right = info->dq->cosets[i].min->right[j]->coset->index;
|
||||
bit2left = left < size/2 ? bv_get_bit(pos, left) : !bv_get_bit(pos, size - 1 - left);
|
||||
bit2right = right < size/2 ? bv_get_bit(pos, right) : !bv_get_bit(pos, size - 1 - right);
|
||||
if(bit1 != bit2left)
|
||||
left_invariance &= ~BIT(j);
|
||||
if(bit1 != bit2right)
|
||||
right_invariance &= ~BIT(j);
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < size; i++) {
|
||||
bit1 = i < size/2 ? bv_get_bit(pos, i) : !bv_get_bit(pos, size - 1 - i);
|
||||
for(int j = 0; j < info->rank; j++) {
|
||||
left = info->dq->cosets[i].min->left[j]->coset->index;
|
||||
right = info->dq->cosets[i].min->right[j]->coset->index;
|
||||
bit2left = left < size/2 ? bv_get_bit(pos, left) : !bv_get_bit(pos, size - 1 - left);
|
||||
bit2right = right < size/2 ? bv_get_bit(pos, right) : !bv_get_bit(pos, size - 1 - right);
|
||||
if(bit1 != bit2left)
|
||||
left_invariance &= ~BIT(j);
|
||||
if(bit1 != bit2right)
|
||||
right_invariance &= ~BIT(j);
|
||||
}
|
||||
}
|
||||
|
||||
printf("%4d left: ", totcount++);
|
||||
for(int j = 0; j < info->rank; j++)
|
||||
printf("%c", left_invariance & (1 << j) ? j + 'a' : ' ');
|
||||
printf(" right: ");
|
||||
for(int j = 0; j < info->rank; j++)
|
||||
printf("%c", right_invariance & (1 << j) ? j + 'a' : ' ');
|
||||
printf("%4d left: ", totcount++);
|
||||
for(int j = 0; j < info->rank; j++)
|
||||
printf("%c", left_invariance & (1 << j) ? j + 'a' : ' ');
|
||||
printf(" right: ");
|
||||
for(int j = 0; j < info->rank; j++)
|
||||
printf("%c", right_invariance & (1 << j) ? j + 'a' : ' ');
|
||||
|
||||
if(info->buffer) {
|
||||
bitvec_t low, high;
|
||||
bv_copy(pos, &low);
|
||||
bv_negate(pos, &high);
|
||||
int length_profile[65]; // can't handle more that 64 positive roots anyway
|
||||
|
||||
// printf(" set: ");
|
||||
// bv_print(stdout, &low, size/2);
|
||||
// printf(" ");
|
||||
// bv_print(stdout, &high, size/2);
|
||||
memset(length_profile, 0, (info->positive+1)*sizeof(int));
|
||||
|
||||
printf(" gen: ");
|
||||
for(int i = 0; i < size; i++) {
|
||||
bit1 = i < size/2 ? bv_get_bit(pos, i) : !bv_get_bit(pos, size - 1 - i);
|
||||
if(bit1)
|
||||
length_profile[info->dq->cosets[i].min->wordlength]++;
|
||||
}
|
||||
|
||||
printf(" length profile:");
|
||||
for(int i = 0; i <= info->positive; i++)
|
||||
printf(" %d", length_profile[i]);
|
||||
|
||||
if(info->buffer) {
|
||||
bitvec_t low, high;
|
||||
bv_copy(pos, &low);
|
||||
bv_negate(pos, &high);
|
||||
|
||||
// printf(" set: ");
|
||||
// bv_print(stdout, &low, size/2);
|
||||
// printf(" ");
|
||||
// bv_print(stdout, &high, size/2);
|
||||
|
||||
printf(" gen: ");
|
||||
|
||||
|
||||
for(int i = 0; i < size/2; i++) {
|
||||
if(!bv_get_bit(&high, i))
|
||||
continue;
|
||||
for(int i = 0; i < size/2; i++) {
|
||||
if(!bv_get_bit(&high, i))
|
||||
continue;
|
||||
|
||||
printf("%s ", alphabetize(info->dq->cosets[size-1-i].min, stringbuffer));
|
||||
printf("%s ", alphabetize(info->dq->cosets[size-1-i].min, stringbuffer));
|
||||
|
||||
bv_difference(&high, &ei->principal_neg[size-1-i], &high);
|
||||
bv_difference(&low, &ei->principal_pos[size-1-i], &low);
|
||||
}
|
||||
bv_difference(&high, &ei->principal_neg[size-1-i], &high);
|
||||
bv_difference(&low, &ei->principal_pos[size-1-i], &low);
|
||||
}
|
||||
|
||||
for(int i = size/2 - 1; i >= 0; i--) {
|
||||
if(!bv_get_bit(&low, i))
|
||||
continue;
|
||||
for(int i = size/2 - 1; i >= 0; i--) {
|
||||
if(!bv_get_bit(&low, i))
|
||||
continue;
|
||||
|
||||
printf("%s ", alphabetize(info->dq->cosets[i].min, stringbuffer));
|
||||
printf("%s ", alphabetize(info->dq->cosets[i].min, stringbuffer));
|
||||
|
||||
bv_difference(&low, &ei->principal_pos[i], &low);
|
||||
}
|
||||
}
|
||||
bv_difference(&low, &ei->principal_pos[i], &low);
|
||||
}
|
||||
}
|
||||
|
||||
int max_length = 0;
|
||||
for(int i = 0; i < size/2; i++) {
|
||||
if(bv_get_bit(pos, i)) {
|
||||
if(info->dq->cosets[i].max->wordlength > max_length)
|
||||
max_length = info->dq->cosets[i].max->wordlength;
|
||||
} else {
|
||||
if(info->dq->cosets[size-i-1].max->wordlength > max_length)
|
||||
max_length = info->dq->cosets[size-i-1].max->wordlength;
|
||||
}
|
||||
}
|
||||
// printf(" max length: %d", max_length);
|
||||
int max_length = 0;
|
||||
for(int i = 0; i < size/2; i++) {
|
||||
if(bv_get_bit(pos, i)) {
|
||||
if(info->dq->cosets[i].max->wordlength > max_length)
|
||||
max_length = info->dq->cosets[i].max->wordlength;
|
||||
} else {
|
||||
if(info->dq->cosets[size-i-1].max->wordlength > max_length)
|
||||
max_length = info->dq->cosets[size-i-1].max->wordlength;
|
||||
}
|
||||
}
|
||||
// printf(" max length: %d", max_length);
|
||||
|
||||
/*
|
||||
if(info->buffer) {
|
||||
printf(" generators:");
|
||||
queue_t queue;
|
||||
int cur, left, right;
|
||||
int *buffer = info->buffer;
|
||||
/*
|
||||
if(info->buffer) {
|
||||
printf(" generators:");
|
||||
queue_t queue;
|
||||
int cur, left, right;
|
||||
int *buffer = info->buffer;
|
||||
|
||||
for(int i = 0; i < size/2; i++) {
|
||||
buffer[i] = bv_get_bit(pos, i);
|
||||
buffer[size-1-i] = !buffer[i];
|
||||
}
|
||||
for(int i = size-1; i >= 0; i--) {
|
||||
if(buffer[i]) {
|
||||
weylgroup_element_t *shortest = shorten(i, left_invariance, right_invariance, info->dq);
|
||||
printf(" %s", alphabetize(shortest, stringbuffer));
|
||||
buffer[i] = 0;
|
||||
queue_init(&queue);
|
||||
queue_put(&queue, i);
|
||||
while((cur = queue_get(&queue)) != -1) {
|
||||
for(doublecoset_list_t *current = info->dq->coset[cur].bruhat_lower; current; current = current->next) {
|
||||
int idx = current->to - info->dq->cosets;
|
||||
if(buffer[idx]) {
|
||||
buffer[idx] = 0;
|
||||
queue_put(&queue, idx);
|
||||
}
|
||||
}
|
||||
for(int j = 0; j < info->rank; j++) {
|
||||
left = info->dq->coset[cur].min.left[j] - info->dq->cosets;
|
||||
if(left_invariance & (1 << j) &&
|
||||
info->graph[left].wordlength < info->graph[cur].wordlength &&
|
||||
buffer[left]) {
|
||||
buffer[left] = 0;
|
||||
queue_put(&queue, left);
|
||||
}
|
||||
right = info->graph[cur].left[j];
|
||||
if(right_invariance & (1 << j) &&
|
||||
info->graph[right].wordlength < info->graph[cur].wordlength &&
|
||||
buffer[right]) {
|
||||
buffer[right] = 0;
|
||||
queue_put(&queue, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < size/2; i++) {
|
||||
buffer[i] = bv_get_bit(pos, i);
|
||||
buffer[size-1-i] = !buffer[i];
|
||||
}
|
||||
for(int i = size-1; i >= 0; i--) {
|
||||
if(buffer[i]) {
|
||||
weylgroup_element_t *shortest = shorten(i, left_invariance, right_invariance, info->dq);
|
||||
printf(" %s", alphabetize(shortest, stringbuffer));
|
||||
buffer[i] = 0;
|
||||
queue_init(&queue);
|
||||
queue_put(&queue, i);
|
||||
while((cur = queue_get(&queue)) != -1) {
|
||||
for(doublecoset_list_t *current = info->dq->coset[cur].bruhat_lower; current; current = current->next) {
|
||||
int idx = current->to - info->dq->cosets;
|
||||
if(buffer[idx]) {
|
||||
buffer[idx] = 0;
|
||||
queue_put(&queue, idx);
|
||||
}
|
||||
}
|
||||
for(int j = 0; j < info->rank; j++) {
|
||||
left = info->dq->coset[cur].min.left[j] - info->dq->cosets;
|
||||
if(left_invariance & (1 << j) &&
|
||||
info->graph[left].wordlength < info->graph[cur].wordlength &&
|
||||
buffer[left]) {
|
||||
buffer[left] = 0;
|
||||
queue_put(&queue, left);
|
||||
}
|
||||
right = info->graph[cur].left[j];
|
||||
if(right_invariance & (1 << j) &&
|
||||
info->graph[right].wordlength < info->graph[cur].wordlength &&
|
||||
buffer[right]) {
|
||||
buffer[right] = 0;
|
||||
queue_put(&queue, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(info->level >= 5) {
|
||||
printf(" ids: [0");
|
||||
for(int i = 1; i < size/2; i++)
|
||||
if(bv_get_bit(pos, i))
|
||||
printf(", %d", info->graph[i].id);
|
||||
for(int i = 0; i < size/2; i++)
|
||||
if(!bv_get_bit(pos, i))
|
||||
printf(", %d", info->graph[size-1-i].id);
|
||||
printf("]");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
if(info->level >= 5) {
|
||||
printf(" ids: [0");
|
||||
for(int i = 1; i < size/2; i++)
|
||||
if(bv_get_bit(pos, i))
|
||||
printf(", %d", info->graph[i].id);
|
||||
for(int i = 0; i < size/2; i++)
|
||||
if(!bv_get_bit(pos, i))
|
||||
printf(", %d", info->graph[size-1-i].id);
|
||||
printf("]");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void balanced_thickening_simple_callback(const bitvec_t *pos, int size, const enumeration_info_t *ei)
|
||||
{
|
||||
long *count = (long*)ei->callback_data;
|
||||
long *count = (long*)ei->callback_data;
|
||||
|
||||
if((++(*count)) % 100000000 == 0) {
|
||||
bv_print(stderr, pos, size/2);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
if((++(*count)) % 100000000 == 0) {
|
||||
bv_print(stderr, pos, size/2);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
semisimple_type_t type;
|
||||
unsigned long right_invariance, left_invariance;
|
||||
int rank, order, positive;
|
||||
int fixpoints;
|
||||
semisimple_type_t type;
|
||||
unsigned long right_invariance, left_invariance;
|
||||
int rank, order, positive;
|
||||
int fixpoints;
|
||||
|
||||
doublequotient_t *dq;
|
||||
doublequotient_t *dq;
|
||||
|
||||
const char *alphabet = "abcdefghijklmnopqrstuvwxyz";
|
||||
const char *alphabet = "abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
// read arguments
|
||||
// read arguments
|
||||
|
||||
ERROR(argc < 2, "Too few arguments!\n");
|
||||
ERROR(argc < 2, "Too few arguments!\n");
|
||||
|
||||
type.n = 0;
|
||||
for(int i = 0; i < argc - 1; i++) {
|
||||
if(argv[i+1][0] < 'A' || argv[i+1][0] > 'G')
|
||||
break;
|
||||
type.n++;
|
||||
}
|
||||
type.n = 0;
|
||||
for(int i = 0; i < argc - 1; i++) {
|
||||
if(argv[i+1][0] < 'A' || argv[i+1][0] > 'G')
|
||||
break;
|
||||
type.n++;
|
||||
}
|
||||
|
||||
type.factors = (simple_type_t*)malloc(type.n*sizeof(simple_type_t));
|
||||
for(int i = 0; i < type.n; 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] > 'G' || argv[i+1][1] < '1' || argv[i+1][1] > '9', "Arguments must be Xn with X out of A-G and n out of 1-9\n");
|
||||
}
|
||||
type.factors = (simple_type_t*)malloc(type.n*sizeof(simple_type_t));
|
||||
for(int i = 0; i < type.n; 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] > 'G' || argv[i+1][1] < '1' || argv[i+1][1] > '9', "Arguments must be Xn with X out of A-G and n out of 1-9\n");
|
||||
}
|
||||
|
||||
left_invariance = right_invariance = 0;
|
||||
left_invariance = right_invariance = 0;
|
||||
|
||||
if(argc - type.n >= 3) {
|
||||
if(strcmp(argv[type.n + 1], "-") != 0)
|
||||
for(int i = 0; i < strlen(argv[type.n + 1]); i++)
|
||||
left_invariance |= (1 << (argv[type.n + 1][i] - 'a'));
|
||||
if(strcmp(argv[type.n + 2], "-") != 0)
|
||||
for(int i = 0; i < strlen(argv[type.n + 2]); i++)
|
||||
right_invariance |= (1 << (argv[type.n + 2][i] - 'a'));
|
||||
}
|
||||
if(argc - type.n >= 3) {
|
||||
if(strcmp(argv[type.n + 1], "-") != 0)
|
||||
for(int i = 0; i < strlen(argv[type.n + 1]); i++)
|
||||
left_invariance |= (1 << (argv[type.n + 1][i] - 'a'));
|
||||
if(strcmp(argv[type.n + 2], "-") != 0)
|
||||
for(int i = 0; i < strlen(argv[type.n + 2]); i++)
|
||||
right_invariance |= (1 << (argv[type.n + 2][i] - 'a'));
|
||||
}
|
||||
|
||||
// generate graph
|
||||
// generate graph
|
||||
|
||||
dq = weyl_generate_bruhat(type, left_invariance, right_invariance);
|
||||
dq = weyl_generate_bruhat(type, left_invariance, right_invariance);
|
||||
|
||||
// print stuff
|
||||
// print stuff
|
||||
|
||||
int output_level = 2;
|
||||
if(getenv("OUTPUT_LEVEL"))
|
||||
output_level = atoi(getenv("OUTPUT_LEVEL"));
|
||||
int output_level = 2;
|
||||
if(getenv("OUTPUT_LEVEL"))
|
||||
output_level = atoi(getenv("OUTPUT_LEVEL"));
|
||||
|
||||
rank = weyl_rank(type); // number of simple roots
|
||||
order = weyl_order(type); // number of Weyl group elements
|
||||
positive = weyl_positive(type); // number of positive roots
|
||||
rank = weyl_rank(type); // number of simple roots
|
||||
order = weyl_order(type); // number of Weyl group elements
|
||||
positive = weyl_positive(type); // number of positive roots
|
||||
|
||||
if(output_level >= 1) {
|
||||
if(left_invariance) {
|
||||
printf("<");
|
||||
for(int j = 0; j < rank; j++)
|
||||
if(left_invariance & BIT(j))
|
||||
fputc(alphabet[j], stdout);
|
||||
printf("> \\ ");
|
||||
}
|
||||
if(output_level >= 1) {
|
||||
if(left_invariance) {
|
||||
printf("<");
|
||||
for(int j = 0; j < rank; j++)
|
||||
if(left_invariance & BIT(j))
|
||||
fputc(alphabet[j], stdout);
|
||||
printf("> \\ ");
|
||||
}
|
||||
|
||||
for(int i = 0; i < type.n; i++)
|
||||
printf("%s%c%d", i == 0 ? "" : " x ", type.factors[i].series, type.factors[i].rank);
|
||||
for(int i = 0; i < type.n; i++)
|
||||
printf("%s%c%d", i == 0 ? "" : " x ", type.factors[i].series, type.factors[i].rank);
|
||||
|
||||
if(right_invariance) {
|
||||
printf(" / <");
|
||||
for(int j = 0; j < rank; j++)
|
||||
if(right_invariance & BIT(j))
|
||||
fputc(alphabet[j], stdout);
|
||||
printf(">");
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
if(right_invariance) {
|
||||
printf(" / <");
|
||||
for(int j = 0; j < rank; j++)
|
||||
if(right_invariance & BIT(j))
|
||||
fputc(alphabet[j], stdout);
|
||||
printf(">");
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
fprintf(stdout, "Rank: %d\tOrder: %d\tPositive Roots: %d\tCosets: %d\n\n", rank, order, positive, dq->count);
|
||||
}
|
||||
fprintf(stdout, "Rank: %d\tOrder: %d\tPositive Roots: %d\tCosets: %d\n\n", rank, order, positive, dq->count);
|
||||
}
|
||||
|
||||
if(output_level >= 3) {
|
||||
fprintf(stdout, "Shortest coset representatives: \n");
|
||||
for(int i = 0, wl = 0; i < dq->count; i++) {
|
||||
if(dq->cosets[i].min->wordlength > wl) {
|
||||
printf("\n");
|
||||
wl = dq->cosets[i].min->wordlength;
|
||||
}
|
||||
// fprintf(stdout, "%s(%d) ", alphabetize(dq->cosets[i].min, stringbuffer), dq->cosets[i].max->wordlength);
|
||||
fprintf(stdout, "%s ", alphabetize(dq->cosets[i].min, stringbuffer));
|
||||
}
|
||||
fprintf(stdout, "\n\n");
|
||||
}
|
||||
if(output_level >= 3) {
|
||||
fprintf(stdout, "Shortest coset representatives: \n");
|
||||
for(int i = 0, wl = 0; i < dq->count; i++) {
|
||||
if(dq->cosets[i].min->wordlength > wl) {
|
||||
printf("\n");
|
||||
wl = dq->cosets[i].min->wordlength;
|
||||
}
|
||||
// fprintf(stdout, "%s(%d) ", alphabetize(dq->cosets[i].min, stringbuffer), dq->cosets[i].max->wordlength);
|
||||
fprintf(stdout, "%s ", alphabetize(dq->cosets[i].min, stringbuffer));
|
||||
}
|
||||
fprintf(stdout, "\n\n");
|
||||
}
|
||||
|
||||
if(output_level >= 4) {
|
||||
fprintf(stdout, "Bruhat order in graphviz format:\n");
|
||||
fprintf(stdout, "digraph test123 {\n");
|
||||
for(int i = 0; i < dq->count; i++)
|
||||
for(doublecoset_list_t *current = dq->cosets[i].bruhat_lower; current; current = current->next)
|
||||
fprintf(stdout, "%s -> %s;\n",
|
||||
alphabetize(dq->cosets[i].min, stringbuffer),
|
||||
alphabetize(current->to->min, stringbuffer2));
|
||||
fprintf(stdout, "}\n\n");
|
||||
}
|
||||
if(output_level >= 4) {
|
||||
fprintf(stdout, "Bruhat order in graphviz format:\n");
|
||||
fprintf(stdout, "digraph test123 {\n");
|
||||
for(int i = 0; i < dq->count; i++)
|
||||
for(doublecoset_list_t *current = dq->cosets[i].bruhat_lower; current; current = current->next)
|
||||
fprintf(stdout, "%s -> %s;\n",
|
||||
alphabetize(dq->cosets[i].min, stringbuffer),
|
||||
alphabetize(current->to->min, stringbuffer2));
|
||||
fprintf(stdout, "}\n\n");
|
||||
}
|
||||
|
||||
if(output_level >= 4) {
|
||||
fprintf(stdout, "Opposites:\n");
|
||||
for(int i = 0; i < dq->count; i++)
|
||||
fprintf(stdout, "%s <-> %s\n",
|
||||
alphabetize(dq->cosets[i].min, stringbuffer),
|
||||
alphabetize(dq->cosets[i].opposite->min, stringbuffer2));
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
if(output_level >= 4) {
|
||||
fprintf(stdout, "Opposites:\n");
|
||||
for(int i = 0; i < dq->count; i++)
|
||||
fprintf(stdout, "%s <-> %s\n",
|
||||
alphabetize(dq->cosets[i].min, stringbuffer),
|
||||
alphabetize(dq->cosets[i].opposite->min, stringbuffer2));
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
|
||||
fixpoints = 0;
|
||||
for(int i = 0; i < dq->count; i++)
|
||||
if(dq->cosets[i].opposite == &dq->cosets[i]) {
|
||||
if(output_level >= 1) {
|
||||
if(fixpoints == 0)
|
||||
fprintf(stdout, "No balanced ideals since the longest element fixes the following cosets:");
|
||||
fprintf(stdout, " %s", alphabetize(dq->cosets[i].min, stringbuffer));
|
||||
}
|
||||
fixpoints++;
|
||||
}
|
||||
if(output_level >= 1 && fixpoints)
|
||||
fprintf(stdout, "\n\n");
|
||||
fixpoints = 0;
|
||||
for(int i = 0; i < dq->count; i++)
|
||||
if(dq->cosets[i].opposite == &dq->cosets[i]) {
|
||||
if(output_level >= 1) {
|
||||
if(fixpoints == 0)
|
||||
fprintf(stdout, "No balanced ideals since the longest element fixes the following cosets:");
|
||||
fprintf(stdout, " %s", alphabetize(dq->cosets[i].min, stringbuffer));
|
||||
}
|
||||
fixpoints++;
|
||||
}
|
||||
if(output_level >= 1 && fixpoints)
|
||||
fprintf(stdout, "\n\n");
|
||||
|
||||
|
||||
if(!fixpoints) {
|
||||
int *buffer = (int*)malloc(dq->count*sizeof(int));
|
||||
if(!fixpoints) {
|
||||
int *buffer = (int*)malloc(dq->count*sizeof(int));
|
||||
|
||||
info_t info;
|
||||
info.dq = dq;
|
||||
info.rank = weyl_rank(type);
|
||||
info.order = weyl_order(type);
|
||||
info.positive = weyl_positive(type);
|
||||
info.buffer = buffer;
|
||||
info.level = output_level;
|
||||
info_t info;
|
||||
info.dq = dq;
|
||||
info.rank = weyl_rank(type);
|
||||
info.order = weyl_order(type);
|
||||
info.positive = weyl_positive(type);
|
||||
info.buffer = buffer;
|
||||
info.level = output_level;
|
||||
|
||||
ERROR(dq->count > 2*BV_BLOCKSIZE*BV_RANK, "We can handle at most %d cosets. Increase BV_RANK if more is needed.\n", 2*BV_BLOCKSIZE*BV_RANK);
|
||||
ERROR(dq->count > 2*BV_BLOCKSIZE*BV_RANK, "We can handle at most %d cosets. Increase BV_RANK if more is needed.\n", 2*BV_BLOCKSIZE*BV_RANK);
|
||||
|
||||
long count;
|
||||
if(output_level >= 2) {
|
||||
fprintf(stdout, "Balanced ideals:\n");
|
||||
count = enumerate_balanced_thickenings(dq, balanced_thickening_callback, &info);
|
||||
fprintf(stdout, "\n");
|
||||
} else {
|
||||
long outputcount = 0;
|
||||
count = enumerate_balanced_thickenings(dq, balanced_thickening_simple_callback, &outputcount);
|
||||
}
|
||||
long count;
|
||||
if(output_level >= 2) {
|
||||
fprintf(stdout, "Balanced ideals:\n");
|
||||
count = enumerate_balanced_thickenings(dq, balanced_thickening_callback, &info);
|
||||
fprintf(stdout, "\n");
|
||||
} else {
|
||||
long outputcount = 0;
|
||||
count = enumerate_balanced_thickenings(dq, balanced_thickening_simple_callback, &outputcount);
|
||||
}
|
||||
|
||||
if(output_level >= 1)
|
||||
fprintf(stdout, "Found %ld balanced ideal%s\n", count, count == 1 ? "" : "s");
|
||||
}
|
||||
if(output_level >= 1)
|
||||
fprintf(stdout, "Found %ld balanced ideal%s\n", count, count == 1 ? "" : "s");
|
||||
}
|
||||
|
||||
weyl_destroy_bruhat(dq);
|
||||
free(type.factors);
|
||||
weyl_destroy_bruhat(dq);
|
||||
free(type.factors);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -110,12 +110,12 @@ static void generate_principal_ideals(doublequotient_t *dq, bitvec_t *pos, bitve
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if(is_slim[i]) {
|
||||
fprintf(stderr, " ids: [0");
|
||||
for(int j = 1; j < size; j++)
|
||||
if(principal[j])
|
||||
fprintf(stderr, ", %d", dq->cosets[j].min->id);
|
||||
fprintf(stderr, "]\n");
|
||||
if(is_slim[i] && dq->cosets[0].min) { // sometimes we don't want to define min and max
|
||||
fprintf(stderr, " ids: [0");
|
||||
for(int j = 1; j < size; j++)
|
||||
if(principal[j])
|
||||
fprintf(stderr, ", %d", dq->cosets[j].min->id);
|
||||
fprintf(stderr, "]\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
// if this happens, there can be no balanced thickenings
|
||||
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;
|
||||
|
||||
// we can only handle bitvectors up to BV_BLOCKSIZE*BV_RANK bits, but we only store half of the weyl group
|
||||
|
||||
Reference in New Issue
Block a user