jax-ml/jax · error · ValueError
only real valued inputs supported for rfft
Error message
only real valued inputs supported for rfft
What it means
jax.lax.fft with type RFFT requires a real-valued (floating-point) input; it converts to inexact dtype and, if the input is already complex (np.iscomplexobj), raises this ValueError. Use plain 'fft' for complex inputs instead.
Source
Thrown at jax/_src/lax/fft.py:78
elif s in ("rfft", "RFFT"):
return FftType.RFFT
elif s in ("irfft", "IRFFT"):
return FftType.IRFFT
else:
raise ValueError(f"Unknown FFT type '{s}'")
@jit(static_argnums=(1, 2))
def fft(x, fft_type: FftType | str, fft_lengths: Sequence[int]):
if isinstance(fft_type, str):
typ = _str_to_fft_type(fft_type)
elif isinstance(fft_type, FftType):
typ = fft_type
else:
raise TypeError(f"Unknown FFT type value '{fft_type}'")
if typ == FftType.RFFT:
if np.iscomplexobj(x):
raise ValueError("only real valued inputs supported for rfft")
x = lax.convert_element_type(x, dtypes.to_inexact_dtype(dtypes.dtype(x)))
else:
x = lax.convert_element_type(x, dtypes.to_complex_dtype(dtypes.dtype(x)))
if len(fft_lengths) == 0:
# XLA FFT doesn't support 0-rank.
return x
fft_lengths = tuple(fft_lengths)
return fft_p.bind(x, fft_type=typ, fft_lengths=fft_lengths)
def _fft_impl(x, fft_type, fft_lengths):
return dispatch.apply_primitive(fft_p, x, fft_type=fft_type, fft_lengths=fft_lengths)
_complex_dtype = lambda dtype: (np.zeros((), dtype) + np.zeros((), np.complex64)).dtype
_real_dtype = lambda dtype: np.finfo(dtype).dtype
def fft_abstract_eval(x, fft_type, fft_lengths):
if len(fft_lengths) > x.ndim:
raise ValueError(f"FFT input shape {x.shape} must have at least as many "View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Use 'fft' (or jnp.fft.fft) for complex inputs
- Take the real part first (z.real) if you genuinely want an rfft of real-valued data embedded in complex
- Use irfft to go from complex spectrum back to real signal
Example fix
# before y = lax.fft(jnp.exp(1j * x), 'rfft', (64,)) # after y = lax.fft(jnp.exp(1j * x), 'fft', (64,)) # or, if real data intended: y = lax.fft(x, 'rfft', (64,))
Defensive patterns
Strategy: type-guard
Validate before calling
if np.iscomplexobj(x):
fft_type = 'fft' # rfft requires real input
assert not (fft_type in ('rfft', lax.FftType.RFFT) and np.iscomplexobj(x)) Type guard
def real_input(x) -> bool:
return not jnp.issubdtype(x.dtype, jnp.complexfloating) Prevention
- Use irfft/fft for complex inputs; rfft only for real data
- Insert x.real or an fft/irfft pair in spectrogram chains instead of rfft on complex arrays
When it happens
Trigger: Calling jax.lax.fft(z, 'rfft', (n,)) where z has a complex dtype, or jnp.fft.rfft on complex data via wrappers that hit lax.fft.
Common situations: Data pipelines where an earlier op (e.g. fft then rfft in a spectrogram chain) leaves complex arrays; forgetting that rfft's inverse counterpart is irfft, not rfft.
Related errors
- Unknown FFT type '{s}'
- {name} wrapped function must be passed at least one argument
- primal and tangent arguments to jax.jvp must be tuples or li
- primal and tangent arguments to jax.jvp do not match; dtypes
- unexpected JAX type (e.g. shape/dtype) for gradient ref pass
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/642934d337b7d011.
Report an issue: GitHub.