Example #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;
}
Example #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;
}