U
    ZÊ¹jI  ã                   @   s  d Z ddlmZmZ ddlmZ ddlmZmZm	Z	m
Z
 ddlmZ ddlmZmZ ddlmZ ddlmZmZ ed(d
d„ƒZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Z d"d#„ Z!G d$d%„ d%ƒZ"eG d&d'„ d'eƒƒZ#d	S ))z@Tools and arithmetics for monomials of distributed polynomials. é    )Úcombinations_with_replacementÚproduct)Údedent)ÚMulÚSÚTupleÚsympify)ÚExactQuotientFailed)ÚPicklableWithSlotsÚdict_from_expr)Úpublic)Úis_sequenceÚiterableNc                 #   s|  t | ƒ}tˆ ƒr~t ˆ ƒ|kr$tdƒ‚ˆdkr8dg| ‰n@tˆƒsJtdƒ‚n.t ˆƒ|kr^tdƒ‚tdd„ ˆD ƒƒrxtdƒ‚d}n:ˆ }|dk r’td	ƒ‚ˆdkr d}nˆdk r°td
ƒ‚ˆ}d}|�rø||krÊdS | rÖ|dkrâtjV  dS t| ƒtjg } tdd„ | D ƒƒ�r~g }t| |ƒD ]X}t	 
| d¡}	|D ] }
|
dk�r(|	|
  d7  < �q(t|	 ¡ ƒ|k�r| t|Ž ¡ �qt|ƒE dH  nxg }t| |d�D ]X}t	 
| d¡}	|D ] }
|
dk�r¢|	|
  d7  < �q¢t|	 ¡ ƒ|k�rŽ| t|Ž ¡ �qŽt|ƒE dH  n€t‡ ‡fdd„t|ƒD ƒƒ�rtdƒ‚g }t| ˆˆ ƒD ].\‰}}| ‡fdd„t||d ƒD ƒ¡ �q.t|Ž D ]}	t|	Ž V  �qfdS )a‚  
    ``max_degrees`` and ``min_degrees`` are either both integers or both lists.
    Unless otherwise specified, ``min_degrees`` is either ``0`` or
    ``[0, ..., 0]``.

    A generator of all monomials ``monom`` is returned, such that
    either
    ``min_degree <= total_degree(monom) <= max_degree``,
    or
    ``min_degrees[i] <= degree_list(monom)[i] <= max_degrees[i]``,
    for all ``i``.

    Case I. ``max_degrees`` and ``min_degrees`` are both integers
    =============================================================

    Given a set of variables $V$ and a min_degree $N$ and a max_degree $M$
    generate a set of monomials of degree less than or equal to $N$ and greater
    than or equal to $M$. The total number of monomials in commutative
    variables is huge and is given by the following formula if $M = 0$:

        .. math::
            \frac{(\#V + N)!}{\#V! N!}

    For example if we would like to generate a dense polynomial of
    a total degree $N = 50$ and $M = 0$, which is the worst case, in 5
    variables, assuming that exponents and all of coefficients are 32-bit long
    and stored in an array we would need almost 80 GiB of memory! Fortunately
    most polynomials, that we will encounter, are sparse.

    Consider monomials in commutative variables $x$ and $y$
    and non-commutative variables $a$ and $b$::

        >>> from sympy import symbols
        >>> from sympy.polys.monomials import itermonomials
        >>> from sympy.polys.orderings import monomial_key
        >>> from sympy.abc import x, y

        >>> sorted(itermonomials([x, y], 2), key=monomial_key('grlex', [y, x]))
        [1, x, y, x**2, x*y, y**2]

        >>> sorted(itermonomials([x, y], 3), key=monomial_key('grlex', [y, x]))
        [1, x, y, x**2, x*y, y**2, x**3, x**2*y, x*y**2, y**3]

        >>> a, b = symbols('a, b', commutative=False)
        >>> set(itermonomials([a, b, x], 2))
        {1, a, a**2, b, b**2, x, x**2, a*b, b*a, x*a, x*b}

        >>> sorted(itermonomials([x, y], 2, 1), key=monomial_key('grlex', [y, x]))
        [x, y, x**2, x*y, y**2]

    Case II. ``max_degrees`` and ``min_degrees`` are both lists
    ===========================================================

    If ``max_degrees = [d_1, ..., d_n]`` and
    ``min_degrees = [e_1, ..., e_n]``, the number of monomials generated
    is:

    .. math::
        (d_1 - e_1 + 1) (d_2 - e_2 + 1) \cdots (d_n - e_n + 1)

    Let us generate all monomials ``monom`` in variables $x$ and $y$
    such that ``[1, 2][i] <= degree_list(monom)[i] <= [2, 4][i]``,
    ``i = 0, 1`` ::

        >>> from sympy import symbols
        >>> from sympy.polys.monomials import itermonomials
        >>> from sympy.polys.orderings import monomial_key
        >>> from sympy.abc import x, y

        >>> sorted(itermonomials([x, y], [2, 4], [1, 2]), reverse=True, key=monomial_key('lex', [x, y]))
        [x**2*y**4, x**2*y**3, x**2*y**2, x*y**4, x*y**3, x*y**2]
    zArgument sizes do not matchNr   zmin_degrees is not a listc                 s   s   | ]}|d k V  qdS ©r   N© ©Ú.0Úir   r   úT/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/polys/monomials.pyÚ	<genexpr>b   s     z itermonomials.<locals>.<genexpr>z+min_degrees cannot contain negative numbersFzmax_degrees cannot be negativezmin_degrees cannot be negativeTc                 s   s   | ]}|j V  qd S ©N)Zis_commutative)r   Úvariabler   r   r   r   x   s     é   )Úrepeatc                 3   s   | ]}ˆ| ˆ | kV  qd S r   r   r   )Úmax_degreesÚmin_degreesr   r   r   �   s     z2min_degrees[i] must be <= max_degrees[i] for all ic                    s   g | ]}ˆ | ‘qS r   r   r   )Úvarr   r   Ú
