void precise_generators( MatrixPairList *gen_list) { MatrixPair *matrix_pair; for (matrix_pair = gen_list->begin.next; matrix_pair != &gen_list->end; matrix_pair = matrix_pair->next) { precise_matrix(matrix_pair->m[0]); o31_invert(matrix_pair->m[0], matrix_pair->m[1]); } }
void conjugate_matrices( MatrixPairList *gen_list, double displacement[3]) { /* * We want to conjugate each MatrixPair on the gen_list so as to move * the basepoint the distance given by the displacement. The * displacement, which is a translation (dx, dy, dz) in the tangent * space to H^3 at (1, 0, 0, 0), is a linear approximation to where the * basepoint ought to be. * * It won't do simply to conjugate by the matrix T1 = * * 1 dx dy dz * dx 1 0 0 * dy 0 1 0 * dz 0 0 1 * * Even though T1 is a linear approximation to the desired translation, * it's columns are not quite orthonormal (they are orthonormal to a * first order approximation, but not exactly). We need to use a * translation matrix which is exactly orthonormal, so that the * MatrixPairs on the gen_list remain elements of O(3,1) to full * accuracy. * * One approach would be to apply the Gram-Schmidt process to find an * element of O(3,1) close to T1. The problem here is that the * Gram-Schmidt process itself may introduce additional error. * * Better to start instead with a second order approximation to the * translation matrix, given by T2 = * * 1 + (dx^2 + dy^2 + dz^2)/2 dx dy dz * dx 1 + (dx^2)/2 (dx dy)/2 (dx dz)/2 * dy (dx dy)/2 1 + (dy^2)/2 (dy dz)/2 * dz (dx dz)/2 (dy dz)/2 1 + (dz^2)/2 * * Note that T2 is actually orthonormal to third order; that is, * its columns fail to be orthonormal only by fourth order terms. * * We will start with the second order approximation T2 and apply * Gram-Schmidt to it. The correction terms -- all of fourth order -- * will not significantly affect the closeness of the approximation. * * Digression. * * You may be wondering where the matrix T2 came from. * Drop down a dimension, and consider the product of a translation * (dx, 0) and a translation (0, dy). The result you get depends * on the order of the factors. * * ( 1 dx 0) ( 1 0 dy) ( 1 dx dy ) * ( dx 1 0) ( 0 1 0 ) = ( dx 1 dxdy) * ( 0 0 1) ( dy 0 1 ) ( dy 0 1 ) * * ( 1 0 dy) ( 1 dx 0) ( 1 dx dy ) * ( 0 1 0 ) ( dx 1 0) = ( dx 1 0 ) * ( dy 0 1 ) ( 0 0 1) ( dy dxdy 1 ) * * Averaging the two results leads to the matrix T2 shown above. * * End of digression. */ O31Matrix t2; MatrixPair *matrix_pair; /* * Initialize t2 to be the second order approximation shown above. */ initialize_t2(displacement, t2); /* * Apply the Gram-Schmidt process to bring t2 to a nearby element * of O(3,1). */ o31_GramSchmidt(t2); /* * For each MatrixPair on gen_list . . . */ for (matrix_pair = gen_list->begin.next; matrix_pair != &gen_list->end; matrix_pair = matrix_pair->next) { /* * Conjugate m[0] by t2. * That is, replace m[0] by (t2^-1) m[0] t2. */ o31_conjugate(matrix_pair->m[0], t2, matrix_pair->m[0]); /* * Recompute m[1] as the inverse of m[0]. */ o31_invert(matrix_pair->m[0], matrix_pair->m[1]); /* * Set the height. */ matrix_pair->height = matrix_pair->m[0][0][0]; } }