U
    L?hg                     @  s   d 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
 ddlmZ ddlmZ dd	lmZ dd
lmZ dddddZdddddZdddddZeddddZeddddZeddddZeddd d!Zd"dd#d$Zd%S )&a  A module for special angle formulas for trigonometric functions

TODO
====

This module should be developed in the future to contain direct square root
representation of

.. math
    F(\frac{n}{m} \pi)

for every

- $m \in \{ 3, 5, 17, 257, 65537 \}$
- $n \in \mathbb{N}$, $0 \le n < m$
- $F \in \{\sin, \cos, \tan, \csc, \sec, \cot\}$

Without multi-step rewrites
(e.g. $\tan \to \cos/\sin \to \cos/\sqrt \to \ sqrt$)
or using chebyshev identities
(e.g. $\cos \to \cos + \cos^2 + \cdots \to \sqrt{} + \sqrt{}^2 + \cdots $),
which are trivial to implement in sympy,
and had used to give overly complicated expressions.

The reference can be found below, if anyone may need help implementing them.

References
==========

.. [*] Gottlieb, Christian. (1999). The Simple and straightforward construction
   of the regular 257-gon. The Mathematical Intelligencer. 21. 31-37.
   10.1007/BF03024829.
.. [*] https://resources.wolframcloud.com/FunctionRepository/resources/Cos2PiOverFermatPrime
    )annotations)Callable)reduce)Expr)S)igcdex)Integersqrt)cacheitintztuple[tuple[int, ...], int])xreturnc                    s   | sdS t | dkr d| d fS t | dkrPt| d | d \} }| f|fS t| dd  \}}t| d |\} }|f fdd|D |fS )	aN  Compute extended gcd for multiple integers.

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

    Given the integers $x_1, \cdots, x_n$ and
    an extended gcd for multiple arguments are defined as a solution
    $(y_1, \cdots, y_n), g$ for the diophantine equation
    $x_1 y_1 + \cdots + x_n y_n = g$ such that
    $g = \gcd(x_1, \cdots, x_n)$.

    Examples
    ========

    >>> from sympy.functions.elementary._trigonometric_special import migcdex
    >>> migcdex()
    ((), 0)
    >>> migcdex(4)
    ((1,), 4)
    >>> migcdex(4, 6)
    ((-1, 1), 2)
    >>> migcdex(6, 10, 15)
    ((1, 1, -1), 1)
    ) r      )r   r      Nc                 3  s   | ]} | V  qd S Nr   ).0ivr   c/var/www/html/venv/lib/python3.8/site-packages/sympy/functions/elementary/_trigonometric_special.py	<genexpr>S   s     zmigcdex.<locals>.<genexpr>)lenr   migcdex)r   uhygr   r   r   r   .   s    r   ztuple[int, ...])denomsr   c                    sF   | sdS dddddd}t ||   fdd| D }t| \}}|S )a  Compute the partial fraction decomposition.

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

    Given a rational number $\frac{1}{q_1 \cdots q_n}$ where all
    $q_1, \cdots, q_n$ are pairwise coprime,

    A partial fraction decomposition is defined as

    .. math::
        \frac{1}{q_1 \cdots q_n} = \frac{p_1}{q_1} + \cdots + \frac{p_n}{q_n}

    And it can be derived from solving the following diophantine equation for
    the $p_1, \cdots, p_n$

    .. math::
        1 = p_1 \prod_{i \ne 1}q_i + \cdots + p_n \prod_{i \ne n}q_i

    Where $q_1, \cdots, q_n$ being pairwise coprime implies
    $\gcd(\prod_{i \ne 1}q_i, \cdots, \prod_{i \ne n}q_i) = 1$,
    which guarantees the existence of the solution.

    It is sufficient to compute partial fraction decomposition only
    for numerator $1$ because partial fraction decomposition for any
    $\frac{n}{q_1 \cdots q_n}$ can be easily computed by multiplying
    the result by $n$ afterwards.

    Parameters
    ==========

    denoms : int
        The pairwise coprime integer denominators $q_i$ which defines the
        rational number $\frac{1}{q_1 \cdots q_n}$

    Returns
    =======

    tuple[int, ...]
        The list of numerators which semantically corresponds to $p_i$ of the
        partial fraction decomposition
        $\frac{1}{q_1 \cdots q_n} = \frac{p_1}{q_1} + \cdots + \frac{p_n}{q_n}$

    Examples
    ========

    >>> from sympy import Rational, Mul
    >>> from sympy.functions.elementary._trigonometric_special import ipartfrac

    >>> denoms = 2, 3, 5
    >>> numers = ipartfrac(2, 3, 5)
    >>> numers
    (1, 7, -14)

    >>> Rational(1, Mul(*denoms))
    1/30
    >>> out = 0
    >>> for n, d in zip(numers, denoms):
    ...    out += Rational(n, d)
    >>> out
    1/30
    r   r   )r   r   r   c                 S  s   | | S r   r   )r   r   r   r   r   mul   s    zipartfrac.<locals>.mulc                   s   g | ]} | qS r   r   )r   r   denomr   r   
