�
��g�G � � � d Z ddlmZmZmZ ddlmZ ddlmZm Z m
Z
mZmZm
Z
mZmZ ddlmZmZ ddlmZ ddlmZ dd �Zdd
�Zd� Zd� Zd
� Zd� Zd� Zd� ZdS )zl
Convolution (using **FFT**, **NTT**, **FWHT**), Subset Convolution,
Covering Product, Intersecting Product
� )�S�sympify�Rational��
expand_mul)�fft�ifft�ntt�intt�fwht�ifwht�mobius_transform�inverse_mobius_transform)�MPZ�lcm)�iterable)�as_intNc � ����� t |� � ��dk rt d� � �|rdnd}|rdnd}t d� �|||fD � � � � dk rt d� � ���3t | |��� � ��s�n���fd �t �� � D � � S |rt
| |� � �ny|rt | |� � �nfd
� }d� || � � }|�A ||� � } | �4|| c\ }
}\ }}
||
z �t |
|� � ��dk r�fd��D � � ���t | ||� � ��s�n��fd�t �� � D � � S )
a�
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]
r z6The length for cyclic convolution must be non-negativeTNc 3 � K � | ]}|d uV � � d S �N� )�.0�xs �k/home/asafur/pinokio/api/open-webui.git/app/env/lib/python3.11/site-packages/sympy/discrete/convolutions.py� <genexpr>zconvolution.<locals>.<genexpr>Q s&