<listcomp>‘   s     z!itermonomials.<locals>.<listcomp>)Úlenr   Ú
ValueErrorÚanyr   ZOneÚlistÚallr   ÚdictÚfromkeysÚsumÚvaluesÚappendr   Úsetr   ÚrangeÚzip)Ú	variablesr   r   ÚnZtotal_degreeZ
max_degreeZ
min_degreeZmonomials_list_commÚitemZpowersr   Zmonomials_list_non_commZpower_listsZmin_dZmax_dr   )r   r   r   r   Úitermonomials   sn    J


&r.   c                 C   s(   ddl m} || | ƒ|| ƒ ||ƒ S )aW  
    Computes the number of monomials.

    The number of monomials is given by the following formula:

    .. math::

        \frac{(\#V + N)!}{\#V! N!}

    where `N` is a total degree and `V` is a set of variables.

    Examples
    ========

    >>> from sympy.polys.monomials import itermonomials, monomial_count
    >>> from sympy.polys.orderings import monomial_key
    >>> from sympy.abc import x, y

    >>> monomial_count(2, 2)
    6

    >>> M = list(itermonomials([x, y], 2))

    >>> sorted(M, key=monomial_key('grlex', [y, x]))
    [1, x, y, x**2, x*y, y**2]
    >>> len(M)
    6

    r   )Ú	factorial)Z(sympy.functions.combinatorial.factorialsr/   )ÚVÚNr/   r   r   r   Úmonomial_count•   s    r2   c                 C   s   t dd„ t| |ƒD ƒƒS )a%  
    Multiplication of tuples representing monomials.

    Examples
    ========

    Lets multiply `x**3*y**4*z` with `x*y**2`::

        >>> from sympy.polys.monomials import monomial_mul

        >>> monomial_mul((3, 4, 1), (1, 2, 0))
        (4, 6, 1)

    which gives `x**4*y**5*z`.

    c                 S   s   g | ]\}}|| ‘qS r   r   ©r   ÚaÚbr   r   r   r   Ç   s     z monomial_mul.<locals>.<listcomp>©Útupler*   ©ÚAÚBr   r   r   Úmonomial_mul¶   s    r;   c                 C   s,   t | |ƒ}tdd„ |D ƒƒr$t|ƒS dS dS )aœ  
    Division of tuples representing monomials.

    Examples
    ========

    Lets divide `x**3*y**4*z` by `x*y**2`::

        >>> from sympy.polys.monomials import monomial_div

        >>> monomial_div((3, 4, 1), (1, 2, 0))
        (2, 2, 1)

    which gives `x**2*y**2*z`. However::

        >>> monomial_div((3, 4, 1), (1, 2, 2)) is None
        True

    `x*y**2*z**2` does not divide `x**3*y**4*z`.

    c                 s   s   | ]}|d kV  qdS r   r   )r   Úcr   r   r   r   á   s     zmonomial_div.<locals>.<genexpr>N)Úmonomial_ldivr"   r7   )r9   r:   ÚCr   r   r   Úmonomial_divÉ   s    
