Skip to content

Fix numba CauchyRV loc/scale - #2309

Open
notluquis wants to merge 2 commits into
pymc-devs:mainfrom
notluquis:fix-numba-cauchy-loc-scale
Open

Fix numba CauchyRV loc/scale#2309
notluquis wants to merge 2 commits into
pymc-devs:mainfrom
notluquis:fix-numba-cauchy-loc-scale

Conversation

@notluquis

@notluquis notluquis commented Jul 27, 2026

Copy link
Copy Markdown

Closes #2308.

The numba dispatch computed (loc + z) / scale instead of loc + scale * z, so the sampled variable had location loc/scale and scale 1/scale.

-        return (loc + rng.standard_cauchy()) / scale
+        return loc + scale * rng.standard_cauchy()

rng_fn_scipy and the JAX dispatch were already correct, so only numba was affected — but it is the default linker. logp is untouched, so NUTS posteriors were fine; anything that draws was not, including sample_prior_predictive on a HalfCauchy prior (HalfCauchyRV.rv_op builds abs(cauchy(0, beta))).

Tests

test_unaligned_RandomVariable is the only test checking these samplers against their distribution, and it has three cases. Two used a degenerate scale:

case was now
cauchy scale=1.0 scale=3.0 catches the bug above: p=1.7e-08 → passes
gumbel scale=1.0 scale=4.0 no bug, but was blind
t scale=np.pi unchanged already fine

At scale=1, (loc ± z) / 1 is algebraically identical to loc ± 1 * z, so both the location and scale errors vanish together and Cramér–von Mises passes.

GumbelRV has a hand-written core too (loc - scale * np.log(-np.log(U))) and is correct, but was equally undetectable. Verified by injecting the analogous slip: the new case fails at p=7.2e-08 with it, passes without.

Audit

Checked every hand-written numba core (t, halfnormal, pareto, invgamma, gumbel, wald) plus the default-path RVs against scipy with non-degenerate parameters. All match — cauchy was the only real bug.

tests/link/numba/test_random.py: 84 passed, 2 xfailed.

Note for reviewers reproducing this: PyTensor reuses the cached compiled graph across source edits, so a naive before/after run shows both variants passing. The numbers above use a separate base_compiledir per run.

The numba dispatch computed `(loc + z) / scale` instead of `loc + scale * z`,
giving the sampled variable location `loc/scale` and scale `1/scale`.

`rng_fn_scipy` and the JAX dispatch are both correct, so only the numba backend
was affected -- but it is the default linker. `logp` is untouched, so NUTS
posteriors were fine; everything that draws was not, including
`sample_prior_predictive` on a `HalfCauchy` prior.

The existing `cauchy` case in `test_unaligned_RandomVariable` passed `scale=1.0`,
where `(loc + z) / 1` is algebraically identical to `loc + 1 * z`, so both the
location and scale errors vanished together. Bumping that to `scale=3.0` makes
the Cramer-von Mises check fail on the old code (p = 1.7e-08) and pass on the new.

Closes pymc-devs#2308
`test_unaligned_RandomVariable` is the only test that checks these samplers
against their distribution, and it has three cases. `cauchy` and `gumbel` both
used `scale=1.0`; `t` already passes `scale=np.pi`.

`GumbelRV` has a hand-written core too (`loc - scale * np.log(-np.log(U))`) and
is correct, but at `scale=1` a `(loc - z) / scale`-style slip would be invisible
there for the same algebraic reason. Bumped to `scale=4.0`. Verified by injecting
exactly that slip: the test fails at p=7.2e-08 with it and passes without.

Audited the other hand-written numba cores (`t`, `halfnormal`, `pareto`,
`invgamma`, `gumbel`, `wald`, plus the default-path RVs) against scipy with
non-degenerate parameters -- all match, so `cauchy` was the only actual bug.
@notluquis notluquis changed the title Fix numba CauchyRV loc/scale Fix numba CauchyRV loc/scale; un-degenerate the loc-scale GOF test cases Jul 27, 2026
@ricardoV94 ricardoV94 changed the title Fix numba CauchyRV loc/scale; un-degenerate the loc-scale GOF test cases Fix numba CauchyRV loc/scale Jul 27, 2026
@ricardoV94 ricardoV94 added bug Something isn't working numba random variables labels Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working numba random variables

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: numba backend samples Cauchy/HalfCauchy with the wrong loc and scale

2 participants