jax-ml/jax · error · ValueError

expi does not support complex-valued inputs.

Error message

expi does not support complex-valued inputs.

What it means

jax.scipy.special.expi (exponential integral Ei) is implemented via jnp.piecewise with real-valued branches (_expi_pos/_expi_neg), so complex inputs are explicitly rejected after promotion by promote_args_inexact. The ValueError fires before any computation; the JVP rule inherits the restriction.

Source

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

  JAX implementation of :obj:`scipy.special.expi`

  .. math::

     \mathrm{expi}(x) = \int_{-\infty}^x \frac{e^t}{t} \mathrm{d}t

  Args:
    x: arraylike, real-valued

  Returns:
    array of expi values

  See also:
    - :func:`jax.scipy.special.expn`
    - :func:`jax.scipy.special.exp1`
  """
  x_arr, = promote_args_inexact("expi", x)
  if dtypes.issubdtype(x_arr.dtype, np.complexfloating):
    raise ValueError("expi does not support complex-valued inputs.")
  return jnp.piecewise(x_arr, [x_arr < 0], [_expi_neg, _expi_pos])

@expi.defjvp
@jit
def expi_jvp(primals, tangents):
  (x,) = primals
  (x_dot,) = tangents
  return expi(x), jnp.exp(x) / x * x_dot


@custom_derivatives.custom_jvp
@jit
def sici(x: ArrayLike) -> tuple[Array, Array]:
  r"""Sine and cosine integrals.

  JAX implementation of :obj:`scipy.special.sici`.

  .. math::

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Use the complex-capable equivalent: jax.scipy.special.exp1 or the generalized expn are also real-only, so compute Ei(x) for complex x via a custom implementation (e.g. relation to E1 with branch handling) or call scipy.special.expi on the host.
  2. Validate dtype and split into real/imaginary parts only if your math permits (generally it does not for Ei).
  3. Request/track complex support in the JAX issue tracker.

Example fix

# before (raises)
y = jax.scipy.special.expi(1 + 2j)

# after: use SciPy for complex arguments
import scipy.special
y = scipy.special.expi(1 + 2j)
Defensive patterns

Strategy: type-guard

Validate before calling

x = jnp.asarray(x)
if dtypes.issubdtype(x.dtype, jnp.complexfloating):
    raise TypeError('use scipy.special.expi for complex arguments')

Type guard

def is_real_array(x) -> bool:
    return not dtypes.issubdtype(jnp.asarray(x).dtype, jnp.complexfloating)

Try / catch

try:
    y = jax.scipy.special.expi(x)
except ValueError as e:
    if 'complex' in str(e):
        y = jax.pure_callback(scipy.special.expi, x.real.dtype, x)
    else:
        raise

Prevention

When it happens

Trigger: Passing a complex array or Python complex to jax.scipy.special.expi, including under jit, grad, or via expi_jvp with complex tangents.

Common situations: Porting SciPy code where scipy.special.expi accepts complex arguments; complex-valued physics/EM computations that need Ei of complex arguments.

Related errors


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