jax-ml/jax · error · ValueError

Argument `x` to sici must be real-valued. Got dtype {x.dtype

Error message

Argument `x` to sici must be real-valued. Got dtype {x.dtype}.

What it means

jax.scipy.special.sici (sine and cosine integrals) only supports real-valued inputs. After promote_args_inexact, a complex dtype triggers ValueError with the actual dtype in the message. The series/branch implementation is real-only.

Source

Thrown at jax/_src/scipy/special.py:2637

  where :math:`\gamma` is the Euler–Mascheroni constant.

  Args:
    x: array-like, real-valued input.

  Returns:
    A tuple of two arrays, each with the same shape as `x`:
      - The first array contains the sine integral values `Si(x)`.
      - The second array contains the cosine integral values `Ci(x)`.

  See also:
    - :func:`jax.numpy.sinc`
  """

  x, = promote_args_inexact("sici", x)

  if dtypes.issubdtype(x.dtype, np.complexfloating):
    raise ValueError(
      f"Argument `x` to sici must be real-valued. Got dtype {x.dtype}."
    )

  x_abs = jnp.abs(x)

  si_series, ci_series = _sici_series(x_abs)
  si_asymp,  ci_asymp  = _sici_asympt(x_abs)
  si_approx, ci_approx  = _sici_approx(x_abs)

  cond1 = x_abs <= 4
  cond2 = (x_abs > 4) & (x_abs <= 1e9)

  si = jnp.select([cond1, cond2], [si_series, si_asymp], si_approx)
  ci = jnp.select([cond1, cond2], [ci_series, ci_asymp], ci_approx)

  si = jnp.sign(x) * si
  ci = jnp.where(isneginf(x), np.nan, ci)

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Use scipy.special.sici for complex arguments (host-side or via pure_callback).
  2. Guard your pipeline: assert real dtype before calling sici.
  3. Splitting into real/imaginary parts is not valid for Si/Ci; do not attempt it without a proper complex implementation.

Example fix

# before (raises)
si, ci = jax.scipy.special.sici(complex_array)

# after: host callback to SciPy
si, ci = jax.pure_callback(scipy.special.sici, (x.real.dtype, x.real.dtype), x)
Defensive patterns

Strategy: type-guard

Validate before calling

x = jnp.asarray(x)
if dtypes.issubdtype(x.dtype, jnp.complexfloating):
    raise TypeError('sici in JAX is real-only; use scipy.special.sici for complex x')

Type guard

def assert_real(x):
    d = jnp.asarray(x).dtype
    assert not dtypes.issubdtype(d, jnp.complexfloating), f'complex dtype {d}'
    return x

Try / catch

try:
    si, ci = jax.scipy.special.sici(x)
except ValueError:
    si, ci = jax.pure_callback(scipy.special.sici, (x.real.dtype, x.real.dtype), x)

Prevention

When it happens

Trigger: Calling jax.scipy.special.sici with complex arrays or complex scalars; also reachable through sici_jvp when tangents are complex.

Common situations: Signal processing or electromagnetics code that computes Si/Ci of complex arguments with SciPy (which supports complex) and is then moved to JAX.

Related errors


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