#cython: language_level=3, boundscheck=False """ Cython inverse efuncs for cosmology integrals""" cimport cython from libc.math cimport exp, pow ## Inverse efunc methods for various dark energy subclasses ## These take only scalar arguments since that is what the integral ## routines give them. ## Implementation notes: ## * Using a python list for nu_y seems to be faster than a ndarray, ## given that nu_y generally has a small number of elements, ## even when you turn off bounds checking, etc. ## * Using pow(x, -0.5) is slightly faster than x**(-0.5) and ## even more so than 1.0 / sqrt(x) ## * Hardwiring in the p, 1/p, k, prefac values in nufunc is ## nontrivially faster than declaring them with cdef ######### LambdaCDM # No relativistic species def lcdm_inv_efunc_norel(double z, double Om0, double Ode0, double Ok0): cdef double opz = 1.0 + z return pow(opz**2 * (opz * Om0 + Ok0) + Ode0, -0.5) # Massless neutrinos def lcdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Ok0, double Or0): cdef double opz = 1.0 + z return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0, -0.5) # With massive neutrinos def lcdm_inv_efunc(double z, double Om0, double Ode0, double Ok0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0, -0.5) ######## FlatLambdaCDM # No relativistic species def flcdm_inv_efunc_norel(double z, double Om0, double Ode0): return pow((1. + z)**3 * Om0 + Ode0, -0.5) # Massless neutrinos def flcdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Or0): cdef double opz = 1.0 + z return pow(opz**3 * (opz * Or0 + Om0) + Ode0, -0.5) # With massive neutrinos def flcdm_inv_efunc(double z, double Om0, double Ode0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) return pow(opz**3 * (opz * Or0 + Om0) + Ode0, -0.5) ######## wCDM # No relativistic species def wcdm_inv_efunc_norel(double z, double Om0, double Ode0, double Ok0, double w0): cdef double opz = 1.0 + z return pow(opz**2 * (opz * Om0 + Ok0) + Ode0 * opz**(3. * (1.0 + w0)), -0.5) # Massless neutrinos def wcdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Ok0, double Or0, double w0): cdef double opz = 1.0 + z return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * opz**(3. * (1.0 + w0)), -0.5) # With massive neutrinos def wcdm_inv_efunc(double z, double Om0, double Ode0, double Ok0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y, double w0): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * opz**(3. * (1.0 + w0)), -0.5) ######## Flat wCDM # No relativistic species def fwcdm_inv_efunc_norel(double z, double Om0, double Ode0, double w0): cdef double opz = 1.0 + z return pow(opz**3 * Om0 + Ode0 * opz**(3. * (1.0 + w0)), -0.5) # Massless neutrinos def fwcdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Or0, double w0): cdef double opz = 1.0 + z return pow(opz**3 * (opz * Or0 + Om0) + Ode0 * opz**(3. * (1.0 + w0)), -0.5) # With massive neutrinos def fwcdm_inv_efunc(double z, double Om0, double Ode0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y, double w0): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) return pow(opz**3 * (opz * Or0 + Om0) + Ode0 * opz**(3. * (1.0 + w0)), -0.5) ######## w0waCDM # No relativistic species def w0wacdm_inv_efunc_norel(double z, double Om0, double Ode0, double Ok0, double w0, double wa): cdef double opz = 1.0 + z cdef double Odescl = opz**(3. * (1 + w0 + wa)) * exp(-3.0 * wa * z / opz) return pow(opz**2 * (opz * Om0 + Ok0) + Ode0 * Odescl, -0.5) # Massless neutrinos def w0wacdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Ok0, double Or0, double w0, double wa): cdef double opz = 1.0 + z cdef double Odescl = opz**(3. * (1 + w0 + wa)) * exp(-3.0 * wa * z / opz) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * Odescl, -0.5) def w0wacdm_inv_efunc(double z, double Om0, double Ode0, double Ok0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y, double w0, double wa): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) cdef double Odescl = opz**(3. * (1 + w0 + wa)) * exp(-3.0 * wa * z / opz) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * Odescl, -0.5) ######## Flatw0waCDM # No relativistic species def fw0wacdm_inv_efunc_norel(double z, double Om0, double Ode0, double w0, double wa): cdef double opz = 1.0 + z cdef double Odescl = opz**(3. * (1 + w0 + wa)) * exp(-3.0 * wa * z / opz) return pow(opz**3 * Om0 + Ode0 * Odescl, -0.5) # Massless neutrinos def fw0wacdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Or0, double w0, double wa): cdef double opz = 1.0 + z cdef double Odescl = opz**(3. * (1 + w0 + wa)) * exp(-3.0 * wa * z / opz) return pow((opz * Or0 + Om0) * opz**3 + Ode0 * Odescl, -0.5) # With massive neutrinos def fw0wacdm_inv_efunc(double z, double Om0, double Ode0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y, double w0, double wa): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) cdef double Odescl = opz**(3. * (1 + w0 + wa)) * exp(-3.0 * wa * z / opz) return pow((opz * Or0 + Om0) * opz**3 + Ode0 * Odescl, -0.5) ######## wpwaCDM # No relativistic species def wpwacdm_inv_efunc_norel(double z, double Om0, double Ode0, double Ok0, double wp, double apiv, double wa): cdef double opz = 1.0 + z cdef double Odescl = opz**(3. * (1. + wp + apiv * wa)) * exp(-3. * wa * z / opz) return pow(opz**2 * (opz * Om0 + Ok0) + Ode0 * Odescl, -0.5) # Massless neutrinos def wpwacdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Ok0, double Or0, double wp, double apiv, double wa): cdef double opz = 1.0 + z cdef double Odescl = opz**(3. * (1. + wp + apiv * wa)) * exp(-3. * wa * z / opz) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * Odescl, -0.5) # With massive neutrinos def wpwacdm_inv_efunc(double z, double Om0, double Ode0, double Ok0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y, double wp, double apiv, double wa): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) cdef double Odescl = opz**(3. * (1. + wp + apiv * wa)) * exp(-3. * wa * z / opz) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * Odescl, -0.5) ######## FlatwpwaCDM # No relativistic species def fwpwacdm_inv_efunc_norel(double z, double Om0, double Ode0, double wp, double apiv, double wa): cdef double opz = 1.0 + z cdef double Odescl = opz**(3. * (1. + wp + apiv * wa)) * exp(-3. * wa * z / opz) return pow(opz**3 * Om0 + Ode0 * Odescl, -0.5) # Massless neutrinos def fwpwacdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Or0, double wp, double apiv, double wa): cdef double opz = 1.0 + z cdef double Odescl = opz**(3. * (1. + wp + apiv * wa)) * exp(-3. * wa * z / opz) return pow((opz * Or0 + Om0) * opz**3 + Ode0 * Odescl, -0.5) # With massive neutrinos def fwpwacdm_inv_efunc(double z, double Om0, double Ode0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y, double wp, double apiv, double wa): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) cdef double Odescl = opz**(3. * (1. + wp + apiv * wa)) * exp(-3. * wa * z / opz) return pow((opz * Or0 + Om0) * opz**3 + Ode0 * Odescl, -0.5) ######## w0wzCDM # No relativistic species def w0wzcdm_inv_efunc_norel(double z, double Om0, double Ode0, double Ok0, double w0, double wz): cdef double opz = 1.0 + z cdef double Odescl = opz**(3. * (1. + w0 - wz)) * exp(3. * wz * z) return pow(opz**2 * (opz * Om0 + Ok0) + Ode0 * Odescl, -0.5) # Massless neutrinos def w0wzcdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Ok0, double Or0, double w0, double wz): cdef double opz = 1.0 + z cdef double Odescl = opz**(3. * (1. + w0 - wz)) * exp(3. * wz * z) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * Odescl, -0.5) # With massive neutrinos def w0wzcdm_inv_efunc(double z, double Om0, double Ode0, double Ok0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y, double w0, double wz): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) cdef double Odescl = opz**(3. * (1. + w0 - wz)) * exp(3. * wz * z) return pow((((opz * Or0 + Om0) * opz) + Ok0) * opz**2 + Ode0 * Odescl, -0.5) ######## Flatw0wzCDM # No relativistic species def fw0wzcdm_inv_efunc_norel(double z, double Om0, double Ode0, double w0, double wz): cdef double opz = 1.0 + z cdef double Odescl = opz**(3. * (1. + w0 - wz)) * exp(3. * wz * z) return pow(opz**3 * Om0 + Ode0 * Odescl, -0.5) # Massless neutrinos def fw0wzcdm_inv_efunc_nomnu(double z, double Om0, double Ode0, double Or0, double w0, double wz): cdef double opz = 1.0 + z cdef double Odescl = opz**(3. * (1. + w0 - wz)) * exp(3. * wz * z) return pow((opz * Or0 + Om0) * opz**3 + Ode0 * Odescl, -0.5) # With massive neutrinos def fw0wzcdm_inv_efunc(double z, double Om0, double Ode0, double Ogamma0, double NeffPerNu, int nmasslessnu, list nu_y, double w0, double wz): cdef double opz = 1.0 + z cdef double Or0 = Ogamma0 * (1.0 + nufunc(opz, NeffPerNu, nmasslessnu, nu_y)) cdef double Odescl = opz**(3. * (1. + w0 - wz)) * exp(3. * wz * z) return pow((opz * Or0 + Om0) * opz**3 + Ode0 * Odescl, -0.5) ######## Neutrino relative density function # Scalar equivalent to FLRW.nu_realative_density in core.py # Please see that for further discussion. # This should only be called with massive neutrinos (e.g., nu_y is not empty) # Briefly, this is just a numerical fitting function to the true relationship, # which is too expensive to want to evaluate directly. The # constants which appear are: # p = 1.83 -> numerical fitting constant from Komatsu et al. # 1/p = 0.54644... -> same constant # k = 0.3173 -> another fitting constant # 7/8 (4/11)^(4/3) = 0.2271... -> fermion/boson constant for neutrino # contribution -- see any cosmology book # The Komatsu reference is: Komatsu et al. 2011, ApJS 192, 18 cdef nufunc(double opz, double NeffPerNu, int nmasslessnu, list nu_y): cdef Py_ssize_t i, N = len(nu_y) cdef double k = 0.3173 / opz cdef double rel_mass_sum = nmasslessnu for i in range(N): rel_mass_sum += pow(1.0 + (k * nu_y[i])**1.83, 0.54644808743) return 0.22710731766 * NeffPerNu * rel_mass_sum