def mixture(
    val: Any, default: Any = RaiseTypeErrorIfNotProvided
) -> Sequence[tuple[float, np.ndarray]]:
    """Return a sequence of tuples representing a probabilistic unitary.

    A mixture is described by an iterable of tuples of the form

        (probability of unitary, unitary as numpy array)

    The probability components of the tuples must sum to 1.0 and be
    non-negative.

    Args:
        val: The value to decompose into a mixture of unitaries.
        default: A default value if val does not support mixture.

    Returns:
        An iterable of tuples of size 2. The first element of the tuple is a
        probability (between 0 and 1) and the second is the object that occurs
        with that probability in the mixture. The probabilities will sum to 1.0.

    Raises:
        TypeError: If `val` has no `_mixture_` or `_unitary_` method, or if it
            does and this method returned `NotImplemented`.
    """

    mixture_getter = getattr(val, '_mixture_', None)
    result = NotImplemented if mixture_getter is None else mixture_getter()
    if result is not NotImplemented and result is not None:
        return tuple((p, u if isinstance(u, np.ndarray) else unitary(u)) for p, u in result)

    unitary_getter = getattr(val, '_unitary_', None)
    result = NotImplemented if unitary_getter is None else unitary_getter()
    if result is not NotImplemented:
        return ((1.0, result),)

    if default is not RaiseTypeErrorIfNotProvided:
        return default

    if mixture_getter is None and unitary_getter is None:
        raise TypeError(f"object of type '{type(val)}' has no _mixture_ or _unitary_ method.")

    raise TypeError(
        f"object of type '{type(val)}' does have a _mixture_ or _unitary_ "
        "method, but it returned NotImplemented."
    )
Return a sequence of tuples representing a probabilistic unitary.

    A mixture is described by an iterable of tuples of the form

        (probability of unitary, unitary as numpy array)

    The probability components of the tuples must sum to 1.0 and be
    non-negative.

    Args:
        val: The value to decompose into a mixture of unitaries.
        default: A default value if val does not support mixture.

    Returns:
        An iterable of tuples of size 2. The first element of the tuple is a
        probability (between 0 and 1) and the second is the object that occurs
        with that probability in the mixture. The probabilities will sum to 1.0.

    Raises:
        TypeError: If `val` has no `_mixture_` or `_unitary_` method, or if it
            does and this method returned `NotImplemented`.
    
cirq-core/cirq/protocols/mixture_protocol.py