PDE-based numerical Green’s function (spectroxide.greens_table)#

Precomputed numerical Green’s function from the Rust PDE, tabulated for fast convolution of arbitrary injection histories. Strictly more accurate than the analytic Green’s function, especially in the μ↔y transition region (3 × 10⁴ < z < 10⁵) where the analytic visibility fits break down.

Use this when you need fast convolution but want PDE-quality results (e.g. parameter scans where running the full PDE per point is too expensive). For one-off solves, run the PDE directly.

Quick example#

from spectroxide.greens_table import load_or_build_greens_table

# Loads from cache; builds via Rust PDE if missing
table = load_or_build_greens_table()

# Convolve over a heating history dQ/dz
import numpy as np
x  = np.logspace(-2, 1.5, 200)
dq_dz = lambda z: 1e-9 / (1.0 + z)
dn = table.convolve(x, dq_dz, z_min=1e3, z_max=1e7)

Precomputed Green’s-function tables for CMB spectral distortions.

Two table classes#

  • GreensTable — 2-D heating Green’s function G_th(x, z_h).

  • PhotonGreensTable — 3-D photon-injection Green’s function G_ph(x, x_inj, z_h).

Tables are built by running the PDE solver at many injection redshifts, then interpolating for fast convolution of arbitrary injection histories. This eliminates the 30–70% shape errors of the analytic Green’s function in the μ-to-y transition region 3 × 10⁴ < z < 10⁵.

Usage:

from spectroxide import load_or_build_greens_table

# Build (or load cached) heating table
table = load_or_build_greens_table()
# Force a rebuild via:
table = load_or_build_greens_table(rebuild=True)

# Evaluate Δn(x) per unit Δρ/ρ at injection redshift z_h
dn = table.greens_function(x, z_h=5e4) * delta_rho

# Convolve with an arbitrary heating history
dn = table.distortion_from_heating(x, dq_dz, z_min=1e3, z_max=3e6)

Tables#

Two table classes wrap the precomputed Rust output: GreensTable for energy injection (single z_h axis) and PhotonGreensTable for monochromatic photon injection (two-dimensional (x_inj, z_h) axis).

GreensTable#

GreensTable

Precomputed heating Green's function table.

GreensTable.greens_function

Evaluate the tabulated PDE Green's function G_th(x, z_h).

GreensTable.distortion_from_heating

Convolve the table with an arbitrary heating history.

GreensTable.mu_y_from_heating

Compute (μ, y) from arbitrary heating.

GreensTable.save

Save the table to a compressed .npz file.

GreensTable.load

Load a table from a .npz file.

class spectroxide.greens_table.GreensTable[source]#

Bases: object

Precomputed heating Green’s function table.

Stores G_th(x, z_h) = Delta-n per unit Delta-rho/rho at each (frequency, injection redshift) grid point. Built from PDE solver runs at each z_h.

Variables:
  • z_h (np.ndarray) – Injection redshifts, shape (N_z,).

  • x (np.ndarray) – Frequency grid, shape (N_x,).

  • g_th (np.ndarray) – Green’s function values, shape (N_x, N_z). g_th[:, j] is Delta-n(x) per unit Delta-rho/rho for injection at z_h[j].

  • mu (np.ndarray) – Mu parameter per z_h, shape (N_z,).

  • y_param (np.ndarray) – y parameter per z_h, shape (N_z,).

  • delta_rho_over_rho (np.ndarray) – Energy conservation check per z_h, shape (N_z,).

  • metadata (dict) – Build parameters and provenance info.

GreensTable.greens_function(x, z_h)[source]#

Evaluate the tabulated PDE Green’s function G_th(x, z_h).

Cubic-spline interpolation in ln(z_h) per stored frequency, followed by linear interpolation across frequencies in ln x. Both axes are clipped to the stored range; queries outside the range are pinned to the nearest edge (no extrapolation).

No analytic Green’s function is consulted — the result depends only on the cached PDE table.

Parameters:
  • x (float or array_like) – Dimensionless frequency.

  • z_h (float) – Injection redshift.

Returns:

ndarray of float64Δn(x) per unit Δρ/ρ.

GreensTable.distortion_from_heating(x_grid, dq_dz, z_min, z_max, n_z=5000)[source]#