r?   c                 C   s   t dd„ t| |ƒD ƒƒS )a…  
    Division of tuples representing monomials.

    Examples
    ========

    Lets divide `x**3*y**4*z` by `x*y**2`::

        >>> from sympy.polys.monomials import monomial_ldiv

        >>> monomial_ldiv((3, 4, 1), (1, 2, 0))
        (2, 2, 1)

    which gives `x**2*y**2*z`.

        >>> monomial_ldiv((3, 4, 1), (1, 2, 2))
        (2, 2, -1)

    which gives `x**2*y**2*z**-1`.

    c                 S   s   g | ]\}}|| ‘qS r   r   r3   r   r   r   r   ü   s     z!monomial_ldiv.<locals>.<listcomp>r6   r8   r   r   r   r=   æ   s    r=   c                    s   t ‡ fdd„| D ƒƒS )z%Return the n-th pow of the monomial. c                    s   g | ]}|ˆ  ‘qS r   r   ©r   r4   ©r,   r   r   r      s     z monomial_pow.<locals>.<listcomp>)r7   )r9   r,   r   rA   r   Úmonomial_powþ   s    rB   c                 C   s   t dd„ t| |ƒD ƒƒS )a.  
    Greatest common divisor of tuples representing monomials.

    Examples
    ========

    Lets compute GCD of `x*y**4*z` and `x**3*y**2`::

        >>> from sympy.polys.monomials import monomial_gcd

        >>> monomial_gcd((1, 4, 1), (3, 2, 0))
        (1, 2, 0)

    which gives `x*y**2`.

    c                 S   s   g | ]\}}t ||ƒ‘qS r   )Úminr3   r   r   r   r     s     z monomial_gcd.<locals>.<listcomp>r6   r8   r   r   r   Úmonomial_gcd  s    rD   c                 C   s   t dd„ t| |ƒD ƒƒS )a1  
    Least common multiple of tuples representing monomials.

    Examples
    ========

    Lets compute LCM of `x*y**4*z` and `x**3*y**2`::

        >>> from sympy.polys.monomials import monomial_lcm

        >>> monomial_lcm((1, 4, 1), (3, 2, 0))
        (3, 4, 1)

    which gives `x**3*y**4*z`.

    c                 S   s   g | ]\}}t ||ƒ‘qS r   )Úmaxr3   r   r   r   r   &  s     z monomial_lcm.<locals>.<listcomp>r6   r8   r   r   r   Úmonomial_lcm  s    rF   c                 C   s   t dd„ t| |ƒD ƒƒS )zö
    Does there exist a monomial X such that XA == B?

    Examples
    ========

    >>> from sympy.polys.monomials import monomial_divides
    >>> monomial_divides((1, 2), (3, 4))
    True
    >>> monomial_divides((1, 2), (0, 2))
    False
    c                 s   s   | ]\}}||kV  qd S r   r   r3   r   r   r   r   5  s     z#monomial_divides.<locals>.<genexpr>)r"   r*   r8   r   r   r   Úmonomial_divides(  s    rG   c                  G   sJ   t | d ƒ}| dd… D ](}t|ƒD ]\}}t|| |ƒ||< q$qt|ƒS )a‘  
    Returns maximal degree for each variable in a set of monomials.

    Examples
    ========

    Consider monomials `x**3*y**4*z**5`, `y**5*z` and `x**6*y**3*z**9`.
    We wish to find out what is the maximal degree for each of `x`, `y`
    and `z` variables::

        >>> from sympy.polys.monomials import monomial_max

        >>> monomial_max((3,4,5), (0,5,1), (6,3,9))
        (6, 5, 9)

    r   r   N)r!   Ú	enumeraterE   r7   ©ZmonomsÚMr1   r   r,   r   r   r   Úmonomial_max7  s
    rK   c                  G   sJ   t | d ƒ}| dd… D ](}t|ƒD ]\}}t|| |ƒ||< q$qt|ƒS )a‘  
    Returns minimal degree for each variable in a set of monomials.

    Examples
    ========

    Consider monomials `x**3*y**4*z**5`, `y**5*z` and `x**6*y**3*z**9`.
    We wish to find out what is the minimal degree for each of `x`, `y`
    and `z` variables::

        >>> from sympy.polys.monomials import monomial_min

        >>> monomial_min((3,4,5), (0,5,1), (6,3,9))
        (0, 3, 1)

    r   r   N)r!   rH   rC   r7   rI   r   r   r   Úmonomial_minP  s
    rL   c                 C   s   t | ƒS )zÍ
    Returns the total degree of a monomial.

    Examples
    ========

    The total degree of `xy^2` is 3:

    >>> from sympy.polys.monomials import monomial_deg
    >>> monomial_deg((1, 2))
    3
    )r%   )rJ   r   r   r   Úmonomial_degi  s    rM   c                 C   sf   | \}}|\}}t ||ƒ}|jr>|dk	r8|| ||¡fS dS n$|dks^|| s^|| ||¡fS dS dS )z,Division of two terms in over a ring/field. N)r?   Zis_FieldZquo)r4   r5   ÚdomainZa_lmZa_lcZb_lmZb_lcÚmonomr   r   r   Úterm_divx  s    
rP   c                   @   s`   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ ZdS )ÚMonomialOpsz6Code generator of fast monomial arithmetic functions. c                 C   s
   || _ d S r   )Úngens)ÚselfrR   r   r   r   Ú__init__�  s    zMonomialOps.__init__c                 C   s   i }t ||ƒ || S r   )Úexec)rS   ÚcodeÚnameÚnsr   r   r   Ú_build�  s    
zMonomialOps._buildc                    s   ‡ fdd„t | jƒD ƒS )Nc                    s   g | ]}d ˆ |f ‘qS )z%s%sr   r   ©rW   r   r   r   –  s     z%MonomialOps._vars.<locals>.<listcomp>)r)   rR   )rS   rW   r   rZ   r   Ú_vars•  s    zMonomialOps._varsc                 C   sd   d}t dƒ}|  d¡}|  d¡}dd„ t||ƒD ƒ}||d |¡d |¡d |¡dœ }|  ||¡S )	Nr;   ús        def %(name)s(A, B):
            (%(A)s,) = A
            (%(B)s,) = B
            return (%(AB)s,)
        r4   r5   c                 S   s   g | ]\}}d ||f ‘qS )z%s + %sr   r3   r   r   r   r   ¢  s     z#MonomialOps.mul.<locals>.<listcomp>ú, ©rW   r9   r:   ÚAB©r   r[   r*   ÚjoinrY   ©rS   rW   Útemplater9   r:   r_   rV   r   r   r   Úmul˜  s    

$zMonomialOps.mulc                 C   sL   d}t dƒ}|  d¡}dd„ |D ƒ}||d |¡d |¡dœ }|  ||¡S )NrB   zZ        def %(name)s(A, k):
            (%(A)s,) = A
            return (%(Ak)s,)
        r4   c                 S   s   g | ]}d | ‘qS )z%s*kr   r@   r   r   r   r   ®  s     z#MonomialOps.pow.<locals>.<listcomp>r]   )rW   r9   ÚAk)r   r[   ra   rY   )rS   rW   rc   r9   re   rV   r   r   r   Úpow¦  s    
zMonomialOps.powc                 C   sd   d}t dƒ}|  d¡}|  d¡}dd„ t||ƒD ƒ}||d |¡d |¡d |¡dœ }|  ||¡S )	NZmonomial_mulpowzw        def %(name)s(A, B, k):
            (%(A)s,) = A
            (%(B)s,) = B
            return (%(ABk)s,)
        r4   r5   c                 S   s   g | ]\}}d ||f ‘qS )z	%s + %s*kr   r3   r   r   r   r   ¼  s     z&MonomialOps.mulpow.<locals>.<listcomp>r]   )rW   r9   r:   ÚABkr`   )rS   rW   rc   r9   r:   rg   rV   r   r   r   Úmulpow²  s    

