Пример #1
0
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
Пример #2
0
    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()
Пример #3
0
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)
Пример #4
0
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)
Пример #5
0
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)
Пример #6
0
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)
Пример #7
0
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)
Пример #8
0
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)
Пример #9
0
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
Пример #10
0
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)
Пример #11
0
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)
Пример #12
0
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)
Пример #13
0
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)
Пример #14
0
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)
Пример #15
0
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)
Пример #16
0
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)
Пример #17
0
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)
Пример #18
0
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)
Пример #19
0
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)
Пример #20
0
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)
Пример #21
0
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)
Пример #22
0
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]
Пример #23
0
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)
Пример #24
0
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]
Пример #25
0
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)
Пример #26
0
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
Пример #28
0
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)
Пример #29
0
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))
Пример #30
0
    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
Пример #31
0
def test_ret_err_and_cumsum():
    ht = HankelTransform(N=50)
    res, err, cumsum = ht.integrate(lambda x: 1.0 / x, True, True)
Пример #32
0
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
Пример #33
0
def test_ret_err():
    ht = HankelTransform(N=50)
    res, err = ht.integrate(lambda x: 1.0 / x, True)
Пример #34
0
def test_ret_cumsum():
    ht = HankelTransform(N=50)
    res, cumsum = ht.integrate(lambda x: 1.0 / x, False, True)
Пример #35
0
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
Пример #36
0
def test_k_scalar():
    k = 1
    ht = HankelTransform(N=50)
    res = ht.transform(lambda x: 1.0 / x, k, False)
    assert np.isscalar(res)
Пример #37
0
def test_array_h():
    with pytest.raises(TypeError):
        HankelTransform(h=np.logspace(-3, 0, 10))
Пример #38
0
def test_array_nu():
    with pytest.raises(ValueError):
        HankelTransform(nu=np.linspace(0, 1, 2))
Пример #39
0
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)
Пример #40
0
def test_array_n():
    with pytest.raises(ValueError):
        HankelTransform(N=np.linspace(100, 200, 10))
Пример #41
0
def test_k_scalar():
    k = 1
    ht = HankelTransform(N=50)
    res = ht.transform(lambda x: 1. / x, k, False)
    assert np.isscalar(res)
Пример #42
0
def test_ret_err():
    ht = HankelTransform(N=50)
    res, err = ht.integrate(lambda x: 1. / x, True)
Пример #43
0
def test_ret_cumsum():
    ht = HankelTransform(N=50)
    res, cumsum = ht.integrate(lambda x: 1. / x, False, True)
Пример #44
0
def test_ret_err_and_cumsum():
    ht = HankelTransform(N=50)
    res, err, cumsum = ht.integrate(lambda x: 1. / x, True, True)
Пример #45
0
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
Пример #46
0
    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)
Пример #47
0
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