home *** CD-ROM | disk | FTP | other *** search
- #include "options.h"
- #include "complex.h"
- #include "projective.h"
-
- /* sl2c_to_proj() converts sl2c_matrices to proj_matrices. It is based on
- an explanation provided by Craig Hodgson of a program written by
- Diane Hoffoss which in turn was based on an algorithm explained to her
- by Bill Thurston. */
-
- void sl2c_to_proj(s, p)
- sl2c_matrix s;
- proj_matrix p;
- {
- int j; /* which column of p */
- sl2c_matrix ad_s, /* s* = adjoint of s */
- fs, /* f(s) = s m s* */
- temp;
- static sl2c_matrix m[4] = {{{{ 0.0, 0.0},{ 0.0, 1.0}},
- {{ 0.0,-1.0},{ 0.0, 0.0}}},
-
- {{{ 0.0, 0.0},{ 1.0, 0.0}},
- {{ 1.0, 0.0},{ 0.0, 0.0}}},
-
- {{{-1.0, 0.0},{ 0.0, 0.0}},
- {{ 0.0, 0.0},{ 1.0, 0.0}}},
-
- {{{ 1.0, 0.0},{ 0.0, 0.0}},
- {{ 0.0, 0.0},{ 1.0, 0.0}}}};
-
- for (j=0; j<4; j++) {
- sl2c_adjoint(s, ad_s);
- sl2c_mult(s, m[j], temp);
- sl2c_mult(temp, ad_s, fs);
- p[0][j] = fs[0][1].imag;
- p[1][j] = fs[0][1].real;
- p[2][j] = 0.5 * (fs[1][1].real - fs[0][0].real);
- p[3][j] = 0.5 * (fs[1][1].real + fs[0][0].real);
- }
-
- return;
- }
-
-
- void proj_to_sl2c(p, s)
- proj_matrix p;
- sl2c_matrix s;
- {
- double t2,
- t3,
- aa,
- bb;
-
- /* Notation: The entries of s are a, b, c, d (as is standard). */
- /* The complex conjugate of a is written as a' (read "a-bar"). */
-
- /* Outline of algorithm: Write down the four matrices {sM0s*, */
- /* sM1s*, sM2s*, sM3s*} in terms of {a, b, c, d}, and find */
- /* expressions for {2a'a, 2a'b, 2a'c, 2a'd} as differences of */
- /* matrix entries. Express these differences as functions of */
- /* the entries of p. The matrix (2a'a, 2a'b; 2a'c, 2a'd) is a */
- /* multiple of the desired matrix (a, b; c, d), so when we */
- /* normalize the former we get the latter (we'd have to */
- /* normalize in any case, since this scheme can find */
- /* (a, b; c, d) only up to multiplication by a complex number */
- /* of modulus one). */
-
- /* a may be zero, but a and b can't both be zero. We'll use */
- /* the one with the bigger norm. */
-
- t2 = p[3][2] - p[2][2]; /* 00 entry of F(M2) */
- t3 = p[3][3] - p[2][3]; /* 00 entry of F(M3) */
- aa = t3 - t2; /* aa = 2 * |a|^2 */
- bb = t3 + t2; /* bb = 2 * |b|^2 */
- if (aa > bb) {
- s[0][0].real = aa;
- s[0][0].imag = 0.0;
- s[0][1].real = p[3][1] - p[2][1];
- s[0][1].imag = p[3][0] - p[2][0];
- s[1][0].real = p[1][3] - p[1][2];
- s[1][0].imag = p[0][2] - p[0][3];
- s[1][1].real = p[0][0] + p[1][1];
- s[1][1].imag = p[1][0] - p[0][1];
- }
- else {
- s[0][0].real = p[3][1] - p[2][1];
- s[0][0].imag = p[2][0] - p[3][0];
- s[0][1].real = bb;
- s[0][1].imag = 0.0;
- s[1][0].real = p[1][1] - p[0][0];
- s[1][0].imag = - p[0][1] - p[1][0];
- s[1][1].real = p[1][3] + p[1][2];
- s[1][1].imag = - p[0][2] - p[0][3];
- }
-
- sl2c_normalize(s);
-
- return;
- }
-
-
- void proj_mult(a, b, product)
- proj_matrix a,
- b,
- product;
- {
- register int i,
- j,
- k;
- register double sum;
- proj_matrix temp;
-
- for (i=0; i<4; i++)
- for (j=0; j<4; j++) {
- sum = 0.0;
- for (k=0; k<4; k++)
- sum += a[i][k] * b[k][j];
- temp[i][j] = sum;
- }
-
- for (i=0; i<4; i++)
- for (j=0; j<4; j++)
- product[i][j] = temp[i][j];
-
- return;
- }
-
-
- void proj_copy(a, b)
- proj_matrix a,
- b;
- {
- register int i,
- j;
-
- for (i=0; i<4; i++)
- for (j=0; j<4; j++)
- a[i][j] = b[i][j];
-
- return;
- }
-
-
- /* proj_invert() assumes the matrix a is nonsingular, as will always */
- /* be the case for matrices representing isometries of H^3. */
-
- void proj_invert(m, m_inv)
- proj_matrix m,
- m_inv;
- {
- int i, j, k;
- double scratch[4][8],
- *a[4],
- *temp;
-
- /* set up */
- for (i=4; --i>=0; ) {
- for (j=4; --j>=0; ) {
- scratch[i][j] = m[i][j];
- scratch[i][j+4] = (i == j) ? 1.0 : 0.0;
- }
- a[i] = scratch[i];
- }
-
- /* do the forward part of Gaussian elimination */
- for (j=0; j<4; j++) {
- /* find the best pivot */
- for (i=j+1; i<4; i++)
- if (fabs(a[i][j]) > fabs(a[j][j])) {
- temp = a[i];
- a[i] = a[j];
- a[j] = temp;
- }
-
- /* normalize row j */
- for (i=j+1; i<8; i++)
- a[j][i] /= a[j][j];
-
- /* clear the lower part of column j */
- for (i=j+1; i<4; i++)
- for (k=j+1; k<8; k++)
- a[i][k] -= a[i][j] * a[j][k];
- }
-
- /* do the back substitution */
- for (j=4; --j>=0; )
- for (i=j; --i>=0; )
- for (k=4; k<8; k++)
- a[i][k] -= a[i][j] * a[j][k];
-
- /* copy the answer into m_inv */
- for (i=4; --i>=0; )
- for (j=4; --j>=0; )
- m_inv[i][j] = a[i][j+4];
-
- return;
- }
-
-