def equal_up_to_global_phase(val: Any, other: Any, *, atol: Union[(int, float)]=1e-08) -> bool:
    'Determine whether two objects are equal up to global phase.\n\n    If `val` implements a `_equal_up_to_global_phase_` method then it is\n    invoked and takes precedence over all other checks:\n     - For complex primitive type the magnitudes of the values are compared.\n     - For `val` and `other` both iterable of the same length, consecutive\n       elements are compared recursively. Types of `val` and `other` does not\n       necessarily needs to match each other. They just need to be iterable and\n       have the same structure.\n     - For all other types, fall back to `_approx_eq_`\n\n    Args:\n        val: Source object for approximate comparison.\n        other: Target object for approximate comparison.\n        atol: The minimum absolute tolerance. This places an upper bound on\n        the differences in *magnitudes* of two compared complex numbers.\n\n    Returns:\n        True if objects are approximately equal up to phase, False otherwise.\n    '
    eq_up_to_phase_getter = getattr(val, '_equal_up_to_global_phase_', None)
    if (eq_up_to_phase_getter is not None):
        result = eq_up_to_phase_getter(other, atol)
        if (result is not NotImplemented):
            return result
    other_eq_up_to_phase_getter = getattr(other, '_equal_up_to_global_phase_', None)
    if (other_eq_up_to_phase_getter is not None):
        result = other_eq_up_to_phase_getter(val, atol)
        if (result is not NotImplemented):
            return result
    if (isinstance(val, Iterable) and isinstance(other, Iterable)):
        a = np.asarray(val)
        b = np.asarray(other)
        if ((a.dtype.kind in 'uifc') and (b.dtype.kind in 'uifc')):
            return linalg.allclose_up_to_global_phase(a, b, atol=atol)
    if (isinstance(val, numbers.Number) and isinstance(other, numbers.Number)):
        result = approx_eq(abs(val), abs(other), atol=atol)
        if (result is not NotImplemented):
            return result
    return approx_eq(val, other, atol=atol)
Determine whether two objects are equal up to global phase.

If `val` implements a `_equal_up_to_global_phase_` method then it is
invoked and takes precedence over all other checks:
 - For complex primitive type the magnitudes of the values are compared.
 - For `val` and `other` both iterable of the same length, consecutive
   elements are compared recursively. Types of `val` and `other` does not
   necessarily needs to match each other. They just need to be iterable and
   have the same structure.
 - For all other types, fall back to `_approx_eq_`

Args:
    val: Source object for approximate comparison.
    other: Target object for approximate comparison.
    atol: The minimum absolute tolerance. This places an upper bound on
    the differences in *magnitudes* of two compared complex numbers.

Returns:
    True if objects are approximately equal up to phase, False otherwise.
def equal_up_to_global_phase(val: Any, other: Any, *, atol: Union[(int, float)]=1e-08) -> bool:
    'Determine whether two objects are equal up to global phase.\n\n    If `val` implements a `_equal_up_to_global_phase_` method then it is\n    invoked and takes precedence over all other checks:\n     - For complex primitive type the magnitudes of the values are compared.\n     - For `val` and `other` both iterable of the same length, consecutive\n       elements are compared recursively. Types of `val` and `other` does not\n       necessarily needs to match each other. They just need to be iterable and\n       have the same structure.\n     - For all other types, fall back to `_approx_eq_`\n\n    Args:\n        val: Source object for approximate comparison.\n        other: Target object for approximate comparison.\n        atol: The minimum absolute tolerance. This places an upper bound on\n        the differences in *magnitudes* of two compared complex numbers.\n\n    Returns:\n        True if objects are approximately equal up to phase, False otherwise.\n    '
    eq_up_to_phase_getter = getattr(val, '_equal_up_to_global_phase_', None)
    if (eq_up_to_phase_getter is not None):
        result = eq_up_to_phase_getter(other, atol)
        if (result is not NotImplemented):
            return result
    other_eq_up_to_phase_getter = getattr(other, '_equal_up_to_global_phase_', None)
    if (other_eq_up_to_phase_getter is not None):
        result = other_eq_up_to_phase_getter(val, atol)
        if (result is not NotImplemented):
            return result
    if (isinstance(val, Iterable) and isinstance(other, Iterable)):
        a = np.asarray(val)
        b = np.asarray(other)
        if ((a.dtype.kind in 'uifc') and (b.dtype.kind in 'uifc')):
            return linalg.allclose_up_to_global_phase(a, b, atol=atol)
    if (isinstance(val, numbers.Number) and isinstance(other, numbers.Number)):
        result = approx_eq(abs(val), abs(other), atol=atol)
        if (result is not NotImplemented):
            return result
    return approx_eq(val, other, atol=atol)