Repository: pymc-devs/pytensor

Issue:
BUG: `convolve1d` `mode="same"` indexing error
### Describe the issue:

The new rewrite of `convolve1d` in https://github.com/pymc-devs/pytensor/pull/1318 and discussed in https://github.com/pymc-devs/pytensor/issues/1319 introduced a bug for `mode="same"`. The documentation says:

```
        A string indicating the size of the output:
        - 'full': The output is the full discrete linear convolution of the inputs, with shape (..., N+M-1,).
        - 'valid': The output consists only of elements that do not rely on zero-padding, with shape (..., max(N, M) - min(N, M) + 1,).
        - 'same': The output is the same size as in1, centered with respect to the 'full' output.
 ```

Here it is the *first* axis of `in2` that is compared for padding, rather than the intended *last* axis.
https://github.com/pymc-devs/pytensor/blob/3af923ba1593320cf0a5bfb29a04263406652731/pytensor/tensor/signal/conv.py#L119-L130

### Reproducable code example:

```python
from pytensor.tensor import matrix, vector
from pytensor.tensor.signal.conv import convolve1d

def test_convolve1d_same():
    x = matrix("data")
    y = matrix("kernel")
    out = convolve1d(x, y, mode="same")

    rng = np.random.default_rng(38)
    x_test = rng.normal(size=(2, 8)).astype(x.dtype)
    y_test = rng.normal(size=(2, 8)).astype(x.dtype)

    res = out.eval({x: x_test, y: y_test})
    assert res.shape == (2, 8)
```

### Error message:

```shell

```

### PyTensor version information:

2.30.1

### Context for the issue:

_No response_

Hints from issue comments:
@jessegrabowski: Closed by #1337 

Solution patch:
diff --git a/pytensor/tensor/signal/conv.py b/pytensor/tensor/signal/conv.py
index 1152f02d8..ab2856b69 100644
--- a/pytensor/tensor/signal/conv.py
+++ b/pytensor/tensor/signal/conv.py
@@ -119,8 +119,8 @@ def convolve1d(
     if mode == "same":
         # We implement "same" as "valid" with padded `in1`.
         in1_batch_shape = tuple(in1.shape)[:-1]
-        zeros_left = in2.shape[0] // 2
-        zeros_right = (in2.shape[0] - 1) // 2
+        zeros_left = in2.shape[-1] // 2
+        zeros_right = (in2.shape[-1] - 1) // 2
         in1 = join(
             -1,
             zeros((*in1_batch_shape, zeros_left), dtype=in2.dtype),


Test patch:
diff --git a/tests/tensor/signal/test_conv.py b/tests/tensor/signal/test_conv.py
index 968e40848..fe353b18f 100644
--- a/tests/tensor/signal/test_conv.py
+++ b/tests/tensor/signal/test_conv.py
@@ -47,3 +47,16 @@ def test_convolve1d_batch():
     res_np = np.convolve(x_test[0], y_test[0])
     np.testing.assert_allclose(res[0], res_np, rtol=rtol)
     np.testing.assert_allclose(res[1], res_np, rtol=rtol)
+
+
+def test_convolve1d_batch_same():
+    x = matrix("data")
+    y = matrix("kernel")
+    out = convolve1d(x, y, mode="same")
+
+    rng = np.random.default_rng(38)
+    x_test = rng.normal(size=(2, 8)).astype(x.dtype)
+    y_test = rng.normal(size=(2, 8)).astype(x.dtype)
+
+    res = out.eval({x: x_test, y: y_test})
+    assert res.shape == (2, 8)