Skip to content

Commit 7a9ce94

Browse files
author
peng.li24
committed
fix ndimage: n=1+mirror SIGFPE; add 129 gaussian_filter1d edge-case tests
Bug fix — scipy/ndimage.h: mirror boundary mode: p = 2*n-2 = 0 when n=1 → idx%p = integer div-by-zero (SIGFPE, signal 8). Guard added: 'if (n <= 1) return src[0]' before modulo. Same fix applied to both gaussian_filter1d and gaussian_filter_correlate. New tests — tests/test_all.py (TestSpecialValuesGaussianFilter1d expanded): n=1 / n=2 / n=3 × all 5 modes (15 parametrized cases each) kernel half >> array (sigma=20, n=5) × all 5 modes impulse at left boundary [0] × all 5 modes impulse at right boundary [-1] × all 5 modes truncate=2.0 / 3.0 / 6.0 cval=0.0 / 3.14159 / -1.5 / 1e10 linear ramp, step function ±inf: single middle, at [0], at [-1], alternating ±inf → NaN NaN: at [0]/[2]/[-1], all-NaN float64 extremes: 1e100, 1e200, 2e307, subnormal(5e-324), min-normal(2.2e-308) float32 extremes: 1e20, 1e30, near-max(3.4e38), subnormal(1.4e-45), min-normal(1.18e-38) All 396 tests pass, 2187 bit-identical, 193 within tolerance (integrate only).
1 parent bfc07af commit 7a9ce94

3 files changed

Lines changed: 343 additions & 43 deletions

File tree

