switch to rational numbers + add variable type matrix library
This commit is contained in:
parent
c19f61b714
commit
c566a8741e
15
Makefile
15
Makefile
@ -1,16 +1,16 @@
|
|||||||
HEADERS=triangle.h linalg.h queue.h
|
HEADERS=triangle.h linalg.h queue.h mat.h
|
||||||
|
|
||||||
#SPECIAL_OPTIONS=-O0 -g -D_DEBUG
|
#SPECIAL_OPTIONS=-O0 -g -D_DEBUG
|
||||||
#SPECIAL_OPTIONS=-O3 -pg -funroll-loops -fno-inline
|
SPECIAL_OPTIONS=-O3 -pg -funroll-loops -fno-inline
|
||||||
SPECIAL_OPTIONS=-O3 -flto -funroll-loops -Winline
|
#SPECIAL_OPTIONS=-O3 -flto -funroll-loops -Winline
|
||||||
#SPECIAL_OPTIONS=
|
#SPECIAL_OPTIONS=
|
||||||
|
|
||||||
OPTIONS=-m64 -march=native -mtune=native -std=gnu99 -D_GNU_SOURCE $(SPECIAL_OPTIONS)
|
OPTIONS=-m64 -march=native -mtune=native -std=gnu99 -D_GNU_SOURCE $(SPECIAL_OPTIONS)
|
||||||
|
|
||||||
all: singular_values
|
all: singular_values
|
||||||
|
|
||||||
singular_values: singular_values.o triangle.o linalg.o
|
singular_values: singular_values.o triangle.o linalg.o mat.o
|
||||||
gcc $(OPTIONS) -o singular_values triangle.o linalg.o singular_values.o -lm -lgsl -lcblas
|
gcc $(OPTIONS) -o singular_values triangle.o linalg.o singular_values.o mat.o -lm -lgsl -lcblas -lgmp
|
||||||
|
|
||||||
singular_values.o: singular_values.c $(HEADERS)
|
singular_values.o: singular_values.c $(HEADERS)
|
||||||
gcc $(OPTIONS) -c singular_values.c
|
gcc $(OPTIONS) -c singular_values.c
|
||||||
@ -21,5 +21,8 @@ linalg.o: linalg.c $(HEADERS)
|
|||||||
triangle.o: triangle.c $(HEADERS)
|
triangle.o: triangle.c $(HEADERS)
|
||||||
gcc $(OPTIONS) -c triangle.c
|
gcc $(OPTIONS) -c triangle.c
|
||||||
|
|
||||||
|
mat.o: mat.c $(HEADERS)
|
||||||
|
gcc $(OPTIONS) -c mat.c
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f singular_values triangle.o linalg.o singular_values.o
|
rm -f singular_values triangle.o linalg.o singular_values.o mat.o
|
||||||
|
158
mat.c
Normal file
158
mat.c
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#include "mat.h"
|
||||||
|
|
||||||
|
mat_workspace *mat_workspace_init(int n)
|
||||||
|
{
|
||||||
|
mat_workspace *ws = (mat_workspace*)malloc(sizeof(mat_workspace));
|
||||||
|
mat_init(ws->tmp_mat, n);
|
||||||
|
INIT(ws->tmp_num);
|
||||||
|
INIT(ws->tmp_num2);
|
||||||
|
return ws;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat_workspace_clear(mat_workspace *ws)
|
||||||
|
{
|
||||||
|
mat_clear(ws->tmp_mat);
|
||||||
|
CLEAR(ws->tmp_num);
|
||||||
|
CLEAR(ws->tmp_num2);
|
||||||
|
free(ws);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat_init(mat m, int n)
|
||||||
|
{
|
||||||
|
m->n = n;
|
||||||
|
m->x = malloc(n*n*sizeof(NUMBER));
|
||||||
|
LOOP(i,n) LOOP(j,n) INIT(m->x[i+j*n]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat_get(NUMBER out, mat m, int i, int j)
|
||||||
|
{
|
||||||
|
SET(out, M(m,i,j));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat_set(mat m, int i, int j, NUMBER x)
|
||||||
|
{
|
||||||
|
SET(M(m,i,j), x);
|
||||||
|
}
|
||||||
|
|
||||||
|
NUMBER *mat_ref(mat m, int i, int j)
|
||||||
|
{
|
||||||
|
return &M(m,i,j);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat_zero(mat m)
|
||||||
|
{
|
||||||
|
LOOP(i,m->n) LOOP(j,m->n) SET_ZERO(M(m,i,j));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat_identity(mat m)
|
||||||
|
{
|
||||||
|
LOOP(i,m->n) LOOP(j,m->n) {
|
||||||
|
if(i == j)
|
||||||
|
SET_ONE(M(m,i,j));
|
||||||
|
else
|
||||||
|
SET_ZERO(M(m,i,j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat_copy(mat to, mat from)
|
||||||
|
{
|
||||||
|
LOOP(i,from->n) LOOP(j,from->n) SET(M(to,i,j), M(from,i,j));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat_clear(mat m)
|
||||||
|
{
|
||||||
|
LOOP(i,m->n) LOOP(j,m->n) CLEAR(M(m,i,j));
|
||||||
|
free(m->x);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mat_same(mat m1, mat m2)
|
||||||
|
{
|
||||||
|
return m1 == m2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mat_multiply_outofplace(mat_workspace *ws, mat out, mat in1, mat in2)
|
||||||
|
{
|
||||||
|
int n = out->n;
|
||||||
|
NUMBER *tmp = &(ws->tmp_num);
|
||||||
|
|
||||||
|
LOOP(i,n) LOOP(j,n) {
|
||||||
|
SET_ZERO(M(out,i,j));
|
||||||
|
LOOP(k,n) {
|
||||||
|
MULTIPLY(*tmp, M(in1,i,k), M(in2,k,j));
|
||||||
|
ADD(M(out,i,j), M(out,i,j), *tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat_multiply(mat_workspace *ws, mat out, mat in1, mat in2)
|
||||||
|
{
|
||||||
|
if(mat_same(out, in1) || mat_same(out, in2)) {
|
||||||
|
mat_multiply_outofplace(ws, ws->tmp_mat, in1, in2);
|
||||||
|
mat_copy(out, ws->tmp_mat);
|
||||||
|
} else {
|
||||||
|
mat_multiply_outofplace(ws, out, in1, in2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat_det(mat_workspace *ws, NUMBER out, mat in)
|
||||||
|
{
|
||||||
|
// let's just assume n = 3 for the moment
|
||||||
|
NUMBER *tmp = &(ws->tmp_num);
|
||||||
|
int n = 3;
|
||||||
|
|
||||||
|
SET_ZERO(out);
|
||||||
|
|
||||||
|
LOOP(i,n) {
|
||||||
|
MULTIPLY(*tmp, M(in,0,i), M(in,1,(i+1)%3));
|
||||||
|
MULTIPLY(*tmp, *tmp, M(in,2,(i+2)%3));
|
||||||
|
ADD(out, out, *tmp);
|
||||||
|
|
||||||
|
MULTIPLY(*tmp, M(in,0,(i+2)%3), M(in,1,(i+1)%3));
|
||||||
|
MULTIPLY(*tmp, *tmp, M(in,2,i));
|
||||||
|
SUB(out, out, *tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mat_pseudoinverse_outofplace(mat_workspace *ws, mat out, mat in)
|
||||||
|
{
|
||||||
|
// let's just assume n = 3 for the moment
|
||||||
|
NUMBER *tmp = &(ws->tmp_num);
|
||||||
|
NUMBER *tmp2 = &(ws->tmp_num2);
|
||||||
|
int n = 3;
|
||||||
|
|
||||||
|
LOOP(i,n) LOOP(j,n) {
|
||||||
|
MULTIPLY(*tmp, M(in,(i+1)%3,(j+1)%3), M(in,(i+2)%3,(j+2)%3));
|
||||||
|
MULTIPLY(*tmp2, M(in,(i+1)%3,(j+2)%3), M(in,(i+2)%3,(j+1)%3));
|
||||||
|
SUB(M(out,j,i), *tmp, *tmp2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat_pseudoinverse(mat_workspace *ws, mat out, mat in)
|
||||||
|
{
|
||||||
|
if(mat_same(out, in)) {
|
||||||
|
mat_pseudoinverse_outofplace(ws, ws->tmp_mat, in);
|
||||||
|
mat_copy(out, ws->tmp_mat);
|
||||||
|
} else {
|
||||||
|
mat_pseudoinverse_outofplace(ws, out, in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat_trace(NUMBER out, mat in)
|
||||||
|
{
|
||||||
|
SET_ZERO(out);
|
||||||
|
ADD(out, out, M(in,0,0));
|
||||||
|
ADD(out, out, M(in,1,1));
|
||||||
|
ADD(out, out, M(in,2,2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat_print(mat in)
|
||||||
|
{
|
||||||
|
int n = in->n;
|
||||||
|
|
||||||
|
LOOP(i,n) {
|
||||||
|
LOOP(j,n) {
|
||||||
|
PRINT(M(in,i,j));
|
||||||
|
fputc(j == n - 1 ? '\n' : ' ', stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
66
mat.h
Normal file
66
mat.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#ifndef MAT_H
|
||||||
|
#define MAT_H
|
||||||
|
|
||||||
|
#include <gmp.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
#define LOOP(i,n) for(int i = 0; i < (n); i++)
|
||||||
|
|
||||||
|
// library for matrix computations in variable rings (based on GMP types)
|
||||||
|
|
||||||
|
/*
|
||||||
|
needed features:
|
||||||
|
x multiply matrices
|
||||||
|
- inverse
|
||||||
|
- pseudoinverse
|
||||||
|
x set
|
||||||
|
- eigenvalues
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NUMBER mpq_t
|
||||||
|
#define INIT mpq_init
|
||||||
|
#define CLEAR mpq_clear
|
||||||
|
#define SET mpq_set
|
||||||
|
#define SET_ZERO(x) mpq_set_ui(x,0,1)
|
||||||
|
#define SET_ONE(x) mpq_set_ui(x,1,1)
|
||||||
|
#define ADD mpq_add
|
||||||
|
#define SUB mpq_sub
|
||||||
|
#define MULTIPLY mpq_mul
|
||||||
|
#define DIV mpq_div
|
||||||
|
#define PRINT(x) gmp_printf("%Qd", x)
|
||||||
|
|
||||||
|
#define M(m,i,j) ((m)->x[(i)+(m)->n*(j)])
|
||||||
|
|
||||||
|
struct _mat{
|
||||||
|
int n;
|
||||||
|
NUMBER *x;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
typedef struct _mat mat[1];
|
||||||
|
|
||||||
|
typedef struct _mat_workspace {
|
||||||
|
mat tmp_mat;
|
||||||
|
NUMBER tmp_num;
|
||||||
|
NUMBER tmp_num2;
|
||||||
|
} mat_workspace;
|
||||||
|
|
||||||
|
mat_workspace *mat_workspace_init(int n);
|
||||||
|
void mat_workspace_clear(mat_workspace *ws);
|
||||||
|
void mat_init(mat m, int n);
|
||||||
|
void mat_get(NUMBER out, mat m, int i, int j);
|
||||||
|
void mat_set(mat m, int i, int j, NUMBER x);
|
||||||
|
NUMBER *mat_ref(mat m, int i, int j);
|
||||||
|
void mat_zero(mat m);
|
||||||
|
void mat_identity(mat m);
|
||||||
|
void mat_copy(mat to, mat from);
|
||||||
|
void mat_clear(mat m);
|
||||||
|
int mat_same(mat m1, mat m2);
|
||||||
|
static void mat_multiply_outofplace(mat_workspace *ws, mat out, mat in1, mat in2);
|
||||||
|
void mat_multiply(mat_workspace *ws, mat out, mat in1, mat in2);
|
||||||
|
void mat_det(mat_workspace *ws, NUMBER out, mat in);
|
||||||
|
static void mat_pseudoinverse_outofplace(mat_workspace *ws, mat out, mat in);
|
||||||
|
void mat_pseudoinverse(mat_workspace *ws, mat out, mat in);
|
||||||
|
void mat_trace(NUMBER out, mat in);
|
||||||
|
void mat_print(mat in);
|
||||||
|
|
||||||
|
#endif
|
@ -1,60 +1,69 @@
|
|||||||
#include "triangle.h"
|
#include "triangle.h"
|
||||||
#include "linalg.h"
|
#include "linalg.h"
|
||||||
|
#include "mat.h"
|
||||||
|
|
||||||
|
#include <gsl/gsl_poly.h>
|
||||||
|
|
||||||
|
//#define MAX_ELEMENTS 2800000
|
||||||
|
//#define MAX_ELEMENTS 720000
|
||||||
#define MAX_ELEMENTS 14000
|
#define MAX_ELEMENTS 14000
|
||||||
//#define DRAW_PICTURE 1
|
//#define DRAW_PICTURE 1
|
||||||
|
|
||||||
void initialize_triangle_generators(workspace_t *ws, gsl_matrix **gen, double a1, double a2, double a3, double s, double t)
|
void mpq_quartic(mpq_t out, mpq_t in, int a, int b, int c, int d, int e)
|
||||||
{
|
{
|
||||||
gsl_matrix **tmp;
|
mpq_t tmp;
|
||||||
tmp = getTempMatrices(ws, 6);
|
mpq_init(tmp);
|
||||||
|
|
||||||
double rho1sqrt = sqrt(s*(s+2*cos(2*M_PI*a1))+1);
|
mpq_set_si(out, a, 1);
|
||||||
double rho2sqrt = sqrt(s*(s+2*cos(2*M_PI*a2))+1);
|
mpq_mul(out, out, in);
|
||||||
double rho3sqrt = sqrt(s*(s+2*cos(2*M_PI*a3))+1);
|
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);
|
||||||
|
|
||||||
for(int i = 0; i < 6; i++)
|
mpq_clear(tmp);
|
||||||
gsl_matrix_set_zero(tmp[i]);
|
}
|
||||||
|
|
||||||
gsl_matrix_set(tmp[0], 0, 0, 1);
|
void initialize_triangle_generators(mat_workspace *ws, mat *gen, mpq_t s, mpq_t t)
|
||||||
gsl_matrix_set(tmp[0], 1, 0, -rho3sqrt/t);
|
{
|
||||||
gsl_matrix_set(tmp[0], 2, 0, -rho2sqrt*t);
|
mpq_set_ui(*mat_ref(gen[0], 0, 0), 0, 1);
|
||||||
gsl_matrix_set(tmp[0], 1, 1, -1);
|
mpq_set_ui(*mat_ref(gen[0], 0, 1), 0, 1);
|
||||||
gsl_matrix_set(tmp[0], 2, 2, -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);
|
||||||
|
|
||||||
gsl_matrix_set(tmp[1], 0, 0, -1);
|
mpq_set_ui(*mat_ref(gen[1], 0, 0), 1, 1);
|
||||||
gsl_matrix_set(tmp[1], 0, 1, -rho3sqrt*t);
|
mpq_set_ui(*mat_ref(gen[1], 1, 0), 0, 1);
|
||||||
gsl_matrix_set(tmp[1], 1, 1, 1);
|
mpq_set_ui(*mat_ref(gen[1], 2, 0), 0, 1);
|
||||||
gsl_matrix_set(tmp[1], 2, 1, -rho1sqrt/t);
|
mpq_quartic(*mat_ref(gen[1], 0, 1), t, 0, 0, 1, -1, 2);
|
||||||
gsl_matrix_set(tmp[1], 2, 2, -1);
|
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);
|
||||||
|
|
||||||
gsl_matrix_set(tmp[2], 0, 0, -1);
|
mat_pseudoinverse(ws, gen[3], gen[0]); // p^{-1}
|
||||||
gsl_matrix_set(tmp[2], 1, 1, -1);
|
mat_pseudoinverse(ws, gen[4], gen[1]); // q^{-1}
|
||||||
gsl_matrix_set(tmp[2], 0, 2, -rho2sqrt/t);
|
mat_multiply(ws, gen[2], gen[4], gen[3]); // r = q^{-1}p^{-1}
|
||||||
gsl_matrix_set(tmp[2], 1, 2, -rho1sqrt*t);
|
mat_pseudoinverse(ws, gen[5], gen[2]);
|
||||||
gsl_matrix_set(tmp[2], 2, 2, 1);
|
|
||||||
|
|
||||||
gsl_matrix_set(tmp[3], 0, 0, 1);
|
// mat_print(gen[0]);
|
||||||
gsl_matrix_set(tmp[3], 1, 1, s);
|
// mat_print(gen[1]);
|
||||||
gsl_matrix_set(tmp[3], 2, 2, 1/s);
|
// mat_print(gen[2]);
|
||||||
|
// mat_print(gen[3]);
|
||||||
gsl_matrix_set(tmp[4], 0, 0, 1/s);
|
// mat_print(gen[4]);
|
||||||
gsl_matrix_set(tmp[4], 1, 1, 1);
|
// mat_print(gen[5]);
|
||||||
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)
|
char *print_word(groupelement_t *g, char *str)
|
||||||
@ -73,138 +82,92 @@ char *print_word(groupelement_t *g, char *str)
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
groupelement_t *group;
|
groupelement_t *group;
|
||||||
workspace_t *ws;
|
mat_workspace *ws;
|
||||||
gsl_matrix **matrices;
|
mat *matrices;
|
||||||
gsl_matrix *gen[6];
|
mat tmp;
|
||||||
gsl_matrix *tmp, *tmp2, *coxeter;
|
mat gen[6];
|
||||||
double mu[6], tr, trinv;
|
char buf[100], buf2[100], buf3[100];
|
||||||
char buf[100];
|
mpq_t s,t;
|
||||||
|
mpq_t det, tr, trinv;
|
||||||
/*
|
|
||||||
if(argc < 2) {
|
|
||||||
fprintf(stderr, "Too few arguments!\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// allocate stuff
|
// allocate stuff
|
||||||
group = malloc(MAX_ELEMENTS*sizeof(groupelement_t));
|
group = malloc(MAX_ELEMENTS*sizeof(groupelement_t));
|
||||||
ws = workspace_alloc(3);
|
ws = mat_workspace_init(3);
|
||||||
matrices = malloc(MAX_ELEMENTS*sizeof(gsl_matrix*));
|
matrices = malloc(MAX_ELEMENTS*sizeof(mat));
|
||||||
for(int i = 0; i < MAX_ELEMENTS; i++)
|
for(int i = 0; i < MAX_ELEMENTS; i++)
|
||||||
matrices[i] = gsl_matrix_alloc(3, 3);
|
mat_init(matrices[i], 3);
|
||||||
for(int i = 0; i < 6; i++)
|
for(int i = 0; i < 6; i++)
|
||||||
gen[i] = gsl_matrix_alloc(3, 3);
|
mat_init(gen[i], 3);
|
||||||
tmp = gsl_matrix_alloc(3, 3);
|
mat_init(tmp, 3);
|
||||||
tmp2 = gsl_matrix_alloc(3, 3);
|
|
||||||
coxeter = gsl_matrix_alloc(3, 3);
|
|
||||||
|
|
||||||
#ifdef DRAW_PICTURE
|
mpq_inits(s, t, det, tr, trinv, NULL);
|
||||||
int width = 800;
|
|
||||||
int height = 800;
|
|
||||||
printf("P3\n%d %d\n255\n", width, height);
|
|
||||||
|
|
||||||
for(int y = 0; y < height; y++) {
|
mpq_set_ui(s,1,1);
|
||||||
for(int x = 0; x < width; x++) {
|
double t_ = atof(argv[1]);
|
||||||
double s = exp(((double)x/width-0.5)*4);
|
mpq_set_ui(t,(int)(t_*100),100);
|
||||||
double t = exp(((double)y/height-0.5)*4);
|
mpq_canonicalize(s);
|
||||||
#else
|
mpq_canonicalize(t);
|
||||||
double s = atof(argv[1]);
|
|
||||||
double t = atof(argv[2]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// the real action
|
// the real action
|
||||||
generate_triangle_group(group, MAX_ELEMENTS, 5, 6, 7);
|
generate_triangle_group(group, MAX_ELEMENTS, 3, 3, 4);
|
||||||
initialize_triangle_generators(ws, gen, 1.0/5.0, 1.0/6.0, 1.0/7.0, s, t);
|
initialize_triangle_generators(ws, gen, s, t);
|
||||||
|
|
||||||
gsl_matrix_set_identity(matrices[0]);
|
mat_identity(matrices[0]);
|
||||||
for(int i = 1; i < MAX_ELEMENTS; i++) {
|
for(int i = 1; i < MAX_ELEMENTS; i++) {
|
||||||
if(group[i].length % 2 != 0)
|
if(group[i].length % 2 != 0)
|
||||||
continue;
|
continue;
|
||||||
|
if(!group[i].inverse)
|
||||||
|
continue;
|
||||||
|
|
||||||
int parent = group[i].parent->id;
|
int parent = group[i].parent->id;
|
||||||
int grandparent = group[i].parent->parent->id;
|
int grandparent = group[i].parent->parent->id;
|
||||||
int letter;
|
int letter;
|
||||||
|
|
||||||
if(group[parent].letter == 0 && group[i].letter == 1)
|
if(group[parent].letter == 1 && group[i].letter == 2)
|
||||||
letter = 3; // p = ab
|
letter = 0; // p = bc
|
||||||
else if(group[parent].letter == 1 && group[i].letter == 2)
|
|
||||||
letter = 4; // q = bc
|
|
||||||
else if(group[parent].letter == 2 && group[i].letter == 0)
|
else if(group[parent].letter == 2 && group[i].letter == 0)
|
||||||
letter = 5; // r = ca
|
letter = 1; // q = ca
|
||||||
else if(group[parent].letter == 1 && group[i].letter == 0)
|
else if(group[parent].letter == 0 && group[i].letter == 1)
|
||||||
letter = 0; // p^{-1} = ba
|
letter = 2; // r = ab
|
||||||
else if(group[parent].letter == 2 && group[i].letter == 1)
|
if(group[parent].letter == 2 && group[i].letter == 1)
|
||||||
letter = 1; // q^{-1} = cb
|
letter = 3; // p^{-1} = cb
|
||||||
else if(group[parent].letter == 0 && group[i].letter == 2)
|
else if(group[parent].letter == 0 && group[i].letter == 2)
|
||||||
letter = 2; // r^{-1} = ac
|
letter = 4; // q^{-1} = ac
|
||||||
|
else if(group[parent].letter == 1 && group[i].letter == 0)
|
||||||
|
letter = 5; // r^{-1} = ba
|
||||||
|
|
||||||
multiply(matrices[grandparent], gen[letter], matrices[i]);
|
mat_multiply(ws, matrices[i], matrices[grandparent], gen[letter]);
|
||||||
}
|
}
|
||||||
|
|
||||||
double excentricity;
|
|
||||||
double max_excentricity = 0;
|
|
||||||
int max_excentricity_index = 0;
|
|
||||||
|
|
||||||
for(int i = 0; i < MAX_ELEMENTS; i++) {
|
for(int i = 0; i < MAX_ELEMENTS; i++) {
|
||||||
if(group[i].length % 2 != 0)
|
if(group[i].length % 2 != 0)
|
||||||
continue;
|
continue;
|
||||||
|
if(!group[i].inverse)
|
||||||
// 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;
|
continue;
|
||||||
|
|
||||||
mu[0] = fabs(GSL_REAL(gsl_vector_complex_get(ws->eval_complex, 0)) / GSL_REAL(gsl_vector_complex_get(ws->eval_complex, 1)));
|
mat_trace(tr, matrices[i]);
|
||||||
mu[1] = fabs(GSL_REAL(gsl_vector_complex_get(ws->eval_complex, 1)) / GSL_REAL(gsl_vector_complex_get(ws->eval_complex, 2)));
|
mat_trace(trinv, matrices[group[i].inverse->id]);
|
||||||
|
|
||||||
excentricity = log(mu[1])/log(mu[0]);
|
double lambda1, lambda2, lambda3;
|
||||||
if(excentricity > max_excentricity + 1e-3) {
|
// int realevs = gsl_poly_solve_cubic(-mpq_get_d(tr), mpq_get_d(trinv), -1, &lambda3, &lambda2, &lambda1);
|
||||||
max_excentricity = excentricity;
|
// if(realevs != 3)
|
||||||
max_excentricity_index = i;
|
// continue;
|
||||||
}
|
// if(lambda1 < 0 || lambda2 < 0 || lambda3 < 0)
|
||||||
|
// continue;
|
||||||
|
|
||||||
#ifndef DRAW_PICTURE
|
// gmp_printf("%d %d %s %Qd %Qd\n", i, group[i].length, print_word(&group[i], buf), tr, trinv);
|
||||||
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));
|
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)));
|
||||||
#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
|
// free stuff
|
||||||
for(int i = 0; i < MAX_ELEMENTS; i++)
|
for(int i = 0; i < MAX_ELEMENTS; i++)
|
||||||
gsl_matrix_free(matrices[i]);
|
mat_clear(matrices[i]);
|
||||||
for(int i = 0; i < 6; i++)
|
for(int i = 0; i < 6; i++)
|
||||||
gsl_matrix_free(gen[i]);
|
mat_clear(gen[i]);
|
||||||
gsl_matrix_free(tmp);
|
mat_clear(tmp);
|
||||||
gsl_matrix_free(tmp2);
|
mpq_clears(s, t, det, tr, trinv, NULL);
|
||||||
gsl_matrix_free(coxeter);
|
mat_workspace_clear(ws);
|
||||||
free(matrices);
|
|
||||||
free(group);
|
|
||||||
workspace_free(ws);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,38 @@
|
|||||||
if(!exists("logt")) logt = log(1.5)
|
if(!exists("logt")) logt = log(7)
|
||||||
if(!exists("logs")) logs = log(1.0)
|
if(!exists("logs")) logs = log(1.0)
|
||||||
|
|
||||||
file = sprintf("< ./singular_values %f %f", exp(logs), exp(logt))
|
file = sprintf("< ./singular_values %f", exp(logt))
|
||||||
title = sprintf("s = %f, t = %f", exp(logs), exp(logt))
|
#title = sprintf("s = %f, t = %f", exp(logs), exp(logt))
|
||||||
|
title = sprintf("t = %.3f", floor(exp(logt)*100)/100.0)
|
||||||
# print title
|
# print title
|
||||||
|
|
||||||
set zeroaxis
|
set zeroaxis
|
||||||
|
set samples 1000
|
||||||
set size square
|
set size square
|
||||||
set xrange [0:25]
|
set xrange [0:20]
|
||||||
set yrange [0:25]
|
set yrange [0:20]
|
||||||
|
set trange [0:20]
|
||||||
set grid
|
set grid
|
||||||
set parametric
|
set parametric
|
||||||
|
|
||||||
plot file using (log($2)):(log($3)) w p pt 7 ps 0.5 lc 1 t title
|
|
||||||
# plot file using 2:3 w p pt 7 ps 0.5 lc 1 t title
|
# plot file using 2:3 w p pt 7 ps 0.5 lc 1 t title
|
||||||
|
|
||||||
|
#tr(a,b) = exp((2*a+b)/3) + exp((b-a)/3) + exp(-(a+2*b)/3)
|
||||||
|
#trinv(a,b) = exp(-(2*a+b)/3) + exp((a-b)/3) + exp((a+2*b)/3)
|
||||||
|
|
||||||
|
tr(a,b) = exp(a) + exp(b-a) + exp(-b)
|
||||||
|
trinv(a,b) = exp(-a) + exp(a-b) + exp(b)
|
||||||
|
|
||||||
|
plot file using 4:5 w p pt 7 ps 0.5 lc 1 t title, \
|
||||||
|
log(tr(t,t*2)),log(trinv(t,2*t)) w l lw 2 t "", \
|
||||||
|
log(tr(t,t/2)),log(trinv(t,t/2)) w l lw 2 t ""
|
||||||
|
|
||||||
|
#plot for[i=-10:10] log(tr(t,t*exp(log(2)*i/10.0))),log(trinv(t,t*exp(log(2)*i/10.0))) w l lw 2 t ""
|
||||||
|
|
||||||
|
#plot for[i=-10:10] t,log(tr(t,t*exp(log(2)*i/10.0)))-t w l lw 2 t ""
|
||||||
|
|
||||||
|
##plot for[i=20:20] t,log(tr(1/t,exp(2*log(2)*i/20.0-log(2)))) w l lw 2 t ""
|
||||||
|
|
||||||
pause mouse keypress
|
pause mouse keypress
|
||||||
if(MOUSE_KEY == 60) logt=logt-0.02
|
if(MOUSE_KEY == 60) logt=logt-0.02
|
||||||
if(MOUSE_KEY == 62) logt=logt+0.02
|
if(MOUSE_KEY == 62) logt=logt+0.02
|
||||||
|
Loading…
Reference in New Issue
Block a user