Convolve the table with an arbitrary heating history.

\[\Delta n(x) = \int_{z_{min}}^{z_{max}} G_{th}(x, z') \frac{d(\Delta\rho/\rho_\gamma)}{dz'} \, dz',\]

integrated in ln(1+z) with the trapezoidal rule.

The convolution evaluates linearly in (log x, log z_h) against the raw cached G_th (no build-time NC strip), summed on the cache’s native self.x grid, then linearly interpolated to x_grid. No NC strip is applied; callers that want the number-conserving Δn should call strip_gbb().

Parameters:
  • x_grid (array_like) – Output frequency grid.

  • dq_dz (callable) – Heating rate d(Δρ/ρ_γ)/dz (positive for heating).

  • z_min (float) – Minimum integration redshift.

  • z_max (float) – Maximum integration redshift.

  • n_z (int, optional) – Number of redshift integration points (default 5000).

Returns:

ndarray of float64Δn(x) evaluated on x_grid.

GreensTable.mu_y_from_heating(dq_dz, z_min, z_max, n_z=5000)[source]#

Compute (μ, y) from arbitrary heating.

Parameters:
  • dq_dz (callable) – Heating rate d(Δρ/ρ)/dz (positive for heating).

  • z_min (float) – Minimum integration redshift.

  • z_max (float) – Maximum integration redshift.

  • n_z (int, optional) – Number of redshift integration points (default 5000).

Returns:

tuple of (float, float)(μ, y) parameters (dimensionless).

GreensTable.save(path=None)[source]#

Save the table to a compressed .npz file.

Parameters:

path (str or Path, optional) – Output path. Default ~/.spectroxide/greens_table.npz.

Returns:

None

classmethod GreensTable.load(path=None, verify_hash=True)[source]#

Load a table from a .npz file.

Parameters:
  • path (str or Path, optional) – Input path. Default ~/.spectroxide/greens_table.npz.

  • verify_hash (bool, optional) – If True (default), check that the cached table’s physics_hash metadata matches the current Rust binary’s compile-time hash; emits a GreensTableHashMismatch warning if not. Disable for synthetic / test tables that were not built by the Rust solver.

Returns:

GreensTable – Reconstructed table object.

Warns:

GreensTableHashMismatch – If verify_hash=True and the cached hash differs from the currently installed binary.

PhotonGreensTable#

Note

The photon Green’s function depends on both the injection redshift z_h and the injection frequency x_inj, so the table is two-dimensional and convolution against an injection history requires a 2-D integral. For dense scans this is often slower than just running the PDE directly.

PhotonGreensTable

Precomputed photon injection Green's function table.

PhotonGreensTable.greens_function_photon

Interpolate G_ph(x_obs, x_inj, z_h).

PhotonGreensTable.distortion_from_photon_injection

Convolve the table with a photon-injection history.

PhotonGreensTable.save

Save the table to a compressed .npz file.

PhotonGreensTable.load

Load a table from a .npz file.

class spectroxide.greens_table.PhotonGreensTable[source]#

Bases: object

Precomputed photon injection Green’s function table.

Stores G_ph(x_obs, x_inj, z_h) = Delta-n per unit Delta-N/N at each (observation frequency, injection frequency, injection redshift) grid point.

Variables:
  • z_h (np.ndarray) – Injection redshifts, shape (N_z,).

  • x (np.ndarray) – Observation frequency grid, shape (N_x,).

  • x_inj (np.ndarray) – Injection frequencies, shape (N_xinj,).

  • g_ph (np.ndarray) – Green’s function values, shape (N_x, N_xinj, N_z).

  • metadata (dict) – Build parameters and provenance info.

PhotonGreensTable.greens_function_photon(x_obs, x_inj, z_h)[source]#

Interpolate G_ph(x_obs, x_inj, z_h).

Drop-in replacement for spectroxide.greens.greens_function_photon(). Uses 3-D linear interpolation in (log x_obs, log x_inj, log z_h) with edge clipping (no extrapolation).

Parameters:
  • x_obs (float or array_like) – Observation frequency.

  • x_inj (float) – Injection frequency.

  • z_h (float) – Injection redshift.

Returns:

ndarray of float64Δn(x_obs) per unit ΔN/N.

PhotonGreensTable.distortion_from_photon_injection(x_grid, x_inj, dn_dz, z_min, z_max, n_z=5000)[source]#

Convolve the table with a photon-injection history.

Parameters:
  • x_grid (array_like) – Observation frequency grid.

  • x_inj (float) – Injection frequency.

  • dn_dz (callable) – Source rate d(ΔN/N)/dz (positive for injection).

  • z_min (float) – Minimum integration redshift.

  • z_max (float) – Maximum integration redshift.

  • n_z (int, optional) – Number of redshift integration points (default 5000).

Returns:

ndarray of float64 – Distortion Δn(x) on x_grid.

PhotonGreensTable.save(path=None)[source]#

Save the table to a compressed .npz file.

Parameters:

path (str or Path, optional) – Output path. Default ~/.spectroxide/photon_greens_table.npz.

Returns:

None

classmethod PhotonGreensTable.load(path=None, verify_hash=True)[source]#

Load a table from a .npz file.

Parameters:
  • path (str or Path, optional) – Input path. Default ~/.spectroxide/photon_greens_table.npz.

  • verify_hash (bool, optional) – If True (default), check the cached table’s physics_hash against the current Rust binary; emits a GreensTableHashMismatch warning on mismatch.

Returns:

PhotonGreensTable – Reconstructed table object.

Warns:

GreensTableHashMismatch – If verify_hash=True and the hashes differ.

Caching#

Tables are expensive to build (one PDE solve per z_h), so the load_or_build_* entry points cache results on disk and reuse them across sessions. Each cached table is tagged with a hash of the physics configuration used to generate it; on load, the hash is checked against the current code and a GreensTableHashMismatch warning is emitted if they disagree, so stale caches from earlier code versions do not silently shadow updated physics. Pass rebuild=True to force a fresh build, or delete the cache file to start over.

class spectroxide.greens_table.GreensTableHashMismatch[source]#

Bases: UserWarning

Warned when a cached Green’s function table was built by a different physics-code version than the currently-installed Rust binary.

The cached table and the current binary may produce inconsistent results. Regenerate via load_or_build_greens_table(rebuild=True) to bring the cache back in sync. To suppress the warning, pass verify_hash=False to load.

Builders / loaders#

Cache-aware constructors that load from disk or trigger a Rust PDE build if no cached table is present.

load_or_build_greens_table

Load a cached heating table, or build one if not found.

load_or_build_photon_greens_table

Load a cached photon table, or build one if not found.

spectroxide.greens_table.load_or_build_greens_table(cache_path=None, rebuild=False, verify_hash=True, **kwargs)[source]#

Load a cached heating table, or build one if not found.

Parameters:
  • cache_path (str or Path, optional) – Cache file path. Default ~/.spectroxide/greens_table.npz.

  • rebuild (bool, optional) – Force rebuild even if the cache exists (default False).

  • verify_hash (bool, optional) – If True (default), verify the cached table’s physics_hash against the current Rust binary; emits a GreensTableHashMismatch warning on mismatch. Pass rebuild=True to regenerate after a code change.

  • **kwargs – Forwarded to the private _build_greens_table builder when a new table needs to be generated (e.g. z_h_grid, n_threads).

Returns:

GreensTable – Loaded or newly built table.

Warns:

GreensTableHashMismatch – If verify_hash=True and the cached hash differs.

spectroxide.greens_table.load_or_build_photon_greens_table(cache_path=None, rebuild=False, verify_hash=True, **kwargs)[source]#

Load a cached photon table, or build one if not found.

Parameters:
  • cache_path (str or Path, optional) – Cache file path. Default ~/.spectroxide/photon_greens_table.npz.

  • rebuild (bool, optional) – Force rebuild even if the cache exists (default False).

  • verify_hash (bool, optional) – If True (default), verify the cached table’s physics_hash against the current Rust binary; emits a GreensTableHashMismatch warning on mismatch.

  • **kwargs – Forwarded to the private _build_photon_greens_table builder when a new table needs to be generated (e.g. x_inj_grid, z_h_grid, n_threads).

Returns:

PhotonGreensTable – Loaded or newly built table.

Warns:

GreensTableHashMismatch – If verify_hash=True and the cached hash differs.