Skip to content

Commit a5d065f

Browse files
committed
fix: validate convolution filter dimensions and unique axes
1 parent 3747492 commit a5d065f

2 files changed

Lines changed: 54 additions & 0 deletions

File tree

‎pylops/signalprocessing/convolvend.py‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ class ConvolveND(LinearOperator):
6464
shape : :obj:`tuple`
6565
Operator shape.
6666
67+
Raises
68+
------
69+
ValueError
70+
If ``h`` has more dimensions than ``dims``, or ``axes`` does not
71+
contain one unique model axis per filter dimension.
72+
6773
Notes
6874
-----
6975
The ConvolveND operator applies n-dimensional convolution
@@ -85,6 +91,9 @@ def __init__(
8591
name: str = "C",
8692
):
8793
dims = _value_or_sized_to_tuple(dims)
94+
if h.ndim > len(dims):
95+
msg = "h cannot have more dimensions than dims"
96+
raise ValueError(msg)
8897
super().__init__(dtype=np.dtype(dtype), dims=dims, dimsd=dims, name=name)
8998

9099
self.axes = (
@@ -94,6 +103,12 @@ def __init__(
94103
[get_normalize_axis_index()(ax, len(self.dims)) for ax in axes]
95104
)
96105
)
106+
if len(self.axes) != h.ndim:
107+
msg = "axes must contain one axis per dimension of h"
108+
raise ValueError(msg)
109+
if len(set(self.axes)) != len(self.axes):
110+
msg = "axes must be unique"
111+
raise ValueError(msg)
97112
self.h = h
98113
hshape = np.array(self.h.shape)
99114

‎pytests/test_convolve.py‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
from pylops.signalprocessing import Convolve1D, Convolve2D, ConvolveND
2121
from pylops.utils import dottest
2222

23+
np.random.seed(10)
24+
2325
# filters
2426
nfilt = (5, 6, 5)
2527
h1 = triang(nfilt[0], sym=True)
@@ -195,6 +197,43 @@ def test_Convolve1D_method_error():
195197
)
196198

197199

200+
@pytest.mark.parametrize("par", [(par1_3d), (par2_3d)])
201+
@pytest.mark.parametrize("axes", [(0, 1), (0, 1, 2, 0)])
202+
def test_ConvolveND_axes_length_error(par, axes):
203+
"""Error raised when axes do not match the filter dimensionality."""
204+
with pytest.raises(ValueError, match="axes must contain one axis per dimension of h"):
205+
ConvolveND(
206+
dims=(par["nz"], par["ny"], par["nx"]),
207+
h=np.random.normal(size=nfilt),
208+
offset=par["offset"],
209+
axes=axes,
210+
)
211+
212+
213+
@pytest.mark.parametrize("par", [(par1_3d), (par2_3d)])
214+
@pytest.mark.parametrize("axes", [(0, 0, 2), (0, 1, -2)])
215+
def test_ConvolveND_axes_unique_error(par, axes):
216+
"""Error raised for repeated axes, including negative aliases."""
217+
with pytest.raises(ValueError, match="axes must be unique"):
218+
ConvolveND(
219+
dims=(par["nz"], par["ny"], par["nx"]),
220+
h=np.random.normal(size=nfilt),
221+
offset=par["offset"],
222+
axes=axes,
223+
)
224+
225+
226+
@pytest.mark.parametrize("par", [(par1_3d), (par2_3d)])
227+
@pytest.mark.parametrize("hshape", [nfilt, (1, 1, 1)])
228+
def test_ConvolveND_shape_error(par, hshape):
229+
"""Error raised when the filter has more dimensions than the model."""
230+
with pytest.raises(ValueError, match="h cannot have more dimensions than dims"):
231+
ConvolveND(
232+
dims=(par["ny"], par["nx"]),
233+
h=np.random.normal(size=hshape),
234+
)
235+
236+
198237
@pytest.mark.parametrize("dims", [nfilt[0] * 4, (3, nfilt[0] * 4)])
199238
@pytest.mark.parametrize("hlen", ["short", "long"])
200239
def test_Convolve1D_hstar_contiguous(dims, hlen):

0 commit comments

Comments
 (0)