Пример #1
0
	def d_phi_helper(self, n, l, m, s, theta):
		"""
		computes the derivatives of dphi/dr and dYlm/dtheta

		"""
		# Radial component
		# From Eqn. 3.29 in Hernquist and Ostriker 1992
		poly_ratio = special.eval_gegenbauer(n-1, 2*l+2.5, ((s-1)/(s+1))) /  special.eval_gegenbauer(n, 2*l+1.5, ((s-1)/(s+1)))
		dphi_dr_factor = (l/s - (2*l+1)/(1+s) + 4*(2*l+1.5)/(1+s)**2 * poly_ratio)


		# Theta component
		# From wolfram: https://functions.wolfram.com/Polynomials/SphericalHarmonicY/20/ShowAll.html
		# Both definitions are okay but this one is faster to compute numerically.

		l_zeros = np.where((l>=0))
		m_zeros = np.where((m<=l-1))

		dpot_dtheta = np.zeros_like(dphi_dr_factor)
		Plm_1 = np.zeros_like(dphi_dr_factor)

		Plm = special.lpmv(m[l_zeros], l[l_zeros], np.cos(theta))
		Plm_1[m_zeros] = special.lpmv(m[m_zeros], l[m_zeros]-1, np.cos(theta)) # check -1 in m-1

		gamma_factor = special.gamma(l[l_zeros]-m[l_zeros]+1)**0.5 / special.gamma(l[l_zeros]+m[l_zeros]+1)**0.5
		constant = ((2*l+1)/(4*np.pi))**0.5
		dpot_dtheta[l_zeros] = constant * gamma_factor * (l[l_zeros]*np.cos(theta) * Plm - (l[l_zeros]+m[l_zeros])*Plm_1)  / np.sin(theta)


		return dphi_dr_factor, dpot_dtheta
Пример #2
0
def pure_py(xyz, Snlm, Tnlm, nmax, lmax):
    from scipy.special import lpmv, gegenbauer, eval_gegenbauer, gamma
    from math import factorial as f

    Plm = lambda l,m,costh: lpmv(m, l, costh)
    Ylmth = lambda l,m,costh: np.sqrt((2*l+1)/(4 * np.pi) * f(l-m)/f(l+m)) * Plm(l,m,costh)

    twopi = 2*np.pi
    sqrtpi = np.sqrt(np.pi)
    sqrt4pi = np.sqrt(4*np.pi)

    r = np.sqrt(np.sum(xyz**2, axis=0))
    X = xyz[2]/r # cos(theta)
    sinth = np.sqrt(1 - X**2)
    phi = np.arctan2(xyz[1], xyz[0])
    xsi = (r - 1) / (r + 1)

    density = 0
    potenti = 0
    gradien = np.zeros_like(xyz)
    sph_gradien = np.zeros_like(xyz)
    for l in range(lmax+1):
        r_term1 = r**l / (r*(1+r)**(2*l+3))
        r_term2 = r**l / (1+r)**(2*l+1)
        for m in range(l+1):
            for n in range(nmax+1):
                Cn = gegenbauer(n, 2*l+3/2)
                Knl = 0.5 * n * (n+4*l+3) + (l+1)*(2*l+1)
                rho_nl = Knl / twopi * sqrt4pi * r_term1 * Cn(xsi)
                phi_nl = -sqrt4pi * r_term2 * Cn(xsi)

                density += rho_nl * Ylmth(l,m,X) * (Snlm[n,l,m]*np.cos(m*phi) +
                                                    Tnlm[n,l,m]*np.sin(m*phi))
                potenti += phi_nl * Ylmth(l,m,X) * (Snlm[n,l,m]*np.cos(m*phi) +
                                                    Tnlm[n,l,m]*np.sin(m*phi))

                # derivatives
                dphinl_dr = (2*sqrtpi*np.power(r,-1 + l)*np.power(1 + r,-3 - 2*l)*
                              (-2*(3 + 4*l)*r*eval_gegenbauer(-1 + n,2.5 + 2*l,(-1 + r)/(1 + r)) +
                              (1 + r)*(l*(-1 + r) + r)*eval_gegenbauer(n,1.5 + 2*l,(-1 + r)/(1 + r))))
                sph_gradien[0] += dphinl_dr * Ylmth(l,m,X) * (Snlm[n,l,m]*np.cos(m*phi) +
                                                              Tnlm[n,l,m]*np.sin(m*phi))

                A = np.sqrt((2*l+1) / (4*np.pi)) * np.sqrt(gamma(l-m+1) / gamma(l+m+1))
                dYlm_dth = A / sinth * (l*X*Plm(l,m,X) - (l+m)*Plm(l-1,m,X))
                sph_gradien[1] += (1/r) * dYlm_dth * phi_nl * (Snlm[n,l,m]*np.cos(m*phi) +
                                                               Tnlm[n,l,m]*np.sin(m*phi))

                sph_gradien[2] += (m/(r*sinth)) * phi_nl * Ylmth(l,m,X) * (-Snlm[n,l,m]*np.sin(m*phi) +
                                                                           Tnlm[n,l,m]*np.cos(m*phi))

    cosphi = np.cos(phi)
    sinphi = np.sin(phi)
    gradien[0] = sinth*cosphi*sph_gradien[0] + X*cosphi*sph_gradien[1] - sinphi*sph_gradien[2]
    gradien[1] = sinth*sinphi*sph_gradien[0] + X*sinphi*sph_gradien[1] + cosphi*sph_gradien[2]
    gradien[2] = X*sph_gradien[0] - sinth*sph_gradien[1]

    return density, potenti, gradien
