def Cl_to_wtheta(nz, table_l, table_Cl, theta, path, nu=0, N=500, h=0.005): assert isinstance(nz, int), 'Invalid nz: {}. Must be an integer'.format(nz) import os from hankel import HankelTransform as HT import numpy as np from scipy.interpolate import UnivariateSpline header = '{:<25s}'.format('# r (deg)') for i in range(nz): header += '{:<25s}'.format('w_{}'.format(i)) ht = HT(nu=nu, N=N, h=h) w = np.empty((nz, theta.size)) for i in range(nz): # Fit Cl's with Spline Cl = UnivariateSpline(table_l, table_Cl[i], s=0, k=1) # Do the Hankel Transform to get the correlation function for j, thetai in zip(range(theta.size), np.deg2rad(theta)): f = lambda x: (x * Cl(x / thetai)) / (2. * np.pi * np.power( thetai, 2)) w[i, j] = ht.transform(f)[0] np.savetxt(path, np.vstack((theta, w)).T, fmt='%-25.18e', header=header, comments='') return w
def __init__(self, wavel, r0, pxScale, air=False): if air: self.wavel = wavel * 1e-10 else: self.wavel = vac_to_air(wavel << u.Angstrom).value * 1e-10 self.r0 = r0 self.pxScale = pxScale self.resolution = 0.98 * self.wavel / self.r0 * 206265 # resolution of the image after being imaged through seeing self.diameter = int(self.resolution / self.pxScale) # diameter of PSF in pixels self.psf = np.zeros(shape=(int(self.diameter), int(self.diameter))) self.pxm = np.linspace( 1.75, 880, int(880 / 1.75) + 1 ) # 1.75 is the size of one pixel in metres and 880 is the size of 840 pixels in metres and the int(880/1.75)+1 is the number of pixels in the field-of-view of 840 pixels, this is an average field-of-view size in pixels with higher field-of-views not adding much to the terms self.modtf = self.mtf(self.wavel, self.r0) self.ht = HankelTransform(nu=0, h=0.05, N=62) self.psf1d = self.ht.transform(self.modtf, self.pxm, ret_err=False) for j in range(self.psf.shape[0]): for i in range(self.psf.shape[1]): idx = int( np.linalg.norm((j - self.psf.shape[0] // 2, i - self.psf.shape[1] // 2))) self.psf[j, i] = self.psf1d[idx] self.psf /= self.psf.sum()
def test_nu0_x4(): """ Result on wikipedia """ ht = HankelTransform(nu=0, N=150, h=10 ** -1.5) ans = ht.integrate(lambda x: x ** 4, False, False) print("Numerical Result: ", ans, " (required 9)") assert np.isclose(ans, 9, rtol=1e-3)
def test_nu_varying_gamma_mod(s, nu, N, h): ht = HankelTransform(nu=nu, N=N, h=h) ans = ht.integrate(lambda x: x ** (nu - 2 * s + 1) * gammainc_(s, x ** 2), False, False) anl = 0.5 ** (2 * s - nu - 1) * gammaincc_(1 - s + nu, 0.25) print("Numerical Result: ", ans, " (required %s)" % anl) assert np.isclose(ans, anl, rtol=1e-3)
def test_nu_varying_powerlaw(s, nu, N, h): ht = HankelTransform(nu=nu, N=N, h=h) ans = ht.integrate(lambda x: x ** (s + 1), False, False) anl = 2 ** (s + 1) * gamma(0.5 * (2 + nu + s)) / gamma(0.5 * (nu - s)) print("Numerical Result: ", ans, " (required %s)" % anl) assert np.isclose(ans, anl, rtol=1e-3)
def test_nu_varying_powerlaw(s, nu, N, h): ht = HankelTransform(nu=nu, N=N, h=h) ans = ht.integrate(lambda x: x**(s + 1), False, False) anl = 2**(s + 1) * gamma(0.5 * (2 + nu + s)) / gamma(0.5 * (nu - s)) print("Numerical Result: ", ans, " (required %s)" % anl) assert np.isclose(ans, anl, rtol=1e-3)
def test_nu0_x4(): """ Result on wikipedia """ ht = HankelTransform(nu=0, N=150, h=10**-1.5) ans = ht.integrate(lambda x: x**4, False, False) print("Numerical Result: ", ans, " (required 9)") assert np.isclose(ans, 9, rtol=1e-3)
def test_nu_varying_gamma_mod(s, nu, N, h): ht = HankelTransform(nu=nu, N=N, h=h) ans = ht.integrate(lambda x: x**(nu - 2 * s + 1) * gammainc_(s, x**2), False, False) anl = 0.5**(2 * s - nu - 1) * gammaincc_(1 - s + nu, 0.25) print("Numerical Result: ", ans, " (required %s)" % anl) assert np.isclose(ans, anl, rtol=1e-3)
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_nu0_f_gauss(): """ Result on wikipedia """ z = 2 ht = HankelTransform(nu=0, N=50, h=0.01) ans = ht.integrate(lambda x: x * np.exp(-0.5 * z**2 * x**2), False, False) anl = 1.0 / z**2 * np.exp(-0.5 / z**2) print("Numerical Result: ", ans, " (required %s)" % anl) assert np.isclose(ans, anl, rtol=1e-3)
def test_nu0_f_gauss(): """ Result on wikipedia """ z = 2 ht = HankelTransform(nu=0, N=50, h=0.01) ans = ht.integrate(lambda x: x * np.exp(-0.5 * z ** 2 * x ** 2), False, False) anl = 1. / z ** 2 * np.exp(-0.5 / z ** 2) print("Numerical Result: ", ans, " (required %s)" % anl) assert np.isclose(ans, anl, rtol=1e-3)
def test_nu0_f_x2(): """ Test f(x) = x^2, nu=0 Result on wikipedia """ ht = HankelTransform(nu=0, N=100, h=10**-1.5) ans = ht.integrate(lambda x: x**2, False, False) print("Numerical Result: ", ans, " (required -1)") assert np.isclose(ans, -1, rtol=1e-3)
def test_nu0_f_x2(): """ Test f(x) = x^2, nu=0 Result on wikipedia """ ht = HankelTransform(nu=0, N=100, h=10 ** -1.5) ans = ht.integrate(lambda x: x ** 2, False, False) print("Numerical Result: ", ans, " (required -1)") assert np.isclose(ans, -1, rtol=1e-3)
def test_nu0_f_x_on_x2(): """ Test f(x) = x/(x**2 + 1), nu=0 This test is done in the Ogata (2005) paper, section 5" """ ht = HankelTransform(nu=0, N=50, h=10 ** -1.5) ans = ht.integrate(lambda x: x / (x ** 2 + 1), False, False) print("Numerical Result: ", ans, " (required %s)" % k0(1)) assert np.isclose(ans, k0(1), rtol=1e-3)
def test_nu0_f_unity(): """ Test f(x) = 1, nu=0 This test is done in the Ogata (2005) paper, section 5" """ ht = HankelTransform(nu=0, N=50, h=0.1) ans = ht.integrate(lambda x: 1, False, False) print("Numerical Result: ", ans, " (required %s)" % 1) assert np.isclose(ans, 1, rtol=1e-3)
def test_nu0_f_x_on_x2(): """ Test f(x) = x/(x**2 + 1), nu=0 This test is done in the Ogata (2005) paper, section 5" """ ht = HankelTransform(nu=0, N=50, h=10**-1.5) ans = ht.integrate(lambda x: x / (x**2 + 1), False, False) print("Numerical Result: ", ans, " (required %s)" % k0(1)) assert np.isclose(ans, k0(1), rtol=1e-3)
def test_nu0_f_unity(): """ Test f(x) = 1, nu=0 This test is done in the Ogata (2005) paper, section 5" """ ht = HankelTransform(nu=0, N=50, h=0.1) ans = ht.integrate(lambda x: 1, False, False) print("Numerical Result: ", ans, " (required %s)" % 1) assert np.isclose(ans, 1, rtol=1e-3)
def test_nu0_1_on_sqrt_x(): """ Result on wikipedia """ # NOTE: this is REALLY finnicky!! (check devel/) ht = HankelTransform(nu=0, N=160, h=10 ** -3.5) ans = ht.integrate(lambda x: 1. / np.sqrt(x), False, False) m = -1.5 anl = 2 ** (m + 1) * gamma(m / 2 + 1) / gamma(-m / 2) print("Numerical Result: ", ans, " (required %s)" % anl) assert np.isclose(ans, anl, rtol=1e-3)
def test_nu0_1_on_sqrt_x(): """ Result on wikipedia """ # NOTE: this is REALLY finnicky!! (check devel/) ht = HankelTransform(nu=0, N=160, h=10**-3.5) ans = ht.integrate(lambda x: 1.0 / np.sqrt(x), False, False) m = -1.5 anl = 2**(m + 1) * gamma(m / 2 + 1) / gamma(-m / 2) print("Numerical Result: ", ans, " (required %s)" % anl) assert np.isclose(ans, anl, rtol=1e-3)
def test_nu0_x_on_sqrt_x2_pz2(): """ Result on wikipedia """ # Note that the number required is highly dependent on z .... smaller z is harder. ht = HankelTransform(nu=0, N=50, h=10 ** -1.3) z = 1 ans = ht.integrate(lambda x: x / np.sqrt(x ** 2 + z ** 2), False, False) anl = np.exp(-z) print("Numerical Result: ", ans, " (required %s)" % anl) assert np.isclose(ans, anl, rtol=1e-3)
def test_nu0_x_on_sqrt_x2_pz2(): """ Result on wikipedia """ # Note that the number required is highly dependent on z .... smaller z is harder. ht = HankelTransform(nu=0, N=50, h=10**-1.3) z = 1 ans = ht.integrate(lambda x: x / np.sqrt(x**2 + z**2), False, False) anl = np.exp(-z) print("Numerical Result: ", ans, " (required %s)" % anl) assert np.isclose(ans, anl, rtol=1e-3)
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 test_k_zero(nu, alt): """Testing k=0.""" threshold = -0.5 if alt else 0 ht = HankelTransform(nu=nu, N=50, h=1e-3, alt=alt) ans = ht.transform(lambda r: np.exp(-(r**2) / 2), 0, False, False) print("Numerical Results: ", ans) if nu < threshold: assert np.isnan(ans) elif nu > threshold: assert np.isclose(ans, 0, rtol=1e-3) else: assert np.isclose(ans, 1, rtol=1e-3)
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 test_powerlaw(s, nu, k, N, h): """ Test f(r) = 1/r, nu=0 """ ht = HankelTransform(nu=nu, N=N, h=h) ans = ht.transform(lambda x: x ** s, k, False, False) if nu - s <= 0 and (nu - s) % 2 == 0: raise Exception("Can't have a negative integer for gamma") anl = 2 ** (s + 1) * gamma(0.5 * (2 + nu + s)) / k ** (s + 2) / gamma(0.5 * (nu - s)) print("Numerical Result: ", ans, " (required %s)" % anl) assert np.isclose(ans, anl, rtol=1e-3)
def test_powerlaw(s, nu, k, N, h): """ Test f(r) = 1/r, nu=0 """ ht = HankelTransform(nu=nu, N=N, h=h) ans = ht.transform(lambda x: x**s, k, False, False) if nu - s <= 0 and (nu - s) % 2 == 0: raise Exception("Can't have a negative integer for gamma") anl = (2**(s + 1) * gamma(0.5 * (2 + nu + s)) / k**(s + 2) / gamma(0.5 * (nu - s))) print("Numerical Result: ", ans, " (required %s)" % anl) assert np.isclose(ans, anl, rtol=1e-3)
def H_3(x,n,mu,dia): y = np.pi * mu / 6.0 lam1 = (1 + 2 * y) ** 2 / ((1.0 - y) ** 4) lam2 = - (1 + y / 2.0) ** 2 / ((1.0 - y) ** 4) x = x/dia C3 = lambda x: -(lam1 * y * x ** 3 / 2.0 + 6 * y * lam2 * x + lam1) if (1 >= x.any() >= 0) else 0 C2 = [] for x2 in x: C2.append(C3(x2)) h = HankelTransform(nu=0, N=1000, h=0.005) Ck_3 = h.transform(C3, k, ret_err=False) Hk_3 = Ck_3 / (1 - n * Ck_3) #Hk_3 = spline(k, Hk_3) # Define a spline to approximate transform #Hx_3 = h.transform(Hk_3, x, False, inverse=True) #Fk = ht.transform(C3, k, ret_err=False) #Ck_3 = fft(C2) return Hk_3
def test_alternative(s, nu, k, N, h): """Test alternative hankel definition.""" ht1 = HankelTransform(nu=nu, N=N, h=h) ht2 = HankelTransform(nu=nu, N=N, h=h, alt=True) ft1 = ht1.transform(lambda r: r**s, k, False, False) ft2 = ht2.transform(lambda r: r**(s + 0.5), k, False, False) / k**0.5 print("Numerical Results: ", ft1, " and ", ft2) assert np.isclose(ft1, ft2, rtol=1e-3)
class SeeingApertureMTF: """ This is the class that generates the effective aperture for a given Fried parameter and can also populate it using the model assuming that the Earth's atmosphere can be modelled as a medium with smoothly varying turbulence. Parameters ---------- wavel : float The wavelength of light in Angstroms. r0 : float The Fried parameter in m. pxScale : float The size of one detector pixel in arcseconds on the observed object. air : bool, optional Whether or not the provided wavelength is air wavelength. If not then the wavelength is converted from vacuum value. Default is False. """ def __init__(self, wavel, r0, pxScale, air=False): if air: self.wavel = wavel * 1e-10 else: self.wavel = vac_to_air(wavel << u.Angstrom).value * 1e-10 self.r0 = r0 self.pxScale = pxScale self.resolution = 0.98 * self.wavel / self.r0 * 206265 # resolution of the image after being imaged through seeing self.diameter = int(self.resolution / self.pxScale) # diameter of PSF in pixels self.psf = np.zeros(shape=(int(self.diameter), int(self.diameter))) self.pxm = np.linspace( 1.75, 880, int(880 / 1.75) + 1 ) # 1.75 is the size of one pixel in metres and 880 is the size of 840 pixels in metres and the int(880/1.75)+1 is the number of pixels in the field-of-view of 840 pixels, this is an average field-of-view size in pixels with higher field-of-views not adding much to the terms self.modtf = self.mtf(self.wavel, self.r0) self.ht = HankelTransform(nu=0, h=0.05, N=62) self.psf1d = self.ht.transform(self.modtf, self.pxm, ret_err=False) for j in range(self.psf.shape[0]): for i in range(self.psf.shape[1]): idx = int( np.linalg.norm((j - self.psf.shape[0] // 2, i - self.psf.shape[1] // 2))) self.psf[j, i] = self.psf1d[idx] self.psf /= self.psf.sum() @staticmethod def mtf(wavel, r0): return lambda x: np.exp(-(6.88 / 2.0) * (wavel * x / (2 * np.pi * r0))**(5 / 3))
def InverseFT3D(self, R, ps, k=None, kmin=None, kmax=None, epsabs=1e-12, epsrel=1e-12, limit=500, split_by_scale=False, method='clenshaw-curtis', use_pb=False, suppression=np.inf): """ Take a power spectrum and perform the inverse (3-D) FT to recover a correlation function. """ assert type(R) == np.ndarray if (type(ps) == FunctionType) or isinstance(ps, interp1d) \ or isinstance(ps, Akima1DInterpolator): k = ps.x elif type(ps) == np.ndarray: # Setup interpolant assert k is not None, "Must supply k vector as well!" #if interpolant == 'akima': # ps = Akima1DInterpolator(k, ps) #elif interpolant == 'cubic': ps = interp1d(np.log(k), ps, kind='cubic', assume_sorted=True, bounds_error=False, fill_value=0.0) #_ps = interp1d(np.log(k), np.log(ps), kind='cubic', assume_sorted=True, # bounds_error=False, fill_value=-np.inf) # #ps = lambda k: np.exp(_ps.__call__(np.log(k))) else: raise ValueError('Do not understand type of `ps`.') if kmin is None: kmin = k.min() if kmax is None: kmax = k.max() norm = 1. / ps(np.log(kmax)) ## # Use Steven Murray's `hankel` package to do the transform ## if method == 'ogata': assert have_hankel, "hankel package required for this!" integrand = lambda kk: four_pi * kk**2 * norm * ps(np.log(kk)) \ * np.exp(-kk * R / suppression) ht = HankelTransform(nu=0, N=k.size, h=0.001) #integrand = lambda kk: ps(np.log(kk)) * norm #ht = SymmetricFourierTransform(3, N=k.size, h=0.001) #print(ht.integrate(integrand)) cf = ht.transform(integrand, k=R, ret_err=False, inverse=True) / norm return cf / (2. * np.pi)**3 else: pass # Otherwise, do it by-hand. ## # Optional progress bar ## pb = ProgressBar(R.size, use=self.pf['progress_bar'] * use_pb, name='ps(k)->cf(R)') # Loop over R and perform integral cf = np.zeros_like(R) for i, RR in enumerate(R): if not pb.has_pb: pb.start() pb.update(i) # Leave sin(k*R) out -- that's the 'weight' for scipy. integrand = lambda kk: norm * four_pi * kk**2 * ps(np.log(kk)) \ * np.exp(-kk * RR / suppression) / kk / RR if method == 'clenshaw-curtis': if split_by_scale: kcri = np.exp(ps.x[np.argmin( np.abs(np.exp(ps.x) - 1. / RR))]) # Integral over small k is easy lowk = np.exp(ps.x) <= kcri klow = np.exp(ps.x[lowk == 1]) plow = ps.y[lowk == 1] sinc = np.sin(RR * klow) / klow / RR integ = norm * four_pi * klow**2 * plow * sinc \ * np.exp(-klow * RR / suppression) cf[i] = np.trapz(integ * klow, x=np.log(klow)) / norm kstart = kcri #print(RR, 1. / RR, kcri, lowk.sum(), ps.x.size - lowk.sum()) # #if lowk.sum() < 1000 and lowk.sum() % 100 == 0: # import matplotlib.pyplot as pl # # pl.figure(2) # # sinc = np.sin(RR * k) / k / RR # pl.loglog(k, integrand(k) * sinc, color='k') # pl.loglog([kcri]*2, [1e-4, 1e4], color='y') # raw_input('<enter>') else: kstart = kmin # Add in the wiggly part cf[i] += quad(integrand, kstart, kmax, epsrel=epsrel, epsabs=epsabs, limit=limit, weight='sin', wvar=RR)[0] / norm else: raise NotImplemented('help') pb.finish() # Our FT convention cf /= (2 * np.pi)**3 return cf
def test_ret_err_and_cumsum(): ht = HankelTransform(N=50) res, err, cumsum = ht.integrate(lambda x: 1.0 / x, True, True)
def test_equivalence_of_integrate_and_transform(): ht = HankelTransform(N=50) intg = ht.integrate(lambda x: 1, False) tr = ht.transform(lambda x: 1.0 / x, ret_err=False) assert intg == tr
def test_ret_err(): ht = HankelTransform(N=50) res, err = ht.integrate(lambda x: 1.0 / x, True)
def test_ret_cumsum(): ht = HankelTransform(N=50) res, cumsum = ht.integrate(lambda x: 1.0 / x, False, True)
def test_k_array(): k = np.logspace(-3, 3, 10) ht = HankelTransform(N=50) res = ht.transform(lambda x: 1.0 / x, k, False) assert len(res) == 10
def test_k_scalar(): k = 1 ht = HankelTransform(N=50) res = ht.transform(lambda x: 1.0 / x, k, False) assert np.isscalar(res)
def test_array_h(): with pytest.raises(TypeError): HankelTransform(h=np.logspace(-3, 0, 10))
def test_array_nu(): with pytest.raises(ValueError): HankelTransform(nu=np.linspace(0, 1, 2))
data.close() refs = [float(val) for val in lines] # Interpolating function for Hankel transform # P2D = interp1d(ls, refs, kind='cubic') spl = Spline(np.log(ths), np.log(refs), k=1) def P2D(x): return np.exp(spl(np.log(x))) # Xi+ htp = HankelTransform( nu=0, # The order of the bessel function N=120000, # Number of steps in the integration h=0.01 # Proxy for "size" of steps in integration ) xip = htp.transform(P2D, ths, ret_err=False) # Xi- htm = HankelTransform( nu=4, # The order of the bessel function N=120000, # Number of steps in the integration h=0.01 # Proxy for "size" of steps in integration ) xim = htm.transform(P2D, ths, ret_err=False) plt.figure(1).set_size_inches((8, 8), forward=False)
def test_array_n(): with pytest.raises(ValueError): HankelTransform(N=np.linspace(100, 200, 10))
def test_k_scalar(): k = 1 ht = HankelTransform(N=50) res = ht.transform(lambda x: 1. / x, k, False) assert np.isscalar(res)
def test_ret_err(): ht = HankelTransform(N=50) res, err = ht.integrate(lambda x: 1. / x, True)
def test_ret_cumsum(): ht = HankelTransform(N=50) res, cumsum = ht.integrate(lambda x: 1. / x, False, True)
def test_ret_err_and_cumsum(): ht = HankelTransform(N=50) res, err, cumsum = ht.integrate(lambda x: 1. / x, True, True)
def test_equivalence_of_integrate_and_transform(): ht = HankelTransform(N=50) int = ht.integrate(lambda x: 1, False) tr = ht.transform(lambda x: 1. / x, ret_err=False) assert int == tr
def FT3D(self, k, cf, R=None, Rmin=None, Rmax=None, epsabs=1e-12, epsrel=1e-12, limit=500, split_by_scale=False, method='clenshaw-curtis', use_pb=False, suppression=np.inf): """ This is nearly identical to the inverse transform function above, I just got tired of having to remember to swap meanings of the k and R variables. Sometimes clarity is better than minimizing redundancy. """ assert type(k) == np.ndarray if (type(cf) == FunctionType) or isinstance(cf, interp1d) \ or isinstance(cf, Akima1DInterpolator): R = cf.x elif type(cf) == np.ndarray: # Setup interpolant assert R is not None, "Must supply R vector as well!" #if interpolant == 'akima': # ps = Akima1DInterpolator(k, ps) #elif interpolant == 'cubic': cf = interp1d(np.log(R), cf, kind='cubic', assume_sorted=True, bounds_error=False, fill_value=0.0) else: raise ValueError('Do not understand type of `ps`.') if Rmin is None: Rmin = R.min() if Rmax is None: Rmax = R.max() norm = 1. / cf(np.log(Rmin)) if method == 'ogata': assert have_hankel, "hankel package required for this!" integrand = lambda RR: four_pi * R**2 * norm * cf(np.log(RR)) ht = HankelTransform(nu=0, N=k.size, h=0.1) #integrand = lambda kk: ps(np.log(kk)) * norm #ht = SymmetricFourierTransform(3, N=k.size, h=0.001) #print(ht.integrate(integrand)) ps = ht.transform(integrand, k=k, ret_err=False, inverse=False) / norm return ps ## # Optional progress bar ## pb = ProgressBar(R.size, use=self.pf['progress_bar'] * use_pb, name='cf(R)->ps(k)') # Loop over k and perform integral ps = np.zeros_like(k) for i, kk in enumerate(k): if not pb.has_pb: pb.start() pb.update(i) if method == 'clenshaw-curtis': # Leave sin(k*R) out -- that's the 'weight' for scipy. # Note the minus sign. integrand = lambda RR: norm * four_pi * RR**2 * cf(np.log(RR)) \ * np.exp(-kk * RR / suppression) / kk / RR if split_by_scale: Rcri = np.exp(cf.x[np.argmin( np.abs(np.exp(cf.x) - 1. / kk))]) # Integral over small k is easy lowR = np.exp(cf.x) <= Rcri Rlow = np.exp(cf.x[lowR == 1]) clow = cf.y[lowR == 1] sinc = np.sin(kk * Rlow) / Rlow / kk integ = norm * four_pi * Rlow**2 * clow * sinc \ * np.exp(-kk * Rlow / suppression) ps[i] = np.trapz(integ * Rlow, x=np.log(Rlow)) / norm Rstart = Rcri #if lowR.sum() < 1000 and lowR.sum() % 100 == 0: # import matplotlib.pyplot as pl # # pl.figure(2) # # sinc = np.sin(kk * R) / kk / R # pl.loglog(R, integrand(R) * sinc, color='k') # pl.loglog([Rcri]*2, [1e-4, 1e4], color='y') # raw_input('<enter>') else: Rstart = Rmin # Use 'chebmo' to save Chebyshev moments and pass to next integral? ps[i] += quad(integrand, Rstart, Rmax, epsrel=epsrel, epsabs=epsabs, limit=limit, weight='sin', wvar=kk)[0] / norm else: raise NotImplemented('help') pb.finish() # return np.abs(ps)
def test_k_array(): k = np.logspace(-3, 3, 10) ht = HankelTransform(N=50) res = ht.transform(lambda x: 1. / x, k, False) assert len(res) == 10