o
    3IhH                     @   s  d Z ddlmZmZ ddl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)cacheit)MulSTuplesympify)ExactQuotientFailed)PicklableWithSlotsdict_from_expr)public)is_sequenceiterableNc                 #   s   t  r{t| }t |krtddu rdg| nt s%tdt|kr/tdtdd D r<tdt fddt|D rNtd	g }t|  D ]\}}|fd
dt||d D  qVt| D ]}t| V  qqdS  }|dk rtddu rd}	n
dk rtd}	|	|krdS | r|dkrt	j
V  dS t| t	j
g } tdd | D rt| |}
nt| |d}
t }||	 }|
D ]}d}|D ]}|dkr|d7 }||k r nq|t|  q|E dH  d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   U/home/air/sanwanet/gpt-api/venv/lib/python3.10/site-packages/sympy/polys/monomials.py	<genexpr>c       z itermonomials.<locals>.<genexpr>z+min_degrees cannot contain negative numbersc                 3   s     | ]}|  | kV  qd S Nr   r   )max_degreesmin_degreesr   r   r   e   s    z2min_degrees[i] must be <= max_degrees[i] for all ic                    s   g | ]} | qS r   r   r   )varr   r   
<listcomp>i       z!itermonomials.<locals>.<listcomp>   zmax_degrees cannot be negativezmin_degrees cannot be negativec                 s   s    | ]}|j V  qd S r   )is_commutative)r   variabler   r   r   r   }   s    )repeat)r   len
ValueErroranyrangezipappendr   r   r   Onelistallr   setadd)	variablesr   r   npower_listsmin_dmax_dpowers
max_degree
min_degreeitmonomials_setditemcountr    r   )r   r   r   r   itermonomials   sf   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)(sympy.functions.combinatorial.factorialsr;   )VNr;   r   r   r   monomial_count   s   r?   c                 C      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          z monomial_mul.<locals>.<listcomp>tupler&   ABr   r   r   monomial_mul      rJ   c                 C   s(   t | |}tdd |D rt|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      r   zmonomial_div.<locals>.<genexpr>N)monomial_ldivr*   rF   )rH   rI   Cr   r   r   monomial_div   s   
rO   c                 C   r@   )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   rA   r   r   r   r      rD   z!monomial_ldiv.<locals>.<listcomp>rE   rG   r   r   r   rM      s   rM   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   rB   r.   r   r   r      r   z monomial_pow.<locals>.<listcomp>)rF   )rH   r.   r   rQ   r   monomial_pow   s   rR   c                 C   r@   )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      g | ]	\}}t ||qS r   )minrA   r   r   r   r         z monomial_gcd.<locals>.<listcomp>rE   rG   r   r   r   monomial_gcd   rK   rV   c                 C   r@   )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   rS   r   )maxrA   r   r   r   r     rU   z monomial_lcm.<locals>.<listcomp>rE   rG   r   r   r   monomial_lcm  rK   rX   c                 C   r@   )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   rA   r   r   r   r   .  s    z#monomial_divides.<locals>.<genexpr>)r*   r&   rG   r   r   r   monomial_divides!  s   rY   c                  G   J   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)   	enumeraterW   rF   monomsMr>   r   r.   r   r   r   monomial_max0     r_   c                  G   rZ   )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)   r[   rT   rF   r\   r   r   r   monomial_minI  r`   ra   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
    )sum)r^   r   r   r   monomial_degb  s   rc   c                 C   s`   | \}}|\}}t ||}|jr|dur||||fS dS |du s.|| s.||||fS dS )z,Division of two terms in over a ring/field. N)rO   is_Fieldquo)rB   rC   domaina_lma_lcb_lmb_lcmonomr   r   r   term_divq  s   
rl   c                       s   e Zd ZdZe fddZdd Zdd Zdd	 Zed
d Z	edd Z
edd Zedd Zedd Zedd Zedd Z  ZS )MonomialOpsz6Code generator of fast monomial arithmetic functions. c                    s   t  | }||_|S r   )super__new__ngens)clsrp   obj	__class__r   r   ro     s   zMonomialOps.__new__c                 C   s   | j fS r   )rp   selfr   r   r   __getnewargs__  s   zMonomialOps.__getnewargs__c                 C   s   i }t || || S r   )exec)rv   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   rz   r   r   r     rD   z%MonomialOps._vars.<locals>.<listcomp>)r%   rp   )rv   rz   r   r}   r   _vars  s   zMonomialOps._varsc                 C   d   d}t d}| d}| d}dd t||D }||d|d|d|d }| ||S )	NrJ   s        def %(name)s(A, B):
            (%(A)s,) = A
            (%(B)s,) = B
            return (%(AB)s,)
        rB   rC   c                 S      g | ]
\}}d ||f qS )z%s + %sr   rA   r   r   r   r         z#MonomialOps.mul.<locals>.<listcomp>, rz   rH   rI   ABr   r~   r&   joinr|   rv   rz   templaterH   rI   r   ry   r   r   r   mul     

$zMonomialOps.mulc                 C   sL   d}t d}| d}dd |D }||d|d|d }| ||S )NrR   zZ        def %(name)s(A, k):
            (%(A)s,) = A
            return (%(Ak)s,)
        rB   c                 S   s   g | ]}d | qS )z%s*kr   rP   r   r   r   r     r   z#MonomialOps.pow.<locals>.<listcomp>r   )rz   rH   Ak)r   r~   r   r|   )rv   rz   r   rH   r   ry   r   r   r   pow  s   
zMonomialOps.powc                 C   r   )	Nmonomial_mulpowzw        def %(name)s(A, B, k):
            (%(A)s,) = A
            (%(B)s,) = B
            return (%(ABk)s,)
        rB   rC   c                 S   r   )z	%s + %s*kr   rA   r   r   r   r     r   z&MonomialOps.mulpow.<locals>.<listcomp>r   )rz   rH   rI   ABkr   )rv   rz   r   rH   rI   r   ry   r   r   r   mulpow  r   zMonomialOps.mulpowc                 C   r   )	NrM   r   rB   rC   c                 S   r   )z%s - %sr   rA   r   r   r   r     r   z$MonomialOps.ldiv.<locals>.<listcomp>r   r   r   r   r   r   r   ldiv  r   zMonomialOps.ldivc                 C   sv   d}t d}| d}| d}dd t| jD }| d}||d|d|d	|d|d
 }| ||S )NrO   z        def %(name)s(A, B):
            (%(A)s,) = A
            (%(B)s,) = B
            %(RAB)s
            return (%(R)s,)
        rB   rC   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     rD   z#MonomialOps.div.<locals>.<listcomp>rr   z
    )rz   rH   rI   RABR)r   r~   r%   rp   r   r|   )rv   rz   r   rH   rI   r   r   ry   r   r   r   div  s   


,zMonomialOps.divc                 C   r   )	NrX   r   rB   rC   c                 S       g | ]\}}d ||||f qS )z%s if %s >= %s else %sr   rA   r   r   r   r          z#MonomialOps.lcm.<locals>.<listcomp>r   r   r   r   r   r   r   lcm  r   zMonomialOps.lcmc                 C   r   )	NrV   r   rB   rC   c                 S   r   )z%s if %s <= %s else %sr   rA   r   r   r   r     r   z#MonomialOps.gcd.<locals>.<listcomp>r   r   r   r   r   r   r   gcd  r   zMonomialOps.gcd)__name__
__module____qualname____doc__r   ro   rw   r|   r~   r   r   r   r   r   r   r   __classcell__r   r   rs   r   rm     s*    





rm   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r't| d dkr't| d }ntd|t	t
t|| _|| _d S )N)r   r   r   zExpected a monomial got {})r   r   r	   r"   r)   valueskeysr#   formatrF   mapintr   r   )rv   rk   r   repr   r   r   __init__  s    
zMonomial.__init__c                 C   s   |  ||p| jS r   )rt   r   )rv   r   r   r   r   r   rebuild  s   zMonomial.rebuildc                 C   
   t | jS r   )r"   r   ru   r   r   r   __len__     
zMonomial.__len__c                 C   r   r   )iterr   ru   r   r   r   __iter__  r   zMonomial.__iter__c                 C   s
   | j | S r   )r   )rv   r8   r   r   r   __getitem__  r   zMonomial.__getitem__c                 C   s   t | jj| j| jfS r   )hashrt   r   r   r   ru   r   r   r   __hash__  s   zMonomial.__hash__c                 C   s6   | j rddd t| j | jD S d| jj| jf S )N*c                 S   r   )z%s**%sr   r   genexpr   r   r   r   "  r   z$Monomial.__str__.<locals>.<listcomp>z%s(%s))r   r   r&   r   rt   r   ru   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   .  rD   z$Monomial.as_expr.<locals>.<listcomp>)r   r#   r   r&   r   )rv   r   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)
isinstancer   r   rF   r   rv   otherr   r   r   r   __eq__0  s   

zMonomial.__eq__c                 C   s
   | |k S r   r   )rv   r   r   r   r   __ne__:  r   zMonomial.__ne__c                 C   s<   t |tr	|j}nt |ttfr|}nt| t| j|S r   )r   r   r   rF   r   NotImplementedErrorr   rJ   r   r   r   r   __mul__=  s   
zMonomial.__mul__c                 C   sV   t |tr	|j}nt |ttfr|}ntt| j|}|d ur$| |S t| t|r   )	r   r   r   rF   r   r   rO   r   r
   )rv   r   r   resultr   r   r   __truediv__G  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)r   r#   r   rR   r   )rv   r   r.   r   r   r   __pow__X  s   zMonomial.__pow__c                 C   D   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   r   r   rF   r   	TypeErrorr   rV   r   r   r   r   r   ^     
zMonomial.gcdc                 C   r   )z$Least common multiple of monomials. r   )r   r   r   rF   r   r   r   rX   r   r   r   r   r   j  r   zMonomial.lcmr   )r   r   r   r   	__slots__r   r   r   r   r   r   r   r   r   r   r   r   __floordiv__r   r   r   r   r   r   r   r      s&    




r   r   )&r   	itertoolsr   r   textwrapr   sympy.core.cacher   
sympy.corer   r   r   r	   sympy.polys.polyerrorsr
   sympy.polys.polyutilsr   r   sympy.utilitiesr   sympy.utilities.iterablesr   r   r:   r?   rJ   rO   rM   rR   rV   rX   rY   r_   ra   rc   rl   rm   r   r   r   r   r   <module>   s4    !}