{"record":{"id":"f538f23b8537697c","repo":"jax-ml/jax","slug":"computations-for-m-n-are-not-yet-supported","errorCode":null,"errorMessage":"Computations for m!=n are not yet supported.","messagePattern":"Computations for m!=n are not yet supported\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"jax/_src/scipy/special.py","lineNumber":2219,"sourceCode":"  Raises:\n    TypeError if elements of array `z` are not in (float32, float64).\n    ValueError if array `z` is not 1D.\n    NotImplementedError if `m!=n`.\n  \"\"\"\n  dtype = lax.dtype(z)\n  if dtype not in (np.float32, np.float64):\n    raise TypeError(\n        'z.dtype={} is not supported, see docstring for supported types.'\n        .format(dtype))\n\n  if z.ndim != 1:\n    raise ValueError('z must be a 1D array.')\n\n  m = core.concrete_or_error(int, m, 'Argument m of lpmn.')\n  n = core.concrete_or_error(int, n, 'Argument n of lpmn.')\n\n  if m != n:\n    raise NotImplementedError('Computations for m!=n are not yet supported.')\n\n  l_max = n\n  is_normalized = False\n  p_vals = _gen_associated_legendre(l_max, z, is_normalized)\n  p_derivatives = _gen_derivatives(p_vals, z, is_normalized)\n\n  return (p_vals, p_derivatives)\n\n\ndef lpmn_values(m: int, n: int, z: Array, is_normalized: bool) -> Array:\n  r\"\"\"The associated Legendre functions (ALFs) of the first kind.\n\n  Unlike `lpmn`, this function only computes the values of ALFs.\n  The ALFs of the first kind can be used in spherical harmonics. The\n  spherical harmonic of degree `l` and order `m` can be written as\n  :math:`Y_l^m(\\theta, \\phi) = N_l^m * P_l^m(\\cos \\theta) * \\exp(i m \\phi)`,\n  where :math:`N_l^m` is the normalization factor and θ and φ are the\n  colatitude and longitude, respectively. :math:`N_l^m` is chosen in the","sourceCodeStart":2201,"sourceCodeEnd":2237,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/scipy/special.py#L2201-L2237","documentation":"jax.scipy.special.lpmn only implements the associated Legendre functions for the case m == n. The implementation computes all values up to degree l_max = n and assumes the m and n arguments are equal; any other combination is unimplemented in JAX (unlike SciPy). It raises NotImplementedError rather than silently returning wrong results.","triggerScenarios":"Calling jax.scipy.special.lpmn(m, n, z) with integer m != n, e.g. lpmn(2, 5, z). The check happens eagerly after concrete-or-error validation of m and n.","commonSituations":"Porting SciPy code that uses scipy.special.lpmn(m, n, x) with arbitrary m <= n; computing Legendre functions of a specific order lower than the degree inside JAX pipelines.","solutions":["Set m equal to n and slice the result: lpmn(n, n, z) returns all orders up to n, so extract the m you need from the output.","If slicing the full table is not enough, use scipy.special.lpmn outside of JAX (e.g. precompute constants) or implement the recurrence yourself.","Check the JAX version/release notes; support for m != n may be added later."],"exampleFix":"// before\np, dp = jax.scipy.special.lpmn(2, 5, z)\n\n// after: compute full table with m == n and slice\np, dp = jax.scipy.special.lpmn(5, 5, z)\np_m2 = p[2]  # values for order m=2","handlingStrategy":"validation","validationCode":"assert m == n, f'lpmn in JAX requires m == n, got m={m}, n={n}'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Wrap lpmn in a helper that enforces m == n and slices the output table.","Add port-time unit tests when migrating scipy.special.lpmn call sites."],"tags":["jax","scipy","legendre","not-implemented","argument-mismatch"],"backgroundTag":"unsupported-argument-value","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}