jax-ml/jax · error · ValueError
nfft must be greater than or equal to nperseg.
Error message
nfft must be greater than or equal to nperseg.
What it means
nfft (FFT length) zero-pads each segment and must be at least nperseg so the windowed segment fits; a smaller nfft would truncate data. If nfft is not given it defaults to nperseg, so this only fires when an explicit too-small nfft is passed.
Source
Thrown at jax/_src/scipy/signal.py:730
# Move time-axis to the end
x = jnp.moveaxis(x, axis, -1)
if y is not None and y_arr.ndim > 1:
y_arr = jnp.moveaxis(y_arr, axis, -1)
# Check if x and y are the same length, zero-pad if necessary
if y is not None and x.shape[-1] != y_arr.shape[-1]:
if x.shape[-1] < y_arr.shape[-1]:
pad_shape = list(x.shape)
pad_shape[-1] = y_arr.shape[-1] - x.shape[-1]
x = jnp.concatenate((x, jnp.zeros_like(x, shape=pad_shape)), -1)
else:
pad_shape = list(y_arr.shape)
pad_shape[-1] = x.shape[-1] - y_arr.shape[-1]
y_arr = jnp.concatenate((y_arr, jnp.zeros_like(x, shape=pad_shape)), -1)
if nfft_int < nperseg_int:
raise ValueError('nfft must be greater than or equal to nperseg.')
if noverlap_int >= nperseg_int:
raise ValueError('noverlap must be less than nperseg.')
nstep = nperseg_int - noverlap_int
# Apply paddings
if boundary is not None:
ext_func = boundary_funcs[boundary]
x = ext_func(x, nperseg_int // 2, axis=-1)
if y is not None:
y_arr = ext_func(y_arr, nperseg_int // 2, axis=-1)
if padded:
# Pad to integer number of windowed segments
# I.e make x.shape[-1] = nperseg + (nseg-1)*nstep, with integer nseg
nadd = (-(x.shape[-1]-nperseg_int) % nstep) % nperseg_int
x = jnp.concatenate((x, jnp.zeros_like(x, shape=(*x.shape[:-1], nadd))), axis=-1)
if y is not None:
y_arr = jnp.concatenate((y_arr, jnp.zeros_like(x, shape=(*y_arr.shape[:-1], nadd))), axis=-1)View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Set nfft >= nperseg (commonly the next power of two above nperseg)
- Omit nfft to default it to nperseg
- Compute nfft = max(nfft, nperseg) defensively in config-driven code
Example fix
// before jax.scipy.signal.stft(x, nperseg=500, nfft=256) // after jax.scipy.signal.stft(x, nperseg=500, nfft=512)
Defensive patterns
Strategy: validation
Validate before calling
if nfft is not None:
nfft = max(int(nfft), int(nperseg)) Prevention
- Default nfft to nperseg and only increase it (zero-padding)
- Use next power of two: nfft = 1 << (nperseg - 1).bit_length() when padding is wanted
When it happens
Trigger: stft(x, nperseg=256, nfft=128); copying nfft from a config where nperseg was smaller; nfft set to a power of two below the segment size for 'efficiency'.
Common situations: Tuning FFT sizes for frequency resolution and choosing nfft < window length by mistake.
Related errors
- nperseg must be a positive integer
- noverlap must be less than nperseg.
- ind must be a positive integer; got {ind=}
- Expected kind to be on of: {valid_kind}; got {kind}
- Expected kind to be one of: {valid_kind}; got {kind}
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/9929d5f79213a02a.
Report an issue: GitHub.