Source code for pyflation.analysis.nonadiabatic

""" pyflation.analysis.nonadiabatic - Module to calculate relative pressure
perturbations.


"""
#Author: Ian Huston
#For license and copyright information see LICENSE.txt which was distributed with this file.


from __future__ import division
import numpy as np

import utilities

[docs]def soundspeeds(Vphi, phidot, H): """Sound speeds of the background fields Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter Returns ------- calphasq : array sound speed (squared) of the background fields Notes ----- All the arguments should have the same number of dimensions. Vphi and phidot should be arrays of the same size, but H should have a dimension of size 1 corresponding to the "field" dimension of the other variables. """ try: calphasq = 1 + 2*Vphi/(3*H**2*phidot) except ValueError: raise ValueError("""Arrays need to have the correct shape. Vphi and phidot should have exactly the same shape, and H should have a dimension of size 1 corresponding to the field dimension of the others.""") return calphasq
[docs]def totalsoundspeed(Vphi, phidot, H, axis): """Total sound speed of the fluids Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter axis : integer Index of dimension to sum over (field dimension). All the arguments should have the same number of dimensions. Vphi and phidot should be arrays of the same size, but H should have a dimension of size 1 corresponding to the "field" dimension of the other variables. Returns ------- csq : array_like The total sound speed of the fluid, csq = P'/rho' """ try: csq = 1 + 2*np.sum(Vphi*phidot, axis=axis)/(3*np.sum((H*phidot)**2, axis=axis)) except ValueError: raise ValueError("""Arrays need to have the correct shape. Vphi and phidot should have exactly the same shape, and H should have a dimension of size 1 corresponding to the field dimension of the others.""") return csq
[docs]def Pdots(Vphi, phidot, H): """Derivative of pressure of the background fields Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter Returns ------- Pdotalpha : array Derivative of the pressure for the background fields Notes ----- All the arguments should have the same number of dimensions. Vphi and phidot should be arrays of the same size, but H should have a dimension of size 1 corresponding to the "field" dimension of the other variables. """ try: Pdotalpha = -(2*phidot*Vphi + 3*H**2*phidot**2) except ValueError: raise ValueError("""Arrays need to have the correct shape. Vphi and phidot should have exactly the same shape, and H should have a dimension of size 1 corresponding to the field dimension of the others.""") return Pdotalpha
[docs]def fullPdot(Vphi, phidot, H, axis=-1): """Combined derivative in e-fold time of the pressure of the fields. Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter axis : integer, optional Specifies which axis is the field dimension, default is the last one. Returns ------- fullPdot : array The deriative of the pressure of the fields summed over the fields. """ return np.sum(Pdots(Vphi, phidot, H), axis=axis)
[docs]def rhodots(phidot, H): """Derivative in e-fold time of the energy densities of the individual fields. Parameters ---------- phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter Both arrays should have the same number of dimensions, but H should have a dimension of size 1 corresponding to the field dimension of phidot. Returns ------- rhodots : array The derivative of the energy densities of the fields """ return -3*H**2*(phidot**2)
[docs]def fullrhodot(phidot, H, axis=-1): """Combined derivative in e-fold time of the energy density of the field. Parameters ---------- phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter axis : integer, optional Specifies which axis is the field dimension, default is the last one. Returns ------- fullrhodot : array The derivative of the energy density summed over the fields. """ return np.sum(rhodots(phidot, H), axis=axis)
[docs]def deltarhosmatrix(Vphi, phidot, H, modes, modesdot, axis): """Matrix of the first order perturbed energy densities of the field components. Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter modes : array_like Mode matrix of first order perturbations. Component array should have two dimensions of length nfields. modesdot : array_like Mode matrix of N-derivative of first order perturbations. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. Returns ------- result : array_like The matrix of the first order perturbed energy densities. """ Vphi, phidot, H, modes, modesdot, axis = utilities.correct_shapes(Vphi, phidot, H, modes, modesdot, axis) #Change shape of phidot, Vphi, H to add extra dimension of modes Vphi = np.expand_dims(Vphi, axis+1) phidot = np.expand_dims(phidot, axis+1) H = np.expand_dims(H, axis+1) #Do first sum over beta index internalsum = np.sum(phidot*modes, axis=axis) #Add another dimension to internalsum result internalsum = np.expand_dims(internalsum, axis) result = H**2*phidot*modesdot result -= 0.5*H**2*phidot**2*internalsum result += Vphi*modes return result
[docs]def deltaPmatrix(Vphi, phidot, H, modes, modesdot, axis): """Matrix of the first order perturbed pressure of the field components. Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter modes : array_like Mode matrix of first order perturbations. Component array should have two dimensions of length nfields. modesdot : array_like Mode matrix of N-derivative of first order perturbations. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. Returns ------- result : array_like The matrix of the first order perturbed pressure. """ Vphi, phidot, H, modes, modesdot, axis = utilities.correct_shapes(Vphi, phidot, H, modes, modesdot, axis) #Change shape of phidot, Vphi, H to add extra dimension of modes Vphi = np.expand_dims(Vphi, axis+1) phidot = np.expand_dims(phidot, axis+1) H = np.expand_dims(H, axis+1) #Do first sum over beta index internalsum = np.sum(phidot*modes, axis=axis) #Add another dimension to internalsum result internalsum = np.expand_dims(internalsum, axis) result = H**2*phidot*modesdot result -= 0.5*H**2*phidot**2*internalsum result -= Vphi*modes return result
[docs]def deltaPrelmodes(Vphi, phidot, H, modes, modesdot, axis): """Perturbed relative pressure of the fields given as quantum mode functions. Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter modes : array_like Mode matrix of first order perturbations. Component array should have two dimensions of length nfields. modesdot : array_like Mode matrix of N-derivative of first order perturbations. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. Returns ------- result : array Perturbed relative pressure of the fields. """ Vphi, phidot, H, modes, modesdot, axis = utilities.correct_shapes(Vphi, phidot, H, modes, modesdot, axis) cs = soundspeeds(Vphi, phidot, H) rdots = rhodots(phidot, H) rhodot = fullrhodot(phidot, H, axis) drhos = deltarhosmatrix(Vphi, phidot, H, modes, modesdot, axis) res_shape = list(drhos.shape) del res_shape[axis] result = np.zeros(res_shape, dtype=modes.dtype) for ix in np.ndindex(tuple(res_shape[:axis])): for i in range(res_shape[axis]): for a in range(rdots.shape[axis]): for b in range(rdots.shape[axis]): if a != b: result[ix+(i,)] += (1/(2*rhodot[ix]) * (cs[ix+(a,)] - cs[ix+(b,)]) * (rdots[ix+(b,)]*drhos[ix+(a,i)] - rdots[ix+(a,)]*drhos[ix+(b,i)])) return result
[docs]def deltaPnadmodes(Vphi, phidot, H, modes, modesdot, axis): """Perturbed non-adiabatic pressure of the fields given as quantum mode functions. Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter modes : array_like Mode matrix of first order perturbations. Component array should have two dimensions of length nfields. modesdot : array_like Mode matrix of N-derivative of first order perturbations. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. """ Vphi, phidot, H, modes, modesdot, axis = utilities.correct_shapes(Vphi, phidot, H, modes, modesdot, axis) csq = totalsoundspeed(Vphi, phidot, H, axis) csshape = csq.shape # Add two dimensions corresponding to mode axes csq.resize(csshape[:axis] + (1,1) + csshape[axis:]) dP = deltaPmatrix(Vphi, phidot, H, modes, modesdot, axis) drhos = deltarhosmatrix(Vphi, phidot, H, modes, modesdot, axis) result = np.sum(dP - csq*drhos, axis=axis) return result
[docs]def Smodes(Vphi, phidot, H, modes, modesdot, axis): """Isocurvature perturbation S of the fields given as quantum mode functions. Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter modes : array_like Mode matrix of first order perturbations. Component array should have two dimensions of length nfields. modesdot : array_like Mode matrix of N-derivative of first order perturbations. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. Returns ------- result : array Isocurvature perturbation S of the fields """ dpnadmodes = deltaPnadmodes(Vphi, phidot, H, modes, modesdot, axis) Pdot = fullPdot(Vphi, phidot, H, axis) Pdot = np.expand_dims(Pdot, axis) result = dpnadmodes/Pdot return result
[docs]def deltarhospectrum(Vphi, phidot, H, modes, modesdot, axis): """Power spectrum of the perturbed energy density. Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter modes : array_like Mode matrix of first order perturbations. Component array should have two dimensions of length nfields. modesdot : array_like Mode matrix of N-derivative of first order perturbations. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. Returns ------- deltarhospectrum : array Spectrum of the perturbed energy density """ drhomodes = deltarhosmatrix(Vphi, phidot, H, modes, modesdot, axis) drhoI = np.sum(drhomodes, axis=axis) spectrum = utilities.makespectrum(drhoI, axis) return spectrum
[docs]def deltaPspectrum(Vphi, phidot, H, modes, modesdot, axis): """Power spectrum of the full perturbed relative pressure. Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter modes : array_like Mode matrix of first order perturbations. Component array should have two dimensions of length nfields. modesdot : array_like Mode matrix of N-derivative of first order perturbations. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. Returns ------- deltaPspectrum : array Spectrum of the perturbed pressure """ dPmodes = deltaPmatrix(Vphi, phidot, H, modes, modesdot, axis) dPI = np.sum(dPmodes, axis=axis) spectrum = utilities.makespectrum(dPI, axis) return spectrum
[docs]def deltaPrelspectrum(Vphi, phidot, H, modes, modesdot, axis): """Power spectrum of the full perturbed relative pressure. Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter modes : array_like Mode matrix of first order perturbations. Component array should have two dimensions of length nfields. modesdot : array_like Mode matrix of N-derivative of first order perturbations. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. Returns ------- deltaPrelspectrum : array Spectrum of the perturbed relative pressure """ dPrelI = deltaPrelmodes(Vphi, phidot, H, modes, modesdot, axis) spectrum = utilities.makespectrum(dPrelI, axis) return spectrum
[docs]def deltaPnadspectrum(Vphi, phidot, H, modes, modesdot, axis): """Power spectrum of the full perturbed non-adiabatic pressure. Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter modes : array_like Mode matrix of first order perturbations. Component array should have two dimensions of length nfields. modesdot : array_like Mode matrix of N-derivative of first order perturbations. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. Returns ------- deltaPnadspectrum : array Spectrum of the non-adiabatic pressure perturbation """ dPrelI = deltaPnadmodes(Vphi, phidot, H, modes, modesdot, axis) spectrum = utilities.makespectrum(dPrelI, axis) return spectrum
[docs]def Sspectrum(Vphi, phidot, H, modes, modesdot, axis): """Power spectrum of the isocurvature perturbation S. Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter modes : array_like Mode matrix of first order perturbations. Component array should have two dimensions of length nfields. modesdot : array_like Mode matrix of N-derivative of first order perturbations. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. Returns ------- Sspectrum : array Spectrum of the isocurvature perturbation S. """ dSI = Smodes(Vphi, phidot, H, modes, modesdot, axis) spectrum = utilities.makespectrum(dSI, axis) return spectrum
[docs]def scaled_dPnad_spectrum(Vphi, phidot, H, modes, modesdot, axis, k): """Power spectrum of delta Pnad scaled with k^3/(2*pi^2) Assumes that k dimension is last. Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter modes : array_like Mode matrix of first order perturbations. Component array should have two dimensions of length nfields. modesdot : array_like Mode matrix of N-derivative of first order perturbations. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. k : array The values of k to scale the result with. Returns ------- scaled_dPnad_spectrum : array Scaled spectrum of the non-adiabatic pressure perturation. """ spectrum = deltaPnadspectrum(Vphi, phidot, H, modes, modesdot, axis) #Add extra dimensions to k if necessary scaled_spectrum = utilities.kscaling(k) * spectrum return scaled_spectrum
[docs]def scaled_dP_spectrum(Vphi, phidot, H, modes, modesdot, axis, k): """Power spectrum of delta P scaled with k^3/(2*pi^2) Assumes that k dimension is last. Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter modes : array_like Mode matrix of first order perturbations. Component array should have two dimensions of length nfields. modesdot : array_like Mode matrix of N-derivative of first order perturbations. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. k : array The values of k to scale the result with. Returns ------- scaled_dP_spectrum : array Scaled spectrum of the perturbed pressure """ spectrum = deltaPspectrum(Vphi, phidot, H, modes, modesdot, axis) #Add extra dimensions to k if necessary scaled_spectrum = utilities.kscaling(k) * spectrum return scaled_spectrum
[docs]def scaled_S_spectrum(Vphi, phidot, H, modes, modesdot, axis, k): """Power spectrum of S scaled with k^3/(2*pi^2) Assumes that k dimension is last. Parameters ---------- Vphi : array_like First derivative of the potential with respect to the fields phidot : array_like First derivative of the field values with respect to efold number N. H : array_like The Hubble parameter modes : array_like Mode matrix of first order perturbations. Component array should have two dimensions of length nfields. modesdot : array_like Mode matrix of N-derivative of first order perturbations. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. k : array The values of k to scale the result with. Returns ------- scaled_S_spectrum : array Scaled spectrum of the isocurvature perturbation S """ spectrum = Sspectrum(Vphi, phidot, H, modes, modesdot, axis) #Add extra dimensions to k if necessary scaled_spectrum = utilities.kscaling(k) * spectrum return scaled_spectrum
[docs]def scaled_S_from_model(m, tix=None, kix=None): """Return the spectrum of isocurvature perturbations :math:`\mathcal{P}_\mathcal{S}` for each timestep and k mode. This is the scaled power spectrum which is related to the unscaled version by :math:`\mathcal{P}_\mathcal{S} = k^3/(2\pi^2) P_\mathcal{S}`. Parameters ---------- m : Cosmomodels instance Model class instance from which the yresult variable will be used to calculate P_R. tix : integer, optional index of timestep at which to calculate, defaults to full range of steps. kix : integer, optional integer of k value at which to calculate, defaults to full range of ks. Returns ------- scaled_S : array_like Array of spectrum values for all timesteps and k modes """ if kix is None: kslice = slice(None) else: kslice = slice(kix, kix+1) components = utilities.components_from_model(m, tix, kix) spectrum = scaled_S_spectrum(*components, k=m.k[kslice]) return spectrum
[docs]def slope_of_S_spectrum(scaled_S, k, kix=None, running=False): r"""Return the value of the slope of the k-scaled spectrum of S Parameters ---------- scaled_S : array_like Power spectrum of isocurvature perturbations at a specific time This should be the *scaled* power spectrum i.e. .. math:: \rm{scaled_S} = k^3/(2\pi)^2 P_S, <S(k)S(k')> = (2\pi^3) \delta(k+k') P_S The array should be one-dimensional indexed by the k value. k : array_like Array of k values for which sPr has been calculated. kix : integer Index value of k for which to return spec_S. running : boolean, optional Whether running should be allowed or not. If true, a quadratic polynomial fit is made instead of linear and the value of the running is returned along with the slope. Defaults to False. Returns ------- spec_S : float The value of the spectral index of S at the requested k value and timestep. Normalised in the same way as n_s .. math:: \rm{spec_S} = 1 - d \log(\rm{scaled_S}) / d \log(k) evaluated at k[kix]. This is calculated using a polynomial least squares fit with numpy.polyfit. If running is True then a quadratic polynomial is fit, otherwise only a linear fit is made. running_S : float, present only if running = True If running=True the value of the derivative of the slope at k[kix] is returned in a tuple along with spec_S. """ result = utilities.spectral_index(scaled_S, k, kix, running) return result
[docs]def dprel_from_model(m, tix=None, kix=None): """Get the spectrum of delta Prel from a model instance. Parameters ---------- m : Cosmomodels model instance The model instance with which to perform the calculation tix : integer Index for timestep at which to perform calculation. Default is to calculate over all timesteps. kix : integer Index for k mode for which to perform the calculation. Default is to calculate over all k modes. Returns ------- spectrum : array Array of values of the power spectrum of the relativistic pressure perturbation """ components = utilities.components_from_model(m, tix, kix) result = deltaPrelspectrum(*components) return result
[docs]def S_alternate(phidot, Pphi_modes, axis): r"""Return the alternate spectrum of (first order) isocurvature perturbations P_S for each k. This is only available for a two field model and is given by: .. math:: \rm{P_S} = (H/\dot{\sigma})^2 \langle\delta s \delta s*\rangle where .. math:: \dot{\sigma} = \sqrt{\dot{\phi}^2 + \dot{\chi}^2} \delta s = - \dot{\chi}/\dot{\sigma} \delta \phi + \dot{\phi}/\dot{\sigma} \delta \chi This is the unscaled version :math:`P_S` which is related to the scaled version by :math:`\mathcal{P}_S = k^3/(2\pi^2) P_S`. Parameters ---------- phidot : array_like First derivative of the field values with respect to efold number N. Pphi_modes : array_like Mode matrix of first order perturbation power spectrum given by adiabatic.Pphi_matrix. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. Returns ------- Pr : array_like, dtype: float64 Array of Pr values for all timesteps and k modes """ nfields = Pphi_modes.shape[axis] if nfields != 2: raise ValueError("Only two field models can be used in this calculation.") phidot = np.atleast_1d(phidot) phidotsumsq = (np.sum(phidot**2, axis=axis))**2 tslice = (slice(None),)*axis transform = np.ones_like(Pphi_modes) transform[tslice + (0,1)] = -1 transform[tslice + (1,0)] = -1 #Multiply mode matrix by corresponding phidot value phidotI = np.expand_dims(phidot[tslice + (slice(None,None,-1),)], axis) phidotJ = np.expand_dims(phidot[tslice + (slice(None,None,-1),)], axis+1) summatrix = phidotI*phidotJ*Pphi_modes*transform #Flatten mode matrix and sum over all nfield**2 values sumflat = np.sum(utilities.flattenmodematrix(summatrix, nfields, axis, axis+1), axis=1) #Divide by total sum of derivative terms Pr = (sumflat/phidotsumsq).astype(np.float) return Pr
[docs]def scaled_S_alternate_spectrum(phidot, Pphi_modes, axis, k): r"""Return the scaled alternate spectrum of (first order) isocurvature perturbations for each k. This is only available for a two field model and is given by: .. math:: P_{\bar{S}} = (H/\dot{\sigma})^2 <\delta s \delta s*> \dot{\sigma} = \sqrt{\dot{\phi}^2 + \dot{\chi}^2} \delta s = - \dot{\chi}/\dot{\sigma} \delta \phi + \dot{\phi}/\dot{\sigma} \delta \chi This is the scaled version :math:`\mathcal{P}_{\bar{S}}` which is related to the unscaled version by :math:`\mathcal{P}_{\bar{S}} = k^3/(2\pi^2) P_{\bar{S}}`. Parameters ---------- phidot : array_like First derivative of the field values with respect to efold number N. Pphi_modes : array_like Mode matrix of first order perturbation power spectrum given by adiabatic.Pphi_matrix. Component array should have two dimensions of length nfields. axis : integer Specifies which axis is first in mode matrix, e.g. if modes has shape (100,3,3,10) with nfields=3, then axis=1. The two mode matrix axes are assumed to be beside each other so (100,3,10,3) would not be valid. Returns ------- Pr : array_like, dtype: float64 Array of Pr values for all timesteps and k modes """ spectrum = S_alternate(phidot, Pphi_modes, axis) #Add extra dimensions to k if necessary scaled_spectrum = utilities.kscaling(k) * spectrum return scaled_spectrum