{"record":{"id":"28998dba30b0d49d","repo":"jax-ml/jax","slug":"expi-does-not-support-complex-valued-inputs","errorCode":null,"errorMessage":"expi does not support complex-valued inputs.","messagePattern":"expi does not support complex-valued inputs\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/scipy/special.py","lineNumber":2594,"sourceCode":"  JAX implementation of :obj:`scipy.special.expi`\n\n  .. math::\n\n     \\mathrm{expi}(x) = \\int_{-\\infty}^x \\frac{e^t}{t} \\mathrm{d}t\n\n  Args:\n    x: arraylike, real-valued\n\n  Returns:\n    array of expi values\n\n  See also:\n    - :func:`jax.scipy.special.expn`\n    - :func:`jax.scipy.special.exp1`\n  \"\"\"\n  x_arr, = promote_args_inexact(\"expi\", x)\n  if dtypes.issubdtype(x_arr.dtype, np.complexfloating):\n    raise ValueError(\"expi does not support complex-valued inputs.\")\n  return jnp.piecewise(x_arr, [x_arr < 0], [_expi_neg, _expi_pos])\n\n@expi.defjvp\n@jit\ndef expi_jvp(primals, tangents):\n  (x,) = primals\n  (x_dot,) = tangents\n  return expi(x), jnp.exp(x) / x * x_dot\n\n\n@custom_derivatives.custom_jvp\n@jit\ndef sici(x: ArrayLike) -> tuple[Array, Array]:\n  r\"\"\"Sine and cosine integrals.\n\n  JAX implementation of :obj:`scipy.special.sici`.\n\n  .. math::","sourceCodeStart":2576,"sourceCodeEnd":2612,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/scipy/special.py#L2576-L2612","documentation":"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.","triggerScenarios":"Passing a complex array or Python complex to jax.scipy.special.expi, including under jit, grad, or via expi_jvp with complex tangents.","commonSituations":"Porting SciPy code where scipy.special.expi accepts complex arguments; complex-valued physics/EM computations that need Ei of complex arguments.","solutions":["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.","Validate dtype and split into real/imaginary parts only if your math permits (generally it does not for Ei).","Request/track complex support in the JAX issue tracker."],"exampleFix":"# before (raises)\ny = jax.scipy.special.expi(1 + 2j)\n\n# after: use SciPy for complex arguments\nimport scipy.special\ny = scipy.special.expi(1 + 2j)","handlingStrategy":"type-guard","validationCode":"x = jnp.asarray(x)\nif dtypes.issubdtype(x.dtype, jnp.complexfloating):\n    raise TypeError('use scipy.special.expi for complex arguments')","typeGuard":"def is_real_array(x) -> bool:\n    return not dtypes.issubdtype(jnp.asarray(x).dtype, jnp.complexfloating)","tryCatchPattern":"try:\n    y = jax.scipy.special.expi(x)\nexcept ValueError as e:\n    if 'complex' in str(e):\n        y = jax.pure_callback(scipy.special.expi, x.real.dtype, x)\n    else:\n        raise","preventionTips":["Check dtype before calling special functions in mixed pipelines.","Route complex arguments to SciPy/mpmath via pure_callback from the start."],"tags":["jax","expi","complex-numbers","unsupported-dtype"],"backgroundTag":"complex-input-unsupported","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}