Repository: scipy/scipy
File: scipy/linalg/_special_matrices.py (Python)

Code before:
    >>> from scipy.linalg import leslie
    >>> leslie([0.1, 2.0, 1.0, 0.1], [0.2, 0.8, 0.7])
    array([[ 0.1,  2. ,  1. ,  0.1],
           [ 0.2,  0. ,  0. ,  0. ],
           [ 0. ,  0.8,  0. ,  0. ],
           [ 0. ,  0. ,  0.7,  0. ]])

    """
    f = np.atleast_1d(f)
    s = np.atleast_1d(s)

    if f.shape[-1] != s.shape[-1] + 1:
        raise ValueError("Incorrect lengths for f and s. The length of s along "
                         "the last axis must be one less than the length of f.")
    if s.shape[-1] == 0:
        raise ValueError("The length of s must be at least 1.")

    n = f.shape[-1]
    tmp = f[0] + s[0]
    a = np.zeros((n, n), dtype=tmp.dtype)
    a[0] = f
    a[list(range(1, n)), list(range(0, n - 1))] = s
    return a


@xp_capabilities(jax_jit=False, skip_backends=[("dask.array", "dask/dask#1180")])
def block_diag(*arrs):
    """
    Create a block diagonal array from provided arrays.

    For example, given 2-D inputs `A`, `B` and `C`, the output will have these
    arrays arranged on the diagonal::

        [[A, 0, 0],
         [0, B, 0],
         [0, 0, C]]

    Parameters
    ----------
    A, B, C, ... : array_like
        Input arrays.  A 1-D array or array_like sequence of length ``n`` is
        treated as a 2-D array with shape ``(1, n)``. Any dimensions before
        the last two are treated as batch dimensions; see :ref:`linalg_batch`.

    Returns
    -------
    D : ndarray
        Array with `A`, `B`, `C`, ... on the diagonal of the last two
        dimensions. `D` has the same dtype as the result type of the
        inputs.


Review comment (bug):
>I think Dask can skip the test.

One test of a degenerate case fails due to a bug in Dask. I'd suggest that we skip the test rather than skipping all tests. I know this will mark Dask as supported, and I think that's OK. Dask is supported; Dask just happens to have a bug. 

Code after:
    >>> from scipy.linalg import leslie
    >>> leslie([0.1, 2.0, 1.0, 0.1], [0.2, 0.8, 0.7])
    array([[ 0.1,  2. ,  1. ,  0.1],
           [ 0.2,  0. ,  0. ,  0. ],
           [ 0. ,  0.8,  0. ,  0. ],
           [ 0. ,  0. ,  0.7,  0. ]])

    """
    f = np.atleast_1d(f)
    s = np.atleast_1d(s)

    if f.shape[-1] != s.shape[-1] + 1:
        raise ValueError("Incorrect lengths for f and s. The length of s along "
                         "the last axis must be one less than the length of f.")
    if s.shape[-1] == 0:
        raise ValueError("The length of s must be at least 1.")

    n = f.shape[-1]
    tmp = f[0] + s[0]
    a = np.zeros((n, n), dtype=tmp.dtype)
    a[0] = f
    a[list(range(1, n)), list(range(0, n - 1))] = s
    return a


@xp_capabilities(jax_jit=False, allow_dask_compute=2)
def block_diag(*arrs):
    """
    Create a block diagonal array from provided arrays.

    For example, given 2-D inputs `A`, `B` and `C`, the output will have these
    arrays arranged on the diagonal::

        [[A, 0, 0],
         [0, B, 0],
         [0, 0, C]]

    Parameters
    ----------
    A, B, C, ... : array_like
        Input arrays.  A 1-D array or array_like sequence of length ``n`` is
        treated as a 2-D array with shape ``(1, n)``. Any dimensions before
        the last two are treated as batch dimensions; see :ref:`linalg_batch`.

    Returns
    -------
    D : ndarray
        Array with `A`, `B`, `C`, ... on the diagonal of the last two
        dimensions. `D` has the same dtype as the result type of the
        inputs.