
\c           @  sq  d  Z  d d l m Z m Z m Z d d l m Z m Z m Z d d l	 m
 Z
 m Z m Z d d l m Z d d l m Z m Z d d l m Z m Z d d l m Z m Z d d	 l m Z e d
  Z d d  Z d d  Z e j  e _  e d  Z d   Z  d   Z! e  j  e! _  e d  Z" d   Z# d   Z$ e# j  e$ _  d   Z% e& d  Z' e& d  Z( e' j  e( _  d S(   ud   
Discrete Fourier Transform, Number Theoretic Transform,
Walsh Hadamard Transform, Mobius Transform
i(   t   print_functiont   divisiont   unicode_literals(   t   St   Symbolt   sympify(   t   as_intt   ranget   iterable(   t
   expand_mul(   t   pit   I(   t   sint   cos(   t   isprimet   primitive_root(   t   ibinc         C  s  t  |   s t d   n  g  |  D] } t |  ^ q" } t d   | D  r_ t d   n  t |  } | d k  r{ | S| j   d } | | d @r | d 7} d | } n  | t j g | t |  7} xn t	 d |  D]] } t
 t | | d t d d d  d  } | | k  r | | | | | | <| | <q q W| rSd	 t | n d t | }	 | d k	 r|	 j | d  }	 n  g  t	 | d  D]( } t |	 |  t t |	 |  ^ q}
 d } x | | k r| d | | } } x t	 d
 | |  D]y } xp t	 |  D]b } | | | t | | | | |
 | |  } } | | | | | | | <| | | | <qWqW| d 9} qW| r| d k	 rg  | D]6 } | | j |  ^ qn g  | D] } | | ^ q} n  | S(   u3   Utility function for the Discrete Fourier TransformuA   Expected a sequence of numeric coefficients for Fourier Transformc         s  s   |  ] } | j  t  Vq d  S(   N(   t   hasR   (   t   .0t   x(    (    s8   lib/python2.7/site-packages/sympy/discrete/transforms.pys	   <genexpr>    s    u"   Expected non-symbolic coefficientsi   i   t   strNiii    (   R   t	   TypeErrorR   t   anyt
   ValueErrort   lent
   bit_lengthR   t   ZeroR   t   intR   t   TrueR
   t   Nonet   evalfR   R   R   R	   (   t   seqt   dpst   inverset   argt   at   nt   bt   it   jt   angt   wt   ht   hft   utt   ut   vR   (    (    s8   lib/python2.7/site-packages/sympy/discrete/transforms.pyt   _fourier_transform   sB    
+$"?312 c         C  s   t  |  d | S(   ul  
    Performs the Discrete Fourier Transform (**DFT**) in the complex domain.

    The sequence is automatically padded to the right with zeros, as the
    *radix-2 FFT* requires the number of sample points to be a power of 2.

    This method should be used with default arguments only for short sequences
    as the complexity of expressions increases with the size of the sequence.

    Parameters
    ==========

    seq : iterable
        The sequence on which **DFT** is to be applied.
    dps : Integer
        Specifies the number of decimal digits for precision.

    Examples
    ========

    >>> from sympy import fft, ifft

    >>> fft([1, 2, 3, 4])
    [10, -2 - 2*I, -2, -2 + 2*I]
    >>> ifft(_)
    [1, 2, 3, 4]

    >>> ifft([1, 2, 3, 4])
    [5/2, -1/2 + I/2, -1/2, -1/2 - I/2]
    >>> fft(_)
    [1, 2, 3, 4]

    >>> ifft([1, 7, 3, 4], dps=15)
    [3.75, -0.5 - 0.75*I, -1.75, -0.5 + 0.75*I]
    >>> fft(_)
    [1.0, 7.0, 3.0, 4.0]

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm
    .. [2] http://mathworld.wolfram.com/FastFourierTransform.html

    R    (   R/   (   R   R    (    (    s8   lib/python2.7/site-packages/sympy/discrete/transforms.pyt   fftI   s    .c         C  s   t  |  d | d t S(   NR    R!   (   R/   R   (   R   R    (    (    s8   lib/python2.7/site-packages/sympy/discrete/transforms.pyt   ifftz   s    c         C  s  t  |   s t d   n  t |  } t |  sB t d   n  g  |  D] } t |  | ^ qI } t |  } | d k  r | S| j   d } | | d @r | d 7} d | } n  | d | r t d   n  | d g | t |  7} xn t d |  D]] } t t	 | | d t
 d d d	  d  }	 | |	 k  r | |	 | | | | <| |	 <q q Wt |  }
 t |
 | d | |  } | rt | | d |  } n  d g | d } x5 t d | d  D]  } | | d | | | | <qWd } x | | k r| d | | } } x t d | |  D]{ } xr t |  D]d }	 | | |	 | | |	 | | | |	 } } | | | | | | | | |	 <| | |	 | <q=Wq*W| d 9} qW| rt | | d |  } g  | D] } | | | ^ q} n  | S(
   u3   Utility function for the Number Theoretic TransformuJ   Expected a sequence of integer coefficients for Number Theoretic Transformu5   Expected prime modulus for Number Theoretic Transformi   i   u/   Expected prime modulus of the form (m*2**k + 1)i    R   Ni(   R   R   R   R   R   R   R   R   R   R   R   R   t   pow(   R   t   primeR!   t   pR   R#   R$   R%   R&   R'   t   prt   rtR)   R*   R+   R,   R-   R.   t   rv(    (    s8   lib/python2.7/site-packages/sympy/discrete/transforms.pyt   _number_theoretic_transform   sN    #
+$-9$c         C  s   t  |  d | S(   uQ  
    Performs the Number Theoretic Transform (**NTT**), which specializes the
    Discrete Fourier Transform (**DFT**) over quotient ring `Z/pZ` for prime
    `p` instead of complex numbers `C`.

    The sequence is automatically padded to the right with zeros, as the
    *radix-2 NTT* requires the number of sample points to be a power of 2.

    Parameters
    ==========

    seq : iterable
        The sequence on which **DFT** is to be applied.
    prime : Integer
        Prime modulus of the form `(m 2^k + 1)` to be used for performing
        **NTT** on the sequence.

    Examples
    ========

    >>> from sympy import ntt, intt
    >>> ntt([1, 2, 3, 4], prime=3*2**8 + 1)
    [10, 643, 767, 122]
    >>> intt(_, 3*2**8 + 1)
    [1, 2, 3, 4]
    >>> intt([1, 2, 3, 4], prime=3*2**8 + 1)
    [387, 415, 384, 353]
    >>> ntt(_, prime=3*2**8 + 1)
    [1, 2, 3, 4]

    References
    ==========

    .. [1] http://www.apfloat.org/ntt.html
    .. [2] http://mathworld.wolfram.com/NumberTheoreticTransform.html
    .. [3] https://en.wikipedia.org/wiki/Discrete_Fourier_transform_(general%29

    R3   (   R8   (   R   R3   (    (    s8   lib/python2.7/site-packages/sympy/discrete/transforms.pyt   ntt   s    (c         C  s   t  |  d | d t S(   NR3   R!   (   R8   R   (   R   R3   (    (    s8   lib/python2.7/site-packages/sympy/discrete/transforms.pyt   intt   s    c         C  su  t  |   s t d   n  g  |  D] } t |  ^ q" } t |  } | d k  rV | S| | d @rw d | j   } n  | t j g | t |  7} d } x | | k rJ| d | | } } x{ t d | |  D]g } x^ t |  D]P }	 | | |	 | | |	 | }
 } |
 | |
 | | | |	 <| | |	 | <q Wq W| d 9} q W| rqg  | D] } | | ^ qX} n  | S(   u1   Utility function for the Walsh Hadamard Transformu@   Expected a sequence of coefficients for Walsh Hadamard Transformi   i   i    (   R   R   R   R   R   R   R   R   (   R   R!   R"   R#   R$   R*   R+   R,   R&   R'   R-   R.   R   (    (    s8   lib/python2.7/site-packages/sympy/discrete/transforms.pyt   _walsh_hadamard_transform   s(    !1 c         C  s
   t  |   S(   uN  
    Performs the Walsh Hadamard Transform (**WHT**), and uses Hadamard
    ordering for the sequence.

    The sequence is automatically padded to the right with zeros, as the
    *radix-2 FWHT* requires the number of sample points to be a power of 2.

    Parameters
    ==========

    seq : iterable
        The sequence on which WHT is to be applied.

    Examples
    ========

    >>> from sympy import fwht, ifwht
    >>> fwht([4, 2, 2, 0, 0, 2, -2, 0])
    [8, 0, 8, 0, 8, 8, 0, 0]
    >>> ifwht(_)
    [4, 2, 2, 0, 0, 2, -2, 0]

    >>> ifwht([19, -1, 11, -9, -7, 13, -15, 5])
    [2, 0, 4, 0, 3, 10, 0, 0]
    >>> fwht(_)
    [19, -1, 11, -9, -7, 13, -15, 5]

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Hadamard_transform
    .. [2] https://en.wikipedia.org/wiki/Fast_Walsh%E2%80%93Hadamard_transform

    (   R;   (   R   (    (    s8   lib/python2.7/site-packages/sympy/discrete/transforms.pyt   fwht  s    $c         C  s   t  |  d t S(   NR!   (   R;   R   (   R   (    (    s8   lib/python2.7/site-packages/sympy/discrete/transforms.pyt   ifwht=  s    c         C  sk  t  |   s t d   n  g  |  D] } t |  ^ q" } t |  } | d k  rV | S| | d @rw d | j   } n  | t j g | t |  7} | rd } x | | k  r x= t |  D]/ } | | @r | | c | | | | A7<q q W| d 9} q Wnf d } x] | | k  rfx@ t |  D]2 } | | @r9q#n  | | c | | | | A7<q#W| d 9} q
W| S(   u]   Utility function for performing Möbius Transform using
    Yate's Dynamic Programming methodu#   Expected a sequence of coefficientsi   i   (   R   R   R   R   R   R   R   R   (   R   t   sgnt   subsetR"   R#   R$   R&   R'   (    (    s8   lib/python2.7/site-packages/sympy/discrete/transforms.pyt   _mobius_transformI  s0    
#
 c         C  s   t  |  d d 
d | S(   u  
    Performs the Möbius Transform for subset lattice with indices of
    sequence as bitmasks.

    The indices of each argument, considered as bit strings, correspond
    to subsets of a finite set.

    The sequence is automatically padded to the right with zeros, as the
    definition of subset/superset based on bitmasks (indices) requires
    the size of sequence to be a power of 2.

    Parameters
    ==========

    seq : iterable
        The sequence on which Möbius Transform is to be applied.
    subset : bool
        Specifies if Möbius Transform is applied by enumerating subsets
        or supersets of the given set.

    Examples
    ========

    >>> from sympy import symbols
    >>> from sympy import mobius_transform, inverse_mobius_transform
    >>> x, y, z = symbols('x y z')

    >>> mobius_transform([x, y, z])
    [x, x + y, x + z, x + y + z]
    >>> inverse_mobius_transform(_)
    [x, y, z, 0]

    >>> mobius_transform([x, y, z], subset=False)
    [x + y + z, y, z, 0]
    >>> inverse_mobius_transform(_, subset=False)
    [x, y, z, 0]

    >>> mobius_transform([1, 2, 3, 4])
    [1, 3, 4, 10]
    >>> inverse_mobius_transform(_)
    [1, 2, 3, 4]
    >>> mobius_transform([1, 2, 3, 4], subset=False)
    [10, 6, 7, 4]
    >>> inverse_mobius_transform(_, subset=False)
    [1, 2, 3, 4]

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/M%C3%B6bius_inversion_formula
    .. [2] https://people.csail.mit.edu/rrw/presentations/subset-conv.pdf
    .. [3] https://arxiv.org/pdf/1211.0189.pdf

    R>   i   R?   (   R@   (   R   R?   (    (    s8   lib/python2.7/site-packages/sympy/discrete/transforms.pyt   mobius_transformo  s    8c         C  s   t  |  d d d | S(   NR>   iR?   (   R@   (   R   R?   (    (    s8   lib/python2.7/site-packages/sympy/discrete/transforms.pyt   inverse_mobius_transform  s    N()   t   __doc__t
   __future__R    R   R   t
   sympy.coreR   R   R   t   sympy.core.compatibilityR   R   R   t   sympy.core.functionR	   t   sympy.core.numbersR
   R   t(   sympy.functions.elementary.trigonometricR   R   t   sympy.ntheoryR   R   t   sympy.utilities.iterablesR   t   FalseR/   R   R0   R1   R8   R9   R:   R;   R<   R=   R@   R   RA   RB   (    (    (    s8   lib/python2.7/site-packages/sympy/discrete/transforms.pyt   <module>   s0   	11	:	+			'			&: