#include "triangle.h" #include "linalg.h" #include "mat.h" #include //#define MAX_ELEMENTS 2800000 //#define MAX_ELEMENTS 720000 #define MAX_ELEMENTS 14000 //#define DRAW_PICTURE 1 void mpq_quartic(mpq_t out, mpq_t in, int a, int b, int c, int d, int e) { mpq_t tmp; mpq_init(tmp); mpq_set_si(out, a, 1); mpq_mul(out, out, in); mpq_set_si(tmp, b, 1); mpq_add(out, out, tmp); mpq_mul(out, out, in); mpq_set_si(tmp, c, 1); mpq_add(out, out, tmp); mpq_mul(out, out, in); mpq_set_si(tmp, d, 1); mpq_add(out, out, tmp); mpq_mul(out, out, in); mpq_set_si(tmp, e, 1); mpq_add(out, out, tmp); mpq_clear(tmp); } void initialize_triangle_generators(mat_workspace *ws, mat *gen, mpq_t s, mpq_t t) { mpq_set_ui(*mat_ref(gen[0], 0, 0), 0, 1); mpq_set_ui(*mat_ref(gen[0], 0, 1), 0, 1); mpq_set_ui(*mat_ref(gen[0], 0, 2), 1, 1); mpq_set_ui(*mat_ref(gen[0], 1, 0), 1, 1); mpq_set_ui(*mat_ref(gen[0], 1, 1), 0, 1); mpq_set_ui(*mat_ref(gen[0], 1, 2), 0, 1); mpq_set_ui(*mat_ref(gen[0], 2, 0), 0, 1); mpq_set_ui(*mat_ref(gen[0], 2, 1), 1, 1); mpq_set_ui(*mat_ref(gen[0], 2, 2), 0, 1); mpq_set_ui(*mat_ref(gen[1], 0, 0), 1, 1); mpq_set_ui(*mat_ref(gen[1], 1, 0), 0, 1); mpq_set_ui(*mat_ref(gen[1], 2, 0), 0, 1); mpq_quartic(*mat_ref(gen[1], 0, 1), t, 0, 0, 1, -1, 2); mpq_quartic(*mat_ref(gen[1], 1, 1), t, 0, 0, -1, 2, -2); mpq_quartic(*mat_ref(gen[1], 2, 1), t, 0, 0, 1, -3, 3); mpq_quartic(*mat_ref(gen[1], 0, 2), t, 0, 0, 1, 0, 3); mpq_quartic(*mat_ref(gen[1], 1, 2), t, 0, 0, -1, 1, -1); mpq_quartic(*mat_ref(gen[1], 2, 2), t, 0, 0, 1, -2, 1); mat_pseudoinverse(ws, gen[3], gen[0]); // p^{-1} mat_pseudoinverse(ws, gen[4], gen[1]); // q^{-1} mat_multiply(ws, gen[2], gen[4], gen[3]); // r = q^{-1}p^{-1} mat_pseudoinverse(ws, gen[5], gen[2]); // mat_print(gen[0]); // mat_print(gen[1]); // mat_print(gen[2]); // mat_print(gen[3]); // mat_print(gen[4]); // mat_print(gen[5]); } 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; mat_workspace *ws; mat *matrices; mat tmp; mat gen[6]; char buf[100], buf2[100], buf3[100]; mpq_t s,t; mpq_t det, tr, trinv; // allocate stuff group = malloc(MAX_ELEMENTS*sizeof(groupelement_t)); ws = mat_workspace_init(3); matrices = malloc(MAX_ELEMENTS*sizeof(mat)); for(int i = 0; i < MAX_ELEMENTS; i++) mat_init(matrices[i], 3); for(int i = 0; i < 6; i++) mat_init(gen[i], 3); mat_init(tmp, 3); mpq_inits(s, t, det, tr, trinv, NULL); mpq_set_ui(s,1,1); double t_ = atof(argv[1]); mpq_set_ui(t,(int)(t_*100),100); mpq_canonicalize(s); mpq_canonicalize(t); // the real action generate_triangle_group(group, MAX_ELEMENTS, 3, 3, 4); initialize_triangle_generators(ws, gen, s, t); mat_identity(matrices[0]); for(int i = 1; i < MAX_ELEMENTS; i++) { if(group[i].length % 2 != 0) continue; if(!group[i].inverse) continue; int parent = group[i].parent->id; int grandparent = group[i].parent->parent->id; int letter; if(group[parent].letter == 1 && group[i].letter == 2) letter = 0; // p = bc else if(group[parent].letter == 2 && group[i].letter == 0) letter = 1; // q = ca else if(group[parent].letter == 0 && group[i].letter == 1) letter = 2; // r = ab if(group[parent].letter == 2 && group[i].letter == 1) letter = 3; // p^{-1} = cb else if(group[parent].letter == 0 && group[i].letter == 2) letter = 4; // q^{-1} = ac else if(group[parent].letter == 1 && group[i].letter == 0) letter = 5; // r^{-1} = ba mat_multiply(ws, matrices[i], matrices[grandparent], gen[letter]); } for(int i = 0; i < MAX_ELEMENTS; i++) { if(group[i].length % 2 != 0) continue; if(!group[i].inverse) continue; mat_trace(tr, matrices[i]); mat_trace(trinv, matrices[group[i].inverse->id]); double lambda1, lambda2, lambda3; // int realevs = gsl_poly_solve_cubic(-mpq_get_d(tr), mpq_get_d(trinv), -1, &lambda3, &lambda2, &lambda1); // if(realevs != 3) // continue; // if(lambda1 < 0 || lambda2 < 0 || lambda3 < 0) // continue; // gmp_printf("%d %d %s %Qd %Qd\n", i, group[i].length, print_word(&group[i], buf), tr, trinv); printf("%d %d %s %f %f %f\n", i, group[i].length, print_word(&group[i], buf), log(mpq_get_d(tr)), log(mpq_get_d(trinv))); } // free stuff for(int i = 0; i < MAX_ELEMENTS; i++) mat_clear(matrices[i]); for(int i = 0; i < 6; i++) mat_clear(gen[i]); mat_clear(tmp); mpq_clears(s, t, det, tr, trinv, NULL); mat_workspace_clear(ws); return 0; }