Пример #3
0
def get_potl(lmax, nmax, r):
    """
    get the Hernquist potential value 

    inputs
    lmax : 
    nmax :
    r    :
    
    """

    p = np.zeros([lmax + 1, nmax, r.size])

    zeta = r_to_zeta(r)
    #fac = 0.25*(1.0 - x*x);
    #rfac = 0.5*(1.0 - x);

    for l in range(0, lmax + 1):
        lfac = -(r**l) / ((1. + r)**(2. * l + 1.))

        for n in range(0, nmax):
            u = eval_gegenbauer(n, 2.0 * l + 1.5, zeta)
            p[l][n] = lfac * u

    return p
Пример #4
0
def test_roots_gegenbauer():
    rootf = lambda a: lambda n, mu: sc.roots_gegenbauer(n, a, mu)
    evalf = lambda a: lambda n, x: sc.eval_gegenbauer(n, a, x)
    weightf = lambda a: lambda x: (1 - x**2)**(a - 0.5)

    vgq = verify_gauss_quad
    vgq(rootf(-0.25), evalf(-0.25), weightf(-0.25), -1., 1., 5)
    vgq(rootf(-0.25), evalf(-0.25), weightf(-0.25), -1., 1., 25, atol=1e-12)
    vgq(rootf(-0.25), evalf(-0.25), weightf(-0.25), -1., 1., 100, atol=1e-11)

    vgq(rootf(0.1), evalf(0.1), weightf(0.1), -1., 1., 5)
    vgq(rootf(0.1), evalf(0.1), weightf(0.1), -1., 1., 25, atol=1e-13)
    vgq(rootf(0.1), evalf(0.1), weightf(0.1), -1., 1., 100, atol=1e-12)

    vgq(rootf(1), evalf(1), weightf(1), -1., 1., 5)
    vgq(rootf(1), evalf(1), weightf(1), -1., 1., 25, atol=1e-13)
    vgq(rootf(1), evalf(1), weightf(1), -1., 1., 100, atol=1e-12)

    vgq(rootf(10), evalf(10), weightf(10), -1., 1., 5)
    vgq(rootf(10), evalf(10), weightf(10), -1., 1., 25, atol=1e-13)
    vgq(rootf(10), evalf(10), weightf(10), -1., 1., 100, atol=1e-12)

    vgq(rootf(50), evalf(50), weightf(50), -1., 1., 5, atol=1e-13)
    vgq(rootf(50), evalf(50), weightf(50), -1., 1., 25, atol=1e-12)
    vgq(rootf(50), evalf(50), weightf(50), -1., 1., 100, atol=1e-11)

    # Alpha=170 is where the approximation used in roots_gegenbauer changes
    vgq(rootf(170), evalf(170), weightf(170), -1., 1., 5, atol=1e-13)
    vgq(rootf(170), evalf(170), weightf(170), -1., 1., 25, atol=1e-12)
    vgq(rootf(170), evalf(170), weightf(170), -1., 1., 100, atol=1e-11)
    vgq(rootf(170.5), evalf(170.5), weightf(170.5), -1., 1., 5, atol=1e-13)
    vgq(rootf(170.5), evalf(170.5), weightf(170.5), -1., 1., 25, atol=1e-12)
    vgq(rootf(170.5), evalf(170.5), weightf(170.5), -1., 1., 100, atol=1e-11)

    # Test for failures, e.g. overflows, resulting from large alphas
    vgq(rootf(238), evalf(238), weightf(238), -1., 1., 5, atol=1e-13)
    vgq(rootf(238), evalf(238), weightf(238), -1., 1., 25, atol=1e-12)
    vgq(rootf(238), evalf(238), weightf(238), -1., 1., 100, atol=1e-11)
    vgq(rootf(512.5), evalf(512.5), weightf(512.5), -1., 1., 5, atol=1e-12)
    vgq(rootf(512.5), evalf(512.5), weightf(512.5), -1., 1., 25, atol=1e-11)
    vgq(rootf(512.5), evalf(512.5), weightf(512.5), -1., 1., 100, atol=1e-10)

    # this is a special case that the old code supported.
    # when alpha = 0, the gegenbauer polynomial is uniformly 0. but it goes
    # to a scaled down copy of T_n(x) there.
    vgq(rootf(0), sc.eval_chebyt, weightf(0), -1., 1., 5)
    vgq(rootf(0), sc.eval_chebyt, weightf(0), -1., 1., 25)
    vgq(rootf(0), sc.eval_chebyt, weightf(0), -1., 1., 100, atol=1e-12)

    x, w = sc.roots_gegenbauer(5, 2, False)
    y, v, m = sc.roots_gegenbauer(5, 2, True)
    assert_allclose(x, y, 1e-14, 1e-14)
    assert_allclose(w, v, 1e-14, 1e-14)

    muI, muI_err = integrate.quad(weightf(2), -1, 1)
    assert_allclose(m, muI, rtol=muI_err)

    assert_raises(ValueError, sc.roots_gegenbauer, 0, 2)
    assert_raises(ValueError, sc.roots_gegenbauer, 3.3, 2)
    assert_raises(ValueError, sc.roots_gegenbauer, 3, -.75)
