U
    ZÊ¹jõ*  ã                   @   sÌ   d dl mZ d dlmZmZ d dlmZmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZ d dlmZmZ d d	lmZ d d
lmZ d dlmZmZmZ edƒZG dd„ deƒZdd„ ZG dd„ deƒZdS )é    )ÚExpr)ÚFunctionÚArgumentIndexError)ÚIÚpi)ÚS)ÚDummy)Úassoc_legendre)Ú	factorial)ÚAbsÚ	conjugate)Úexp)Úsqrt)ÚsinÚcosÚcotÚxc                   @   s`   e Zd ZdZedd„ ƒZdd„ Zddd„Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zddd„Zdd„ ZdS )ÚYnma4  
    Spherical harmonics defined as

    .. math::
        Y_n^m(\theta, \varphi) := \sqrt{\frac{(2n+1)(n-m)!}{4\pi(n+m)!}}
                                  \exp(i m \varphi)
                                  \mathrm{P}_n^m\left(\cos(\theta)\right)

    Explanation
    ===========

    ``Ynm()`` gives the spherical harmonic function of order $n$ and $m$
    in $\theta$ and $\varphi$, $Y_n^m(\theta, \varphi)$. The four
    parameters are as follows: $n \geq 0$ an integer and $m$ an integer
    such that $-n \leq m \leq n$ holds. The two angles are real-valued
    with $\theta \in [0, \pi]$ and $\varphi \in [0, 2\pi]$.

    Examples
    ========

    >>> from sympy import Ynm, Symbol, simplify
    >>> from sympy.abc import n,m
    >>> theta = Symbol("theta")
    >>> phi = Symbol("phi")

    >>> Ynm(n, m, theta, phi)
    Ynm(n, m, theta, phi)

    Several symmetries are known, for the order:

    >>> Ynm(n, -m, theta, phi)
    (-1)**m*exp(-2*I*m*phi)*Ynm(n, m, theta, phi)

    As well as for the angles:

    >>> Ynm(n, m, -theta, phi)
    Ynm(n, m, theta, phi)

    >>> Ynm(n, m, theta, -phi)
    exp(-2*I*m*phi)*Ynm(n, m, theta, phi)

    For specific integers $n$ and $m$ we can evaluate the harmonics
    to more useful expressions:

    >>> simplify(Ynm(0, 0, theta, phi).expand(func=True))
    1/(2*sqrt(pi))

    >>> simplify(Ynm(1, -1, theta, phi).expand(func=True))
    sqrt(6)*exp(-I*phi)*sin(theta)/(4*sqrt(pi))

    >>> simplify(Ynm(1, 0, theta, phi).expand(func=True))
    sqrt(3)*cos(theta)/(2*sqrt(pi))

    >>> simplify(Ynm(1, 1, theta, phi).expand(func=True))
    -sqrt(6)*exp(I*phi)*sin(theta)/(4*sqrt(pi))

    >>> simplify(Ynm(2, -2, theta, phi).expand(func=True))
    sqrt(30)*exp(-2*I*phi)*sin(theta)**2/(8*sqrt(pi))

    >>> simplify(Ynm(2, -1, theta, phi).expand(func=True))
    sqrt(30)*exp(-I*phi)*sin(2*theta)/(8*sqrt(pi))

    >>> simplify(Ynm(2, 0, theta, phi).expand(func=True))
    sqrt(5)*(3*cos(theta)**2 - 1)/(4*sqrt(pi))

    >>> simplify(Ynm(2, 1, theta, phi).expand(func=True))
    -sqrt(30)*exp(I*phi)*sin(2*theta)/(8*sqrt(pi))

    >>> simplify(Ynm(2, 2, theta, phi).expand(func=True))
    sqrt(30)*exp(2*I*phi)*sin(theta)**2/(8*sqrt(pi))

    We can differentiate the functions with respect
    to both angles:

    >>> from sympy import Ynm, Symbol, diff
    >>> from sympy.abc import n,m
    >>> theta = Symbol("theta")
    >>> phi = Symbol("phi")

    >>> diff(Ynm(n, m, theta, phi), theta)
    m*cot(theta)*Ynm(n, m, theta, phi) + sqrt((-m + n)*(m + n + 1))*exp(-I*phi)*Ynm(n, m + 1, theta, phi)

    >>> diff(Ynm(n, m, theta, phi), phi)
    I*m*Ynm(n, m, theta, phi)

    Further we can compute the complex conjugation:

    >>> from sympy import Ynm, Symbol, conjugate
    >>> from sympy.abc import n,m
    >>> theta = Symbol("theta")
    >>> phi = Symbol("phi")

    >>> conjugate(Ynm(n, m, theta, phi))
    (-1)**(2*m)*exp(-2*I*m*phi)*Ynm(n, m, theta, phi)

    To get back the well known expressions in spherical
    coordinates, we use full expansion:

    >>> from sympy import Ynm, Symbol, expand_func
    >>> from sympy.abc import n,m
    >>> theta = Symbol("theta")
    >>> phi = Symbol("phi")

    >>> expand_func(Ynm(n, m, theta, phi))
    sqrt((2*n + 1)*factorial(-m + n)/factorial(m + n))*exp(I*m*phi)*assoc_legendre(n, m, cos(theta))/(2*sqrt(pi))

    See Also
    ========

    Ynm_c, Znm

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Spherical_harmonics
    .. [2] https://mathworld.wolfram.com/SphericalHarmonic.html
    .. [3] https://functions.wolfram.com/Polynomials/SphericalHarmonicY/
    .. [4] https://dlmf.nist.gov/14.30

    c                 C   sŠ   |  ¡ r:| }tj| tdt | | ƒ t||||ƒ S |  ¡ rV| }t||||ƒS |  ¡ r†| }tdt | | ƒt||||ƒ S d S )Néþÿÿÿ)Zcould_extract_minus_signr   ÚNegativeOner   r   r   )ÚclsÚnÚmÚthetaÚphi© r   új/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/functions/special/spherical_harmonics.pyÚeval‰   s    ,zYnm.evalc                 K   s€   | j \}}}}td| d dt  t|| ƒ t|| ƒ ƒtt| | ƒ t||t|ƒƒ }| tt|ƒd  d ƒt	|ƒ¡S ©Né   é   é   )
Úargsr   r   r
   r   r   r	   r   Úsubsr   )ÚselfÚhintsr   r   r   r   Úrvr   r   r   Ú_eval_expand_func˜   s    .ÿÿzYnm._eval_expand_funcr!   c                 C   sÊ   |dkrt | |ƒ‚n²|dkr(t | |ƒ‚nž|dkr�| j\}}}}|t|ƒ t||||ƒ t|| || d  ƒtt | ƒ t||d ||ƒ  S |dkr¼| j\}}}}t| t||||ƒ S t | |ƒ‚d S )Nr    r   é   r!   )r   r"   r   r   r   r   r   )r$   Zargindexr   r   r   r   r   r   r   ÚfdiffŸ   s    6ÿz	Ynm.fdiffc                 K   s   | j dd�S )NT©Úfunc)Úexpand©r$   r   r   r   r   Úkwargsr   r   r   Ú_eval_rewrite_as_polynomial²   s    zYnm._eval_rewrite_as_polynomialc                 K   s
   |   t¡S ©N)Zrewriter   r-   r   r   r   Ú_eval_rewrite_as_sin·   s    zYnm._eval_rewrite_as_sinc           	      K   sF   ddl m}m} || jdd�ƒ}| tt|ƒƒt|ƒi¡}|||ƒƒS )Nr   )ÚsimplifyÚtrigsimpTr*   )Zsympy.simplifyr2   r3   r,   Zxreplacer   r   )	r$   r   r   r   r   r.   r2   r3   Útermr   r   r   Ú_eval_rewrite_as_cosº   s    zYnm._eval_rewrite_as_cosc                 C   s*   | j \}}}}tj| |  || ||¡ S r0   )r"   r   r   r+   )r$   r   r   r   r   r   r   r   Ú_eval_conjugateÄ   s    zYnm._eval_conjugateTc           	      K   s®   | j \}}}}td| d dt  t|| ƒ t|| ƒ ƒt|| ƒ t||t|ƒƒ }td| d dt  t|| ƒ t|| ƒ ƒt|| ƒ t||t|ƒƒ }||fS r   )r"   r   r   r
   r   r	   r   )	r$   Údeepr%   r   r   r   r   ÚreZimr   r   r   Úas_real_imagÉ   s    .
ÿÿ.
ÿÿzYnm.as_real_imagc           	   	   C   s€   ddl m}m} | jd  |¡}| jd  |¡}| jd  |¡}| jd  |¡}||ƒ� | ||||¡}W 5 Q R X t ||¡S )Nr   )ÚmpÚworkprecr    r   r(   )Zmpmathr:   r;   r"   Z
_to_mpmathZ	spherharmr   Z_from_mpmath)	r$   Úprecr:   r;   r   r   r   r   Úresr   r   r   Ú_eval_evalfÒ   s    
zYnm._eval_evalfN)r!   )T)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úclassmethodr   r'   r)   r/   r1   r5   r6   r9   r>   r   r   r   r   r      s   y



	r   c                 C   s   t t| |||ƒƒS )a0  
    Conjugate spherical harmonics defined as

    .. math::
        \overline{Y_n^m(\theta, \varphi)} := (-1)^m Y_n^{-m}(\theta, \varphi).

    Examples
    ========

    >>> from sympy import Ynm_c, Symbol, simplify
    >>> from sympy.abc import n,m
    >>> theta = Symbol("theta")
    >>> phi = Symbol("phi")
    >>> Ynm_c(n, m, theta, phi)
    (-1)**(2*m)*exp(-2*I*m*phi)*Ynm(n, m, theta, phi)
    >>> Ynm_c(n, m, -theta, phi)
    (-1)**(2*m)*exp(-2*I*m*phi)*Ynm(n, m, theta, phi)

    For specific integers $n$ and $m$ we can evaluate the harmonics
    to more useful expressions:

    >>> simplify(Ynm_c(0, 0, theta, phi).expand(func=True))
    1/(2*sqrt(pi))
    >>> simplify(Ynm_c(1, -1, theta, phi).expand(func=True))
    sqrt(6)*exp(I*(-phi + 2*conjugate(phi)))*sin(theta)/(4*sqrt(pi))

    See Also
    ========

    Ynm, Znm

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Spherical_harmonics
    .. [2] https://mathworld.wolfram.com/SphericalHarmonic.html
    .. [3] https://functions.wolfram.com/Polynomials/SphericalHarmonicY/

    )r   r   )r   r   r   r   r   r   r   ÚYnm_cà   s    (rD   c                   @   s   e Zd ZdZedd„ ƒZdS )ÚZnma{  
    Real spherical harmonics defined as

    .. math::

        Z_n^m(\theta, \varphi) :=
        \begin{cases}
          \frac{Y_n^m(\theta, \varphi) + \overline{Y_n^m(\theta, \varphi)}}{\sqrt{2}} &\quad m > 0 \\
          Y_n^m(\theta, \varphi) &\quad m = 0 \\
          \frac{Y_n^m(\theta, \varphi) - \overline{Y_n^m(\theta, \varphi)}}{i \sqrt{2}} &\quad m < 0 \\
        \end{cases}

    which gives in simplified form

    .. math::

        Z_n^m(\theta, \varphi) =
        \begin{cases}
          \frac{Y_n^m(\theta, \varphi) + (-1)^m Y_n^{-m}(\theta, \varphi)}{\sqrt{2}} &\quad m > 0 \\
          Y_n^m(\theta, \varphi) &\quad m = 0 \\
          \frac{Y_n^m(\theta, \varphi) - (-1)^m Y_n^{-m}(\theta, \varphi)}{i \sqrt{2}} &\quad m < 0 \\
        \end{cases}

    Examples
    ========

    >>> from sympy import Znm, Symbol, simplify
    >>> from sympy.abc import n, m
    >>> theta = Symbol("theta")
    >>> phi = Symbol("phi")
    >>> Znm(n, m, theta, phi)
    Znm(n, m, theta, phi)

    For specific integers n and m we can evaluate the harmonics
    to more useful expressions:

    >>> simplify(Znm(0, 0, theta, phi).expand(func=True))
    1/(2*sqrt(pi))
    >>> simplify(Znm(1, 1, theta, phi).expand(func=True))
    -sqrt(3)*sin(theta)*cos(phi)/(2*sqrt(pi))
    >>> simplify(Znm(2, 1, theta, phi).expand(func=True))
    -sqrt(15)*sin(2*theta)*cos(phi)/(4*sqrt(pi))

    See Also
    ========

    Ynm, Ynm_c

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Spherical_harmonics
    .. [2] https://mathworld.wolfram.com/SphericalHarmonic.html
    .. [3] https://functions.wolfram.com/Polynomials/SphericalHarmonicY/

    c                 C   sx   |j r.t||||ƒt||||ƒ tdƒ }|S |jrBt||||ƒS |jrtt||||ƒt||||ƒ tdƒt  }|S d S )Nr   )Zis_positiver   rD   r   Úis_zeroZis_negativer   )r   r   r   r   r   Úzzr   r   r   r   E  s    $(zZnm.evalN)r?   r@   rA   rB   rC   r   r   r   r   r   rE     s   9rE   N)Zsympy.core.exprr   Zsympy.core.functionr   r   Zsympy.core.numbersr   r   Zsympy.core.singletonr   Zsympy.core.symbolr   Zsympy.functionsr	   Z(sympy.functions.combinatorial.factorialsr
   Z$sympy.functions.elementary.complexesr   r   Z&sympy.functions.elementary.exponentialr   Z(sympy.functions.elementary.miscellaneousr   Z(sympy.functions.elementary.trigonometricr   r   r   Z_xr   rD   rE   r   r   r   r   Ú<module>   s    R+