compute whether a representation in the barbot component of the (5,5,5) group is (almost) all loxodromic
This commit is contained in:
134
mat.h
134
mat.h
@@ -8,27 +8,139 @@
|
||||
|
||||
// library for matrix computations in variable rings (based on GMP types)
|
||||
|
||||
/*
|
||||
needed features:
|
||||
x multiply matrices
|
||||
- inverse
|
||||
x pseudoinverse
|
||||
x set
|
||||
- eigenvalues
|
||||
*/
|
||||
#ifdef QEXT_SQRT5
|
||||
|
||||
typedef mpq_t NUMBER [2];
|
||||
#define INIT(x) do { mpq_init((x)[0]); mpq_init((x)[1]); } while(0)
|
||||
#define CLEAR(x) do { mpq_clear((x)[0]); mpq_clear((x)[1]); } while(0)
|
||||
#define SET(x,y) do { mpq_set((x)[0],(y)[0]); mpq_set((x)[1],(y)[1]); } while(0)
|
||||
#define SET_INT(x,y) do { mpq_set_si((x)[0],(y),1); mpq_set_si((x)[1],0,1); } while(0)
|
||||
#define SET_ZERO(x) SET_INT(x,0)
|
||||
#define SET_ONE(x) SET_INT(x,1)
|
||||
#define ADD(x,y,z) do { mpq_add((x)[0],(y)[0],(z)[0]); mpq_add((x)[1],(y)[1],(z)[1]); } while(0)
|
||||
#define SUB(x,y,z) do { mpq_sub((x)[0],(y)[0],(z)[0]); mpq_sub((x)[1],(y)[1],(z)[1]); } while(0)
|
||||
#define MUL multiply_sqrt5
|
||||
#define DIV divide_sqrt5
|
||||
#define CMP compare_sqrt5
|
||||
#define PRINT(x) gmp_printf("%Qd + %Qd*sqrt(5)", (x)[0], (x)[1])
|
||||
#define SPRINT(buf, x) gmp_sprintf(buf, "%Qd+%Qd*sqrt(5)", (x)[0], (x)[1])
|
||||
|
||||
static void multiply_sqrt5(NUMBER out, NUMBER a, NUMBER b)
|
||||
{
|
||||
// could be in place!!!
|
||||
|
||||
mpq_t tmp, result[2];
|
||||
mpq_inits(tmp, result[0], result[1], 0);
|
||||
|
||||
mpq_mul(result[0], a[1], b[1]);
|
||||
mpq_set_si(tmp, 5, 1);
|
||||
mpq_mul(result[0], result[0], tmp);
|
||||
mpq_mul(tmp, a[0], b[0]);
|
||||
mpq_add(result[0], result[0], tmp);
|
||||
|
||||
mpq_mul(result[1], a[1], b[0]);
|
||||
mpq_mul(tmp, a[0], b[1]);
|
||||
mpq_add(result[1], result[1], tmp);
|
||||
|
||||
mpq_set(out[0], result[0]);
|
||||
mpq_set(out[1], result[1]);
|
||||
|
||||
mpq_clears(tmp, result[0], result[1], 0);
|
||||
}
|
||||
|
||||
static void divide_sqrt5(NUMBER out, NUMBER a, NUMBER b)
|
||||
{
|
||||
mpq_t denom, num, tmp, neg5, result[2];
|
||||
mpq_inits(denom, num, tmp, neg5, result[0], result[1], 0);
|
||||
mpq_set_si(neg5, -5, 1);
|
||||
|
||||
mpq_mul(denom, b[1], b[1]);
|
||||
mpq_mul(denom, denom, neg5);
|
||||
mpq_mul(tmp, b[0], b[0]);
|
||||
mpq_add(denom, denom, tmp);
|
||||
|
||||
mpq_mul(num, a[1], b[1]);
|
||||
mpq_mul(num, num, neg5);
|
||||
mpq_mul(tmp, a[0], b[0]);
|
||||
mpq_add(num, num, tmp);
|
||||
|
||||
mpq_div(result[0], num, denom);
|
||||
|
||||
mpq_mul(num, a[1], b[0]);
|
||||
mpq_mul(tmp, a[0], b[1]);
|
||||
mpq_sub(num, num, tmp);
|
||||
|
||||
mpq_div(result[1], num, denom);
|
||||
|
||||
mpq_set(out[0], result[0]);
|
||||
mpq_set(out[1], result[1]);
|
||||
|
||||
mpq_clears(denom, num, tmp, neg5, result[0], result[1], 0);
|
||||
}
|
||||
|
||||
static int compare_sqrt5(NUMBER x, NUMBER y)
|
||||
{
|
||||
int result;
|
||||
mpq_t p, q, p2, q2, c5;
|
||||
mpq_inits(p, q, p2, q2, c5, 0);
|
||||
|
||||
mpq_sub(p, x[0], y[0]);
|
||||
mpq_sub(q, x[1], y[1]);
|
||||
|
||||
/*
|
||||
want to know if p + sqrt(5) q > 0
|
||||
if p>0 and q>0: always true
|
||||
if p>0 and q<0: equivalent to |p|^2 > 5 |q|^2
|
||||
if p<0 and q>0: equivalent to |p|^2 < 5 |q|^2
|
||||
if p<0 and q<0: always false
|
||||
*/
|
||||
|
||||
if(mpq_sgn(p) > 0 && mpq_sgn(q) > 0) {
|
||||
result = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if(mpq_sgn(p) < 0 && mpq_sgn(q) < 0) {
|
||||
result = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
mpq_mul(p2, p, p);
|
||||
mpq_mul(q2, q, q);
|
||||
mpq_set_si(c5, 5, 1);
|
||||
mpq_mul(q2, q2, c5);
|
||||
|
||||
if(mpq_sgn(p) > 0)
|
||||
result = mpq_cmp(p2, q2); // this can't be zero, or else |p/q| = sqrt(5), but it's irrational
|
||||
else if(mpq_sgn(p) < 0)
|
||||
result = -mpq_cmp(p2, q2); // this can be zero if p = 0 and q = 0
|
||||
else // p = 0
|
||||
return mpq_sgn(q);
|
||||
|
||||
done:
|
||||
mpq_clears(p, q, p2, q2, c5, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef QEXT_TRIVIAL
|
||||
|
||||
#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 SET_INT(x,y) mpq_set_si(x,y,1)
|
||||
#define SET_ZERO(x) SET_INT(x,0)
|
||||
#define SET_ONE(x) SET_INT(x,1)
|
||||
#define ADD mpq_add
|
||||
#define SUB mpq_sub
|
||||
#define MULTIPLY mpq_mul
|
||||
#define MUL mpq_mul
|
||||
#define DIV mpq_div
|
||||
#define PRINT(x) gmp_printf("%Qd", x)
|
||||
|
||||
#endif
|
||||
|
||||
#define M(m,i,j) ((m)->x[(i)+(m)->n*(j)])
|
||||
|
||||
struct _mat{
|
||||
|
||||
Reference in New Issue
Block a user