$zMonomialOps.mulpowc                 C   sd   d}t dƒ}|  d¡}|  d¡}dd„ t||ƒD ƒ}||d |¡d |¡d |¡dœ }|  ||¡S )	Nr=   r\   r4   r5   c                 S   s   g | ]\}}d ||f ‘qS )z%s - %sr   r3   r   r   r   r   Ê  s     z$MonomialOps.ldiv.<locals>.<listcomp>r]   r^   r`   rb   r   r   r   ÚldivÀ  s    

$zMonomialOps.ldivc                 C   sv   d}t dƒ}|  d¡}|  d¡}dd„ t| jƒD ƒ}|  d¡}||d |¡d |¡d	 |¡d |¡d
œ }|  ||¡S )Nr?   z†        def %(name)s(A, B):
            (%(A)s,) = A
            (%(B)s,) = B
            %(RAB)s
            return (%(R)s,)
        r4   r5   c                 S   s   g | ]}d d|i ‘qS )z7r%(i)s = a%(i)s - b%(i)s
    if r%(i)s < 0: return Noner   r   r   r   r   r   r   Ù  s     z#MonomialOps.div.<locals>.<listcomp>Úrr]   z
    )rW   r9   r:   ÚRABÚR)r   r[   r)   rR   ra   rY   )rS   rW   rc   r9   r:   rk   rl   rV   r   r   r   ÚdivÎ  s    


,zMonomialOps.divc                 C   sd   d}t dƒ}|  d¡}|  d¡}dd„ t||ƒD ƒ}||d |¡d |¡d |¡dœ }|  ||¡S )	NrF   r\   r4   r5   c                 S   s    g | ]\}}d ||||f ‘qS )z%s if %s >= %s else %sr   r3   r   r   r   r   è  s     z#MonomialOps.lcm.<locals>.<listcomp>r]   r^   r`   rb   r   r   r   ÚlcmÞ  s    

$zMonomialOps.lcmc                 C   sd   d}t dƒ}|  d¡}|  d¡}dd„ t||ƒD ƒ}||d |¡d |¡d |¡dœ }|  ||¡S )	NrD   r\   r4   r5   c                 S   s    g | ]\}}d ||||f ‘qS )z%s if %s <= %s else %sr   r3   r   r   r   r   ö  s     z#MonomialOps.gcd.<locals>.<listcomp>r]   r^   r`   rb   r   r   r   Úgcdì  s    

