{"record":{"id":"5a72d13e2648a998","repo":"jax-ml/jax","slug":"gaussian-kde-does-not-support-complex-coordinates","errorCode":null,"errorMessage":"gaussian_kde does not support complex coordinates","messagePattern":"gaussian_kde does not support complex coordinates","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"jax/_src/scipy/stats/kde.py","lineNumber":234,"sourceCode":"    result = _gaussian_kernel_eval(True, self.dataset.T, self.weights[:, None],\n                                   x.T, self.inv_cov)\n    return result[:, 0]\n\n  def integrate_box(self, low_bounds, high_bounds, maxpts=None):\n    \"\"\"This method is not implemented in the JAX interface.\"\"\"\n    del low_bounds, high_bounds, maxpts\n    raise NotImplementedError(\n        \"only 1D box integrations are supported; use `integrate_box_1d`\")\n\n  def set_bandwidth(self, bw_method=None):\n    \"\"\"This method is not implemented in the JAX interface.\"\"\"\n    del bw_method\n    raise NotImplementedError(\n        \"dynamically changing the bandwidth method is not supported\")\n\n  def _reshape_points(self, points):\n    if dtypes.issubdtype(lax.dtype(points), np.complexfloating):\n      raise NotImplementedError(\n          \"gaussian_kde does not support complex coordinates\")\n    points = jnp.atleast_2d(points)\n    d, m = points.shape\n    if d != self.d:\n      if d == 1 and m == self.d:\n        points = jnp.reshape(points, (self.d, 1))\n      else:\n        raise ValueError(\n            \"points have dimension {}, dataset has dimension {}\".format(\n                d, self.d))\n    return points\n\n\ndef _gaussian_kernel_convolve(chol, norm, target, weights, mean):\n  diff = target - mean[:, None]\n  alpha = linalg.cho_solve(chol, diff)\n  arg = 0.5 * jnp.sum(diff * alpha, axis=0)\n  return norm * jnp.sum(jnp.exp(-arg) * weights)","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/scipy/stats/kde.py#L216-L252","documentation":"All evaluation methods of gaussian_kde (evaluate, logpdf, pdf) reject complex-valued query points via _reshape_points, mirroring the complex-dataset restriction in __init__. The kernel math is real-only.","triggerScenarios":"kde.evaluate(jnp.array([1+1j, 2-1j])) or kde.logpdf(complex_grid).","commonSituations":"Evaluating a KDE on the output of an FFT/analytic-signal pipeline left in complex dtype; complex creeping in via promotion with a complex constant.","solutions":["Evaluate on real coordinates: kde.evaluate(points.real)","Cast the query array: points = points.astype(jnp.float64)","Split into real/imaginary grids and evaluate separately if both are needed"],"exampleFix":"// before\nvals = kde.evaluate(z)  # z complex\n// after\nvals = kde.evaluate(z.real)","handlingStrategy":"type-guard","validationCode":"if jnp.iscomplexobj(points):\n    points = points.real","typeGuard":"def points_are_real(points) -> bool:\n    return not jnp.iscomplexobj(jnp.asarray(points))","tryCatchPattern":null,"preventionTips":["Project to .real before evaluation","Sanitize dtypes at pipeline boundaries","Keep KDE input and query dtypes consistent float types"],"tags":["jax","scipy","kde","complex-dtype","not-implemented"],"backgroundTag":"unsupported-dtype","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}