Пример #5
0
def laguerre_wave_function_mom(p, zeta, n, l):
    """
    Brute force fourier transformation of Laguerre function
    """
    xi = zeta * p * 0.5
    x = 0.5 / np.sqrt( 0.25 + xi*xi )
    r = 0.0
    prefact = np.sqrt( zeta * gamma(n+1) * gamma(n+2*l+3) /np.pi ) * (0.5*zeta) * (2*x)**(2*l+3) * (2*xi)**l * gamma(l+1)
    for k in range(n+1):
        r += (-1)**k * (k+1) * (2*x)**k * eval_gegenbauer(k+1, l+1, x) / (gamma(n+1-k) * gamma(2*l+3+k) )
    return r*prefact
Пример #6
0
def gegenbauerReconstruction(self, A, N):
    # np.set_printoptions(precision=3, suppress=True)
    entireA = np.hstack((A[1:][::-1], A))

    n = np.size(entireA)
    x = self.chebNodes(n=N)
    k = np.arange(-A.size + 1, A.size)

    xx, kk = np.meshgrid(x, k)
    M = np.exp(1j * kk * np.pi * xx).T

    fx = M.dot(entireA)

    cfx = self.chebTransform(fx)
    # gamma = 1

    # print(gamma)
    l = N
    # l = 4.5
    xx, NN = np.meshgrid(x, np.arange(N))
    gx = special.eval_gegenbauer(NN, l, xx)
    # print(gx)
    cgx = (self.chebTransform(gx.T)).T
    # print(cgx)
    wx = np.power(1 - x * x, l - 0.5)
    cwx = self.chebTransform(wx)
    cIx = []
    for i in range(gx.shape[0]):
        cIx.append(np_cheb.chebmul(cwx, cgx[i, :]))
        # print(cgx[i, :])
    cIx = np.asarray(cIx)
    I = []
    h = np.sqrt(np.pi) * special.eval_gegenbauer(np.arange(N), l, 1) * special.gamma(l + 0.5) / special.gamma(l) / (
            N + l)
    for it in cIx:
        I.append(np.real(self.integrate(it, cfx)))
    I /= h
    # print(np.array(I))
    # print(gx)
    plt.plot(x, (gx.T).dot(I))
    plt.show()
Пример #7
0
def phi_nl_f(r, n, l):
    """
    Input:
    ------
    r: Particles coordinates
    n: n
    l: l
    Output:
    -------
    phi_nl: The potential basis. Eq.11 Lowing e.a (2011)
    """

    factor = r**l * (1.+r)**(-2.*l-1.) * np.sqrt(4.*np.pi) 
    s = (r-1.)/(r+1.)
    C_n = special.eval_gegenbauer(n, 2.*l+3./2., s)
    return -factor*C_n.real
