Skip to content

fix(thermo): stable gradients for exp_m_kappa and g visibility splines - #22

Open
MinhMPA wants to merge 6 commits into
smsharma:mainfrom
MinhMPA:fix/thermo-remaining-gradients
Open

fix(thermo): stable gradients for exp_m_kappa and g visibility splines#22
MinhMPA wants to merge 6 commits into
smsharma:mainfrom
MinhMPA:fix/thermo-remaining-gradients

Conversation

@MinhMPA

@MinhMPA MinhMPA commented May 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Stacked on PR-A (#20, `fix/kd-dloga-gradient`). Merge this PR after #20 lands — the commits from #20 are included in this diff and will vanish automatically once #20 is merged.

Extends the n_H_0 rescaling fix from PR-A to the two remaining visibility-function splines: `exp_m_kappa` and `g`. Without this, `jax.grad` through any quantity touching the visibility function (source functions, C_l) produces `nan`/`inf`.

Fix: Same rescaling pattern as PR-A (#20):
```python
_emk_safe = stop_gradient(exp_m_kappa) * (n_H_0 / stop_gradient(n_H_0))
_g_safe = stop_gradient(g) * (n_H_0 / stop_gradient(n_H_0))
```

Changes (on top of PR-A)

  • `clax/thermodynamics.py`: `_emk_safe` and `_g_safe` rescaling for `exp_m_kappa` and `g`
  • `tests/test_thermodynamics.py`: 3 new FD-vs-AD gradient tests + 3 new JVP tests for the visibility function splines

Merge order (4-PR AD-correctness series)

  1. Merge PR-A (fix(thermo): stable kappa_dot/dkd_dloga gradient via n_H_0 rescaling #20, `fix/kd-dloga-gradient` → `main`) first
  2. Merge PR-B (feat(thermo/shooting): forward-mode AD via custom_jvp for _find_z_reio and shoot_fn #21, `feat/forward-mode-ad` → `main`) — concurrent with PR-A
  3. After fix(thermo): stable kappa_dot/dkd_dloga gradient via n_H_0 rescaling #20 lands: merge this PR — its diff will shrink to just the `exp_m_kappa`/`g` changes
  4. After all three land in `smsharma/clax:main`: merge PR-D (`MinhMPA/clax-pt: fix/ad-correctness-clax-pt` → `benchmark/clax-pt`)

Test plan

  • `pytest tests/test_thermodynamics.py -x -q` — all new gradient + JVP tests GREEN
  • `pytest tests/ --fast -x -q` — smoke gate GREEN

MinhMPA and others added 6 commits May 9, 2026 02:40
…ling

The Friedmann-scan accumulates a spurious d(a_grid[i])/d(omega_b) eigenvalue
product (~10^14 at loga=-8). The spline derivative's 1/h factor amplifies this
by ~1200x, causing AD to return ~10^17 instead of the physical ~-335.

Fix: stop all accumulated gradient in kappa_dot_grid, then restore only the
n_H_0 ∝ omega_b path (exact, since kappa_dot ∝ n_H_0 linearly):
  _kappa_dot_for_deriv = sg(kappa_dot_grid) * n_H_0 / sg(n_H_0)

Also adds dkappa_dot_dloga_of_loga to ThermoResult and the regression test
test_opacity_logderivative_gradient_matches_fd_for_omega_b (<1% vs FD).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s (RED)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Applies n_H_0 rescaling to kappa_dot_of_loga, exp_m_kappa_of_loga, and
g_of_loga to stop the accumulated Friedmann-scan gradient (~10^8x FD blowup).
Unifies the _kappa_dot_for_deriv helper into _kd_safe, reused for the
kappa_dot spline itself and for g_prime_grid computation.

Gradient accuracy: exact where x_e~const (loga<-8); 10-30% residual
near recombination (loga~-7) from d(xe)/d(omega_b) — still finite vs
the prior blowup.

GREEN: test_kappa_dot_gradient_matches_fd_for_omega_b
GREEN: test_exp_m_kappa_gradient_matches_fd_for_omega_b
GREEN: test_g_gradient_matches_fd_for_omega_b
10/10 thermodynamics tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents forward-mode AD fixes (z_reio, shoot_fn, kappa/g splines)
and notes PR URLs for manual opening (gh CLI unavailable on compute node).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…_kappa, g

Three new xfail tests in TestThermoForwardModeAD confirm the intent: once
PR-B (_find_z_reio custom_jvp) and the background DirectAdjoint wiring are
merged, jax.jvp through the n_H_0-rescaled splines should be finite and
match centred FD to <1% at loga=-8.

Marked xfail(raises=TypeError) on this branch because two custom_vjp
barriers block full-pipeline forward-mode:
  1. background_solve uses RecursiveCheckpointAdjoint by default
  2. _find_z_reio still uses custom_vjp (fixed in feat/forward-mode-ad)

Also adds _thermo_jvp_fd_pair helper analogous to _thermo_ad_fd_pair.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant