Skip to content

Curvature#35

Draft
cgiovanetti wants to merge 22 commits into
mainfrom
curvature
Draft

Curvature#35
cgiovanetti wants to merge 22 commits into
mainfrom
curvature

Conversation

@cgiovanetti

Copy link
Copy Markdown
Collaborator

Flagging this as done pending review. Eliminates tabulated bessel functions at a cost of 0.2s with or without lensing. Fully implements curvature.

@TonyZhou729 I'll give it a review first and let you know when it's ready for you.

Cara Giovanetti and others added 22 commits June 12, 2026 15:52
Three research reports (ABCMB flat-geometry audit, CLASS curvature
equations, CLASS hyperspherical/transfer machinery) plus the condensed
design doc for the Omega_k implementation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s_l hierarchy factors, curved Einstein constraints and ICs

- main.py: omega_k (=Omega_k h^2) default + derived K = -omega_k H100^2;
  closure omega_Lambda subtracts omega_k; expected_keys updated.
- species.py: Curvature(BackgroundFluid) pseudo-fluid (rho ~ a^-2, w=-1/3)
  makes H/aH_prime automatically curved; curvature_s_l() free-streaming
  coefficients; CLASS-verbatim (arXiv:1305.3261) s_l factors in the photon
  T/pol, massless-nu and massive-nu hierarchies; cot_K l_max truncations;
  s2^2 = 1-3K/k^2 factors in all adiabatic ICs.
- perturbations.py: (k^2-3K) Einstein constraints + K h'/2 in eta'
  (both get_derivatives and make_output_table copies); s2^2 in eta_ini.
- background.py: sqrt(1-K rs^2) in the rs ODE; rA_rec = sin_K(chi_rec).
- ABCMBTools.py: sin_K/cot_K helpers via entire functions of K chi^2
  (series at small argument: smooth through K=0, AD-safe branches).
- model_specs.py: Curvature registered in LCDM species; static
  curvature/omega_k_ref specs; curved k_min for the perturbation grid
  (closed: sqrt(8K) nu=3 cutoff; open: sqrt(|K|)); |K| in scale2.

All value-level changes reduce exactly to the flat equations at K = 0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… + curved Limber lensing

- spectrum.py: _transfer_sources extracted (shared flat/curved; s_2 factor in
  the polarization weight, = 1 exactly at K=0); Cl_one_ell consumes prebuilt
  sources; new _Cl_all_ells_curved generates Phi_l^nu(chi) by the exact
  dimensionful forward recurrence (seeds Phi_0, Phi_1 in closed form; smooth
  through K=0) in one chunked, checkpointed lax.scan over ALL integer ells,
  contracting against the LOS sources at each l — radial functions
  T0/T1/T2/E per CLASS transfer_radial_function; evanescent region clamped
  and masked at the same |Phi|~1e-10 threshold as the flat tables (cutoff
  variable q*S_K(chi), thresholds reused from the tables' lower edges);
  closed-universe l>=nu termination and open supercurvature q^2<=0 masks.
  get_Cl: static specs['curvature'] switch (False = existing flat tables).
- lensing_Cl: curved-sky Limber (q=(l+1/2)/S_K, sin_K window, 1/(S_K^2 k^3)
  measure, WKB amplitude (1-K l^2/q^2)^(-1/2)) — reduces exactly to the
  prior flat integrand at K=0. lensing_power_spectrum: curved Poisson
  k^3/(k^2-3K)^2 and Omega_k(1+z)^2 in Om(z).
- species.py truncations use the dimensionless g = tau*cot_K(tau) factor so
  the flat path keeps the original floating-point evaluation order.
- main.py: pass specs['curvature'] into SpectrumSolver.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n region)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e edges

The flat Bessel tables start at x = 0 for l <= 17, so interpolating their
lower edges left the low-l mask wide open and clipped deep-evanescent
recurrence garbage (|Phi| ~ 1e10) entered the transfer integral (smoke test:
ClTT ~ 1e13 vs 1e-12). Use CLASS's hyperspherical_get_xmin_from_approx
closed form for every l; it matches the table edges where they exist
(l=5000: 4899 vs 4895).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…teger-nu lattice

For closed references the angular diameter distance shrinks, so k_max is
divided by the fiducial angular rescaling S_K(chi*)/chi* (CLASS does the
same); the transfer grid's low end is resampled to the exact Delta nu = 1
integer lattice up to nu = 512 (covers the sharp ell ~ nu C_l onsets and
makes the k-trapezoid the exact discrete-mode sum there), then the flat-built
grid snapped to distinct integers. Also: Clpp comparison added to the
vs-CLASS script.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…r grid

(1) At exact integer nu the recurrence coefficient q^2-K(l+1)^2 is
analytically zero but numerically O(eps q^2) of either sign; a positive
sliver divided the advance by ~1e-11 and produced unmasked 1e10 garbage at
ell = nu (the -0.05 unlensed control blew up 1e7 at ell 24-54). Threshold at
1e-6 q^2 (legitimate minimum is 2 q^2/nu).
(2) Open universes: walk the transfer grid in q (the oscillation variable)
and map to k = sqrt(q^2-K), sampling the q->0 region the flat k-walk missed
(CLASS densifies low-q for open; EE ell~3 was 3.5e-3 off).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nsition style)

The abrupt Delta nu = 1 -> ~7 jump at nu = 512 left a trapezoid boundary
artifact in the oscillatory k-integrand, degrading C_l for ell whose support
crosses the junction (-0.01: 2e-2 at ell~137; -0.05: 6.5e-2 at ell~237 —
both map to nu just below the junction). Ramp the integer step linearly
over 250 points instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…verse crash)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…trum path

get_Cl now always uses _Cl_all_ells_curved (smooth through K=0 -> j_l), for flat and curved cosmologies alike. Removes the tabulated flat path entirely: the 79 MB bessel_tab/*.txt, the sparse-ell CubicSpline reconstruction, the Q/J/j large-x asymptotic, the module-level phi0/phi1/phi2, the Cl_one_ell method, the ells_indices/lensing_ells_indices fields, and the scipy.special.spherical_jn import (~256 lines). Drops bessel_tab from setup.cfg package_data.

This eliminates the hard l=5000 cap (raise l_top, no re-tabulation) and the flat path's one genuine approximation (the spline); the recurrence matches scipy.special.spherical_jn to ~1e-14 at K=0, so it is the more correct generator. The 'curvature' flag now only gates k-grid construction, not spectrum-path selection.

Validated (1xA100): forward finite + sane for lensing off and on (warm 9.96/10.69 s, a wash); K=0 reverse-AD final gradients finite; accuracy_test PASSED vs CLASS at the 1% gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…drop dead code

Remove the tracked notes_curvature/ directory (test scripts, design .md notes, changelog drafts; ~3700 lines, not production code). Trim verbose inline comments (ABCMBTools header, the recurrence body in spectrum.py, the CLASS-internals blocks in model_specs.py, the repeated s_l hierarchy comments in species.py) while keeping the NumPy-structured docstrings with the project's Parameters:/Returns: colon convention for autodoc.

Drop dead code: model_specs angular_rescaling_ref was set but never read, and the angular rescaling is now computed only in the closed branch where it is used.

Behavior unchanged: flat/open k-grids bit-identical, closed algebraically identical. Validated flat+open+closed forwards finite and accuracy_test PASSED (vs CLASS, 1% gate).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cgiovanetti cgiovanetti requested a review from TonyZhou729 June 15, 2026 19:11
@cgiovanetti cgiovanetti self-assigned this Jun 15, 2026
@cgiovanetti cgiovanetti marked this pull request as draft June 17, 2026 21:17
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