{"record":{"id":"642934d337b7d011","repo":"jax-ml/jax","slug":"only-real-valued-inputs-supported-for-rfft","errorCode":null,"errorMessage":"only real valued inputs supported for rfft","messagePattern":"only real valued inputs supported for rfft","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/lax/fft.py","lineNumber":78,"sourceCode":"  elif s in (\"rfft\", \"RFFT\"):\n    return FftType.RFFT\n  elif s in (\"irfft\", \"IRFFT\"):\n    return FftType.IRFFT\n  else:\n    raise ValueError(f\"Unknown FFT type '{s}'\")\n\n@jit(static_argnums=(1, 2))\ndef fft(x, fft_type: FftType | str, fft_lengths: Sequence[int]):\n  if isinstance(fft_type, str):\n    typ = _str_to_fft_type(fft_type)\n  elif isinstance(fft_type, FftType):\n    typ = fft_type\n  else:\n    raise TypeError(f\"Unknown FFT type value '{fft_type}'\")\n\n  if typ == FftType.RFFT:\n    if np.iscomplexobj(x):\n      raise ValueError(\"only real valued inputs supported for rfft\")\n    x = lax.convert_element_type(x, dtypes.to_inexact_dtype(dtypes.dtype(x)))\n  else:\n    x = lax.convert_element_type(x, dtypes.to_complex_dtype(dtypes.dtype(x)))\n  if len(fft_lengths) == 0:\n    # XLA FFT doesn't support 0-rank.\n    return x\n  fft_lengths = tuple(fft_lengths)\n  return fft_p.bind(x, fft_type=typ, fft_lengths=fft_lengths)\n\ndef _fft_impl(x, fft_type, fft_lengths):\n  return dispatch.apply_primitive(fft_p, x, fft_type=fft_type, fft_lengths=fft_lengths)\n\n_complex_dtype = lambda dtype: (np.zeros((), dtype) + np.zeros((), np.complex64)).dtype\n_real_dtype = lambda dtype: np.finfo(dtype).dtype\n\ndef fft_abstract_eval(x, fft_type, fft_lengths):\n  if len(fft_lengths) > x.ndim:\n    raise ValueError(f\"FFT input shape {x.shape} must have at least as many \"","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/lax/fft.py#L60-L96","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\ny = lax.fft(jnp.exp(1j * x), 'rfft', (64,))\n# after\ny = lax.fft(jnp.exp(1j * x), 'fft', (64,))\n# or, if real data intended: y = lax.fft(x, 'rfft', (64,))","handlingStrategy":"type-guard","validationCode":"if np.iscomplexobj(x):\n    fft_type = 'fft'  # rfft requires real input\nassert not (fft_type in ('rfft', lax.FftType.RFFT) and np.iscomplexobj(x))","typeGuard":"def real_input(x) -> bool:\n    return not jnp.issubdtype(x.dtype, jnp.complexfloating)","tryCatchPattern":null,"preventionTips":["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"],"tags":["jax","fft","dtype","api-misuse"],"backgroundTag":"dtype-mismatch","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}