$zMonomialOps.gcdN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rT   rY   r[   rd   rf   rh   ri   rm   rn   ro   r   r   r   r   rQ   Š  s   rQ   c                   @   s”   e Zd ZdZdZd"dd„Zd#dd„Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZeZdd„ Zdd„ Zd d!„ ZdS )$ÚMonomialz9Class representing a monomial, i.e. a product of powers. )Ú	exponentsÚgensNc                 C   sv   t |ƒs\tt|ƒ|d�\}}t|ƒdkrNt| ¡ ƒd dkrNt| ¡ ƒd }ntd |¡ƒ‚t	t
t|ƒƒ| _|| _d S )N)rv   r   r   zExpected a monomial got {})r   r   r   r   r!   r&   Úkeysr   Úformatr7   ÚmapÚintru   rv   )rS   rO   rv   Úrepr   r   r   rT      s     zMonomial.__init__c                 C   s   |   ||p| j¡S r   )Ú	__class__rv   )rS   ru   rv   r   r   r   Úrebuild  s    zMonomial.rebuildc                 C   s
   t | jƒS r   )r   ru   ©rS   r   r   r   Ú__len__  s    zMonomial.__len__c                 C   s
   t | jƒS r   )Úiterru   r~   r   r   r   Ú__iter__  s    zMonomial.__iter__c                 C   s
   | j | S r   )ru   )rS   r-   r   r   r   Ú__getitem__  s    zMonomial.__getitem__c                 C   s   t | jj| j| jfƒS r   )Úhashr|   rp   ru   rv   r~   r   r   r   Ú__hash__  s    zMonomial.__hash__c                 C   s:   | j r$d dd„ t| j | jƒD ƒ¡S d| jj| jf S d S )NÚ*c                 S   s   g | ]\}}d ||f ‘qS )z%s**%sr   ©r   ÚgenÚexpr   r   r   r     s     z$Monomial.__str__.<locals>.<listcomp>z%s(%s))rv   ra   r*   ru   r|   rp   r~   r   r   r   Ú__str__  s    zMonomial.__str__c                 G   s4   |p| j }|std|  ƒ‚tdd„ t|| jƒD ƒŽ S )z3Convert a monomial instance to a SymPy expression. z5Cannot convert %s to an expression without generatorsc                 S   s   g | ]\}}|| ‘qS r   r   r†   r   r   r   r   (  s     z$Monomial.as_expr.<locals>.<listcomp>)rv   r   r   r*   ru   )rS   rv   r   r   r   Úas_expr   s    
ÿzMonomial.as_exprc                 C   s4   t |tƒr|j}nt |ttfƒr&|}ndS | j|kS )NF)Ú
isinstancert   ru   r7   r   ©rS   Úotherru   r   r   r   Ú__eq__*  s    
zMonomial.__eq__c                 C   s
   | |k S r   r   )rS   r�   r   r   r   Ú__ne__4  s    zMonomial.__ne__c                 C   s<   t |tƒr|j}nt |ttfƒr&|}nt‚|  t| j|ƒ¡S r   )r‹   rt   ru   r7   r   ÚNotImplementedErrorr}   r;   rŒ   r   r   r   Ú__mul__7  s    
zMonomial.__mul__c                 C   sZ   t |tƒr|j}nt |ttfƒr&|}nt‚t| j|ƒ}|d k	rH|  |¡S t| t|ƒƒ‚d S r   )	r‹   rt   ru   r7   r   r�   r?   r}   r	   )rS   r�   ru   Úresultr   r   r   Ú__truediv__A  s    

zMonomial.__truediv__c                 C   s.   t |ƒ}|dk rtd| ƒ‚|  t| j|ƒ¡S )Nr   z'a non-negative integer expected, got %s)rz   r   r}   rB   ru   )rS   r�   r,   r   r   r   Ú__pow__R  s    zMonomial.__pow__c                 C   sD   t |tƒr|j}n t |ttfƒr&|}ntd| ƒ‚|  t| j|ƒ¡S )z&Greatest common divisor of monomials. ú.an instance of Monomial class expected, got %s)r‹   rt   ru   r7   r   Ú	TypeErrorr}   rD   rŒ   r   r   r   ro   X  s    
ÿzMonomial.gcdc                 C   sD   t |tƒr|j}n t |ttfƒr&|}ntd| ƒ‚|  t| j|ƒ¡S )z$Least common multiple of monomials. r•   )r‹   rt   ru   r7   r   r–   r}   rF   rŒ   r   r   r   rn   d  s    
ÿzMonomial.lcm)N)N)rp   rq   rr   rs   Ú	__slots__rT   r}   r   r�   r‚   r„   r‰   rŠ   rŽ   r�   r‘   r“   Ú__floordiv__r”   ro   rn   r   r   r   r   rt   ú  s$   




rt   )N)$rs   Ú	itertoolsr   r   Útextwrapr   Z
sympy.corer   r   r   r   Zsympy.polys.polyerrorsr	   Zsympy.polys.polyutilsr
   r   Zsympy.utilitiesr   Zsympy.utilities.iterablesr   r   r.   r2   r;   r?   r=   rB   rD   rF   rG   rK   rL   rM   rP   rQ   rt   r   r   r   r   Ú<module>   s2    !p