Пример #8
0
	def bfe_density(self):
		# Eq 13 in Lowing+11
		nlist, llist, mlist, Slist, Tlist = self.nlm_list()
		Knl = 0.5*nlist*(nlist+4*llist+3) + (llist+1)*(2*llist+1)

		# Factor in the spherical harmonics that to compute as Ylm(theta) = factor*Plm(theta)
		rho_total = np.zeros(self.nparticles)

		# Loop over particle positions
		for k in range(self.nparticles):
			rho_nl = np.sqrt(4*np.pi) * Knl * self.s[k]**(llist) / (self.s[k]*(1+self.s[k])**(2*llist+3)) / (2*np.pi) # Eq. 10
			# Polynomials
			Ylm = special.sph_harm(mlist, llist, 0, self.theta[k]).real
			Xi_nl = special.eval_gegenbauer(nlist, 2*llist+1.5, (self.s[k]-1)/(self.s[k]+1))
			# Azymuthal component
			SpT = Slist * np.cos(mlist * self.phi[k]) + Tlist * np.sin(mlist * self.phi[k])
			# Sum over n,l,m
			rho_total[k] = np.sum(rho_nl * Xi_nl * Ylm * SpT)
		return rho_total * self.M/self.rs**3
Пример #9
0
def gottliebShu(sig, N, gam=0.25):
    """
    :param sig: numpy.array input signal.
    :param N: Number of spectral partial sum or number of overtone.
    :param gam: Positive real constant.
    """
    lam = gam * N  # N が大きいと eval_gegenbauerでオーバーフローする。

    x = numpy.linspace(-1.0, 1.0, len(sig))
    k = numpy.arange(0, int(N / 2))
    ggnbr = eval_gegenbauer(numpy.tile(numpy.vstack(k), len(sig)), lam, x)
    ggnbr_t = numpy.transpose(ggnbr)

    h_k_lam = numpy.sqrt(numpy.pi) \
        * ggnbr_t[-1] \
        * gamma(lam + 0.5) / gamma(lam) / (k + lam)

    g_hat = numpy.sum(
        numpy.power(1 - x * x, numpy.abs(lam - 0.5)) * sig * ggnbr,
        axis=1) / h_k_lam

    return (numpy.sum(g_hat * ggnbr_t, axis=1), g_hat)
Пример #10
0
 def test_gegenbauer_complex_general(self):
     assert_mpmath_equal(lambda n, a, x: sc.eval_gegenbauer(n.real, a.real, x),
                         _exception_to_nan(mpmath.gegenbauer),
                         [Arg(-1e3, 1e3), Arg(), ComplexArg()])
Пример #11
0
 def test_gegenbauer_complex(self):
     assert_mpmath_equal(lambda n, a, x: sc.eval_gegenbauer(int(n), a.real, x),
                         _exception_to_nan(mpmath.gegenbauer),
                         [IntArg(0, 100), Arg(), ComplexArg()])
Пример #12
0
def phiV(u, a1, a2):
    """Vector meson light-cone distribution amplitude to second order
    in the Gegenbauer expansion."""
    c1 = eval_gegenbauer(1, 3 / 2., 2 * u - 1)
    c2 = eval_gegenbauer(2, 3 / 2., 2 * u - 1)
    return 6 * u * (1 - u) * (1 + a1 * c1 + a2 * c2)
