jax-ml/jax · error · ValueError

dtype must be a complex floating-point type; got {dtype}.

Error message

dtype must be a complex floating-point type; got {dtype}.

What it means

jax.scipy.linalg.dft returns a complex matrix, so an explicitly passed dtype must be a complex floating subtype (complex64/complex128). The check runs after canonicalizing the user dtype.

Source

Thrown at jax/_src/scipy/linalg.py:3207

  Returns:
    A DFT matrix of shape ``(n, n)``.

  Examples:
    >>> jax.scipy.linalg.dft(4).round(3)
    Array([[ 1.+0.j,  1.+0.j,  1.+0.j,  1.+0.j],
           [ 1.+0.j, -0.-1.j, -1.+0.j,  0.+1.j],
           [ 1.+0.j, -1.+0.j,  1.-0.j, -1.+0.j],
           [ 1.+0.j,  0.+1.j, -1.+0.j, -0.-1.j]], dtype=complex64)
  """
  if scale is not None and scale not in ('sqrtn', 'n'):
    raise ValueError(
        f"scale must be None, 'sqrtn', or 'n'; got {scale!r}.")
  if dtype is None:
    dtype = dtypes.default_complex_dtype()
  else:
    dtype = dtypes.check_and_canonicalize_user_dtype(dtype, "dft")
    if not dtypes.issubdtype(dtype, np.complexfloating):
      raise ValueError(
          f"dtype must be a complex floating-point type; got {dtype}.")
  a = jnp.arange(n, dtype=dtype)
  omegas = jnp.exp(-2j * np.pi * a[:, None] * a[None, :] / n)
  if scale == 'sqrtn':
    omegas = omegas / jnp.sqrt(n)
  elif scale == 'n':
    omegas = omegas / n
  return omegas


def _solve_sylvester_triangular_scan(R: Array, S: Array, F: Array) -> Array:
  """
  Solves the Sylvester equation using Bartels-Stewart algorithm
  .. math::

    RY + YS^T = F

  where R and S are upper triangular matrices following a Schur decomposition.

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Omit dtype to use the default complex dtype
  2. Pass jnp.complex64 or jnp.complex128
  3. Cast to real afterwards if you only need real parts

Example fix

# before
F = linalg.dft(n, dtype=jnp.float32)
# after
F = linalg.dft(n, dtype=jnp.complex64)
Defensive patterns

Strategy: type-guard

Validate before calling

dtype = jnp.complex64 if dtype is None else dtype
assert jnp.issubdtype(dtype, jnp.complexfloating)

Type guard

def is_complex_dtype(dt) -> bool: return jnp.issubdtype(jnp.dtype(dt), jnp.complexfloating)

Prevention

When it happens

Trigger: Calling dft(n, dtype=jnp.float32) or dtype=np.float64; passing a default real dtype variable.

Common situations: Reusing a dtype config meant for real-valued transforms; porting real-FFT code that assumed float output.

Related errors


AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27). Data as JSON: /api/errors/84627429c38c92c5. Report an issue: GitHub.