{"record":{"id":"9abae1c611e6eed0","repo":"jax-ml/jax","slug":"jax-numpy-var-does-not-yet-support-real-dtype-para","errorCode":null,"errorMessage":"jax.numpy.var does not yet support real dtype parameters when computing the variance of an array of complex values. The semantics of numpy.var seem unclear in this case. Please comment on https://github.com/jax-ml/jax/issues/2283 if this behavior is important to you.","messagePattern":"jax\\.numpy\\.var does not yet support real dtype parameters when computing the variance of an array of complex values\\. The semantics of numpy\\.var seem unclear in this case\\. Please comment on https://github\\.com/jax-ml/jax/issues/2283 if this behavior is important to you\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/numpy/reductions.py","lineNumber":1175,"sourceCode":"\n  normalizer = lax.sub(normalizer, lax.convert_element_type(correction, computation_dtype))\n  result = sum(centered, axis, dtype=computation_dtype, keepdims=keepdims, where=where)\n  result = lax.div(result, normalizer).astype(dtype)\n  with config.debug_nans(False):\n    result = _where(normalizer > 0, result, np.nan)\n  return result\n\n\ndef _var_promote_types(a_dtype: DTypeLike, dtype: DTypeLike | None) -> tuple[DType, DType]:\n  if dtype:\n    if (not dtypes.issubdtype(dtype, np.complexfloating) and\n        dtypes.issubdtype(a_dtype, np.complexfloating)):\n      msg = (\"jax.numpy.var does not yet support real dtype parameters when \"\n             \"computing the variance of an array of complex values. The \"\n             \"semantics of numpy.var seem unclear in this case. Please comment \"\n             \"on https://github.com/jax-ml/jax/issues/2283 if this behavior is \"\n             \"important to you.\")\n      raise ValueError(msg)\n    computation_dtype = dtype\n  else:\n    if not dtypes.issubdtype(a_dtype, np.inexact):\n      dtype = dtypes.to_inexact_dtype(a_dtype)\n      computation_dtype = dtype\n    else:\n      dtype = np.array(0, a_dtype).real.dtype\n      computation_dtype = a_dtype\n  return _upcast_f16(computation_dtype), np.dtype(dtype)\n\n\n@export\ndef std(a: ArrayLike, axis: Axis = None, dtype: DTypeLike | None = None,\n        out: None = None, ddof: int = 0, keepdims: bool = False, *,\n        where: ArrayLike | None = None, mean: ArrayLike | None = None,\n        correction: int | float | None = None) -> Array:\n  r\"\"\"Compute the standard deviation along a given axis.\n","sourceCodeStart":1157,"sourceCodeEnd":1193,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/numpy/reductions.py#L1157-L1193","documentation":"jax.numpy.var (and nanvar) explicitly refuses to compute the variance of a complex-valued array when the dtype parameter is a real (non-complex) dtype. Because NumPy's own semantics for this case are ambiguous, JAX raises a ValueError and points to GitHub issue #2283 rather than guessing.","triggerScenarios":"Calling jnp.var(x, dtype=jnp.float32) or jnp.nanvar(x, dtype=jnp.float64) where x has a complex dtype (e.g. complex64); also any dtype that is real while a.dtype is complexfloating inside _var_promote_types.","commonSituations":"Porting NumPy signal-processing or FFT-magnitude code that computes variance of complex spectra while explicitly passing a float dtype; reusing a dtype derived from a real array on complex data.","solutions":["Pass a complex dtype (e.g. dtype=jnp.complex64) or omit the dtype argument so JAX chooses it","Compute variance on the magnitude/real projection: jnp.var(jnp.abs(x)) or jnp.var(x.real)","If you need NumPy parity, follow up on the linked issue jax-ml/jax#2283"],"exampleFix":"// before\nvar = jnp.var(complex_spec, dtype=jnp.float32)\n// after\nvar = jnp.var(jnp.abs(complex_spec), dtype=jnp.float32)","handlingStrategy":"validation","validationCode":"import jax.numpy as jnp, numpy as np\n\ndef safe_var(x, dtype=None):\n    if np.issubdtype(x.dtype, np.complexfloating) and dtype is not None and not np.issubdtype(dtype, np.complexfloating):\n        x = jnp.abs(x)  # or require complex dtype\n    return jnp.var(x, dtype=dtype)","typeGuard":"def is_complex_real_dtype_mismatch(x, dtype) -> bool:\n    import numpy as np\n    return np.issubdtype(x.dtype, np.complexfloating) and dtype is not None and not np.issubdtype(dtype, np.complexfloating)","tryCatchPattern":"try:\n    v = jnp.var(x, dtype=dtype)\nexcept ValueError as e:\n    if 'complex' in str(e):\n        v = jnp.var(jnp.abs(x), dtype=dtype)\n    else:\n        raise","preventionTips":["Never pass explicit real dtypes to variance of complex arrays","Centralize dtype policy in one helper for complex pipelines","Take jnp.abs of spectra before real-valued statistics"],"tags":["jax","numpy","variance","complex-numbers","dtype"],"backgroundTag":"unsupported-dtype-argument","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}