{"record":{"id":"8bca81354a941b5b","repo":"jax-ml/jax","slug":"jnp-unwrap-does-not-support-complex-inputs","errorCode":null,"errorMessage":"jnp.unwrap does not support complex inputs.","messagePattern":"jnp\\.unwrap does not support complex inputs\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/numpy/lax_numpy.py","lineNumber":3852,"sourceCode":"    The first few values match the input angle ``theta`` above, but after this the\n    values are wrapped because the ``sin`` and ``cos`` observations obscure the phase\n    information. The purpose of the :func:`unwrap` function is to recover the original\n    signal from this wrapped view of it:\n\n    >>> jnp.unwrap(theta_out, period=360)\n    Array([ 76., 133., 179., 203., 230., 233., 239., 240., 255., 328., 386.,\n           468., 513., 567., 654., 719., 775., 823., 873., 957.],      dtype=float32)\n\n    It does this by assuming that the true underlying sequence does not differ by more than\n    ``discont`` (which defaults to ``period / 2``) within a single step, and when it encounters\n    a larger discontinuity it adds factors of the period to the data. For periodic signals\n    that satisfy this assumption, :func:`unwrap` can recover the original phased signal.\n  \"\"\"\n  p = util.ensure_arraylike(\"unwrap\", p)\n  p, period = util.promote_dtypes(p, period)\n\n  if issubdtype(p.dtype, np.complexfloating):\n    raise ValueError(\"jnp.unwrap does not support complex inputs.\")\n  if p.shape[axis] == 0:\n    return p\n\n  if discont is None:\n    discont = period / 2\n  if dtypes.issubdtype(p.dtype, np.integer):\n    interval = period // 2\n  else:\n    interval = period / 2\n\n  dd = diff(p, axis=axis)\n  ddmod = ufuncs.mod(dd + interval, period) - interval\n  ddmod = where((ddmod == -interval) & (dd > 0), interval, ddmod)\n\n  ph_correct = where(ufuncs.abs(dd) < discont, 0, ddmod - dd)\n\n  up = concatenate((\n    lax_slicing.slice_in_dim(p, 0, 1, axis=axis),","sourceCodeStart":3834,"sourceCodeEnd":3870,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/numpy/lax_numpy.py#L3834-L3870","documentation":"jnp.unwrap reconstructs a real phase signal by removing discontinuities larger than discont. Phase math has no meaning for complex arrays, so complex inputs are rejected.","triggerScenarios":"jnp.unwrap(jnp.array([0.1+0j, 6.2+0j])) — even complex arrays with zero imaginary parts, because promotion made the dtype complex.","commonSituations":"Unwrapping phases from FFT or analytic-signal pipelines (hilbert transform output) where dtype is complex; accidental complex promotion from a complex period argument.","solutions":["Take the real part: jnp.unwrap(jnp.real(p)) or jnp.angle(p) for complex phases","Cast dtype: p.astype(jnp.float32)","Check period: pass a real-valued period to avoid complex promotion"],"exampleFix":"// before\nphase_unwrapped = jnp.unwrap(hilbert_out)  # complex\n// after\nphase_unwrapped = jnp.unwrap(jnp.angle(hilbert_out))","handlingStrategy":"type-guard","validationCode":"if jnp.iscomplexobj(p):\n    p = jnp.angle(p)  # or jnp.real(p)","typeGuard":"def is_real_phase(a) -> bool:\n    return not jnp.iscomplexobj(a)","tryCatchPattern":null,"preventionTips":["Use jnp.angle on complex signals before unwrap","Keep a real-valued period argument to avoid dtype promotion"],"tags":["jax","unwrap","complex-dtype","unsupported-operation"],"backgroundTag":"unsupported-dtype","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}