triangle_reflection_complex/singular_values.c
2020-07-01 09:59:16 -05:00

211 lines
5.8 KiB
C

#include "triangle.h"
#include "linalg.h"
#define MAX_ELEMENTS 14000
//#define DRAW_PICTURE 1
void initialize_triangle_generators(workspace_t *ws, gsl_matrix **gen, double a1, double a2, double a3, double s, double t)
{
gsl_matrix **tmp;
tmp = getTempMatrices(ws, 6);
double rho1sqrt = sqrt(s*(s+2*cos(2*M_PI*a1))+1);
double rho2sqrt = sqrt(s*(s+2*cos(2*M_PI*a2))+1);
double rho3sqrt = sqrt(s*(s+2*cos(2*M_PI*a3))+1);
for(int i = 0; i < 6; i++)
gsl_matrix_set_zero(tmp[i]);
gsl_matrix_set(tmp[0], 0, 0, 1);
gsl_matrix_set(tmp[0], 1, 0, -rho3sqrt/t);
gsl_matrix_set(tmp[0], 2, 0, -rho2sqrt*t);
gsl_matrix_set(tmp[0], 1, 1, -1);
gsl_matrix_set(tmp[0], 2, 2, -1);
gsl_matrix_set(tmp[1], 0, 0, -1);
gsl_matrix_set(tmp[1], 0, 1, -rho3sqrt*t);
gsl_matrix_set(tmp[1], 1, 1, 1);
gsl_matrix_set(tmp[1], 2, 1, -rho1sqrt/t);
gsl_matrix_set(tmp[1], 2, 2, -1);
gsl_matrix_set(tmp[2], 0, 0, -1);
gsl_matrix_set(tmp[2], 1, 1, -1);
gsl_matrix_set(tmp[2], 0, 2, -rho2sqrt/t);
gsl_matrix_set(tmp[2], 1, 2, -rho1sqrt*t);
gsl_matrix_set(tmp[2], 2, 2, 1);
gsl_matrix_set(tmp[3], 0, 0, 1);
gsl_matrix_set(tmp[3], 1, 1, s);
gsl_matrix_set(tmp[3], 2, 2, 1/s);
gsl_matrix_set(tmp[4], 0, 0, 1/s);
gsl_matrix_set(tmp[4], 1, 1, 1);
gsl_matrix_set(tmp[4], 2, 2, s);
gsl_matrix_set(tmp[5], 0, 0, s);
gsl_matrix_set(tmp[5], 1, 1, 1/s);
gsl_matrix_set(tmp[5], 2, 2, 1);
multiply_many(ws, gen[0], 3, tmp[2], tmp[3], tmp[1]);
multiply_many(ws, gen[1], 3, tmp[0], tmp[4], tmp[2]);
multiply_many(ws, gen[2], 3, tmp[1], tmp[5], tmp[0]);
invert(gen[0], gen[3], ws);
invert(gen[1], gen[4], ws);
invert(gen[2], gen[5], ws);
releaseTempMatrices(ws, 6);
}
char *print_word(groupelement_t *g, char *str)
{
int i = g->length - 1;
str[g->length] = 0;
while(g->parent) {
str[i--] = 'a' + g->letter;
g = g->parent;
}
return str;
}
int main(int argc, char *argv[])
{
groupelement_t *group;
workspace_t *ws;
gsl_matrix **matrices;
gsl_matrix *gen[6];
gsl_matrix *tmp, *tmp2, *coxeter;
double mu[6], tr, trinv;
char buf[100];
/*
if(argc < 2) {
fprintf(stderr, "Too few arguments!\n");
return 1;
}
*/
// allocate stuff
group = malloc(MAX_ELEMENTS*sizeof(groupelement_t));
ws = workspace_alloc(3);
matrices = malloc(MAX_ELEMENTS*sizeof(gsl_matrix*));
for(int i = 0; i < MAX_ELEMENTS; i++)
matrices[i] = gsl_matrix_alloc(3, 3);
for(int i = 0; i < 6; i++)
gen[i] = gsl_matrix_alloc(3, 3);
tmp = gsl_matrix_alloc(3, 3);
tmp2 = gsl_matrix_alloc(3, 3);
coxeter = gsl_matrix_alloc(3, 3);
#ifdef DRAW_PICTURE
int width = 800;
int height = 800;
printf("P3\n%d %d\n255\n", width, height);
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
double s = exp(((double)x/width-0.5)*4);
double t = exp(((double)y/height-0.5)*4);
#else
double s = atof(argv[1]);
double t = atof(argv[2]);
#endif
// the real action
generate_triangle_group(group, MAX_ELEMENTS, 5, 6, 7);
initialize_triangle_generators(ws, gen, 1.0/5.0, 1.0/6.0, 1.0/7.0, s, t);
gsl_matrix_set_identity(matrices[0]);
for(int i = 1; i < MAX_ELEMENTS; i++) {
if(group[i].length % 2 != 0)
continue;
int parent = group[i].parent->id;
int grandparent = group[i].parent->parent->id;
int letter;
if(group[parent].letter == 0 && group[i].letter == 1)
letter = 3; // p = ab
else if(group[parent].letter == 1 && group[i].letter == 2)
letter = 4; // q = bc
else if(group[parent].letter == 2 && group[i].letter == 0)
letter = 5; // r = ca
else if(group[parent].letter == 1 && group[i].letter == 0)
letter = 0; // p^{-1} = ba
else if(group[parent].letter == 2 && group[i].letter == 1)
letter = 1; // q^{-1} = cb
else if(group[parent].letter == 0 && group[i].letter == 2)
letter = 2; // r^{-1} = ac
multiply(matrices[grandparent], gen[letter], matrices[i]);
}
double excentricity;
double max_excentricity = 0;
int max_excentricity_index = 0;
for(int i = 0; i < MAX_ELEMENTS; i++) {
if(group[i].length % 2 != 0)
continue;
// jordan projection
gsl_matrix_memcpy(tmp, matrices[i]);
gsl_eigen_nonsymmv_params(0, ws->work_nonsymmv);
int r = gsl_eigen_nonsymmv(tmp, ws->eval_complex, ws->evec_complex, ws->work_nonsymmv);
ERROR(r, "gsl_eigen_nonsymmv failed!\n");
gsl_eigen_nonsymmv_sort(ws->eval_complex, ws->evec_complex, GSL_EIGEN_SORT_ABS_DESC);
int real_evs = 0;
for(int j = 0; j < 3; j++)
if(FCMP(GSL_IMAG(gsl_vector_complex_get(ws->eval_complex, j)), 0) == 0)
real_evs++;
if(real_evs != 3)
continue;
mu[0] = fabs(GSL_REAL(gsl_vector_complex_get(ws->eval_complex, 0)) / GSL_REAL(gsl_vector_complex_get(ws->eval_complex, 1)));
mu[1] = fabs(GSL_REAL(gsl_vector_complex_get(ws->eval_complex, 1)) / GSL_REAL(gsl_vector_complex_get(ws->eval_complex, 2)));
excentricity = log(mu[1])/log(mu[0]);
if(excentricity > max_excentricity + 1e-3) {
max_excentricity = excentricity;
max_excentricity_index = i;
}
#ifndef DRAW_PICTURE
printf("%d %f %f %f %f 0x0000ff %d %s\n", group[i].length, mu[0], mu[1], tr, trinv, i, print_word(&group[i], buf));
#endif
}
#ifdef DRAW_PICTURE
int color = (int)((max_excentricity-1)/(max_excentricity+4)*255);
if(color < 0)
color = 0;
if(color > 255)
color = 255;
printf("%d %d %d\n", color, color, color);
}
fprintf(stderr, "y = %d\n", y);
}
#else
fprintf(stderr, "max = %f %s\n", max_excentricity, print_word(&group[max_excentricity_index], buf));
#endif
// free stuff
for(int i = 0; i < MAX_ELEMENTS; i++)
gsl_matrix_free(matrices[i]);
for(int i = 0; i < 6; i++)
gsl_matrix_free(gen[i]);
gsl_matrix_free(tmp);
gsl_matrix_free(tmp2);
gsl_matrix_free(coxeter);
free(matrices);
free(group);
workspace_free(ws);
return 0;
}