Esempio n. 1
0
void compute_core_geodesic(
    Cusp    *cusp,
    int     *singularity_index,
    Complex length[2])
{
    int         i;
    long int    positive_d,
                negative_c;
    Real      pi_over_n;

    /*
     *  If the Cusp is unfilled or the Dehn filling coefficients aren't
     *  integers, then just write in some zeros (as explained at the top
     *  of this file) and return.
     */

    if (cusp->is_complete == TRUE
     || Dehn_coefficients_are_integers(cusp) == FALSE)
    {
        *singularity_index  = 0;
        length[ultimate]    = Zero;
        length[penultimate] = Zero;

        return;
    }

    /*
     *  The euclidean_algorithm() will give the singularity index
     *  directly (as the g.c.d.), and the coefficients lead to the
     *  complex length (cf. the explanation at the top of this file).
     */

    *singularity_index = euclidean_algorithm(
                            (long int) cusp->m,
                            (long int) cusp->l,
                            &positive_d,
                            &negative_c);

    for (i = 0; i < 2; i++)     /* i = ultimate, penultimate */
    {
        /*
         *  length[i] = c H(m) + d H(l)
         *
         *  (The holonomies are already in logarithmic form.)
         */
        length[i] = complex_plus(
                complex_real_mult(
		    (Real) (double)(- negative_c),
                    cusp->holonomy[i][M]
                ),
                complex_real_mult(
		    (Real) (double) positive_d,
                    cusp->holonomy[i][L]
                )
            );

        /*
         *  Make sure the length is positive.
         */
        if (length[i].real < 0.0)
            length[i] = complex_negate(length[i]);

        /*
         *  We want to normalize the torsion to the range
         *  [-pi/n + epsilon, pi/n + epsilon], where n is
         *  the order of the singular locus.
         */

        pi_over_n = PI / *singularity_index;

        while (length[i].imag < - pi_over_n + TORSION_EPSILON)
            length[i].imag += 2.0 * pi_over_n;

        while (length[i].imag >   pi_over_n + TORSION_EPSILON)
            length[i].imag -= 2.0 * pi_over_n;

        /*
         *  In the case of a Klein bottle cusp, H(m) will be purely
         *  rotational and H(l) will be purely translational
         *  (cf. the documentation at the top of holonomy.c).
         *  But the longitude used in practice is actually the
         *  double cover of the true longitude, so we have to
         *  divide the core_length by two to compensate.
         */
        if (cusp->topology == Klein_cusp)
            length[i].real /= 2.0;

    }
}
	bool MultiplyCrypter::isKeyUnambiguous( const Restklasse& key )
	{
		return euclidean_algorithm( key.getSmallestIntegerRepresentation(), key.getModulo() ) == 1;
	}
Esempio n. 3
0
static void current_curve_basis_on_cusp(
    Cusp            *cusp,
    MatrixInt22     basis_change)
{
    int     m_int,
            l_int,
            the_gcd;
    long    a,
            b;
    Complex new_shape;
    int     multiple;
    int     i,
            j;

    m_int = (int) cusp->m;
    l_int = (int) cusp->l;

    if (cusp->is_complete == FALSE  /*  cusp is filled and          */
     && m_int == cusp->m            /*  coefficients are integers   */
     && l_int == cusp->l)
    {
        /*
         *  Find a and b such that am + bl = gcd(m, l).
         */
        the_gcd = euclidean_algorithm(m_int, l_int, &a, &b);

        /*
         *  Divide through by the g.c.d.
         */
        m_int /= the_gcd;
        l_int /= the_gcd;

        /*
         *  Set basis_change to
         *
         *               m  l
         *              -b  a
         */
        basis_change[0][0] = m_int;
        basis_change[0][1] = l_int;
        basis_change[1][0] = -b;
        basis_change[1][1] = a;

        /*
         *  Make sure the new longitude is as short as possible.
         *  The ratio (new longitude)/(new meridian) should have a
         *  real part in the interval (-1/2, +1/2].
         */

        /*
         *  Compute the new_shape, using the tentative longitude.
         */
        new_shape = transformed_cusp_shape( cusp->cusp_shape[initial],
                                            basis_change);

        /*
         *  96/10/1  There is a danger that for nonhyperbolic solutions
         *  the cusp shape will be ill-defined (either very large or NaN).
         *  However for some nonhyperbolic solutions (flat solutions
         *  for example) it may make good sense.  So we attempt to
         *  make the longitude short iff the new_shape is defined and
         *  not outrageously large;  otherwise we're content with an
         *  arbitrary longitude.
         */
        if (complex_modulus(new_shape) < BIG_MODULUS)
        {
            /*
             *  Figure out how many meridians we need to subtract
             *  from the longitude.
             */
            multiple = (int) floor(new_shape.real - (-0.5 + EPSILON));
    
            /*
             *  longitude -= multiple * meridian
             */
            for (j = 0; j < 2; j++)
                basis_change[1][j] -= multiple * basis_change[0][j];
        }
    }
    else
    {
        /*
         *  Set basis_change to the identity.
         */
        for (i = 0; i < 2; i++)
            for (j = 0; j < 2; j++)
                basis_change[i][j] = (i == j);
    }
}