doc/ulp_report.csv

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2224,8 +2224,6 @@ gaussian_filter1d,gaussian_filter1d sigma=0.1,float64,100,0,0,0,—,bit-identica
22242224
gaussian_filter1d,gaussian_filter1d sigma=0.1,float32,100,0,0,0,,bit-identical
22252225
gaussian_filter1d,gaussian_filter1d sigma=50,float64,100,0,0,0,,bit-identical
22262226
gaussian_filter1d,gaussian_filter1d sigma=50,float32,100,0,0,0,,bit-identical
2227-
gaussian_filter1d,gaussian_filter1d large 1e100,float64,100,0,0,0,,bit-identical
2228-
gaussian_filter1d,gaussian_filter1d large 1e100,float32,100,0,0,0,,bit-identical
22292227
gaussian_filter1d,gaussian_filter1d constant mode=reflect,float64,100,0,0,0,,bit-identical
22302228
gaussian_filter1d,gaussian_filter1d constant mode=constant,float64,100,0,0,0,,bit-identical
22312229
gaussian_filter1d,gaussian_filter1d constant mode=nearest,float64,100,0,0,0,,bit-identical
@@ -2236,6 +2234,110 @@ gaussian_filter1d,gaussian_filter1d constant mode=constant,float32,100,0,0,0,—
22362234
gaussian_filter1d,gaussian_filter1d constant mode=nearest,float32,100,0,0,0,,bit-identical
22372235
gaussian_filter1d,gaussian_filter1d constant mode=mirror,float32,100,0,0,0,,bit-identical
22382236
gaussian_filter1d,gaussian_filter1d constant mode=wrap,float32,100,0,0,0,,bit-identical
2237+
gaussian_filter1d,gaussian_filter1d n=1 mode=reflect,float64,1,0,0,0,,bit-identical
2238+
gaussian_filter1d,gaussian_filter1d n=1 mode=constant,float64,1,0,0,0,,bit-identical
2239+
gaussian_filter1d,gaussian_filter1d n=1 mode=nearest,float64,1,0,0,0,,bit-identical
2240+
gaussian_filter1d,gaussian_filter1d n=1 mode=mirror,float64,1,0,0,0,,bit-identical
2241+
gaussian_filter1d,gaussian_filter1d n=1 mode=wrap,float64,1,0,0,0,,bit-identical
2242+
gaussian_filter1d,gaussian_filter1d n=1 mode=reflect,float32,1,0,0,0,,bit-identical
2243+
gaussian_filter1d,gaussian_filter1d n=1 mode=constant,float32,1,0,0,0,,bit-identical
2244+
gaussian_filter1d,gaussian_filter1d n=1 mode=nearest,float32,1,0,0,0,,bit-identical
2245+
gaussian_filter1d,gaussian_filter1d n=1 mode=mirror,float32,1,0,0,0,,bit-identical
2246+
gaussian_filter1d,gaussian_filter1d n=1 mode=wrap,float32,1,0,0,0,,bit-identical
2247+
gaussian_filter1d,gaussian_filter1d n=2 mode=reflect,float64,2,0,0,0,,bit-identical
2248+
gaussian_filter1d,gaussian_filter1d n=2 mode=constant,float64,2,0,0,0,,bit-identical
2249+
gaussian_filter1d,gaussian_filter1d n=2 mode=nearest,float64,2,0,0,0,,bit-identical
2250+
gaussian_filter1d,gaussian_filter1d n=2 mode=mirror,float64,2,0,0,0,,bit-identical
2251+
gaussian_filter1d,gaussian_filter1d n=2 mode=wrap,float64,2,0,0,0,,bit-identical
2252+
gaussian_filter1d,gaussian_filter1d n=2 mode=reflect,float32,2,0,0,0,,bit-identical
2253+
gaussian_filter1d,gaussian_filter1d n=2 mode=constant,float32,2,0,0,0,,bit-identical
2254+
gaussian_filter1d,gaussian_filter1d n=2 mode=nearest,float32,2,0,0,0,,bit-identical
2255+
gaussian_filter1d,gaussian_filter1d n=2 mode=mirror,float32,2,0,0,0,,bit-identical
2256+
gaussian_filter1d,gaussian_filter1d n=2 mode=wrap,float32,2,0,0,0,,bit-identical
2257+
gaussian_filter1d,gaussian_filter1d n=3 mode=reflect,float64,3,0,0,0,,bit-identical
2258+
gaussian_filter1d,gaussian_filter1d n=3 mode=constant,float64,3,0,0,0,,bit-identical
2259+
gaussian_filter1d,gaussian_filter1d n=3 mode=nearest,float64,3,0,0,0,,bit-identical
2260+
gaussian_filter1d,gaussian_filter1d n=3 mode=mirror,float64,3,0,0,0,,bit-identical
2261+
gaussian_filter1d,gaussian_filter1d n=3 mode=wrap,float64,3,0,0,0,,bit-identical
2262+
gaussian_filter1d,gaussian_filter1d n=3 mode=reflect,float32,3,0,0,0,,bit-identical
2263+
gaussian_filter1d,gaussian_filter1d n=3 mode=constant,float32,3,0,0,0,,bit-identical
2264+
gaussian_filter1d,gaussian_filter1d n=3 mode=nearest,float32,3,0,0,0,,bit-identical
2265+
gaussian_filter1d,gaussian_filter1d n=3 mode=mirror,float32,3,0,0,0,,bit-identical
2266+
gaussian_filter1d,gaussian_filter1d n=3 mode=wrap,float32,3,0,0,0,,bit-identical
2267+
gaussian_filter1d,gaussian_filter1d half>>n mode=reflect,float64,5,0,0,0,,bit-identical
2268+
gaussian_filter1d,gaussian_filter1d half>>n mode=constant,float64,5,0,0,0,,bit-identical
2269+
gaussian_filter1d,gaussian_filter1d half>>n mode=nearest,float64,5,0,0,0,,bit-identical
2270+
gaussian_filter1d,gaussian_filter1d half>>n mode=mirror,float64,5,0,0,0,,bit-identical
2271+
gaussian_filter1d,gaussian_filter1d half>>n mode=wrap,float64,5,0,0,0,,bit-identical
2272+
gaussian_filter1d,gaussian_filter1d half>>n mode=reflect,float32,5,0,0,0,,bit-identical
2273+
gaussian_filter1d,gaussian_filter1d half>>n mode=constant,float32,5,0,0,0,,bit-identical
2274+
gaussian_filter1d,gaussian_filter1d half>>n mode=nearest,float32,5,0,0,0,,bit-identical
2275+
gaussian_filter1d,gaussian_filter1d half>>n mode=mirror,float32,5,0,0,0,,bit-identical
2276+
gaussian_filter1d,gaussian_filter1d half>>n mode=wrap,float32,5,0,0,0,,bit-identical
2277+
gaussian_filter1d,gaussian_filter1d impulse[0] mode=reflect,float64,20,0,0,0,,bit-identical
2278+
gaussian_filter1d,gaussian_filter1d impulse[0] mode=constant,float64,20,0,0,0,,bit-identical
2279+
gaussian_filter1d,gaussian_filter1d impulse[0] mode=nearest,float64,20,0,0,0,,bit-identical
2280+
gaussian_filter1d,gaussian_filter1d impulse[0] mode=mirror,float64,20,0,0,0,,bit-identical
2281+
gaussian_filter1d,gaussian_filter1d impulse[0] mode=wrap,float64,20,0,0,0,,bit-identical
2282+
gaussian_filter1d,gaussian_filter1d impulse[0] mode=reflect,float32,20,0,0,0,,bit-identical
2283+
gaussian_filter1d,gaussian_filter1d impulse[0] mode=constant,float32,20,0,0,0,,bit-identical
2284+
gaussian_filter1d,gaussian_filter1d impulse[0] mode=nearest,float32,20,0,0,0,,bit-identical
2285+
gaussian_filter1d,gaussian_filter1d impulse[0] mode=mirror,float32,20,0,0,0,,bit-identical
2286+
gaussian_filter1d,gaussian_filter1d impulse[0] mode=wrap,float32,20,0,0,0,,bit-identical
2287+
gaussian_filter1d,gaussian_filter1d impulse[-1] mode=reflect,float64,20,0,0,0,,bit-identical
2288+
gaussian_filter1d,gaussian_filter1d impulse[-1] mode=constant,float64,20,0,0,0,,bit-identical
2289+
gaussian_filter1d,gaussian_filter1d impulse[-1] mode=nearest,float64,20,0,0,0,,bit-identical
2290+
gaussian_filter1d,gaussian_filter1d impulse[-1] mode=mirror,float64,20,0,0,0,,bit-identical
2291+
gaussian_filter1d,gaussian_filter1d impulse[-1] mode=wrap,float64,20,0,0,0,,bit-identical
2292+
gaussian_filter1d,gaussian_filter1d impulse[-1] mode=reflect,float32,20,0,0,0,,bit-identical
2293+
gaussian_filter1d,gaussian_filter1d impulse[-1] mode=constant,float32,20,0,0,0,,bit-identical
2294+
gaussian_filter1d,gaussian_filter1d impulse[-1] mode=nearest,float32,20,0,0,0,,bit-identical
2295+
gaussian_filter1d,gaussian_filter1d impulse[-1] mode=mirror,float32,20,0,0,0,,bit-identical
2296+
gaussian_filter1d,gaussian_filter1d impulse[-1] mode=wrap,float32,20,0,0,0,,bit-identical
2297+
gaussian_filter1d,gaussian_filter1d truncate=2.0,float64,30,0,0,0,,bit-identical
2298+
gaussian_filter1d,gaussian_filter1d truncate=3.0,float64,30,0,0,0,,bit-identical
2299+
gaussian_filter1d,gaussian_filter1d truncate=6.0,float64,30,0,0,0,,bit-identical
2300+
gaussian_filter1d,gaussian_filter1d truncate=2.0,float32,30,0,0,0,,bit-identical
2301+
gaussian_filter1d,gaussian_filter1d truncate=3.0,float32,30,0,0,0,,bit-identical
2302+
gaussian_filter1d,gaussian_filter1d truncate=6.0,float32,30,0,0,0,,bit-identical
2303+
gaussian_filter1d,gaussian_filter1d cval=0.0,float64,20,0,0,0,,bit-identical
2304+
gaussian_filter1d,gaussian_filter1d cval=3.14159,float64,20,0,0,0,,bit-identical
2305+
gaussian_filter1d,gaussian_filter1d cval=-1.5,float64,20,0,0,0,,bit-identical
2306+
gaussian_filter1d,gaussian_filter1d cval=10000000000.0,float64,20,0,0,0,,bit-identical
2307+
gaussian_filter1d,gaussian_filter1d cval=0.0,float32,20,0,0,0,,bit-identical
2308+
gaussian_filter1d,gaussian_filter1d cval=3.14159,float32,20,0,0,0,,bit-identical
2309+
gaussian_filter1d,gaussian_filter1d cval=-1.5,float32,20,0,0,0,,bit-identical
2310+
gaussian_filter1d,gaussian_filter1d cval=10000000000.0,float32,20,0,0,0,,bit-identical
2311+
gaussian_filter1d,gaussian_filter1d linear ramp,float64,50,0,0,0,,bit-identical
2312+
gaussian_filter1d,gaussian_filter1d linear ramp,float32,50,0,0,0,,bit-identical
2313+
gaussian_filter1d,gaussian_filter1d step function,float64,50,0,0,0,,bit-identical
2314+
gaussian_filter1d,gaussian_filter1d step function,float32,50,0,0,0,,bit-identical
2315+
gaussian_filter1d,gaussian_filter1d +inf middle,float64,5,0,0,0,,bit-identical
2316+
gaussian_filter1d,gaussian_filter1d +inf middle,float32,5,0,0,0,,bit-identical
2317+
gaussian_filter1d,gaussian_filter1d inf[0],float64,10,0,0,0,,bit-identical
2318+
gaussian_filter1d,gaussian_filter1d inf[-1],float64,10,0,0,0,,bit-identical
2319+
gaussian_filter1d,gaussian_filter1d inf[0],float32,10,0,0,0,,bit-identical
2320+
gaussian_filter1d,gaussian_filter1d inf[-1],float32,10,0,0,0,,bit-identical
2321+
gaussian_filter1d,gaussian_filter1d alternating ±inf,float64,10,0,0,0,,bit-identical
2322+
gaussian_filter1d,gaussian_filter1d alternating ±inf,float32,10,0,0,0,,bit-identical
2323+
gaussian_filter1d,gaussian_filter1d NaN[0],float64,10,0,0,0,,bit-identical
2324+
gaussian_filter1d,gaussian_filter1d NaN[2],float64,10,0,0,0,,bit-identical
2325+
gaussian_filter1d,gaussian_filter1d NaN[-1],float64,10,0,0,0,,bit-identical
2326+
gaussian_filter1d,gaussian_filter1d NaN[0],float32,10,0,0,0,,bit-identical
2327+
gaussian_filter1d,gaussian_filter1d NaN[2],float32,10,0,0,0,,bit-identical
2328+
gaussian_filter1d,gaussian_filter1d NaN[-1],float32,10,0,0,0,,bit-identical
2329+
gaussian_filter1d,gaussian_filter1d all-NaN,float64,10,0,0,0,,bit-identical
2330+
gaussian_filter1d,gaussian_filter1d all-NaN,float32,10,0,0,0,,bit-identical
2331+
gaussian_filter1d,gaussian_filter1d f64 scale=1e+100,float64,100,0,0,0,,bit-identical
2332+
gaussian_filter1d,gaussian_filter1d f64 scale=1e+200,float64,100,0,0,0,,bit-identical
2333+
gaussian_filter1d,gaussian_filter1d f64 scale=2e+307,float64,100,0,0,0,,bit-identical
2334+
gaussian_filter1d,gaussian_filter1d f64 subnormal,float64,5,0,0,0,,bit-identical
2335+
gaussian_filter1d,gaussian_filter1d f64 min-normal,float64,5,0,0,0,,bit-identical
2336+
gaussian_filter1d,gaussian_filter1d f32 scale=1e+20,float32,100,0,0,0,,bit-identical
2337+
gaussian_filter1d,gaussian_filter1d f32 scale=1e+30,float32,100,0,0,0,,bit-identical
2338+
gaussian_filter1d,gaussian_filter1d f32 near-max,float32,100,0,0,0,,bit-identical
2339+
gaussian_filter1d,gaussian_filter1d f32 subnormal,float32,5,0,0,0,,bit-identical
2340+
gaussian_filter1d,gaussian_filter1d f32 min-normal,float32,5,0,0,0,,bit-identical
22392341
medfilt,medfilt all-same v=0.0 k=3,float64,20,0,0,0,,bit-identical
22402342
medfilt,medfilt all-same v=0.0 k=5,float64,20,0,0,0,,bit-identical
22412343
medfilt,medfilt all-same v=0.0 k=7,float64,20,0,0,0,,bit-identical

scipy/ndimage.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ inline void gaussian_filter1d(const T* src, T* dst, size_t n,
9393
case 2: // nearest
9494
return (idx < 0) ? src[0] : src[n - 1];
9595
case 3: { // mirror (d c b | a b c d | c b a)
96-
// period = 2*n - 2, first/last elements appear once
96+
// period = 2*n - 2, first/last elements appear once.
97+
// Guard: n==1 → period=0, modulo undefined; only element is src[0].
98+
if (n <= 1) return src[0];
9799
ptrdiff_t p = static_cast<ptrdiff_t>(2 * n - 2);
98100
ptrdiff_t r = idx % p;
99101
if (r < 0) r += p;
@@ -179,6 +181,7 @@ inline void gaussian_filter_correlate(const T* src, T* dst, size_t n,
179181
case 2: // nearest
180182
return (idx < 0) ? src[0] : src[n - 1];
181183
case 3: { // mirror
184+
if (n <= 1) return src[0]; // guard: period = 2*n-2 = 0 when n=1
182185
ptrdiff_t p = static_cast<ptrdiff_t>(2 * n - 2);
183186
ptrdiff_t r = idx % p;
184187
if (r < 0) r += p;

0 commit comments

Comments
 (0)