{"record":{"id":"ad600dd69906a414","repo":"jax-ml/jax","slug":"argument-x-to-sici-must-be-real-valued-got-dtyp","errorCode":null,"errorMessage":"Argument `x` to sici must be real-valued. Got dtype {x.dtype}.","messagePattern":"Argument `x` to sici must be real-valued\\. Got dtype (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/scipy/special.py","lineNumber":2637,"sourceCode":"\n  where :math:`\\gamma` is the Euler–Mascheroni constant.\n\n  Args:\n    x: array-like, real-valued input.\n\n  Returns:\n    A tuple of two arrays, each with the same shape as `x`:\n      - The first array contains the sine integral values `Si(x)`.\n      - The second array contains the cosine integral values `Ci(x)`.\n\n  See also:\n    - :func:`jax.numpy.sinc`\n  \"\"\"\n\n  x, = promote_args_inexact(\"sici\", x)\n\n  if dtypes.issubdtype(x.dtype, np.complexfloating):\n    raise ValueError(\n      f\"Argument `x` to sici must be real-valued. Got dtype {x.dtype}.\"\n    )\n\n  x_abs = jnp.abs(x)\n\n  si_series, ci_series = _sici_series(x_abs)\n  si_asymp,  ci_asymp  = _sici_asympt(x_abs)\n  si_approx, ci_approx  = _sici_approx(x_abs)\n\n  cond1 = x_abs <= 4\n  cond2 = (x_abs > 4) & (x_abs <= 1e9)\n\n  si = jnp.select([cond1, cond2], [si_series, si_asymp], si_approx)\n  ci = jnp.select([cond1, cond2], [ci_series, ci_asymp], ci_approx)\n\n  si = jnp.sign(x) * si\n  ci = jnp.where(isneginf(x), np.nan, ci)\n","sourceCodeStart":2619,"sourceCodeEnd":2655,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/scipy/special.py#L2619-L2655","documentation":"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.","triggerScenarios":"Calling jax.scipy.special.sici with complex arrays or complex scalars; also reachable through sici_jvp when tangents are complex.","commonSituations":"Signal processing or electromagnetics code that computes Si/Ci of complex arguments with SciPy (which supports complex) and is then moved to JAX.","solutions":["Use scipy.special.sici for complex arguments (host-side or via pure_callback).","Guard your pipeline: assert real dtype before calling sici.","Splitting into real/imaginary parts is not valid for Si/Ci; do not attempt it without a proper complex implementation."],"exampleFix":"# before (raises)\nsi, ci = jax.scipy.special.sici(complex_array)\n\n# after: host callback to SciPy\nsi, ci = jax.pure_callback(scipy.special.sici, (x.real.dtype, x.real.dtype), x)","handlingStrategy":"type-guard","validationCode":"x = jnp.asarray(x)\nif dtypes.issubdtype(x.dtype, jnp.complexfloating):\n    raise TypeError('sici in JAX is real-only; use scipy.special.sici for complex x')","typeGuard":"def assert_real(x):\n    d = jnp.asarray(x).dtype\n    assert not dtypes.issubdtype(d, jnp.complexfloating), f'complex dtype {d}'\n    return x","tryCatchPattern":"try:\n    si, ci = jax.scipy.special.sici(x)\nexcept ValueError:\n    si, ci = jax.pure_callback(scipy.special.sici, (x.real.dtype, x.real.dtype), x)","preventionTips":["Keep integrals/signals real dtype end-to-end; watch for complex promotion by fft/ifft.","Wrap sici with a real-dtype assert in shared math utilities."],"tags":["jax","sici","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"}