Exemple #1
0
    def solve(self, init, x):
        A = np.zeros([2, 2])
        A[0][0] = special.lpmn(self.order, self.degree,
                               self.function(x[0]))[0][self.order][self.degree]
        A[0][1] = special.lqmn(self.order, self.degree,
                               self.function(x[0]))[0][self.order][self.degree]
        A[1][0] = self.function.deriv(1)(x[0]) * special.lpmn(
            self.order, self.degree, self.function(
                x[0]))[1][self.order][self.degree]
        A[1][1] = self.function.deriv(1)(x[0]) * special.lqmn(
            self.order, self.degree, self.function(
                x[0]))[1][self.order][self.degree]
        print(A)
        c = np.linalg.solve(A, init)
        self.c = c
        y = np.zeros((len(x), 2))
        for i in range(len(x)):
            for j in range(2):
                if j == 0:
                    y[i][j] = \
                    c[0]*special.lpmn(self.order, self.degree, self.function(x[i]))[j][self.order][self.degree] + \
                    c[1]*special.lqmn(self.order, self.degree, self.function(x[i]))[j][self.order][self.degree]

                elif j == 1:
                    y[i][j] = \
                    c[0]*self.function.deriv(1)(x[i])*special.lpmn(self.order, self.degree, self.function(x[i]))[j][self.order][self.degree] + \
                    c[1]*self.function.deriv(1)(x[i])*special.lqmn(self.order, self.degree, self.function(x[i]))[j][self.order][self.degree]
        self.x = x
        self.y = y
        return y
Exemple #2
0
def lpy1(nmax, z):
    """
    Associated legendre function and its derivatative at z in the 'y-indexing'.
    (Without Condon-Shortley phase AFAIK.)
    NOT THOROUGHLY TESTED
    
    Parameters
    ----------
    
    nmax: int
        The maximum order to which the Legendre functions will be evaluated..
        
    z: float
        The point at which the Legendre functions are evaluated.
        
    output: (P_y, dP_y) TODO
        y-indexed legendre polynomials and their derivatives
    
    """
    pmn_plus, dpmn_plus = lpmn(nmax, nmax, z)
    pmn_minus, dpmn_minus = lpmn(-nmax, nmax, z)
    nelem = nmax * nmax + 2*nmax
    P_y = np.empty((nelem,), dtype=np.float_)
    dP_y = np.empty((nelem,), dtype=np.float_)
    mn_p_y, mn_n_y = get_y_mn_unsigned(nmax)
    mn_plus_mask = (mn_p_y >= 0)
    mn_minus_mask = (mn_n_y >= 0)
    #print( mn_n_y[mn_minus_mask])
    P_y[mn_p_y[mn_plus_mask]] = pmn_plus[mn_plus_mask]
    P_y[mn_n_y[mn_minus_mask]] = pmn_minus[mn_minus_mask]
    dP_y[mn_p_y[mn_plus_mask]] = dpmn_plus[mn_plus_mask]
    dP_y[mn_n_y[mn_minus_mask]] = dpmn_minus[mn_minus_mask]
    return (P_y, dP_y)
Exemple #3
0
def y(F, n, m, H_0, sign):
    OmH = H_0 / (4 * np.pi * M) - (1 / 3)
    Omega = F + OmH
    kappa = -OmH / (F * (F + 2 * OmH))
    nu = -(F + OmH) / (F * (F + 2 * OmH))
    xi = np.sqrt(1 + 1 / kappa)
    #print(1 + 1/kappa)
    nu = -(F + OmH) / (F * (F + 2 * OmH))
    return (n + 1 + sign * m * nu) * lpmn(m, n, xi)[0][m][n] + xi * lpmn(
        m, n, xi)[1][m][n]
