Пример #1
0
FuncResult compute_symmetry_group(
    Triangulation   *manifold,
    SymmetryGroup   **symmetry_group_of_manifold,
    SymmetryGroup   **symmetry_group_of_link,
    Triangulation   **symmetric_triangulation,
    Boolean         *is_full_group)
{
    Triangulation   *simplified_manifold;
    FuncResult      result;

    /*
     *  Make sure the variables used to pass back our results
     *  are all initially empty.
     */
    if (*symmetry_group_of_manifold != NULL
     || *symmetry_group_of_link     != NULL
     || *symmetric_triangulation    != NULL)
        uFatalError("compute_symmetry_group", "symmetry_group");

    /*
     *  If the space isn't a manifold, return func_bad_input.
     */
    if (all_Dehn_coefficients_are_relatively_prime_integers(manifold) == FALSE)
        return func_bad_input;

    /*
     *  Whether the manifold is cusped or not, we want to begin
     *  by getting rid of "unnecessary" cusps.
     */
    simplified_manifold = fill_reasonable_cusps(manifold);
    if (simplified_manifold == NULL)
        return func_failed;

    /*
     *  Split into cases according to whether the manifold is
     *  closed or cusped (i.e. whether all cusps are filled or not).
     */
    if (all_cusps_are_filled(simplified_manifold) == TRUE)
        result = compute_closed_symmetry_group(
                                    simplified_manifold,
                                    symmetry_group_of_manifold,
                                    symmetric_triangulation,
                                    is_full_group);
    else
    {
        result = compute_cusped_symmetry_group(
                                    simplified_manifold,
                                    symmetry_group_of_manifold,
                                    symmetry_group_of_link);
        *is_full_group = TRUE;
    }

    free_triangulation(simplified_manifold);

    return result;
}
Пример #2
0
FuncResult compute_isometries(
	Triangulation	*manifold0,
	Triangulation	*manifold1,
	Boolean			*are_isometric,
	IsometryList	**isometry_list,
	IsometryList	**isometry_list_of_links)
{
	Triangulation	*simplified_manifold0,
					*simplified_manifold1;
	IsometryList	*the_isometry_list,
					*the_isometry_list_of_links;
	FuncResult		result;

	/*
	 *	Make sure the variables used to pass back our results
	 *	are initially empty.
	 */

	if ((isometry_list          != NULL && *isometry_list          != NULL)
	 || (isometry_list_of_links != NULL && *isometry_list_of_links != NULL))
		uFatalError("compute_isometries", "isometry");

	/*
	 *	If one of the spaces isn't a manifold, return func_bad_input.
	 */

	if (all_Dehn_coefficients_are_relatively_prime_integers(manifold0) == FALSE
	 || all_Dehn_coefficients_are_relatively_prime_integers(manifold1) == FALSE)
		return func_bad_input;

	/*
	 *	Check whether the manifolds are obviously nonhomeomorphic.
	 *
	 *	(In the interest of a robust, beyond-a-shadow-of-a-doubt algorithm,
	 *	stick to discrete invariants like the number of cusps and the
	 *	first homology group, and avoid real-valued invariants like
	 *	the volume which require judging when two floating point numbers
	 *	are equal.)  [96/12/6  Comparing canonical triangulations
	 *	relies on having at least a vaguely correct hyperbolic structure,
	 *	so it should be safe to reject manifolds whose volumes differ
	 *	by more than, say, 0.01.]
	 */

	if (count_unfilled_cusps(manifold0) != count_unfilled_cusps(manifold1)
	 || same_homology(manifold0, manifold1) == FALSE
	 || (	manifold0->solution_type[filled] == geometric_solution
		 && manifold1->solution_type[filled] == geometric_solution
	 	 && fabs(volume(manifold0, NULL) - volume(manifold1, NULL)) > CRUDE_VOLUME_EPSILON))
	{
		*are_isometric = FALSE;
		return func_OK;
	}

	/*
	 *	Whether the actual manifolds (after taking into account Dehn
	 *	fillings) have cusps or not, we want to begin by getting rid
	 *	of "unnecessary" cusps.
	 */

	simplified_manifold0 = fill_reasonable_cusps(manifold0);
	if (simplified_manifold0 == NULL)
		return func_failed;

	simplified_manifold1 = fill_reasonable_cusps(manifold1);
	if (simplified_manifold1 == NULL)
		return func_failed;

	/*
	 *	Split into cases according to whether the manifolds are
	 *	closed or cusped (i.e. whether all cusps are filled or not).
	 *	The above tests insure that either both are closed or both
	 *	are cusped.
	 */

	if (all_cusps_are_filled(simplified_manifold0) == TRUE)

		result = compute_closed_isometry(	simplified_manifold0,
											simplified_manifold1,
											are_isometric);
	else
	{
		result = compute_cusped_isometries(	simplified_manifold0,
											simplified_manifold1,
											&the_isometry_list,
											&the_isometry_list_of_links);
		if (result == func_OK)
		{
			*are_isometric = the_isometry_list->num_isometries > 0;

			if (isometry_list != NULL)
				*isometry_list = the_isometry_list;
			else
				free_isometry_list(the_isometry_list);

			if (isometry_list_of_links != NULL)
				*isometry_list_of_links = the_isometry_list_of_links;
			else
				free_isometry_list(the_isometry_list_of_links);
		}
	}

	/*
	 *	We no longer need the simplified manifolds.
	 */
	free_triangulation(simplified_manifold0);
	free_triangulation(simplified_manifold1);

	return result;
}
Пример #3
0
FuncResult compute_closed_symmetry_group(
    Triangulation   *manifold,
    SymmetryGroup   **symmetry_group,
    Triangulation   **symmetric_triangulation,
    Boolean         *is_full_group)
{
    FuncResult  result;

    /*
     *  Make sure the variables used to pass back our results
     *  are all initially empty.
     */
    if (*symmetry_group             != NULL
     || *symmetric_triangulation    != NULL)
        uFatalError("compute_closed_symmetry_group", "symmetry_group");

    /*
     *  compute_symmetry_group() should have passed us a 1-cusp
     *  manifold with a Dehn filling on its cusp.
     */
    if (get_num_cusps(manifold) != 1
     || all_cusps_are_filled(manifold) == FALSE
     || all_Dehn_coefficients_are_relatively_prime_integers(manifold) == FALSE)
    {
        uFatalError("compute_closed_symmetry_group", "symmetry_group_closed");
    }

    /*
     *  For later convenience, change the basis on the cusp
     *  so that the Dehn filling curve becomes a meridian.
     */
    {
        MatrixInt22     basis_change[1];

        current_curve_basis(manifold, 0, basis_change[0]);
        change_peripheral_curves(manifold, basis_change);
    }

    /*
     *  At the very least, we can try to establish a (possibly trivial)
     *  lower bound on the symmetry group by computing the group
     *  which preserves the given core geodesic.
     */
    {
        SymmetryGroup   *dummy = NULL;

        if (compute_cusped_symmetry_group(manifold, &dummy, symmetry_group) == func_OK)
        {
            copy_triangulation(manifold, symmetric_triangulation);
            free_symmetry_group(dummy);     /*  we don't need dummy */
        }
        else
        {
            /*
             *  The only way compute_cusped_symmetry_group() may fail
             *  is if a canonical cell decomposition cannot be found,
             *  e.g. because the manifold is not hyperbolic.
             */
            return func_failed;
        }
    }

    /*
     *  For small to medium sized manifolds we should have
     *  no trouble getting a Dirichlet domain.  But if we can't,
     *  then we want to muddle along as best we can without one.
     */
    {
        WEPolyhedron    *polyhedron;

        polyhedron = compute_polyhedron(manifold);

        if (polyhedron != NULL)
        {
            result = compute_symmetry_group_using_polyhedron(
                                                manifold,
                                                symmetry_group,
                                                symmetric_triangulation,
                                                is_full_group,
                                                polyhedron);
            free_Dirichlet_domain(polyhedron);
        }
        else
            result = compute_symmetry_group_without_polyhedron(
                                                manifold,
                                                symmetry_group,
                                                symmetric_triangulation,
                                                is_full_group);
    }

    return result;
}