o
    GZhg                     @  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Zd'ddZd(ddZed)ddZed)ddZed)ddZed)d d!Z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xintreturntuple[tuple[int, ...], int]c                    s   | sdS t | dkrd| d fS t | dkr(t| d | d \} }| f|fS t| dd  \}}t| d |\} }|g fdd|D R |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   `/var/www/auris/lib/python3.10/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   denomstuple[int, ...]c                    s>   | sdS 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>N)r   r   r   r   r   r   )r   r   )r    r"   ar   _r   r#   r   	ipartfracV   s   ?

r(   nlist[int] | Nonec                 C  sF   g }dD ]}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   
r3   r   c                   C  s   t jS )z-Computes $\cos \frac{\pi}{3}$ in square roots)r   Halfr   r   r   r   cos_3   s   r5   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   r7   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   "$
r<   c            )      C  s  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&   r   br   tuple[Expr, Expr]c                 S  s0   | t | d |  d | t | d |  d fS Nr   r	   r&   r=   r   r   r   f1   s   0zcos_257.<locals>.f1c                 S  s   | t | d |  d S r?   r	   r@   r   r   r   f2   s   zcos_257.<locals>.f2   @   r6   r,   r      N)r&   r   r=   r   r   r>   )r&   r   r=   r   r   r   )r   ZNegativeOner   r
   r4   ))rA   rB   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x16v1v2Zv3Zv4Zv5Zv6u1u2Zw1r   r   r   cos_257   s6   


"""""""""rR   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.   )r5   r7   r<   rR   r   r   r   r   	cos_table   s
   rT   N)r   r   r   r   )r    r   r   r!   )r)   r   r   r*   )r   r   )r   rS   )__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(   r3   r5   r7   r<   rR   rT   r   r   r   r   <module>   s,    "

(
K*