Exemple #4
0
def sph_harm_large(m, n, az, el):
    """Compute spherical harmonics for large orders > 84

    Parameters
    ----------
    m : (int)
        Order of the spherical harmonic. abs(m) <= n

    n : (int)
        Degree of the harmonic, sometimes called l. n >= 0

    az: (float)
        Azimuthal (longitudinal) coordinate [0, 2pi], also called Theta.

    el : (float)
        Elevation (colatitudinal) coordinate [0, pi], also called Phi.

    Returns
    -------
    y_mn : (complex float)
        Complex spherical harmonic of order m and degree n,
        sampled at theta = az, phi = el

    Notes
    -----
    Y_n,m (theta, phi) = ((n - m)! * (2l + 1)) / (4pi * (l + m))^0.5 * exp(i m phi) * P_n^m(cos(theta))
    as per http://dlmf.nist.gov/14.30
    Pmn(z) is the associated Legendre function of the first kind, like scipy.special.lpmv
    scipy.special.lpmn calculates P(0...m 0...n) and its derivative but won't return +inf at high orders
    """
    if _np.all(_np.abs(m) < 84):
        return scy.sph_harm(m, n, az, el)
    else:
        # TODO: confirm that this uses the correct SH definition

        mAbs = _np.abs(m)
        if isinstance(el, _np.ndarray):
            P = _np.empty(el.size)
            for k in range(0, el.size):
                P[k] = scy.lpmn(mAbs, n, _np.cos(el[k]))[0][-1][-1]
        else:
            P = scy.lpmn(mAbs, n, _np.cos(el))[0][-1][-1]
        preFactor1 = _np.sqrt((2 * n + 1) / (4 * _np.pi))
        try:
            preFactor2 = _np.sqrt(fact(n - mAbs) / fact(n + mAbs))
        except OverflowError:  # integer division for very large orders
            preFactor2 = _np.sqrt(fact(n - mAbs) // fact(n + mAbs))

        Y = preFactor1 * preFactor2 * _np.exp(1j * m * az) * P
        if m < 0:
            return _np.conj(Y)
        else:
            return Y
Exemple #5
0
 def test_legendre(self):
     xs = np.linspace(0, 1, 10000)
     ys = np.zeros(10000 * 16)
     ys2 = np.zeros(10000 * 16)
     for i in range(xs.shape[0]):
         if i == 0: print(lpmn(-3, 3, xs[i])[0])
         ys[16 * i:16 * (i + 1)] = lpmn(-3, 3, xs[i])[0].flatten()
     for i in range(xs.shape[0]):
         for l in range(4):
             for m in range(0, -l - 1, -1):
                 ys2[i * 16 - m * 4 + l] = pawpyc.legendre(l, m, xs[i])
     assert_almost_equal(np.linalg.norm(ys - ys2), 0.0)
Exemple #6
0
def sph_harm_large(m, n, az, el):
    """Compute spherical harmonics for large orders > 84

    Parameters
    ----------
    m : (int)
        Order of the spherical harmonic. abs(m) <= n

    n : (int)
        Degree of the harmonic, sometimes called l. n >= 0

    az: (float)
        Azimuthal (longitudinal) coordinate [0, 2pi], also called Theta.

    el : (float)
        Elevation (colatitudinal) coordinate [0, pi], also called Phi.

    Returns
    -------
    y_mn : (complex float)
        Complex spherical harmonic of order m and degree n,
        sampled at theta = az, phi = el

    Y_n,m (theta, phi) = ((n - m)! * (2l + 1)) / (4pi * (l + m))^0.5 * exp(i m phi) * P_n^m(cos(theta))
    as per http://dlmf.nist.gov/14.30
    Pmn(z) is the associated Legendre function of the first kind, like scipy.special.lpmv
    scipy.special.lpmn calculates P(0...m 0...n) and its derivative but won't return +inf at high orders
    """
    if _np.all(_np.abs(m) < 84):
        return scy.sph_harm(m, n, az, el)
    else:

        # TODO: confirm that this uses the correct SH definition

        mAbs = _np.abs(m)
        if isinstance(el, _np.ndarray):
            P = _np.empty(el.size)
            for k in range(0, el.size):
                P[k] = scy.lpmn(mAbs, n, _np.cos(el[k]))[0][-1][-1]
        else:
            P = scy.lpmn(mAbs, n, _np.cos(el))[0][-1][-1]
        preFactor1 = _np.sqrt((2 * n + 1) / (4 * _np.pi))
        try:
            preFactor2 = _np.sqrt(fact(n - mAbs) / fact(n + mAbs))
        except OverflowError:  # integer division for very large orders
            preFactor2 = _np.sqrt(fact(n - mAbs) // fact(n + mAbs))

        Y = preFactor1 * preFactor2 * _np.exp(1j * m * az) * P
        if m < 0:
            return _np.conj(Y)
        else:
            return Y
Exemple #7
0
def getfreq_2(n,m,H_0):
    fr = np.linspace(0,100,16000)#GHz
    yr, yr2, yr3 = [], [], []
    for f in fr:
        Omega = f*1e9/(4*np.pi*gamma*M)
        H_i = H_0 - (4*np.pi/3)*M
        Omega_H = H_i/(4*np.pi*M)
        nu = Omega/(Omega_H**2-Omega**2)
        kappa = Omega_H/(Omega_H**2-Omega**2)
        xi=np.sqrt(1+1/kappa)
        yr.append(xi*lpmn(m,n,xi)[1][m][n]/lpmn(m,n,xi)[0][m][n])
        yr2.append(-1*(n+1)+m*nu)
        yr3.append(-1*(n+1)-m*nu)
Exemple #8
0
def y_t(F, n, m, H_0, sign):
    OmH = H_0 / (4 * np.pi * M) - (1 / 3)
    kappa = -OmH / (F * (F + 2 * OmH))
    nu = -(F + OmH) / (F * (F + 2 * OmH))
    xi = np.sqrt(abs(1 + 1 / kappa))
    nu = -(F + OmH) / (F * (F + 2 * OmH))
    if kappa <= -1:
        return (n + 1 + sign * m * nu) * lpmn(m, n, xi)[0][m][n] + xi * lpmn(
            m, n, xi)[1][m][n]
    else:
        return -((n + 1 + sign * m * nu) * lpmn(m, n, xi)[0][m][n] +
                 xi * lpmn(m, n, xi)[1][m][n])
    return 9 + (3 * O)
Exemple #9
0
def y_2(f, n, m, H_0, sign):
    Omega = f / (4 * np.pi * gamma * M)
    #print ('Omega: {}'.format(Omega))
    H_i = H_0 - (4 * np.pi / 3) * M
    Omega_H = H_i / (4 * np.pi * M)
    #print ('OmegaH: {}'.format(Omega_H))
    nu = Omega / (Omega_H**2 - Omega**2)
    kappa = Omega_H / (Omega_H**2 - Omega**2)
    xi = np.sqrt(1.0 + 1.0 / kappa)
    #print (Omega - Omega_H)
    #return n + 1 + xi*lpmn(m,n,xi)[1][m][n]/lpmn(m,n,xi)[0][m][n] + sign*m*nu
    return (n + 1 + sign * m * nu) * lpmn(m, n, xi)[0][m][n] + xi * lpmn(
        m, n, xi)[1][m][n]
Exemple #10
0
def getfreq(n,m,H_0):
    fr = np.linspace(0,100,16000)#GHz
    yr, yr2, yr3 = [], [], []
    for f in fr:
        Omega = f*1e9/(4*np.pi*gamma*M)
        H_i = H_0 - (4*np.pi/3)*M
        Omega_H = H_i/(4*np.pi*M)
        nu = Omega/(Omega_H**2-Omega**2)
        kappa = Omega_H/(Omega_H**2-Omega**2)
        xi=np.sqrt(1+1/kappa)
        yr.append(xi*lpmn(m,n,xi)[1][m][n]/lpmn(m,n,xi)[0][m][n])
        yr2.append(-1*(n+1)+m*nu)
        yr3.append(-1*(n+1)-m*nu)
    
    f = -1
    i=0
    if (yr[0]>yr2[0]):
        while(yr[i]>yr2[i]):
            i+=1
            if i>=len(yr2)-1:
                break
        if (yr[i]<yr2[i]):
            f=fr[i]
    else:
        while(yr[i]<yr2[i]):
            i+=1
            if i>=len(yr2)-1:
                break
        if (yr[i]>yr2[i]):
            f=fr[i]
    i = 0
    if (yr[0]>yr3[0]):
        while(yr[i]>yr3[i]):
            i+=1
            if i>=len(yr3)-1:
                break
        if (yr[i]<yr3[i]):
            f=fr[i]
    else:
        while(yr[i]<yr3[i]):
            i+=1
            if i>=len(yr3)-1:
                break
        if (yr[i]>yr3[i]):
            f=fr[i]
    
    print(f)
    
    if (f<0):
        print("No resonance below 100GHz")
    return f
Exemple #11
0
  def testNormalizedLpmnValues(self, l_max, num_z):
    # Points on which the associated Legendre functions areevaluated.
    z = np.linspace(-0.2, 0.9, num_z)
    is_normalized = True
    actual_p_vals = lsp_special.lpmn_values(l_max, l_max, z, is_normalized)

    # The expected results are obtained from scipy.
    expected_p_vals = np.zeros((l_max + 1, l_max + 1, num_z))
    for i in range(num_z):
      expected_p_vals[:, :, i] = osp_special.lpmn(l_max, l_max, z[i])[0]

    def apply_normalization(a):
      """Applies normalization to the associated Legendre functions."""
      num_m, num_l, _ = a.shape
      a_normalized = np.zeros_like(a)
      for m in range(num_m):
        for l in range(num_l):
          c0 = (2.0 * l + 1.0) * osp_special.factorial(l - m)
          c1 = (4.0 * np.pi) * osp_special.factorial(l + m)
          c2 = np.sqrt(c0 / c1)
          a_normalized[m, l] = c2 * a[m, l]
      return a_normalized

    # The results from scipy are not normalized and the comparison requires
    # normalizing the results.
    expected_p_vals_normalized = apply_normalization(expected_p_vals)

    with self.subTest('Test accuracy.'):
      self.assertAllClose(actual_p_vals, expected_p_vals_normalized, rtol=1e-6, atol=3.2e-6)

    with self.subTest('Test JIT compatibility'):
      args_maker = lambda: [z]
      lsp_special_fn = lambda z: lsp_special.lpmn_values(l_max, l_max, z, is_normalized)
      self._CompileAndCheck(lsp_special_fn, args_maker)
Exemple #12
0
    def _calculate_radial_force(cls, r, phi, theta):
        if len(cls.__COEFFICIENTS) == 0:
            cls.import_coefficients(
                'D:\Users\\tjh97\Dropbox\Workspace\SatelliteSimulator\Model\egm96_coeff.dat'
            )

        R = constant.RADIUS_OF_EARTH
        P, P_prime = sp.lpmn(cls.__MODEL_ORDER_N, cls.__MODEL_ORDER_N,
                             sin(theta))

        tess = 0
        for n in range(2, cls.__MODEL_ORDER_N):
            for m in range(1, n):
                C_nm, S_nm = cls.__C[m][n], cls.__S[m][n]

                C_nm_tilde = -C_nm / (constant.MU * R**n)
                S_nm_tilde = -S_nm / (constant.MU * R**n)

                P_mn = P[m][n]
                tg = C_nm_tilde * cos(m * phi) + S_nm_tilde * sin(m * phi)
                den = (r / R)**n

                tess += (n + 1) * P_mn * tg / den
                # tess += (n+1)*P*(C_nm*cos(m*phi) + S_nm*sin(m*phi))/r**(n+2)
        # tess = 0

        return -(constant.MU / r**2)  # *(1/Universe.MU - tess)
Exemple #13
0
    def calculate_geopotential(cls, r, phi, theta):
        if len(cls.__COEFFICIENTS) == 0:
            cls.import_coefficients(
                'D:\Users\\tjh97\Dropbox\Workspace\SatelliteSimulator\Model\egm96_coeff.dat'
            )
        R = constant.RADIUS_OF_EARTH
        P, P_prime = sp.lpmn(cls.__MODEL_ORDER_N, cls.__MODEL_ORDER_N,
                             sin(theta))

        zonal = 0
        # for n in range(2, cls.__MODEL_ORDER_N):
        #     J_tilde = -1/(Universe.MU*R**n)
        #     P = sp.lpmv(0, n, sin(theta))
        #     den = (r/R)**n
        #
        #     zonal += (J_tilde*P)/den

        tess = 0
        for n in range(2, cls.__MODEL_ORDER_N):
            for m in range(1, n):
                C_nm, S_nm = cls.__C[m][n], cls.__S[m][n]

                C_nm_tilde = -C_nm / (Universe.MU * R**n)
                S_nm_tilde = -S_nm / (Universe.MU * R**n)

                P_mn = P[m][n]
                tg = C_nm_tilde * cos(m * phi) + S_nm_tilde * sin(m * phi)
                den = (r / R)**n

                tess += P_mn * tg / den

        return -(Universe.MU / r) * (1 + zonal + tess)
 def egmF(elements, var, init_jd, t, order_used, lc):
     # translate positions and velocities from GCRS into ITRS frame
     r1, v1 = GCRS2ITRS(var.r, var.v, init_jd, t / 24. / 3600.)
     # translate cartesian coordinates into spherical coordinates of positions in ITRS frame
     r, phi, lamda = coord.cartesian_to_spherical(r1[0], r1[1], r1[2])
     phi, lamda = phi.value, lamda.value
     # get the values of Legendre Polynomials and their derivatives
     Pmn, Pmn_d = special.lpmn(n, n, np.sin(phi))
     Fsc = np.zeros(3)
     for l in range(1, order_used + 1):
         for m in range(l + 1):
             Fsc[0] += -model.GM / r / r * (model.R / r)**l * (l + 1) * Pmn[
                 m, l] * lc[m, l] * (C[l, m] * np.cos(m * lamda) +
                                     S[l, m] * np.sin(m * lamda))
             Fsc[1] += model.GM / r * (model.R / r)**l * m * Pmn[m, l] * lc[
                 m, l] * (S[l, m] * np.cos(m * lamda) -
                          C[l, m] * np.sin(m * lamda))
             Fsc[2] += model.GM / r * (model.R / r)**l * Pmn_d[m, l] * lc[
                 m, l] * np.cos(phi) * (C[l, m] * np.cos(m * lamda) +
                                        S[l, m] * np.sin(m * lamda))
     Fsc[1] /= r * np.cos(phi)
     Fsc[2] /= r
     # translate the force from spherical to cartesian in ITRS frame
     Fxyz = force_spherical_to_cartesian(Fsc, lamda, phi)
     # translate the force from ITRS to GCRS frame
     FF, v = ITRS2GCRS(Fxyz, Fxyz, init_jd, t / 24. / 3600.)
     # matrix transform from Spherical Coordinates to Cartesian Coordinates
     return FF
Exemple #15
0
def gridSHexp(V, xri, yri, zri, order):
    """
V:			gridded values
xri, yri, zri:	relative grid vectors
order:			max l in the spherical harmonic expansion
	"""
    assert xri.ndim == 1 and yri.ndim == 1 and zri.ndim == 1
    n_samp = xri.size * yri.size * zri.size
    assert n_samp >= (order + 1)**2
    Y, X, Z = np.meshgrid(yri, xri, zri)

    for A in [X, Y, Z]:
        A.shape = (-1, )  #flattening
    W = V.reshape(-1, )

    Phi = np.arctan2(Y, X)
    # print(Phi)
    Theta = np.arctan2((X**2 + Y**2)**0.5, Z)
    R = (X**2 + Y**2 + Z**2)**0.5
    r0 = R.max()**0.5
    R /= r0

    Q = np.empty((n_samp, (order + 1)**2), 'd')
    Q[:, 0] = 1
    # We don't expand on scipy.special.sph_harm
    # Instead, expand on P_l^m(cos\theta) * (cos(m\phi), sin(m\phi))^T
    MPhi = (np.atleast_2d(Phi).T) * np.arange(1, order + 1)
    # print(MPhi)
    cos_sin_MPhi = np.stack((np.cos(MPhi), np.sin(MPhi)),
                            axis=-1).reshape(n_samp, -1)
    # print(cos_sin_MPhi)
    for p in range(n_samp):
        # print(X[p], Y[p], Z[p])
        aslegd = lpmn(order, order, np.cos(Theta[p]))[0]
        # aslegd is now an upper triangle order+1 by order+1 mat
        # aslegd[m,l] = P_l^m(Theta[p]) if m<=l else 0
        pt_col = 1
        for l in range(1, order + 1):
            r_pl_theta = (R[p]**l) * aslegd[:l + 1, l]
            # print("\t",r_pl_theta)
            Q[p, pt_col] = r_pl_theta[0]
            pt_col += 1
            Q[p, pt_col:pt_col +
              2 * l] = np.repeat(r_pl_theta[1:], 2) * cos_sin_MPhi[p, :2 * l]
            pt_col += 2 * l
        assert pt_col == (order + 1)**2

    # print(Q)
    # print(W)
    fit = lstsq(Q, W)
    rms = (fit[1] / n_samp)**0.5

    rescale = [1]
    for l in range(1, order + 1):
        rescale = rescale + [r0**l] * (2 * l + 1)
    rescale = np.array(rescale)
    # print(rescale)

    # return fit[0], rms
    return fit[0] / rescale, rms
def Pol_Legendre(l, m, x):
    """
    returns an array[m+1,n+1] of the values of the associated Legendre function
    of all integer degrees l and order m, at point x
    """
    Plm_z, Plm_dz = lpmn(m, l, x)
    return Plm_z, Plm_dz  # use Plm_z[m, l]
Exemple #17
0
def tau_func(n, m, theta):
    """tau special function in modal decomposition"""
    if np.sin(theta) == 0:
        return 0
    # Pnm_d = legendre(n,m,theta,1)
    Pnm_d = -1*np.sin(theta)*special.lpmn(m,n, np.cos(theta))[1][abs(m)][n]
    return Pnm_d
Exemple #18
0
    def testLpmn(self, l_max, num_z):
        # Points on which the associated Legendre functions areevaluated.
        z = np.linspace(-0.2, 0.9, num_z)
        actual_p_vals, actual_p_derivatives = lsp_special.lpmn(m=l_max,
                                                               n=l_max,
                                                               z=z)

        # The expected results are obtained from scipy.
        expected_p_vals = np.zeros((l_max + 1, l_max + 1, num_z))
        expected_p_derivatives = np.zeros((l_max + 1, l_max + 1, num_z))

        for i in range(num_z):
            val, derivative = osp_special.lpmn(l_max, l_max, z[i])
            expected_p_vals[:, :, i] = val
            expected_p_derivatives[:, :, i] = derivative

        with self.subTest('Test values.'):
            self.assertAllClose(actual_p_vals,
                                expected_p_vals,
                                rtol=1e-6,
                                atol=3.2e-6)

        with self.subTest('Test derivatives.'):
            self.assertAllClose(actual_p_derivatives,
                                expected_p_derivatives,
                                rtol=1e-6,
                                atol=8.4e-4)

        with self.subTest('Test JIT compatibility'):
            args_maker = lambda: [z]
            lsp_special_fn = lambda z: lsp_special.lpmn(l_max, l_max, z)
            self._CompileAndCheck(lsp_special_fn, args_maker)
Exemple #19
0
def derlpmn_em(l, m, x):
    """
    Computes derivative of associated Legendre function (Plm) of the first kind of order m and degree l
    with respect to the argument x.

    Parameters
    ----------
    l: int
        degree of Plm
    m: int
        order of Plm
    x: Nx1 array
        evaluation points

    Returns
    -------
    derlp: Nx1 array
        dPlm/dx at `x`

    """

    derlp = np.zeros(x.shape)
    for i in range(x.shape[0]):
        a, b = lpmn(m, l, x[i])
        derlp[i] = b[np.abs(m), l]
    return derlp
Exemple #20
0
 def __normalized_legendre(m, n, x):
     """
     Fully normalized associated legendre polynomials degree n and order m. Cf.
     https://de.mathworks.com/help/matlab/ref/legendre.html#f89-1002493
     :param m: Order
     :param n: Degree
     :param x: Evaluation point
     :return: Function value
     """
     upper_fact = (lambda x: x, n - m)
     lower_fact = (lambda x: 1 / x, n + m)
     factor = RBF_QR_3D.__prodprod(upper_fact, lower_fact)
     factor = (-1)**m * math.sqrt(factor * (n + 0.5))
     if not np.isscalar(x):
         return np.array([lpmn(m, n, x_i)[0][-1, -1] for x_i in x])
     return lpmn(m, n, x)[0][-1, -1] * factor
Exemple #21
0
    def _compute(self, funcTilde, R, z, phi):
        """
        NAME:
           _compute
        PURPOSE:
           evaluate the NxLxM density or potential
        INPUT:
           funcTidle - must be _rhoTilde or _phiTilde
           R - Cylindrical Galactocentric radius
           z - vertical height
           phi - azimuth
        OUTPUT:
           An NxLxM density or potential at (R,z, phi)
        HISTORY:
           2016-05-18 - Written - Aladdin 
        """
        Acos, Asin = self._Acos, self._Asin
        N, L, M = Acos.shape
        r, theta, phi = bovy_coords.cyl_to_spher(R, z, phi)

        PP = lpmn(M - 1, L - 1,
                  nu.cos(theta))[0].T  ##Get the Legendre polynomials
        func_tilde = funcTilde(r, N, L)  ## Tilde of the function of interest

        func = nu.zeros(
            (N, L, M),
            float)  ## The function of interest (density or potential)

        m = nu.arange(0, M)[nu.newaxis, nu.newaxis, :]
        mcos = nu.cos(m * phi)
        msin = nu.sin(m * phi)
        func = func_tilde[:, :, None] * (Acos[:, :, :] * mcos +
                                         Asin[:, :, :] * msin) * PP[None, :, :]
        return func
Exemple #22
0
    def radial_sp(self,
                  radial,
                  theta,
                  phi,
                  radius=None,
                  M=2,
                  mu=1,
                  musp=1,
                  small=False):
        if not small or radius is None:
            max_it = self.max_it(radial)
        else:
            max_it = self.max_it(radius)

        riccati_terms = riccati_jn(max_it, M * self.wave_number * radial)[0]
        legendre_terms = lpmn(max_it, max_it, np.cos(theta))[0]
        nm_func = lambda n, m: n * (n + 1)
        pre_mul = self.e0 / np.power(radial, 2) / M**2 / self.wave_number
        mies = mie_cns(max_it, self.wave_number, radius, M, mu, musp)

        return self.component(radial,
                              theta,
                              phi,
                              riccati_terms,
                              legendre_terms,
                              pre_mul,
                              nm_func,
                              max_it,
                              mies=mies)
Exemple #23
0
def igrf_B(year,ht,lon,lat):
	base=int((year-1900)/5)			# base model
	shift=year-(5*base+1900)		# shift years
	g=(1-shift/5.)*gdat[base][:][:]+(shift/5.)*gdat[base+1][:][:]
	h=(1-shift/5.)*hdat[base][:][:]+(shift/5.)*hdat[base+1][:][:]

	phi=lon*pi/180.	# set phi=longitude dependence - co-sinusoids
	cp=cos(m*phi)
	sp=sin(m*phi)
	az=g*cp+h*sp
	az_phi=m*(-g*sp+h*cp)

	r=a+ht		# set geocentric altitude dependence
	amp=a*((a/r)**(n+1))
	amp_r=-(n+1)*amp/r				# r derivative of amp

	from scipy.special import lpmn
	theta=(90.-lat)*pi/180.	# set theta=colatitude dependence
	ct=cos(theta)
	st=sqrt(1.-ct**2.)
	[lPmn,lPmn_der]=lpmn(10,10,ct)	# assoc legendre function and derivative
	lPmn=lPmn*schmidt	# schmidt normalization
	lPmn_theta=-st*lPmn_der*schmidt

#	figure()
#	imshow(schmidt,interpolation='nearest')
#	colorbar()
#	title("schmidt_mn")

	Z=sum(amp_r*lPmn*az)			# get field components (nT)
	Y=-sum(amp*lPmn*az_phi)/(r*st)
	X=sum(amp*lPmn_theta*az)/r
	B=sqrt(X**2.+Y**2.+Z**2.)

	return X,Y,Z,B
Exemple #24
0
  def _compute(self, funcTilde, R, z, phi):
      """
      NAME:
         _compute
      PURPOSE:
         evaluate the NxLxM density or potential
      INPUT:
         funcTidle - must be _rhoTilde or _phiTilde
         R - Cylindrical Galactocentric radius
         z - vertical height
         phi - azimuth
      OUTPUT:
         An NxLxM density or potential at (R,z, phi)
      HISTORY:
         2016-05-18 - Written - Aladdin 
      """
      Acos, Asin = self._Acos, self._Asin
      N, L, M = Acos.shape    
      r, theta, phi = bovy_coords.cyl_to_spher(R,z,phi)
      
      
 
      PP = lpmn(M-1,L-1,nu.cos(theta))[0].T ##Get the Legendre polynomials
      func_tilde = funcTilde(r, N, L) ## Tilde of the function of interest 
      
      func = nu.zeros((N,L,M), float) ## The function of interest (density or potential)
      
      m = nu.arange(0, M)[nu.newaxis, nu.newaxis, :]
      mcos = nu.cos(m*phi)
      msin = nu.sin(m*phi)
      func = func_tilde[:,:,None]*(Acos[:,:,:]*mcos + Asin[:,:,:]*msin)*PP[None,:,:]
      return func
Exemple #25
0
def lpmn_em(l, m, x):
    """
    Computes associated Legendre function (Plm) of the first kind of order m and degree l.

    Parameters
    ----------

    l: int
        degree of Plm
    m: int
        order of Plm
    x: Nx1 array
        evaluation points

    Returns
    -------
    lp: Nx1 array
        Plm at `x`

    """

    lp = np.zeros(x.shape)
    for i in range(x.shape[0]):
        a, b = lpmn(m, l, x[i])
        lp[i] = a[np.abs(m), l]
    return lp
Exemple #26
0
def igrf_B(year,ht,lon,lat):
	base=int((year-1900)/5)			# base model
	shift=year-(5*base+1900)		# shift years
	g=(1-shift/5.)*gdat[base][:][:]+(shift/5.)*gdat[base+1][:][:]
	h=(1-shift/5.)*hdat[base][:][:]+(shift/5.)*hdat[base+1][:][:]

	phi=lon*pi/180.# set phi=longitude dependence - co-sinusoids
	cp=cos(m*phi)
	sp=sin(m*phi)
	az=g*cp+h*sp
	az_phi=m*(-g*sp+h*cp)

	r=a+ht	       # set geocentric altitude dependence
	amp=a*((a/r)**(n+1))
	amp_r=-(n+1)*amp/r		 # r derivative of amp

	from scipy.special import lpmn
	theta=(90.-lat)*pi/180.	 # set theta=colatitude dependence
	ct=cos(theta)
	st=sqrt(1.-ct**2.)
	[lPmn,lPmn_der]=lpmn(10,10,ct)	# assoc legendre function and derivative
	lPmn=lPmn*schmidt				# schmidt normalization
	lPmn_theta=-st*lPmn_der*schmidt

#	figure()
#	imshow(schmidt,interpolation='nearest')
#	colorbar()
#	title("schmidt_mn")

	Z=sum(amp_r*lPmn*az)			# get field components (nT)
	Y=-sum(amp*lPmn*az_phi)/(r*st)
	X=sum(amp*lPmn_theta*az)/r
	B=sqrt(X**2.+Y**2.+Z**2.)

	return X,Y,Z,B
Exemple #27
0
def pi_func(n, m, theta):
    """pi special function in modal decomposition"""
    if np.sin(theta) == 0:
        return 0
    # Pnm = legendre(n,m,theta)
    Pnm = special.lpmn(m,n, np.cos(theta))[0][abs(m)][n]
    
    return m*Pnm/np.sin(theta)
def Mm(x,m,q,aks):
    "Function M(eta), part of the H2+ solution"
    maxk=len(aks)
    #Plm = polyx.Plmc(x,m,maxk)
    #mm = [aks[il]*Plm[il] for il in range(len(aks))]
    Plm = special.lpmn(m, maxk-1+m, x)[0][m]
    mm = [aks[il]*Plm[il+m] for il in range(len(aks))]
    return sum(mm)*exp(-q*x)
Exemple #29
0
def check_sph_harm(l, m, theta, phi):
    print(sp.sph_harm(m, l, phi, theta))
    Clm = np.sqrt(
        (2 * l + 1.0) / 4 / np.pi * sp.poch(l + abs(m) + 1, -2 * abs(m)))
    [Pmlv, Pmlvdiff] = sp.lpmn(abs(m), l, np.cos(theta))
    ans = Clm * Pmlv[abs(m), l] * np.exp(1j * m * phi)
    if (m < 0):
        ans = (-1)**m * np.conjugate(ans)
    print(ans)
Exemple #30
0
def legendre(z):
    x = []
    for ii in z:
        x.append(((1 + sigma_m0 * ii) / (1 - sigma_m0))**.5)
    r_list = []
    for ii in x:
        #print(lpmn((beta-1)/2, 2,ii)[0][-1][-1])
        r_list.append(lpmn((4 * beta - 1) / 2, 2, ii)[0][-1][-1] / (ii**2 - 1))
    return r_list
Exemple #31
0
def cyl_mom(L, M, dens, H, R):
    gamFac = np.sqrt(np.exp(sp.gammaln(L - M + 1) - sp.gammaln(L + M + 1)))
    fact = np.sqrt((2 * L + 1) /
                   (4 * np.pi)) * gamFac * sp.factorial(L - M) / (2. * np.pi)
    R22 = np.sqrt(R**2 + H**2)
    theta22 = H / R22
    theta21 = -H / R22
    mom = 0
    PLM22 = sp.lpmn(L + 2, L + 2, theta22)[0][:, -1]
    PLM21 = sp.lpmn(L + 2, L + 2, theta21)[0][:, -1]
    momval = PLM22 - PLM21
    ks = np.arange(L - M)
    fac2 = (ks * 2 + 1 + M) * 2 * M / ((M + 2 * ks) * (M + 2 * ks + 2))
    mom = fact * fac2 * R * R22**(L + 2) * momval[-len(ks):]
    mom = np.sum(mom)
    if M == 0:
        mom = fact * R * R22**(L + 2) * momval[1]
    return mom
def multiplet(x, l, freq, width, splitting, inc):
    legendre2 = lpmn(l, l, np.cos(inc))[0]**2
    y = lorentz((x - freq) / width) * factorial(l) * legendre2[0][l]
    for m in range(1, l + 1):
        energy = legendre2[m][l] * factorial(l - m) / factorial(l + m)
        y = y + lorentz((x - freq - m * splitting) / width) * energy
        y = y + lorentz((x - freq + m * splitting) / width) * energy

    return y
Exemple #33
0
	def ydot_geopotential(self, y, C, S, n, m):
		"""Returns the time derivative of only the geopotential effect for a given state.
		!!! Deprecated Method!!!
			Args:
				y(1x6 numpy array): the state vector [rx,ry,rz,vx,vy,vz]
				gravityCoeff (nxm numpy array): the array where you have stored the geopotential coefficients Cnm,Snm
				n (integer): degree of coeffs you want to use for the calculation
				m (integer): order of coeffs you want to use for the calculation
			Returns:
				1x6 numpy array: the time derivative of y [vx,vy,vz,ax,ay,az]
		"""

		r, phi, l = self.cart2geodetic(y[0], y[1], y[2])

		earthR = 6378137
		mu = 398600.4405e+09

		r = r + earthR

		legendreP = sp.lpmn(n+1, m+1, mp.sin(phi))
		legendreP = legendreP[0]
		legendreP = np.transpose(legendreP)
		V = np.zeros((n+1, m+1))
		W = np.zeros((n+1, m+1))

		for i in range(0, n+1):
			for j in range(0, i+1):

				V[i, j] = ((earthR/r) ** (i+1)) * (legendreP[i, j] * mp.cos(j * l))
				W[i, j] = ((earthR/r) ** (i+1)) * (legendreP[i, j] * mp.sin(j * l))

		ax = 0
		ay = 0
		az = 0
		for i in range(0, n-2):
			for j in range(0, i+1):

				if j == 0:
					ax = ax + (mu / earthR**2) * (-C[i, 0] * V[i+1, 1])

					ay = ay + (mu / earthR ** 2) * (-C[i, 0] * W[i + 1, 1])
				else:
					ax = ax + (mu / earthR ** 2) * 0.5 * (-C[i, j] * V[i + 1, j + 1] - S[i, j] * W[i + 1, j + 1]) + \
						 (mp.factorial(i - j + 2) / mp.factorial(i - j)) * (
						 C[i, j] * V[i + 1, j - 1] + S[i, j] * W[i + 1, j - 1])

					ay = ay + (mu / earthR ** 2) * 0.5 * (-C[i, j] * W[i + 1, j + 1] + S[i, j] * V[i + 1, j + 1]) + \
					     (mp.factorial(i - j + 2) / mp.factorial(i - j)) * (
						 -C[i, j] * W[i + 1, j - 1] + S[i, j] * V[i + 1, j - 1])

				az = az + (mu / earthR ** 2) * ((i-j+1) * (-C[i, j] * V[i+1, j] - S[i, j] * W[i+1, j]))

		ax = -ax
		ay = -ay
		# print(ax, ay, az)
		return np.array([ax, ay, az])
Exemple #34
0
    def __init__(self, NSIDE, lmax=10, clv=True):
        """
        Args:
            NSIDE (int) : the healpix NSIDE parameter, must be a power of 2, less than 2**30
            npix (int) : number of pixel in the X and Y axis of the final projected map
            rot_velocity (float) : rotation velocity of the star in the equator in km/s
        
        Returns:
            None
        """
        self.NSIDE = int(NSIDE)        
        self.hp_npix = hp.nside2npix(NSIDE)
        self.lmax = lmax
        self.n_coef_max = (1+lmax)**2
        self.epsilon = 1e-3
        self.l = np.arange(self.lmax+1)

        self.alpha = np.zeros(self.n_coef_max)
        self.beta = np.zeros(self.n_coef_max)
        self.gamma = np.zeros(self.n_coef_max)

        # self.rot_velocity = rot_velocity
        self.clv = clv

# Generate the indices of all healpix pixels
        self.indices = np.arange(hp.nside2npix(NSIDE), dtype='int')
        self.n_healpix_pxl = len(self.indices)

        self.polar_angle, self.azimuthal_angle = hp.pixelfunc.pix2ang(self.NSIDE, np.arange(self.n_healpix_pxl))
        self.pixel_vectors = np.array(hp.pixelfunc.pix2vec(self.NSIDE, self.indices))

# Compute LOS rotation velocity as v=w x r
        self.rotation_velocity = np.cross(np.array([0.0,0.0,1.0])[:,None], self.pixel_vectors, axisa=0, axisb=0, axisc=0)

        self.vec_boundaries = np.zeros((3,4,self.n_healpix_pxl))
        for i in range(self.n_healpix_pxl):
            self.vec_boundaries[:,:,i] = hp.boundaries(self.NSIDE, i)

        self.Plm = np.zeros((self.lmax+2, self.lmax+2, self.n_healpix_pxl))
        self.dPlm = np.zeros((self.lmax+2, self.lmax+2, self.n_healpix_pxl))

        self.Clm = np.zeros((self.lmax+2, self.lmax+2))

        for i in range(self.n_healpix_pxl):
            self.Plm[:,:,i], self.dPlm[:,:,i] = sp.lpmn(self.lmax+1, self.lmax+1, np.cos(self.polar_angle[i]))
            self.dPlm[:,:,i] *= -np.sin(self.polar_angle[i])

        for l in range(self.lmax+2):
            for m in range(0, l+1):
                self.Clm[m,l] = np.sqrt((2.0*l+1) / (4.0*np.pi) * mi.factorial(l-m) / mi.factorial(l+m))

        self.lambda0 = 5000.0
        self.lande = 1.2
        self.constant = -4.6686e-13 * self.lambda0 * self.lande * 3e5
Exemple #35
0
def Pol_Legendre(N, M, X):
    """
    function from scipy directly
    """
    Plm_z, Plm_dz = lpmn(M, N, X)

    for n in range(0, Plm_z.shape[0]):
        for m in range(0, n + 1):
            Plm_z[m, n] = Plm_z[m, n] * Normalize(n, m)

    return Plm_z.T, Plm_dz.T  # use Plm_z[m, l]
Exemple #36
0
def L_fun(theta, l, m):
    """
    Returns the normalized associated legendre with l,m, and x = cos(theta)
    """
    output = factorial_function(l, m)
    product = np.sqrt((np.float64(2) * l + np.float64(1)) / (np.float64(4) * math.pi)) * output
    l_out2 = lpmn(m, np.float64(l), np.cos(theta))
    l_out = lpmv(m, np.float64(l), np.cos(theta))

    #    print l_out, l_out2
    return product * l_out
def cmp_LPQL(Nx,xmin,xmax, maxm,maxl, ist, Sol, Ck, Modd):
	
	Xx=1-xmin+logspace(log10(xmin),log10(xmax),Nx)
	# For rombohedral method we need the change of variable to equidistant mesh
	# We can change the variable Int[f(x),{x,1,Inf}] = Int[ exp(t) f(1-xmin+exp(t)), {t, log(xmin),inf}]
	# Here t is distributed in linear mesh with spacing dxi, and exp(t)=x-1+xmin, because we
	# constructued logarithmic mesh by x=1-xmin+exp(t)
	Expu = Xx-1.+xmin 
	dxi = (log(Expu[-1])-log(Expu[0]))/(len(Expu)-1.)
	
	Qlm_all = array([special.lqmn(maxm,maxl,x)[0] for x in Xx])
	Plm_all = array([special.lpmn(maxm,maxl,x)[0] for x in Xx])
	Qlm_all[0]=0.0  # This diverges, hence we set it to zero
	
	LPL = zeros((len(ist),maxl+1,len(Xx)),dtype=float)
	LQL = zeros((len(ist),maxl+1,len(Xx)),dtype=float)
	LPxL= zeros((len(ist),maxl+1,len(Xx)),dtype=float)
	LQxL= zeros((len(ist),maxl+1,len(Xx)),dtype=float)
	LLP = zeros((len(ist),maxl+1,len(Xx)),dtype=float)
	LLQ = zeros((len(ist),maxl+1,len(Xx)),dtype=float)
	LLPx= zeros((len(ist),maxl+1,len(Xx)),dtype=float)
	LLQx= zeros((len(ist),maxl+1,len(Xx)),dtype=float)
	
	for i,(i1,i2) in enumerate(ist):
		(R1,Ene1,m1,p1,A1) = Sol[i1]
		(R2,Ene2,m2,p2,A2) = Sol[i2]
		print 'i1=', i1, 'i2=', i2, 'm1=', m1, 'm2=', m2
		
		m = abs(m1-m2)
		
		Qlm = transpose(Qlm_all[:,m])
		Plm = transpose(Plm_all[:,m])
		LL   = array([Lambda(x,m1,p1,Ck[i1]) * Lambda(x,m2,p2,Ck[i2]) for ix,x in enumerate(Xx)])
		
		for il in range(m,maxl+1):
			odd = (Modd[i1]+Modd[i2]+il+m)%2
			
			if odd: continue
			

			LLQ [i,il,:] = LL * Qlm[il,:]
			LLQx[i,il,:] = LLQ[i,il,:] * Xx**2
			LLP [i,il,:] = LL * Plm[il,:]
			LLPx[i,il,:] = LLP[i,il,:] * Xx**2


			for ix in range(len(Xx)):
				LPL [i,il,ix] = simps(LLP [i,il,:ix+1],Xx[:ix+1])
				LPxL[i,il,ix] = simps(LLPx[i,il,:ix+1],Xx[:ix+1])
				LQL [i,il,ix] = simps(LLQ [i,il,ix:],Xx[ix:])
				LQxL[i,il,ix] = simps(LLQx[i,il,ix:],Xx[ix:])
	    
	
	return (LPL, LQL, LPxL, LQxL, LLP, LLQ, LLPx, LLQx)
Exemple #38
0
 def integrand(xi, costheta):
     l = numpy.arange(0, L)[numpy.newaxis, :]
     r = _xiToR(xi,a)
     R = r*numpy.sqrt(1 - costheta**2.)
     z = r*costheta
     Legandre = lpmn(0,L-1,costheta)[0].T[numpy.newaxis,:,0]
     dV = (1. + xi)**2. * numpy.power(1. - xi, -4.) 
     phi_nl =  a**3*(1. + xi)**l * (1. - xi)**(l + 1.)*_C(xi, N, L)[:,:] * Legandre
     param[0] = R
     param[1] = z
     return  phi_nl*dV * dens(*param)
Exemple #39
0
 def integrand(xi, costheta):
     l = nu.arange(0, L)[nu.newaxis, :]
     r = _xiToR(xi,a)
     R = r*nu.sqrt(1 - costheta**2.)
     z = r*costheta
     Legandre = lpmn(0,L-1,costheta)[0].T[nu.newaxis,:,0]
     dV = (1. + xi)**2. * nu.power(1. - xi, -4.) 
     phi_nl =  a**3*(1. + xi)**l * (1. - xi)**(l + 1.)*_C(xi, N, L)[:,:] * Legandre
     param[0] = R
     param[1] = z
     return  phi_nl*dV * dens(*param)
def test_assocLegendre_renorm():
    x = linspace(-1.0, 1.0, 100)
    ap_it = assocLegendre_renorm_it(x)
    for l in xrange(0, 100):
        for m in xrange(0, l+1):
            print "l = %s, m = %s" % (l,m)
            Plm = assoc_legendre_p(l, m, x)
            Plm_scipy = array([lpmn(m,l,xi)[0][-1][-1] for xi in x])
            Plm_it = fact2(2*l-1)*ap_it.next()
            dif = sum(abs(Plm_scipy - Plm_it))/sum(abs(Plm_scipy))
            print "dif = %s" % dif
            assert dif < 1e-10
Exemple #41
0
def N(n, m, theta, phi, r, k):
    """electric vector spherical function"""
    # Pnm = legendre(n,m,theta)
    Pnm = special.lpmn(m,n, np.cos(theta))[0][abs(m)][n]
    H = spherical_hankel(n, k*r)
    Hp = spherical_hankel(n, k*r, 1)
    r_comp = n*(n+1)*Pnm*H/(k*r)*np.exp(1j*m*phi)
    theta_comp = tau_func(n,m,theta)
    phi_comp = 1j*pi_func(n,m,theta)
    const = (H + r*k*Hp)*np.exp(1j*m*phi)/(k*r)
    theta_comp *= const
    phi_comp *= const
    return np.array([r_comp, theta_comp, phi_comp])
Exemple #42
0
def legendre(xv, order):

    legout=numpy.zeros((order*(order+2),len(xv)))
    dlegout=legout.copy()
    m,l=degrees(order, start=1)
    sch=schmidt(m,l)
    
    for i,x in enumerate(xv):
        leg, dleg = lpmn(order,order,x)
        legout[:,i]= leg[abs(m),l]*sch
        dlegout[:,i]= dleg[abs(m),l]*sch

    return legout, dlegout
Exemple #43
0
 def integrand(xi, costheta, phi):
     l = nu.arange(0, L)[nu.newaxis, :, nu.newaxis]
     m = nu.arange(0, L)[nu.newaxis,nu.newaxis,:]
     r = _xiToR(xi, a)
     R = r*nu.sqrt(1 - costheta**2.)
     z = r*costheta
     Legandre = lpmn(L - 1,L-1,costheta)[0].T[nu.newaxis,:,:]
     dV = (1. + xi)**2. * nu.power(1. - xi, -4.)
     
     
     phi_nl = - a**3*(1. + xi)**l * (1. - xi)**(l + 1.)*_C(xi, N, L)[:,:,nu.newaxis] * Legandre
     
     return dens(R,z, phi) * phi_nl[nu.newaxis, :,:,:]*nu.array([nu.cos(m*phi), nu.sin(m*phi)])*dV
Exemple #44
0
def legendrePnm_z(n, m, z):
    if m > n:
        return 0.0
    elif n < 0 or m < 0:
        # This should really be replaced with maxima
        return mat.execute_numerical("LegendreP", n, m, z)
    else:
        try:
            result = lpmn(m, n, z)[0][-1][-1]
        except ValueError:
            print n, " ", m
            raise Exception, "Value Error"

        return result
Exemple #45
0
 def _computeforce(self,R,z,phi=0,t=0):
     """
     NAME:
        _computeforce
     PURPOSE:
        Evaluate the first derivative of Phi with respect to R, z and phi
     INPUT:
        R - Cylindrical Galactocentric radius
        z - vertical height
        phi - azimuth
        t - time
     OUTPUT:
        dPhi/dr, dPhi/dtheta, dPhi/dphi
     HISTORY:
        2016-06-07 - Written - Aladdin 
     """
     Acos, Asin = self._Acos, self._Asin
     N, L, M = Acos.shape    
     r, theta, phi = bovy_coords.cyl_to_spher(R,z,phi)
     new_hash= hashlib.md5(nu.array([R, z,phi])).hexdigest()
     
     if new_hash == self._force_hash:
         dPhi_dr = self._cached_dPhi_dr  
         dPhi_dtheta = self._cached_dPhi_dtheta 
         dPhi_dphi = self._cached_dPhi_dphi
         
     else:        
         PP, dPP = lpmn(M-1,L-1,nu.cos(theta)) ##Get the Legendre polynomials
         PP = PP.T[None,:,:]
         dPP = dPP.T[None,:,:]
         phi_tilde = self._phiTilde(r, N, L)[:,:,nu.newaxis] 
         dphi_tilde = self._dphiTilde(r,N,L)[:,:,nu.newaxis]
         
         m = nu.arange(0, M)[nu.newaxis, nu.newaxis, :]
         mcos = nu.cos(m*phi)
         msin = nu.sin(m*phi)
         dPhi_dr = -nu.sum((Acos*mcos + Asin*msin)*PP*dphi_tilde)
         dPhi_dtheta = -nu.sum((Acos*mcos + Asin*msin)*phi_tilde*dPP*(-nu.sin(theta)))
         dPhi_dphi =-nu.sum(m*(Asin*mcos - Acos*msin)*phi_tilde*PP)
         
         self._force_hash = new_hash
         self._cached_dPhi_dr = dPhi_dr
         self._cached_dPhi_dtheta = dPhi_dtheta
         self._cached_dPhi_dphi = dPhi_dphi
     return dPhi_dr,dPhi_dtheta,dPhi_dphi
Exemple #46
0
def legendrePnm_theta(n, m, theta, harmtype="_{n,m}"):
    """
    _{n}^{m} is the P_{n}^{m} type harmonic and
    _{n,m} is the P_{n,m} type harmonic
    
    """
    if m > n:
        result = 0.0
    elif n < 0 or m < 0:
        # This should really be replaced with maxima
        result = mat.execute_numerical("LegendreP", n, m, cos(theta))
    else:
        result = lpmn(m, n, cos(theta))[0][-1][-1]
    if harmtype == "_{n,m}":
        # print "OldResult: ",result
        result = result * pow(-1.0, float(m))
        # print "newresult: ",result
    return result
    def evaluate_V(self, eta_grid, m, mu):
	"""
	result = evaluate_V(eta_grid, m, mu)

	Evaluates V on a grid. V is the basis function for the eta coordinate.
	V is defined in eq. (8) in Kamta2005.
	
	Parameters
	----------
	eta_grid : 1D float array, the eta values for which one wants to
	    evaluate V.
	m : integer, the angular momentum projection quantum number.
	mu : integer, some sort of quantum number associated with V.

	Returns
	-------
	result : 1D complex array, the result of the evaluation. 

	"""
	#Eq. (8) in Kamta2005.

	#Normalization factor, M^m_mu.
	M =  self.find_M(m, mu)

	#Associated Legendre polynomial of the first kind. 
	#P^{order}_{degree} => lpmn(order, degree) 

	#Initalize array.
	legendre_factor = zeros(len(eta_grid), dtype=complex)

	#Function does not allow for array input.
	for i, eta in enumerate(eta_grid):
	    #Function returns all degrees and orders up to those given.
	    P, dP =  lpmn(m, mu, eta)
	    #Selects the correct polynomial.
	    legendre_factor[i] = P[-1,-1]
	    

	#All together now.
	result = M * legendre_factor
	
	return result
Exemple #48
0
 def get_inc(self, n, m, axisymm=False):
     """Return incident field expansion coefficients"""
     #if (self.Pna is None) or (len(self.Pna)!=n):
     self.Pna, self.Pdna = lpmn(n, n, cos(self.alpha))[:]
     self.sina = sin(self.alpha)
     sina = self.sina
     Pna = self.Pna[m, m:]
     l = arange(m, n + 1)
     if axisymm:
         c_inc = 1j ** l * (2 * l + 1.) / (l * (l + 1.)) * Pna
     else:
         Pdna = self.Pdna[m, m:]
         c_inc = zeros(2 * (n - m + 1), dtype=complex)
         if sina == 0. and m == 1:
             c_inc[:n - m + 1] = -1j ** (l - 1) * (2 * l + 1)
         else:
             c_inc[:n - m + 1] = -1j ** (l - 1) / sina\
                                 * 2 * (2 * l + 1)\
                                 * factorial(l - m) / factorial(l + m)\
             * Pna
     return c_inc
Exemple #49
0
def compute_Ylm(l, theta, phi):
    Y = np.zeros([np.size(phi), np.size(theta), 2*l+1])
    L = np.zeros([l+1, np.size(theta)]) 

    for the in range(0, np.size(theta)):
        Pmn_z, Pmn_dz = lpmn(l, l, np.cos(theta[0, the]))
        L[:,the] = Pmn_z[:,-1]

    for m in range(0, l+1):
        L[m, :] = L[m, :]*((-1)**m)*sqrt_function(l,m)

    L = np.sqrt(1/(2*math.pi))*L

    for m in range(-l,l+1):
        if (m>0):
            Y[:,:, l+m] = np.sqrt(2.0)*np.cos(phi*m)*L[m, :]
        elif (m<0):
            Y[:,:, l+m] = np.sqrt(2.0)*np.sin(phi*m)*L[-m, :]
        else:
            Y[:,:, l+m] = np.ones([M,1])*L[0, :]

    return Y
Exemple #50
0
def get_approx(theta, phi, l_range, quad_precision, radius, rand_nums):
    ''' 
    Get the matrix X
    '''
    alpha_vec = get_alpha_vec(l_range, quad_precision, radius)
    output = np.zeros([np.size(theta), np.size(phi)], dtype = 'float64')
    
    coef1 = (0.5/np.sqrt(math.pi))*np.sqrt(alpha_vec[0])
    coef2 = np.zeros(l_range, dtype = 'float64')
    coef3 = np.zeros([l_range, l_range], dtype = 'float64')

    for t in range(0, np.size(theta)):
        if np.mod(t,20) == 0:
            print 'Finished with ', t, 'of ', np.size(theta)
        th = theta[t]

        Pmn_z, Pmn_dz = lpmn(l_range, l_range, np.cos(th))

        for l in range(1, l_range):
            coef2[l] =  np.sqrt(alpha_vec[l])*Pmn_z[0, l]*np.sqrt((2*l+1)/(4*math.pi))
            for m in range(1, l+1):
                coef3[l,m] = np.sqrt(2*alpha_vec[l])*Pmn_z[m,l]*factorial_function(l,m)

        for p in range(0, np.size(phi)):
            count = 0
            ph = phi[p]
            output[t,p] += coef1*rand_nums[count]
            count += 1

            for l in range(1, l_range):
                output[t,p] += coef2[l]*rand_nums[count]
                count += 1
                
                for m in range(1, l+1):
                    output[t,p] += (rand_nums[count]*np.cos(m*ph) + \
                                      rand_nums[count+1]*np.sin(m*ph))*coef3[l,m]
                    count += 2

    return output/radius
def cmp_MPM(Ny, maxm,maxl, ist, ak, Modd):
    Xx = linspace(-1,1,Ny)
    
    MPM =  zeros((len(ist),maxl+1),dtype=float)
    MPxM = zeros((len(ist),maxl+1),dtype=float) 
    for i,(i1,i2) in enumerate(ist):
        (R1,Ene1,m1,p1,A1) = Sol[i1]
        (R2,Ene2,m2,p2,A2) = Sol[i2]
        
        print 'i1=', i1, 'i2=', i2, 'm1=', m1, 'm2=', m2 #, MPM,MPxM
        m = abs(m1-m2)
        
        Plm_all = array([special.lpmn(maxm,maxl,x)[0] for x in Xx])
        MM = array([Mm(x,m1,p1,ak[i1]) * Mm(x,m2,p2,ak[i2]) for x in Xx])
        Plm = transpose(Plm_all[:,m])
        for il in range(m,maxl+1):
            odd = (Modd[i1]+Modd[i2]+il+m)%2
            if not odd:  # If the function is odd, we do not calculate!
                MMP = MM*Plm[il,:]
                MMPx = MMP * Xx**2
                MPM [i,il] = integrate.romb(MMP, Xx[1]-Xx[0])
                MPxM[i,il] = integrate.romb(MMPx,Xx[1]-Xx[0])
    
    return (MPM,MPxM)
    def sphere(self,ka,sosm,soss,sosshear,rhom,rhos,maxang,maxn):

        '''a function which calculates scattering cross sections for spheres
        according to Faran's theory; the output is a size of x3 vector giving
        the scattering length at 180 degrees
        and entries correspond to different values
        of ka (step size and max value of ka can be changed by manipulating the
        initialization of x3); note that the output is the absolute value of the
        scattering length (i.e. square root of the differential scattering cross
        section) times the wavenumber in the host medium (output is therefore
        unitless)

        ka = an array containing the (wavenumber)*(scatter radius) values
        over which scattering length will be calculated.
        sosm = speed of sound in host medium (fluid)
        soss = speed of sound in sphere
        sosshear = speed of sound for shear waves in sphere  (if poisson's ratio
        (sigma)is available, sosshear=soss*sqrt((1-2*sigma)/2/(1-sigma)))
        rhom = host medium density
        rhos = sphere density
        maxang = maximum angle (in degrees) for which to calculate a cross
        section
        maxn = number of terms to include in the summation (higher number =
        greater accuracy but more computation time)

        %UNITS ARE OF NO CONSEQUENCE AS LONG AS THEY ARE CONSISTENT, I.E.
        %SPEEDS OF SOUND MUST HAVE THE SAME UNITS AND DENSITIES MUST HAVE THE SAME
        %UNITS

        %9/20/04 Tony Gerig

        %Hairong Shi added comments:
        % for glass beads we used in lab, Poisson's ratio sigma=0.21,
        %sosm=1540m/s
        %soss=5570m/s
        %so sosshear=3374.7m/s
        %rhom=1020 kg/m^3
        %rhos=2540 kg/m^3
        %
        %so an example to run this code is:
        %   k3absscatlength = sphere(1540,5570,3374.7,1020,2540,180,100);

        '''
        import numpy
        from scipy.special import lpmn

        #initialization
        theta= 180
        x3=ka
        x2=x3*sosm/sosshear  #ka value for shear waves in sphere
        x1=x3*sosm/soss  #ka value for compressional waves in sphere

        #main loop over order n
        coeff = numpy.zeros((maxn + 1, len(x3)) ) + 1j*numpy.zeros((maxn + 1, len(x3)))
        for n in range(0,maxn + 1):
            #spherical bessel functions
            jx1=self.sphbess(n,x1)
            jx2=self.sphbess(n,x2)
            jx3=self.sphbess(n,x3)

            #spherical neumann functions
            nx3=self.sphneumm(n,x3)

            #derivatives of spherical bessel and neumann functions
            jpx3=n/(2*n+1.)*self.sphbess(n-1,x3)-(n+1)/(2*n+1.)*self.sphbess(n+1,x3)
            npx3=n/(2*n+1.)*self.sphneumm(n-1,x3)-(n+1)/(2*n+1.)*self.sphneumm(n+1,x3)
            jpx1=n/(2*n+1.)*self.sphbess(n-1,x1)-(n+1)/(2*n+1.)*self.sphbess(n+1,x1)
            jpx2=n/(2*n+1.)*self.sphbess(n-1,x2)-(n+1)/(2*n+1.)*self.sphbess(n+1,x2)

            #calculation of tandelta, tanalpha, tanbeta
            tandeltax3=-jx3/nx3
            tanalphax3=-x3*jpx3/jx3
            tanbetax3=-x3*npx3/nx3
            tanalphax1=-x1*jpx1/jx1
            tanalphax2=-x2*jpx2/jx2

            #calculation of tanxsi [eq. 30]
            term1=tanalphax1/(tanalphax1+1)
            term2=(n**2+n)/(n**2+n-1-0.5*x2**2+tanalphax2)
            term3=(n**2+n-0.5*x2**2+2*tanalphax1)/(tanalphax1+1)
            term4=((n**2+n)*(tanalphax2+1))/(n**2+n-1-0.5*x2**2+tanalphax2)
            tanxsi=-x2**2/2*(term1-term2)/(term3-term4)

            #calculation of tanphi [eq. 29]
            tanPhi = -rhom/rhos*tanxsi
            #calculation of coefficient (2n+1)*sin(eta)*cos(eta) part of [eqn. 31]
            taneta=tandeltax3*(tanPhi+tanalphax3)/(tanPhi+tanbetax3)
            coeff[n,:]=(2*n+1)*taneta/(1+taneta**2)+1j*(2*n+1)*taneta**2/(1+taneta**2)

        #legendre polynomials
        temp, deriv=lpmn(n,n,numpy.cos(numpy.pi/180*theta))
        #taking the first row is effectively taking m = 0
        legend=temp[0,:].reshape((1,maxn + 1))

        #matrix mult completes summation over n [eqn. 31]
        k3absscatlength=abs(numpy.dot(legend,coeff))
        output = k3absscatlength.reshape( len(x3) )
        output[numpy.isnan(output)] = 0
        return output
Exemple #53
0
def legendre_p_via_lpmn(n, x):
    return lpmn(0, n, x)[0][0,-1]
Exemple #54
0
        r=i*2*dr+(2*rmin-1)
    else:
        r=1+(i-rNum+1)*2.0/rNum
    for j in range(thNum):
        th=j*dth
        XAvalues[i][j]=r*math.sin(th)
        YAvalues[i][j]=r*math.cos(th)

#Create array for multipole coefficients
multipoles=zeros((lNum));
#store P_l^1(cos(theta)) at the surface, used to solve multipoles. I have an array evaluated in midpoints to perform
#the integrations, and another one solve on mesh points to perform alpha evaluation
plone=zeros((lNum,thNum));
plone2=zeros((lNum,thNum));
for j in range(thNum):
    alp=special.lpmn(1, lNum+1, math.cos((j+0.5)*dth))
    alp2=special.lpmn(1, lNum+1, math.cos(j*dth))
    for l in range(lNum):
        plone[l][j]=alp[0][1][l+1]
        plone2[l][j]=alp2[0][1][l+1]

#Create gray-scale printable colormap, cdict taken from user Damon McDougall-2 who posted it in the matplotlib mailing list
cdict = {'red':((0.000, 0.00, 0.00), 
                (0.125, 0.15, 0.15), 
                (0.250, 0.30, 0.30), 
                (0.375, 0.60, 0.60), 
                (0.500, 1.00, 1.00), 
                (0.625, 0.90, 0.90), 
                (0.750, 0.90, 0.90), 
                (0.875, 0.90, 0.90),
                (1.000, 1.00, 1.00)), 
Exemple #55
0
def legendre(n,m,theta, deriv=0):
    Pnm = special.lpmn(m,n, np.cos(theta))[deriv][abs(m)][n]
    return Pnm
    def __init__(self, NSIDE, npix, lmax=10, clv=True):
        """
        Args:
            NSIDE (int) : the healpix NSIDE parameter, must be a power of 2, less than 2**30
            npix (int) : number of pixel in the X and Y axis of the final projected map
            rot_velocity (float) : rotation velocity of the star in the equator in km/s
        
        Returns:
            None
        """
        self.NSIDE = int(NSIDE)
        self.npix = int(npix)
        self.hp_npix = hp.nside2npix(NSIDE)
        self.lmax = lmax
        self.n_coef_max = (1+lmax)**2

        # self.rot_velocity = rot_velocity
        self.clv = clv

# Generate the indices of all healpix pixels
        self.indices = np.arange(hp.nside2npix(NSIDE), dtype='int')
        self.n_healpix_pxl = len(self.indices)

# Define the orthographic projector that generates the maps of the star on the plane of the sky
        self.projector = hp.projector.OrthographicProj(xsize=int(self.npix))

# This function returns the pixel associated with a vector (x,y,z). This is needed by the projector
        self.f_vec2pix = lambda x, y, z: hp.pixelfunc.vec2pix(int(self.NSIDE), x, y, z)

        self.polar_angle, self.azimuthal_angle = hp.pixelfunc.pix2ang(self.NSIDE, np.arange(self.n_healpix_pxl))

# Generate a mesh grid of X and Y points in the plane of the sky that covers only the observed hemisphere of the star
        x = np.linspace(-2.0,0.0,int(self.npix/2))
        y = np.linspace(-1.0,1.0,int(self.npix/2))
        X, Y = np.meshgrid(x,y)

# Rotational velocity vector (pointing in the z direction and unit vector)
        omega = np.array([0,0,1])

# Compute the radial vector at each position in the map and the projected velocity on the plane of the sky
        radial_vector = np.array(self.projector.xy2vec(X.flatten(), Y.flatten())).reshape((3,int(self.npix/2),int(self.npix/2)))
        self.vel_projection = np.cross(omega[:,None,None], radial_vector, axisa=0, axisb=0)[:,:,0]

# Compute the mu angle (astrocentric angle)
        self.mu_angle = radial_vector[0,:,:]        
        
# Generate a fake temperature map in the star using spherical harmonics
        # self.temperature_map = 5000 * np.ones(self.npix)
        # self.temperature_map = 5000 + 250 * hp.sphtfunc.alm2map(np.ones(10,dtype='complex'),self.NSIDE) #np.random.rand(self.n_healpix_pxl) * 2000 + 5000 #

        self.temperature_map = 5000 * np.ones(self.hp_npix)
        self.coeffs = hp.sphtfunc.map2alm(self.temperature_map)

        self.nlambda = 500
        self.v = np.linspace(-100.0, 100.0, self.nlambda)
        self.d = 0.5
        self.delta = 5.0

        self.Plm = np.zeros((self.lmax+2, self.lmax+2, self.n_healpix_pxl))
        self.dPlm = np.zeros((self.lmax+2, self.lmax+2, self.n_healpix_pxl))

        self.Clm = np.zeros((self.lmax+2, self.lmax+2))

        for i in range(self.n_healpix_pxl):
            self.Plm[:,:,i], self.dPlm[:,:,i] = sp.lpmn(self.lmax+1, self.lmax+1, np.cos(self.polar_angle[i]))
            self.dPlm[:,:,i] *= -np.sin(self.polar_angle[i])

        for l in range(self.lmax+2):
            for m in range(0, l+1):
                self.Clm[m,l] = np.sqrt((2.0*l+1) / (4.0*np.pi) * mi.factorial(l-m) / mi.factorial(l+m))

        self.lambda0 = 5000.0
        self.lande = 1.2
        self.constant = -4.6686e-13 * self.lambda0 * self.lande * 3e5
Exemple #57
0
def lpn_normalized(n, z):
    vals, _ = lpmn(0, n, z)

    return vals[0][n] * np.sqrt(n+0.5)
Exemple #58
0
def get_Pmn(m, n, x):
    return array([lpmn(m, n, xl) for xl in x])
Exemple #59
0
 def set_funcs_ang(self):
     P = array([special.lpmn(self.n, self.n, ct) for ct in self.cost])
     self.data_Ang, self.data_Angd = P[:, 0, :, :], P[:, 1, :, :]
Exemple #60
0
 def lpnm(n, m, z):
     if m > n:
         return 0.0
     return sc.lpmn(m, n, z)[0][-1,-1]