Repository: scipy/scipy
File: scipy/signal/_signaltools.py (Python)

Code before:
    b = np.atleast_1d(b)
    a = np.atleast_1d(a)
    x = np.asarray(x)
    if zi is not None:
       zi = np.asarray(zi)

    if not (b.ndim == 1 and xp_size(b) > 0):
        raise ValueError(f"Parameter b is not a non-empty 1d array, since {b.shape=}!")
    if not (a.ndim == 1 and xp_size(a) > 0):
        raise ValueError(f"Parameter a is not a non-empty 1d array, since {a.shape=}!")

    if len(a) == 1:
        # This path only supports types fdgFDGO to mirror _linear_filter below.
        # Any of b, a, x, or zi can set the dtype, but there is no default
        # casting of other types; instead a NotImplementedError is raised.
        b = np.asarray(b)
        a = np.asarray(a)
        x = _validate_x(x)
        inputs = [b, a, x]
        if zi is not None:
            # _linear_filter does not broadcast zi, but does do expansion of
            # singleton dims.
            zi = np.asarray(zi)
            if zi.ndim != x.ndim:
                raise ValueError("Dimensions of parameters x and zi must match, but " +
                                 f"{x.ndim=}, {zi.ndim=}!")
            expected_shape = list(x.shape)
            expected_shape[axis] = b.shape[0] - 1
            expected_shape = tuple(expected_shape)
            # check the trivial case where zi is the right shape first
            if zi.shape != expected_shape:
                strides = zi.ndim * [None]
                if axis < 0:
                    axis += zi.ndim
                for k in range(zi.ndim):
                    if k == axis and zi.shape[k] == expected_shape[k]:
                        strides[k] = zi.strides[k]
                    elif k != axis and zi.shape[k] == expected_shape[k]:
                        strides[k] = zi.strides[k]
                    elif k != axis and zi.shape[k] == 1:
                        strides[k] = 0
                    else:
                        raise ValueError('Unexpected shape for parameter zi: expected '
                                         f'{expected_shape}, found {zi.shape}.')
                zi = np.lib.stride_tricks.as_strided(zi, expected_shape,
                                                     strides)
            inputs.append(zi)
        dtype = np.result_type(*inputs)

        if dtype.char not in 'fdgFDGO':
            p_types = tuple(p_.dtype.char for p_ in inputs)

Review comment (suggestion):
I think this should be something like:
```python
f"x.ndim={x.ndim}, zi.ndim={zi.ndim}!")
```

Code after:
    b = np.atleast_1d(b)
    a = np.atleast_1d(a)
    x = np.asarray(x)
    if zi is not None:
       zi = np.asarray(zi)

    if not (b.ndim == 1 and xp_size(b) > 0):
        raise ValueError(f"Parameter b is not a non-empty 1d array, since {b.shape=}!")
    if not (a.ndim == 1 and xp_size(a) > 0):
        raise ValueError(f"Parameter a is not a non-empty 1d array, since {a.shape=}!")

    if len(a) == 1:
        # This path only supports types fdgFDGO to mirror _linear_filter below.
        # Any of b, a, x, or zi can set the dtype, but there is no default
        # casting of other types; instead a NotImplementedError is raised.
        b = np.asarray(b)
        a = np.asarray(a)
        x = _validate_x(x)
        inputs = [b, a, x]
        if zi is not None:
            # _linear_filter does not broadcast zi, but does do expansion of
            # singleton dims.
            zi = np.asarray(zi)
            if zi.ndim != x.ndim:
                raise ValueError("Dimensions of parameters x and zi must match, but " +
                                 f"{x.ndim=}, {zi.ndim=}!")
            expected_shape = list(x.shape)
            expected_shape[axis] = b.shape[0] - 1
            expected_shape = tuple(expected_shape)
            # check the trivial case where zi is the right shape first
            if zi.shape != expected_shape:
                strides = zi.ndim * [None]
                if axis < 0:
                    axis += zi.ndim
                for k in range(zi.ndim):
                    if k == axis and zi.shape[k] == expected_shape[k]:
                        strides[k] = zi.strides[k]
                    elif k != axis and zi.shape[k] == expected_shape[k]:
                        strides[k] = zi.strides[k]
                    elif k != axis and zi.shape[k] == 1:
                        strides[k] = 0
                    else:
                        raise ValueError('Unexpected shape for parameter zi: expected '
                                         f'{expected_shape}, found {zi.shape}.')
                zi = np.lib.stride_tricks.as_strided(zi, expected_shape,
                                                     strides)
            inputs.append(zi)
        dtype = np.result_type(*inputs)

        if dtype.char not in 'fdgFDGO':
            raise NotImplementedError("Parameter's dtypes produced result type " +