Maths utils

This module contains some fast utility functions that are useful in the same contexts as camb. They are entirely independent of the main camb code.

camb.mathutils.airy_ai_fast(x)[source]

Fast Airy \(Ai(x)\) approximation.

Uses a fitted Fortran implementation optimized for < 1e-7 absolute accuracy.

Parameters:

x – scalar or array-like input values

Returns:

Airy \(Ai(x)\), with scalar or array shape matching x

camb.mathutils.airy_fast(x)[source]

Fast Airy \(Ai(x)\) and derivative \(Ai'(x)\) approximation.

Uses a fitted Fortran implementation optimized for < 1e-7 absolute accuracy.

Parameters:

x – scalar or array-like input values

Returns:

tuple (ai, aip) for Airy \(Ai(x)\) and \(Ai'(x)\), with scalar or array shapes matching x

camb.mathutils.chi_squared(covinv, x)[source]

Utility function to efficiently calculate x^T covinv x

Parameters:
  • covinv – symmetric inverse covariance matrix

  • x – vector

Returns:

covinv.dot(x).dot(x), but parallelized and using symmetry

camb.mathutils.legendre_polynomials(x, lmax)[source]

Legendre polynomials \(P_\ell(x)\) and derivatives \(dP_\ell/dx\) for all \(0\le \ell \le\) lmax (requires \(|x| < 1\)).

Parameters:
  • x – scalar or 1D array of x values

  • lmax – maximum \(\ell\)

Returns:

P, dP arrays; shape (lmax+1,) for scalar x, else (len(x), lmax+1)

camb.mathutils.pcl_coupling_matrix(P, lmax, pol=False)[source]

Get Pseudo-Cl coupling matrix from power spectrum of mask. Uses multiple threads. See Eq A31 of astro-ph/0105302

Parameters:
  • P – power spectrum of mask

  • lmax – lmax for the matrix

  • pol – whether to calculate TE, EE, BB couplings

Returns:

coupling matrix (square but not symmetric), or list of TT, TE, EE, BB if pol

camb.mathutils.phi_derivative(L, K, nu, chi)[source]

Evaluate d phi_L^nu(K, chi) / d chi using the adjacent-order recurrence.

camb.mathutils.phi_first_peak_amplitude(L, K, nu)[source]

Return abs(phi_recurs(L, K, nu, phi_first_peak_chi(L, K, nu))).

If phi_first_peak_chi(..., return_status=True) reports no peak found, this is the amplitude at the search boundary rather than at a stationary point.

camb.mathutils.phi_first_peak_chi(L, K, nu, return_status=False)[source]

Return the first peak position at or after the hyperspherical Bessel turning point.

If return_status is true, also return whether no stationary peak was found before the search boundary, in which case the returned position is that boundary.

camb.mathutils.phi_olver(L, K, nu, chi)[source]

Evaluate the regular hyperspherical Bessel function \(\phi_L^\nu(K,\chi)\) using the leading-order Olver map to a flat spherical Bessel function.

Fast with peak-relative accuracy around 1e-4; use phi_recurs() for a slower high-accuracy reference. For K=0 this returns the spherical Bessel function \(j_L(\nu\chi)\). Falls back to the recursive result where the Olver approximation may be unreliable.

Parameters:
  • L – multipole index

  • K – dimensionless curvature sign, one of -1, 0, 1

  • nu – dimensionless radial eigenvalue; for closed models (K=1), an integer mode with nu >= 3 and nu > L

  • chi – non-negative scalar dimensionless radial distance or 1D array of non-negative values

Returns:

scalar value or 1D array matching chi

camb.mathutils.phi_recurs(L, K, nu, chi)[source]

Evaluate the regular hyperspherical Bessel function \(\phi_L^\nu(K,\chi)\) by recurrence.

Uses upward recurrence in the safe oscillatory region and Miller backward recurrence elsewhere, normalized by the exact low-order solution. The recurrence follows Abbott and Schaefer (1986) for the seed and recurrence formulae. Miller starts use the continued-fraction construction of Tram (2017) and Lesgourgues and Tram (2014) for K=0,-1; for K=1 they use either the finite closed-spectrum endpoint or the closed-space Gegenbauer Miller start.

Parameters:
  • L – multipole index

  • K – dimensionless curvature sign, one of -1, 0, 1

  • nu – dimensionless radial eigenvalue; for closed models (K=1), an integer mode with nu >= 3 and nu > L

  • chi – non-negative scalar dimensionless radial distance or 1D array of non-negative values

Returns:

scalar value or 1D array matching chi

camb.mathutils.scalar_coupling_matrix(P, lmax)[source]

Get scalar Pseudo-Cl coupling matrix from power spectrum of mask, or array of power masks. Uses multiple threads. See Eq A31 of astro-ph/0105302

Parameters:
  • P – power spectrum of mask, or list of mask power spectra

  • lmax – lmax for the matrix (assumed square)

Returns:

coupling matrix (square but not symmetric), or list of couplings for different masks

camb.mathutils.threej(l2, l3, m2, m3)[source]

Convenience wrapper around standard 3j function, returning array for all allowed l1 values

Parameters:
  • l2 – L_2

  • l3 – L_3

  • m2 – M_2

  • m3 – M_3

Returns:

array of 3j from max(abs(l2-l3),abs(m2+m3)) .. l2+l3

camb.mathutils.threej_coupling(W, lmax, pol=False)[source]

Calculate symmetric coupling matrix :math`Xi` for given weights \(W_{\ell}\), where \(\langle\tilde{C}_\ell\rangle = \Xi_{\ell \ell'} (2\ell'+1) C_\ell\). The weights are related to the power spectrum of the mask P by \(W_\ell = (2 \ell + 1) P_\ell / 4 \pi\). See e.g. Eq D16 of arxiv:0801.0554.

If pol is False and W is an array of weights, produces array of temperature couplings, otherwise for pol is True produces set of TT, TE, EE, EB couplings (and weights must have one spectrum - for same masks - or three).

Use scalar_coupling_matrix() or pcl_coupling_matrix() to get the coupling matrix directly from the mask power spectrum.

Parameters:
  • W – 1d array of Weights for each L, or list of arrays of weights (zero based)

  • lmax – lmax for the output matrix (assumed symmetric, though not in principle)

  • pol – if pol, produce TT, TE, EE, EB couplings for three input mask weights (or one if assuming same mask)

Returns:

symmetric coupling matrix or array of matrices

camb.mathutils.threej_pt(l1, l2, l3, m1, m2, m3)[source]

Convenience testing function to get 3j for specific arguments. Normally use threej to get an array at once for same cost.

Parameters:
  • l1 – L_1

  • l2 – L_2

  • l3 – L_3

  • m1 – M_1

  • m2 – M_2

  • m3 – M_3

Returns:

Wigner 3j (integer zero if outside triangle constraints)