ó
¡¼™\c           @  sí   d  Z  d d l m Z m Z d d l 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 m Z m Z m Z m Z m Z m Z d d d d d d „ Z d d	 „ Z d
 „  Z d „  Z d „  Z d „  Z d „  Z d S(   sl   
Convolution (using **FFT**, **NTT**, **FWHT**), Subset Convolution,
Covering Product, Intersecting Product
iÿÿÿÿ(   t   print_functiont   division(   t   St   sympify(   t   ranget   as_intt   iterable(   t
   expand_mul(   t   fftt   ifftt   nttt   inttt   fwhtt   ifwhtt   mobius_transformt   inverse_mobius_transformi    c   
      C  s`  t  | ƒ } | d k  r' t d ƒ ‚ n  | r3 t n d } | rE t n d } t d „  | | | | f Dƒ ƒ d k r‚ t d ƒ ‚ n  | d k	 rá t |  | d | ƒ} | s­ | Sg  t | ƒ D]# }	 t | |	 d | … ƒ | ^ qº S| rù t |  | ƒ } n- | rt	 |  | ƒ } n t
 |  | d | ƒ} | s0| Sg  t | ƒ D] }	 t | |	 d | … ƒ ^ q=S(	   s  
    Performs convolution by determining the type of desired
    convolution using hints.

    Exactly one of ``dps``, ``prime``, ``dyadic``, ``subset`` arguments
    should be specified explicitly for identifying the type of convolution,
    and the argument ``cycle`` can be specified optionally.

    For the default arguments, linear convolution is performed using **FFT**.

    Parameters
    ==========

    a, b : iterables
        The sequences for which convolution is performed.
    cycle : Integer
        Specifies the length for doing cyclic convolution.
    dps : Integer
        Specifies the number of decimal digits for precision for
        performing **FFT** on the sequence.
    prime : Integer
        Prime modulus of the form `(m 2^k + 1)` to be used for
        performing **NTT** on the sequence.
    dyadic : bool
        Identifies the convolution type as dyadic (*bitwise-XOR*)
        convolution, which is performed using **FWHT**.
    subset : bool
        Identifies the convolution type as subset convolution.

    Examples
    ========

    >>> from sympy import convolution, symbols, S, I
    >>> u, v, w, x, y, z = symbols('u v w x y z')

    >>> convolution([1 + 2*I, 4 + 3*I], [S(5)/4, 6], dps=3)
    [1.25 + 2.5*I, 11.0 + 15.8*I, 24.0 + 18.0*I]
    >>> convolution([1, 2, 3], [4, 5, 6], cycle=3)
    [31, 31, 28]

    >>> convolution([111, 777], [888, 444], prime=19*2**10 + 1)
    [1283, 19351, 14219]
    >>> convolution([111, 777], [888, 444], prime=19*2**10 + 1, cycle=2)
    [15502, 19351]

    >>> convolution([u, v], [x, y, z], dyadic=True)
    [u*x + v*y, u*y + v*x, u*z, v*z]
    >>> convolution([u, v], [x, y, z], dyadic=True, cycle=2)
    [u*x + u*z + v*y, u*y + v*x + v*z]

    >>> convolution([u, v, w], [x, y, z], subset=True)
    [u*x, u*y + v*x, u*z + w*x, v*z + w*y]
    >>> convolution([u, v, w], [x, y, z], subset=True, cycle=3)
    [u*x + v*z + w*y, u*y + v*x, u*z + w*x]

    i    s6   The length for cyclic convolution must be non-negativec         s  s   |  ] } | d  k	 Vq d  S(   N(   t   None(   t   .0t   x(    (    s:   lib/python2.7/site-packages/sympy/discrete/convolutions.pys	   <genexpr>P   s    i   s0   Ambiguity in determining the type of convolutiont   primeNt   dps(   R   t
   ValueErrort   TrueR   t   sumt	   TypeErrort   convolution_nttR   t   convolution_fwhtt   convolution_subsett   convolution_fft(
   t   at   bt   cycleR   R   t   dyadict   subsett   ct   lst   i(    (    s:   lib/python2.7/site-packages/sympy/discrete/convolutions.pyt   convolution   s     :(>c         C  sþ   |  | }  } t  |  ƒ t  | ƒ d } } | d k rZ | | d @rZ d | j ƒ  } n  |  t j g | t  |  ƒ 7}  | t j g | t  | ƒ 7} t |  | ƒ t | | ƒ }  } g  t |  | ƒ D] \ } } t | | ƒ ^ qÅ }  t |  | ƒ |  }  |  S(   s  
    Performs linear convolution using Fast Fourier Transform.

    Parameters
    ==========

    a, b : iterables
        The sequences for which convolution is performed.
    dps : Integer
        Specifies the number of decimal digits for precision.

    Examples
    ========

    >>> from sympy import S, I
    >>> from sympy.discrete.convolutions import convolution_fft

    >>> convolution_fft([2, 3], [4, 5])
    [8, 22, 15]
    >>> convolution_fft([2, 5], [6, 7, 3])
    [12, 44, 41, 15]
    >>> convolution_fft([1 + 2*I, 4 + 3*I], [S(5)/4, 6])
    [5/4 + 5*I/2, 11 + 63*I/4, 24 + 18*I]

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Convolution_theorem
    .. [2] https://en.wikipedia.org/wiki/Discrete_Fourier_transform_(general%29

    i   i    i   (   t   lent
   bit_lengthR   t   ZeroR   t   zipR   R	   (   R   R   R   t   nt   mR   t   y(    (    s:   lib/python2.7/site-packages/sympy/discrete/convolutions.pyR   g   s    !2c         C  s  |  | t  | ƒ }  } } t |  ƒ t | ƒ d } } | d k rg | | d @rg d | j ƒ  } n  |  d g | t |  ƒ 7}  | d g | t | ƒ 7} t |  | ƒ t | | ƒ }  } g  t |  | ƒ D] \ } } | | | ^ qÌ }  t |  | ƒ |  }  |  S(   s=  
    Performs linear convolution using Number Theoretic Transform.

    Parameters
    ==========

    a, b : iterables
        The sequences for which convolution is performed.
    prime : Integer
        Prime modulus of the form `(m 2^k + 1)` to be used for performing
        **NTT** on the sequence.

    Examples
    ========

    >>> from sympy.discrete.convolutions import convolution_ntt
    >>> convolution_ntt([2, 3], [4, 5], prime=19*2**10 + 1)
    [8, 22, 15]
    >>> convolution_ntt([2, 5], [6, 7, 3], prime=19*2**10 + 1)
    [12, 44, 41, 15]
    >>> convolution_ntt([333, 555], [222, 666], prime=19*2**10 + 1)
    [15555, 14219, 19404]

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Convolution_theorem
    .. [2] https://en.wikipedia.org/wiki/Discrete_Fourier_transform_(general%29

    i   i    i   (   R   R&   R'   R
   R)   R   (   R   R   R   t   pR*   R+   R   R,   (    (    s:   lib/python2.7/site-packages/sympy/discrete/convolutions.pyR   Ÿ   s     0c         C  sô   |  s | r g  S|  | }  } t  t |  ƒ t | ƒ ƒ } | | d @r] d | j ƒ  } n  |  t j g | t |  ƒ 7}  | t j g | t | ƒ 7} t |  ƒ t | ƒ }  } g  t |  | ƒ D] \ } } t | | ƒ ^ qÂ }  t |  ƒ }  |  S(   s  
    Performs dyadic (*bitwise-XOR*) convolution using Fast Walsh Hadamard
    Transform.

    The convolution 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
    ==========

    a, b : iterables
        The sequences for which convolution is performed.

    Examples
    ========

    >>> from sympy import symbols, S, I
    >>> from sympy.discrete.convolutions import convolution_fwht

    >>> u, v, x, y = symbols('u v x y')
    >>> convolution_fwht([u, v], [x, y])
    [u*x + v*y, u*y + v*x]

    >>> convolution_fwht([2, 3], [4, 5])
    [23, 22]
    >>> convolution_fwht([2, 5 + 4*I, 7], [6*I, 7, 3 + 4*I])
    [56 + 68*I, -10 + 30*I, 6 + 50*I, 48 + 32*I]

    >>> convolution_fwht([S(33)/7, S(55)/6, S(7)/4], [S(2)/3, 5])
    [2057/42, 1870/63, 7/6, 35/4]

    References
    ==========

    .. [1] https://www.radioeng.cz/fulltexts/2002/02_03_40_42.pdf
    .. [2] https://en.wikipedia.org/wiki/Hadamard_transform

    i   i   (	   t   maxR&   R'   R   R(   R   R)   R   R   (   R   R   R*   R   R,   (    (    s:   lib/python2.7/site-packages/sympy/discrete/convolutions.pyR   Ö   s    (2c      	   C  s  |  s | r g  St  |  ƒ s, t  | ƒ r; t d ƒ ‚ n  g  |  D] } t | ƒ ^ qB }  g  | D] } t | ƒ ^ qa } t t |  ƒ t | ƒ ƒ } | | d @rµ d | j ƒ  } n  |  t j g | t |  ƒ 7}  | t j g | t | ƒ 7} t j g | } x‡ t | ƒ D]y } | } xD | d k r`| | c t	 |  | | | | Aƒ 7<| d | @} qW| | c t	 |  | | | | Aƒ 7<qW| S(   sñ  
    Performs Subset Convolution of given sequences.

    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 based on bitmasks (indices) requires the size of
    sequence to be a power of 2.

    Parameters
    ==========

    a, b : iterables
        The sequences for which convolution is performed.

    Examples
    ========

    >>> from sympy import symbols, S, I
    >>> from sympy.discrete.convolutions import convolution_subset
    >>> u, v, x, y, z = symbols('u v x y z')

    >>> convolution_subset([u, v], [x, y])
    [u*x, u*y + v*x]
    >>> convolution_subset([u, v, x], [y, z])
    [u*y, u*z + v*y, x*y, x*z]

    >>> convolution_subset([1, S(2)/3], [3, 4])
    [3, 6]
    >>> convolution_subset([1, 3, S(5)/7], [7])
    [7, 21, 5, 0]

    References
    ==========

    .. [1] https://people.csail.mit.edu/rrw/presentations/subset-conv.pdf

    s3   Expected a sequence of coefficients for convolutioni   i   i    (
   R   R   R   R.   R&   R'   R   R(   R   R   (   R   R   t   argR*   R"   t   maskt   smask(    (    s:   lib/python2.7/site-packages/sympy/discrete/convolutions.pyR     s&    )&*c         C  sô   |  s | r g  S|  | }  } t  t |  ƒ t | ƒ ƒ } | | d @r] d | j ƒ  } n  |  t j g | t |  ƒ 7}  | t j g | t | ƒ 7} t |  ƒ t | ƒ }  } g  t |  | ƒ D] \ } } t | | ƒ ^ qÂ }  t |  ƒ }  |  S(   s®  
    Returns the covering product of given sequences.

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

    The covering product of given sequences is a sequence which contains
    the sum of products of the elements of the given sequences grouped by
    the *bitwise-OR* of the corresponding indices.

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

    Parameters
    ==========

    a, b : iterables
        The sequences for which covering product is to be obtained.

    Examples
    ========

    >>> from sympy import symbols, S, I, covering_product
    >>> u, v, x, y, z = symbols('u v x y z')

    >>> covering_product([u, v], [x, y])
    [u*x, u*y + v*x + v*y]
    >>> covering_product([u, v, x], [y, z])
    [u*y, u*z + v*y + v*z, x*y, x*z]

    >>> covering_product([1, S(2)/3], [3, 4 + 5*I])
    [3, 26/3 + 25*I/3]
    >>> covering_product([1, 3, S(5)/7], [7, 8])
    [7, 53, 5, 40/7]

    References
    ==========

    .. [1] https://people.csail.mit.edu/rrw/presentations/subset-conv.pdf

    i   i   (	   R.   R&   R'   R   R(   R   R)   R   R   (   R   R   R*   R   R,   (    (    s:   lib/python2.7/site-packages/sympy/discrete/convolutions.pyt   covering_producte  s    ,2c         C  s  |  s | r g  S|  | }  } t  t |  ƒ t | ƒ ƒ } | | d @r] d | j ƒ  } n  |  t j g | t |  ƒ 7}  | t j g | t | ƒ 7} t |  d t ƒt | d t ƒ}  } g  t |  | ƒ D] \ } } t | | ƒ ^ qÎ }  t	 |  d t ƒ}  |  S(   sß  
    Returns the intersecting product of given sequences.

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

    The intersecting product of given sequences is the sequence which
    contains the sum of products of the elements of the given sequences
    grouped by the *bitwise-AND* of the corresponding indices.

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

    Parameters
    ==========

    a, b : iterables
        The sequences for which intersecting product is to be obtained.

    Examples
    ========

    >>> from sympy import symbols, S, I, intersecting_product
    >>> u, v, x, y, z = symbols('u v x y z')

    >>> intersecting_product([u, v], [x, y])
    [u*x + u*y + v*x, v*y]
    >>> intersecting_product([u, v, x], [y, z])
    [u*y + u*z + v*y + x*y + x*z, v*z, 0, 0]

    >>> intersecting_product([1, S(2)/3], [3, 4 + 5*I])
    [9 + 5*I, 8/3 + 10*I/3]
    >>> intersecting_product([1, 3, S(5)/7], [7, 8])
    [327/7, 24, 0, 0]

    References
    ==========

    .. [1] https://people.csail.mit.edu/rrw/presentations/subset-conv.pdf

    i   i   R!   (
   R.   R&   R'   R   R(   R   t   FalseR)   R   R   (   R   R   R*   R   R,   (    (    s:   lib/python2.7/site-packages/sympy/discrete/convolutions.pyt   intersecting_product«  s    ,%2N(   t   __doc__t
   __future__R    R   t
   sympy.coreR   R   t   sympy.core.compatibilityR   R   R   t   sympy.core.functionR   t   sympy.discrete.transformsR   R	   R
   R   R   R   R   R   R   R%   R   R   R   R   R2   R4   (    (    (    s:   lib/python2.7/site-packages/sympy/discrete/convolutions.pyt   <module>   s   :X8	7	B	M	F