{"record":{"id":"9b8542407e95869a","repo":"jax-ml/jax","slug":"betainc-does-not-support-complex-valued-inputs","errorCode":null,"errorMessage":"betainc does not support complex-valued inputs.","messagePattern":"betainc does not support complex-valued inputs\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/scipy/special.py","lineNumber":461,"sourceCode":"     \\mathrm{betainc}(a, b, x) = \\frac{1}{B(a, b)}\\int_0^x t^{a-1}(1-t)^{b-1}\\mathrm{d}t\n\n  where :math:`B(a, b)` is the :func:`~jax.scipy.special.beta` function.\n\n  Args:\n    a: arraylike, real-valued. Parameter *a* of the beta distribution.\n    b: arraylike, real-valued. Parameter *b* of the beta distribution.\n    x: arraylike, real-valued. Upper limit of the integration.\n\n  Returns:\n    array containing values of the betainc function\n\n  See Also:\n    - :func:`jax.scipy.special.beta`\n    - :func:`jax.scipy.special.betaln`\n  \"\"\"\n  a, b, x = promote_args_inexact(\"betainc\", a, b, x)\n  if dtypes.issubdtype(x.dtype, np.complexfloating):\n    raise ValueError(\"betainc does not support complex-valued inputs.\")\n  return lax.betainc(a, b, x)\n\n\ndef digamma(x: ArrayLike) -> Array:\n  r\"\"\"The digamma function\n\n  JAX implementation of :obj:`scipy.special.digamma`.\n\n  .. math::\n\n     \\mathrm{digamma}(x) = \\psi(x) = \\frac{\\mathrm{d}}{\\mathrm{d}x}\\log \\Gamma(x)\n\n  where :math:`\\Gamma(x)` is the :func:`~jax.scipy.special.gamma` function.\n\n  Args:\n    x: arraylike, real-valued.\n\n  Returns:","sourceCodeStart":443,"sourceCodeEnd":479,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/scipy/special.py#L443-L479","documentation":"jax.scipy.special.betainc (the regularized incomplete beta function) explicitly rejects complex-valued inputs. After promoting arguments to inexact dtypes, it checks whether x is a complex subtype and raises ValueError because the underlying lax.betainc primitive is only defined for real numbers.","triggerScenarios":"Calling jax.scipy.special.betainc(a, b, x) where any argument (after promotion) yields a complex dtype, e.g. x = 1+2j or mixing a complex scalar with real arrays so promote_args_inexact upgrades the result to complex128.","commonSituations":"Porting SciPy code that operates on complex spectra; accidentally passing complex tensors from a signal-processing or quantum pipeline into a statistical CDF; dtype promotion surprises where one complex operand makes the whole call complex.","solutions":["Convert x (and a, b) to real before calling: jnp.real(x) or x.real if the imaginary part is known to be zero","Check x.dtype with np.issubdtype(x.dtype, np.complexfloating) and branch to a real-only path","If you truly need complex incomplete beta, implement it yourself or use mpmath outside of JAX"],"exampleFix":"// before\njax.scipy.special.betainc(a, b, z)  # z is complex\n// after\njax.scipy.special.betainc(a, b, jnp.real(z))","handlingStrategy":"type-guard","validationCode":"x = jnp.asarray(x)\nif np.issubdtype(x.dtype, np.complexfloating):\n    raise TypeError('betainc requires real x; got ' + str(x.dtype))","typeGuard":"def is_real(x) -> bool:\n    return not np.issubdtype(jnp.dtype(x), np.complexfloating)","tryCatchPattern":null,"preventionTips":["Keep statistical CDF inputs real by design; add dtype assertions at pipeline entry","Log jnp.result_type(a, b, x) before special-function calls to catch promotion surprises"],"tags":["jax","scipy-special","complex-dtype","dtype-validation"],"backgroundTag":"unsupported-complex-input","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}