<listcomp>   s     zipartfrac.<locals>.<listcomp>)r   r   )r   r    ar   _r   r!   r   	ipartfracV   s    ?
r&   zlist[int] | None)nr   c                 C  sF   g }dD ]8}t | |\}}|dkr|} || | dkr|  S qdS )z}If n can be factored in terms of Fermat primes with
    multiplicity of each being 1, return those primes, else
    None
    )           i  r   r   N)divmodappend)r'   ZprimespZquotient	remainderr   r   r   fermat_coords   s    

r0   r   )r   c                   C  s   t jS )z-Computes $\cos \frac{\pi}{3}$ in square roots)r   Halfr   r   r   r   cos_3   s    r2   c                   C  s   t dd d S )z-Computes $\cos \frac{\pi}{5}$ in square rootsr)   r      r	   r   r   r   r   cos_5   s    r4   c                   C  s|   t dt d d t dt dt d t t ddt dt d  dt d t dt d    dt d  d   d  S )	z.Computes $\cos \frac{\pi}{17}$ in square roots   r*       r   ir      "   r	   r   r   r   r   cos_17   s    "$
r9   c            )      C  s  dddddd} dddddd}| t jtd\}}| |td	\}}| |td	\}}| |d
d| d|   \}}	| |d
d| d|   \}
}| |d
d| d|   \}}| |d
d| d|   \}}| |d|| | d|
   \}}| |d|| | d|   \}}| |d|| |	 d|   \}}| |d|| |
 d|   \}}| |	d||	 | d|   \}}| |
d||
 | d|   \}}| |d|| | d|   \}}| |d|| | d|	   \}}||d|| | |  } ||d|| | |  }!||d|| | |  }"||d|| | |  }#||d|| | |  }$||d|| | |  }%||  d|!|"   }&||# d|$|%   }'d||& d|'  }(ttdt|(d
  d t j S )a  Computes $\cos \frac{\pi}{257}$ in square roots

    References
    ==========

    .. [*] https://math.stackexchange.com/questions/516142/how-does-cos2-pi-257-look-like-in-real-radicals
    .. [*] https://r-knott.surrey.ac.uk/Fibonacci/simpleTrig.html
    r   ztuple[Expr, Expr])r$   br   c                 S  s0   | t | d |  d | t | d |  d fS Nr   r	   r$   r:   r   r   r   f1   s    zcos_257.<locals>.f1c                 S  s   | t | d |  d S r;   r	   r<   r   r   r   f2   s    zcos_257.<locals>.f2   @   r3   r)   r      )r   ZNegativeOner   r
   r1   ))r=   r>   t1t2Zz1Zz3Zz2Zz4y1Zy5Zy6y2Zy3Zy7Zy8Zy4x1Zx9Zx2x10Zx3Zx11Zx4Zx12Zx5Zx13Zx6Zx14Zx15Zx7Zx8Zx16Zv1Zv2Zv3Zv4Zv5Zv6u1u2Zw1r   r   r   cos_257   s6    
""""""""rL   zdict[int, Callable[[], Expr]]c                   C  s   t tttdS )ag  Lazily evaluated table for $\cos \frac{\pi}{n}$ in square roots for
    $n \in \{3, 5, 17, 257, 65537\}$.

    Notes
    =====

    65537 is the only other known Fermat prime and it is nearly impossible to
    build in the current SymPy due to performance issues.

    References
    ==========

    https://r-knott.surrey.ac.uk/Fibonacci/simpleTrig.html
    )r(   r)   r*   r+   )r2   r4   r9   rL   r   r   r   r   	cos_table   s
    rM   N)__doc__
__future__r   typingr   	functoolsr   Zsympy.core.exprr   Zsympy.core.singletonr   Zsympy.core.intfuncr   Zsympy.core.numbersr   Z(sympy.functions.elementary.miscellaneousr
   Zsympy.core.cacher   r   r&   r0   r2   r4   r9   rL   rM   r   r   r   r   <module>   s*   "(K*