r"""Find dynamic bottleneck of flux network.

    Parameters
    ----------
    F : scipy.sparse matrix
        The flux network
    A : array_like
        The set of starting states
    B : array_like
        The set of end states

    Returns
    -------
    e : tuple of int
    The edge corresponding to the dynamic bottleneck

def find_bottleneck(F, A, B):
    r"""Find dynamic bottleneck of flux network.

    Parameters
    ----------
    F : scipy.sparse matrix
        The flux network
    A : array_like
        The set of starting states
    B : array_like
        The set of end states

    Returns
    -------
    e : tuple of int
    The edge corresponding to the dynamic bottleneck

    """
    if F.nnz == 0:
        raise PathwayError('no more pathways left: Flux matrix does not contain any positive entries')
    F = F.tocoo()
    n = F.shape[0]

    """Get exdges and corresponding flux values"""
    val = F.data
    row = F.row
    col = F.col

    """Sort edges according to flux"""
    ind = np.argsort(val)
    val = val[ind]
    row = row[ind]
    col = col[ind]

    """Check if edge with largest conductivity connects A and B"""
    b = np.array(row[-1], col[-1])
    if has_path(b, A, B):
        return b
    else:
        """Bisection of flux-value array"""
        r = val.size
        l = 0
        N = 0
        while r - l > 1:
            m = np.int(np.floor(0.5 * (r + l)))
            valtmp = val[m:]
            rowtmp = row[m:]
            coltmp = col[m:]
            C = coo_matrix((valtmp, (rowtmp, coltmp)), shape=(n, n))
            """Check if there is a path connecting A and B by
            iterating over all starting nodes in A"""
            if has_connection(C, A, B):
                l = 1 * m
            else:
                r = 1 * m

        E_AB = coo_matrix((val[l + 1:], (row[l + 1:], col[l + 1:])), shape=(n, n))
        b1 = row[l]
        b2 = col[l]
        return b1, b2, E_AB