Пример #13
0
def pure_py(xyz, Snlm, Tnlm, nmax, lmax):
    from scipy.special import lpmv, gegenbauer, eval_gegenbauer, gamma
    from math import factorial as f

    def Plm(l, m, costh):
        return lpmv(m, l, costh)

    def Ylmth(l, m, costh):
        return np.sqrt((2*l+1)/(4 * np.pi) * f(l-m)/f(l+m)) * Plm(l, m, costh)

    twopi = 2*np.pi
    sqrtpi = np.sqrt(np.pi)
    sqrt4pi = np.sqrt(4*np.pi)

    r = np.sqrt(np.sum(xyz**2, axis=0))
    X = xyz[2] / r  # cos(theta)
    sinth = np.sqrt(1 - X**2)
    phi = np.arctan2(xyz[1], xyz[0])
    xsi = (r - 1) / (r + 1)

    density = 0
    potenti = 0
    gradien = np.zeros_like(xyz)
    sph_gradien = np.zeros_like(xyz)
    for l in range(lmax+1):
        r_term1 = r**l / (r*(1+r)**(2*l+3))
        r_term2 = r**l / (1+r)**(2*l+1)
        for m in range(l+1):
            for n in range(nmax+1):
                Cn = gegenbauer(n, 2*l+3/2)
                Knl = 0.5 * n * (n+4*l+3) + (l+1)*(2*l+1)
                rho_nl = Knl / twopi * sqrt4pi * r_term1 * Cn(xsi)
                phi_nl = -sqrt4pi * r_term2 * Cn(xsi)

                density += rho_nl * Ylmth(l, m, X) * (Snlm[n, l, m]*np.cos(m*phi) +
                                                      Tnlm[n, l, m]*np.sin(m*phi))
                potenti += phi_nl * Ylmth(l, m, X) * (Snlm[n, l, m]*np.cos(m*phi) +
                                                      Tnlm[n, l, m]*np.sin(m*phi))

                # derivatives
                dphinl_dr = (
                    2*sqrtpi*np.power(r, -1 + l)*np.power(1 + r, -3 - 2*l) *
                    (-2*(3 + 4*l)*r*eval_gegenbauer(-1 + n, 2.5 + 2*l, (-1 + r)/(1 + r)) +
                     (1 + r)*(l*(-1 + r) + r)*eval_gegenbauer(n, 1.5 + 2*l, (-1 + r)/(1 + r))))
                sph_gradien[0] += dphinl_dr * Ylmth(l, m, X) * (Snlm[n, l, m]*np.cos(m*phi) +
                                                                Tnlm[n, l, m]*np.sin(m*phi))

                A = np.sqrt((2*l+1) / (4*np.pi)) * np.sqrt(gamma(l-m+1) / gamma(l+m+1))
                dYlm_dth = A / sinth * (l*X*Plm(l, m, X) - (l+m)*Plm(l-1, m, X))
                sph_gradien[1] += (1/r) * dYlm_dth * phi_nl * (Snlm[n, l, m]*np.cos(m*phi) +
                                                               Tnlm[n, l, m]*np.sin(m*phi))

                sph_gradien[2] += (m/(r*sinth)) * phi_nl * Ylmth(l, m, X) * (
                    -Snlm[n, l, m]*np.sin(m*phi) + Tnlm[n, l, m]*np.cos(m*phi))

    cosphi = np.cos(phi)
    sinphi = np.sin(phi)
    gradien[0] = sinth*cosphi*sph_gradien[0] + X*cosphi*sph_gradien[1] - sinphi*sph_gradien[2]
    gradien[1] = sinth*sinphi*sph_gradien[0] + X*sinphi*sph_gradien[1] + cosphi*sph_gradien[2]
    gradien[2] = X*sph_gradien[0] - sinth*sph_gradien[1]

    return density, potenti, gradien
Пример #14
0
 def test_gegenbauer_complex_general(self):
     assert_mpmath_equal(
         lambda n, a, x: sc.eval_gegenbauer(n.real, a.real, x),
         _exception_to_nan(mpmath.gegenbauer),
         [Arg(-1e3, 1e3), Arg(), ComplexArg()])
Пример #15
0
 def test_gegenbauer_complex(self):
     assert_mpmath_equal(
         lambda n, a, x: sc.eval_gegenbauer(int(n), a.real, x),
         _exception_to_nan(mpmath.gegenbauer),
         [IntArg(0, 100), Arg(), ComplexArg()])
Пример #16
0
def phiV(u, a1, a2):
    """Vector meson light-cone distribution amplitude to second order
    in the Gegenbauer expansion."""
    c1 = eval_gegenbauer(1, 3/2., 2*u-1)
    c2 = eval_gegenbauer(2, 3/2., 2*u-1)
    return 6*u * (1-u) * (1 + a1 * c1 + a2 * c2)
Пример #17
0
	def bfe_phi_nl(self, n, l, m, s):
		# Eq. 11 in Lowing
		# TBD: Check if I'm missing a sqrt(4*pi)
		phi_s =  s**l / (1+s)**(2*l+1)
		phi_nl = special.eval_gegenbauer(n, 2*l+1.5, (s-1)/(s+1))
		return phi_s * phi_nl * np.sqrt(4*np.pi)
Пример #18
0
def Dln(r, l, n, Rb):
    rrb = r / Rb
    return Bln(l, n, Rb) * (np.power(rrb, l) /
                            np.power(1 +
                                     (rrb * rrb), l + 2.5)) * eval_gegenbauer(
                                         n - 1, l + 1, rescaled_rho(r, Rb))
Пример #19
0
 def Phinlm(self, n,l,m,r,z,phi):
     #print('now in Phinlm')
     r, theta = transform(rho = r, z = z)
     s = r/1. # 1. is in kpc!!!!!
     return s**l/((1 + s)**(2*l + 1))*eval_gegenbauer(n, 2*l + 3/2, (s - 1)/(s + 1))*np.cos(m*phi)*lpmv(m, l, np.cos(theta))