def hankel_spline_lognormal_cl(ells, cl, plot=False, ell_min=90, ell_max=1e5): ft = SymmetricFourierTransform(ndim=2, N=200, h=0.03) # transform to angular correlation function with inverse hankel transform and spline interpolated C_ell spline_cl = interpolate.InterpolatedUnivariateSpline( np.log10(ells), np.log10(cl)) f = lambda ell: 10**(spline_cl(np.log10(ell))) thetas = np.pi / ells w_theta = ft.transform(f, thetas, ret_err=False, inverse=True) # compute lognormal angular correlation function w_theta_g = np.log(1. + w_theta) # convert back to multipole space spline_w_theta_g = interpolate.InterpolatedUnivariateSpline( np.log10(np.flip(thetas, 0)), np.flip(w_theta_g, 0)) g = lambda theta: spline_w_theta_g(np.log10(theta)) cl_g = ft.transform(g, ells, ret_err=False) spline_cl_g = interpolate.InterpolatedUnivariateSpline( np.log10(ells), np.log10(np.abs(cl_g))) # plotting is just for validation if ever unsure if plot: plt.figure() plt.loglog(ells, cl, label='$C_{\\ell}$', marker='.') plt.loglog(ells, cl_g, label='$C_{\\ell}^G$', marker='.') plt.loglog(np.linspace(ell_min, ell_max, 1000), 10**spline_cl_g( np.log10(np.linspace(ell_min, ell_max, 1000))), label='spline of $C_{\\ell}^G$') plt.legend(fontsize=14) plt.xlabel('$\\ell$', fontsize=16) plt.title('Angular power spectra', fontsize=16) plt.show() return cl_g, spline_cl_g
def test_final_term_amplitude(): g1 = HankelTransform.final_term_amplitude(f=lambda x: x**-4, h=0.5) g2 = HankelTransform.final_term_amplitude(f=lambda x: x**-4, h=0.1) assert g1 > g2 g1 = SymmetricFourierTransform.final_term_amplitude(f=lambda x: x**-4, h=0.5) g2 = SymmetricFourierTransform.final_term_amplitude(f=lambda x: x**-4, h=0.1) assert g1 > g2
def test_roundtrip_broken_pl(s, t, x0, ndim, N, h, r): f = lambda x: x ** s / (x ** t + x0) ht = SymmetricFourierTransform(ndim=ndim, N=N, h=h) k = np.logspace(np.log10(ht.x.min() / r.max() / 10.0), np.log10(10 * ht.x.max() / r.min()), 1000) resk = ht.transform(f, k, False) spl = spline(k, resk) res = ht.transform(spl, r, False, inverse=True) print("Analytic: ", f(r), ", Numerical: ", res) assert np.allclose(res, f(r), atol=1e-2)
def test_xrange(): x1 = HankelTransform.xrange_approx(h=0.5, nu=0) x2 = HankelTransform.xrange_approx(h=0.1, nu=0) assert x1[0] > x2[0] assert x1[1] < x2[1] x1 = SymmetricFourierTransform.xrange_approx(h=0.5, ndim=2) x2 = SymmetricFourierTransform.xrange_approx(h=0.1, ndim=2) assert x1[0] > x2[0] assert x1[1] < x2[1]
def do_FT(r, k_, logkfunc): logsamplespline = UnivariateSpline(k_, logkfunc, s=0., ext='zeros') samplespline = lambda x: np.sqrt(splinefortransform(x, logsamplespline)) deltah, result, N = get_h(samplespline, nu=3, K=[np.min(r), np.max(r)], cls=SymmetricFourierTransform, inverse=True, maxiter=25) ft = SymmetricFourierTransform(ndim=3, N=N, h=deltah) Gr = ft.transform(samplespline, r, ret_err=False, inverse=True) return Gr
def __init__(self, num_nodes=None, h=0.001): """ Parameters ---------- num_nodes : int, optional Number of nodes in FFT h : float, optional Step size of integration """ from hankel import SymmetricFourierTransform self.ft = SymmetricFourierTransform(ndim=3, N=num_nodes, h=h)
def test_powerlaw(s, ndim, k, N, h): ht = SymmetricFourierTransform(ndim=ndim, N=N, h=h) ans = ht.transform(lambda x: x ** s, k, False, False) nu = ndim / 2. - 1 s += nu if nu - s <= 0 and (nu - s) % 2 == 0: raise Exception("Can't have a negative integer for gamma") anl = (2 * np.pi) ** (ndim / 2.) * 2 ** (s + 1) * gamma(0.5 * (2 + nu + s)) / k ** (s + 2) / gamma( 0.5 * (nu - s)) / k ** nu print("Numerical Result: ", ans, " (required %s)" % anl) assert np.isclose(ans, anl, rtol=1e-3)
def test_roundtrip_broken_pl(s, t, x0, ndim, N, h, r): def f(x): return x**s / (x**t + x0) ht = SymmetricFourierTransform(ndim=ndim, N=N, h=h) k = np.logspace( np.log10(ht.x.min() / r.max() / 10.0), np.log10(10 * ht.x.max() / r.min()), 1000, ) resk = ht.transform(f, k, False) spl = Spline(k, resk) res = ht.transform(spl, r, False, inverse=True) print("Analytic: ", f(r), ", Numerical: ", res) assert np.allclose(res, f(r), atol=1e-2)
def _realspace_power(self, nu1, nu2): r = np.logspace(-3, 3, 1000) ht1 = SymmetricFourierTransform(ndim=2, N=1000, h=0.003, a=0, b=2 * np.pi) gres = ht1.transform( lambda u: np.sqrt(self.point_source_power_spec(2 * np.pi * u)) * np .sqrt(self.point_source_power_spec(2 * np.pi * u)), k=r, inverse=True, ret_err=False) # *nu1*nu2 xir = spline(np.log(r), np.log(gres)) return lambda r: np.exp(xir(np.log(r)))
def test_powerlaw(s, ndim, k, N, h): ht = SymmetricFourierTransform(ndim=ndim, N=N, h=h) ans = ht.transform(lambda x: x ** s, k, False, False) nu = ndim / 2.0 - 1 s += nu if nu - s <= 0 and (nu - s) % 2 == 0: raise Exception("Can't have a negative integer for gamma") anl = ( (2 * np.pi) ** (ndim / 2.0) * 2 ** (s + 1) * gamma(0.5 * (2 + nu + s)) / k ** (s + 2) / gamma(0.5 * (nu - s)) / k ** nu ) print("Numerical Result: ", ans, " (required %s)" % anl) assert np.isclose(ans, anl, rtol=1e-3)
class PowerToCorrelationFT(PowerToCorrelation): """ A pk2xi implementation utilising the Hankel library to use explicit FFT. """ def __init__(self, num_nodes=None, h=0.001): """ Parameters ---------- num_nodes : int, optional Number of nodes in FFT h : float, optional Step size of integration """ from hankel import SymmetricFourierTransform self.ft = SymmetricFourierTransform(ndim=3, N=num_nodes, h=h) def __call__(self, ks, pk, ss): pkspline = splrep(ks, pk) f = lambda k: splev(k, pkspline) xi = self.ft.transform(f, ss, inverse=True, ret_err=False) return xi
T2ISW = quad( T2, deltac, 1.0, epsabs=1, epsrel=0.01, limit=30, maxp1=30, limlst=30)[0] / quad(dNddelta, deltac, 1.0, args=rf / TSz0.cosmo.h)[0] DeltaT = sqrt(T2ISW - TISW**2.0) N1 = quad(dNddelta, deltac, 1.0, args=rf / TSz0.cosmo.h, limit=10000000) * (TSz0.cosmo.comoving_volume(0.75) - TSz0.cosmo.comoving_volume(0.4)) N2 = quad(dNddelta, deltac, 1.0, args=rf / TSz0.cosmo.h, limit=10000000)[0] * 5e9 / TSz0.cosmo.h**3.0 rv, RV = R_min(deltac, rf) return deltac, rf, TISW, DeltaT, rv, N2 Power = interpolate.UnivariateSpline(TSz0.k, TSz0.power, k=1, s=0) fft = SymmetricFourierTransform(ndim=3, N=int(1e5), h=1e-8) GF = filters.Gaussian(TSz0.k, TSz0.power) x1 = growth_factor.GrowthFactor(TSz0.cosmo) x = LCDM(Om0=0.29, h=0.69) growth_rate = x.growth_rate_z z = logspace(0, log10(1101), 1000) - 1.0 G = z * 1 for i in range(len(z)): G[i] = (TSz0.cosmo.H(z[i]) * (1.0 - growth_rate(z[i])) * x1.growth_factor(z[i])).value GG = interpolate.UnivariateSpline(z, G, k=1, s=0) rf = 20