Recently I wrote a program that made some calculations on the .5.3.3.-symmetry, to estimate an upper bound for the 600-cell diminishings.
I just realized this could could well be used to generate lace-towers for the polytopes of this group.
Here is the c++ source code of the program:
- Code: Select all
#include <iostream>
#include <fstream>
using namespace std;
class fint{//integers of the ring ax+bf, where x=1 and f=phi, the golden ratio.
public:
short int x;
short int f;
fint(){x=0;f=0;}
fint(int sx){x=sx;f=0;}
fint(int sx,int sf){x=sx;f=sf;}
fint operator*(fint& b){
fint r;
r.x=this->f*b.f+this->x*b.x;
r.f=this->f*(b.f+b.x)+this->x*b.f;
return r;
}
bool operator==(fint x){return(x.x==this->x&&x.f==this->f);}
bool operator!=(fint x){return(x.x!=this->x||x.f!=this->f);}
fint operator=(const int& x){fint r;r.x=x;return r;}
fint operator=(const fint& z){x=z.x;f=z.f;return z;}
fint operator+(fint b){
fint r;
r.x=this->x+b.x;
r.f=this->f+b.f;
return r;
}
};
const fint o(0,0);//0
const fint x(1,0);//1
const fint y(-1,0);//-1
const fint f(0,1);//phi
/*int orders[30];//the number of occurrence for every orbit
int vertes[120];//a group-element for every vertex
fint vertices[120][4];//how the bottom row of the matrix of a group element looks like, for every vertex.
*/
class fintmatrix{//the group elements: orthogonal matrices in R^4 (or actually not R, but Z+fZ)
public:
fint mat[4][4];
short vertex;
int det;
short order;
bool operator==(fintmatrix mat){for(int i=0;i<4;i++)for(int j=0;j<4;j++)if(mat.mat[i][j]!=this->mat[i][j])return false;return true;}
fintmatrix(){for(int i=0;i<4;i++)for(int j=0;j<4;j++)mat[i][j].x=(i==j);det=1;}
explicit fintmatrix(int sdet){for(int i=0;i<4;i++)for(int j=0;j<4;j++)mat[i][j]=(i==j);det=sdet;}
fintmatrix operator*(fintmatrix right){
fintmatrix r;for(int i=0;i<4;i++)for(int j=0;j<4;j++){
fint q;
for(int k=0;k<4;k++)q=q+this->mat[i][k]*right.mat[k][j];
r.mat[i][j]=q;
}r.det=this->det*right.det;
return r;
}
};
class thegroup{//the group itself.
public:
fintmatrix group[14400];
int last;
thegroup(){last=5;
group[1].det=-1;
group[1].mat[0][0]=y;
group[1].mat[0][1]=f;
group[2].det=-1;
group[2].mat[1][0]=f;
group[2].mat[1][1]=y;
group[2].mat[1][2]=x;
group[3].det=-1;
group[3].mat[2][1]=x;
group[3].mat[2][2]=y;
group[3].mat[2][3]=x;
group[4].det=-1;
group[4].mat[3][2]=x;
group[4].mat[3][3]=y;
for(int k=0;k<5;k++)
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
cout<<group[k].mat[i][j].x<<',';
}cout<<endl;
}cout<<endl;
}
int isthere(fint mat[][4]){
int i=last;
bool joepie;
do{joepie=true;
for(int k=0;k<4;k++)
for(int j=0;j<4;j++)
if(group[i].mat[k][j]!=mat[k][j])
joepie=false;
if(joepie)
return i;
i--;
}while(i>=0);return -1;}
void add(fintmatrix& mat){if(last>=14400)cout<<"help :'-(";group[last]=mat;last++;}
};
void ab(int a, int b, int q, thegroup& group){//doing group-operation a and b consecutively.
fintmatrix mat=group.group[q];
do{mat=group.group[a]*mat;
if(group.isthere(mat.mat)==-1){
group.add(mat);
}
mat=group.group[b]*mat;
if(group.isthere(mat.mat)==-1){
group.add(mat);
}
}while(!(mat==group.group[q]));
}
/*
void giveorders(int q, thegroup& group){//calculate the orbit of group-operation q.
fintmatrix mat;
fintmatrix id;
int i=0;
do{mat=group.group[q]*mat;
i++;
}while(!(mat==id));
group.group[q].order=i;
cout<<i;orders[i]++;
}
*/
void makegroup(thegroup& group){//make all elements of the group.
ofstream output("C:/Users/Wout/Documents/group.txt",ios::out);
for(int i=1;i<14400;i++){
ab(1,2,i,group);
ab(1,3,i,group);
ab(2,3,i,group);
ab(1,4,i,group);
ab(2,4,i,group);
ab(3,4,i,group);
if(!(i%100))
cout<<i<<','<<group.last<<":)"<<endl;
}
for(int i=0;i<14400;i++){
output<<endl;
for(int j=0;j<4;j++){
for(int k=0;k<4;k++)
output<<group.group[i].mat[j][k].x<<' '<<group.group[i].mat[j][k].f<<(k<3?";":"");
output<<endl;
}
output<<endl;
}
cout<<group.last<<endl;
cout<<"file weggeschreven, nu door naar berekenen.";
}
/*bool search(fint current[],int last,int& where){//search for 'current' in 'vertices'.
bool rtrnv;
for(where=0;where<last;where++){
rtrnv=true;
for(int j=0;j<4;j++)
if(vertices[where][j]!=current[j])
rtrnv=false;
if(rtrnv)
return true;
}
return false;
}
void make600(thegroup& group){//assign a vertex-number to every group-element.
int lastvertex=1;
fint current[4];
int where;
vertices[0][3]=x;
for(int i=0;i<14400;i++){
for(int j=0;j<4;j++)
current[j]=group.group[i].mat[3][j];
if(search(current,lastvertex,where)){
group.group[i].vertex=where;
}else{
lastvertex++;
group.group[i].vertex=where;
vertes[where]=i;
cout<<lastvertex<<'.'<<where<<"::"<<endl;
for(int j=0;j<4;j++){
cout<<current[j].x<<current[j].f<<' ';
vertices[where][j]=current[j];
}
}
}
}
void biggerorders(thegroup& group){//give the length of the orbits of all vertices of the 600-cell.
int orders[31][50];
int order[30];
bool found;
int k;
int last=0;
for(int i=0;i<31;i++){
for(int j=0;j<50;j++)
orders[i][j]=0;
order[i]=0;
}
for(int i=0;i<14400;i++){
for(int g=0;g<30;g++)
order[g]=0;
for(int j=0;j<120;j++){
k=0;
fintmatrix mat=group.group[vertes[j]];
for(int i=0;i<4;i++)
for(int j=0;j<3;j++)
mat.mat[j][i]=0;
do{mat=mat*group.group[i];
found=true;
for(int i=0;i<4;i++)
if(mat.mat[3][i]!=group.group[vertes[j]].mat[3][i])
found=false;
k++;
}while(!found);
order[k-1]++;
}
k=0;
do{
found=true;
for(int j=0;j<30;j++)
if(orders[j][k]!=order[j])
found=false;
k++;
}while(!found&&k<=last);
if(k>last){
for(int i=0;i<30;i++)
cout<<(orders[i][last]=order[i])<<',';
cout<<endl;//cin.get();
orders[30][last]++;
last++;
}else{
/*for(int i=0;i<30;i++)
cout<<order[i]<<',';cout<<endl;
orders[30][k-1]++;
}
if(!(i%100))
cout<<i;
}
for(int i=0;i<last;i++){
for(int j=0;j<30;j++)
if(orders[j][i])
cout<<j+1<<':'<<orders[j][i]<<' ';
cout<<orders[30][i]<<endl;
}cin.get();
int cf=0;
for(int i=0;i<last;i++)
cf+=orders[30][i];
cout<<cf;
}
void adjustedbiggerorders(thegroup& group){//gives other order information, quite usefull
int orders[33][40];
int order[30];
bool found;
int k;
int last=0;
int orbited;
bool inorbit;
for(int i=0;i<33;i++){
for(int j=0;j<40;j++)
orders[i][j]=0;
order[i]=0;
}cin.get();
for(int i=0;i<14400;i++){
orbited=3;
for(int g=0;g<30;g++)
order[g]=0;
for(int j=0;j<120;j++){
k=0;
fintmatrix mat=group.group[vertes[j]];
for(int i=0;i<4;i++)
for(int j=0;j<3;j++)
mat.mat[j][i]=0;
do{mat=mat*group.group[i];
inorbit=true;
found=true;
for(int i=0;i<4;i++){
if(mat.mat[3][i]!=group.group[vertes[j]].mat[3][i])
found=false;
if(j==0||j==1){
if(!(mat.mat[3][i]==group.group[vertes[2]].mat[3][i]||(j==0&&mat.mat[3][i]==group.group[vertes[1]].mat[3][i])))
inorbit=false;
}else
inorbit=false;
}
if(inorbit&&((orbited==3&&j==1)||j==0)){
orbited--;
if(j!=1)cout<<i<<','<<j<<' '<<orbited<<endl;
}
k++;
}while(!found);
order[k-1]++;
}
k=0;
do{
found=true;
for(int j=0;j<30;j++)
if(orders[j][k]!=order[j])
found=false;
k++;
}while(!found&&k<=last);if(orbited!=2&&orbited!=3)cout<<orbited<<' ';
if(k>last){
for(int i=0;i<30;i++)
/*cout<</*(orders[i][last]=order[i]);/*<<',';
cout<<endl;//cin.get();*
orders[29+orbited][last]++;
last++;
}else{
/*for(int i=0;i<30;i++)
cout<<order[i]<<',';cout<<endl;*
orders[29+orbited][k-1]++;
}
if(!(i%100))
cout<<endl;//i;
}
for(int i=0;i<last;i++){
for(int j=0;j<30;j++)
if(orders[j][i])
cout<<j+1<<':'<<orders[j][i]<<' ';
cout<<'('<<orders[30][i]<<','<<orders[31][i]<<','<<orders[32][i]<<')'<<endl;
}cin.get();
int cf=0;
for(int i=0;i<last;i++)
cf+=orders[30][i]+orders[31][i]+orders[32][i];
cout<<cf;
}
*/
void givecoordinates(int p, thegroup& group){
//ofstream output("C:/Users/Wout/Documents/533tower.txt"),ios::out);
fint vertices[4][3][1200];
fint dynkin[4];
fint currvertex[4];
int last=0;
bool hurray;
bool write;
for(int i=0;i<4;i++){
dynkin[i]=(p%2?x:o);
p/=2;
cout<<dynkin[i].x<<":)";
}cin.get();
for(int symmetry=0;symmetry<4;symmetry++){
last=0;
for(int i=0;i<14400;i++){
for(int j=0;j<4;j++)
currvertex[j]=o;
for(int j=0;j<4;j++){
for(int k=0;k<4;k++)
currvertex[j]=currvertex[j]+dynkin[k]*group.group[i].mat[k][j];
}//cout<<"i:"<<i<<'\t';
hurray=true;
for(int j=0;j<4;j++)
if(j!=symmetry&&currvertex[j].x+currvertex[j].f*1.618033988749894848204586834365638117720309179805762862135<0){
hurray=false;
//if(j!=symmetry)cout<<currvertex[j].x<<','<<currvertex[j].f<<":)"<<endl;
}
if(hurray){
write=true;
for(int j=0;j<=last;j++)
for(int k=0;k<3;k++){
int l=k+(symmetry<=k);
if(currvertex[l]!=vertices[symmetry][k][j])
break;
if(k==2)
write=false;
}
if(write){
//cout<<":) ";for(int q=0;q<4;q++)cout<<currvertex[q].x<<','<<currvertex[q].f<<';';cout<<endl;
last++;
for(int j=0;j<3;j++)
vertices[symmetry][j][last]=currvertex[j+(symmetry<=j)];
}
}//cout<<"i:"<<i<<"last:"<<last<<' ';
//cin.get();
}
cout<<p<<','<<symmetry<<','<<last<<endl;
for(int i=0;i<=last;i++){
for(int j=0;j<3;j++)
cout<<vertices[symmetry][j][i].x<<','<<vertices[symmetry][j][i].f<<';';
cout<<endl;
}
}
}
int main(){//main
cout<<":)"<<endl;
thegroup group;
makegroup(group);
for(int i=1;i<16;i++)
givecoordinates(i,group);
return 1;
}
The error I get says: invalid declaration of 'std::basic_ios<char>::out'
Now what the program does (But doesn't output to a file ):
It has the following classes:
fint: numbers that look like a+b*f, because all uniforms of .5.3.3. have towers that use just these numbers, and now we can do integer calculations.
fintmatrix: This is a matrix that changes the CD-diagram, according to the EKF-rules. Defaults to the identity matrix.
thegroup: this is a set of fintmatrices, that form a group. The first 5 matrices are hardcoded to be the identity, and changing of all 4 nodes.
First we make the complete .5.3.3.-group, that is, we determine all matrices you can get by multiplying the default matrices.
This gives us a set of 14400 matrices, that all correspond to a way of changing any CD-diagram. This can also be interpreted as a symmetry of R^4 according to a weird basis.
Now what's great, is that when we take such a matrix, and multiply it with some CD-dyagram, say x5o3o3o, we get a different cd-diagram (say (-x)5f3o3o. However, this diagram still is part of the x5o3o3o-polytope. When this diagram has only 1 negtaive node, the polytope the other nodes are giving is part of the lace tower. (So when we have (-x)5f3o3o, we know the tower according to .3.3.-symmetry has an f3o3o-part.)
This basically is what the program does: it takes a CD-diagram (any numer 1-16 is converted to binary, a 0 means o, 1 means x, so 4 gives 0010->o5o3x3o), then this is multiplied by all matrices of thegroup, and then tower-elements are written down in the vertices-array.
Now the negative node of such a dynkin-diagram tells you how far down the tower you should be. However, I couldn't implement this in the programm without getting multiple instances of the same tower-element.
When the program is run aas-is, it will give the tower-elements in an near-correct order, but whenever one tower-element should occur multiple times in the tower, it inconveiniently gets ommited.
I hope someone can help me out, then the towers of .5.3.3.-symmetry on Klitzings site can be determined once and for all.