U
    ZÊ¹j  ã                   @   s”   d dl 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 d dlmZmZ d dlmZmZ d dlmZmZ dd	„ Zd
ddœdd„ZdS )é    )Úcombinations_with_replacement)ÚsymbolsÚAddÚDummy)ÚRational)ÚcancelÚComputationFailedÚparallel_poly_from_exprÚreducedÚPoly)ÚMonomialÚmonomial_div)ÚDomainErrorÚPolificationFailed)ÚdebugÚdebugfc                 C   s\   t | ƒ ¡ \}}zt||gddd�\}}W n tk
rF   ||  Y S X t|Ž t || ƒ S )z×
    Put an expression over a common denominator, cancel and reduce.

    Examples
    ========

    >>> from sympy import ratsimp
    >>> from sympy.abc import x, y
    >>> ratsimp(1/x + 1/y)
    (x + y)/(x*y)
    TF)ÚfieldÚexpand)r   Úas_numer_denomr
   r   r   )ÚexprÚfÚgÚQÚr© r   úU/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/simplify/ratsimp.pyÚratsimp	   s    r   TF)ÚquickÚ
polynomialc                   sþ  ddl m‰ td| ƒ t| ƒ ¡ \}}z t||gˆ  f|ž|Ž\}‰W n tk
r^   |  Y S X ˆj}	|	jrx|	 	¡ ˆ_nt
d|	 ƒ‚‡fdd„|dd… D ƒ‰tƒ ‰‡‡‡fd	d
„‰d‡ ‡‡‡‡‡‡fdd„	‰t|ˆ ˆjˆjd�d }t|ˆ ˆjˆjd�d }|�r||  ¡ S ˆt|ˆjˆjd�t|ˆjˆjd�g ƒ\}
}}ˆ�s®|�r®tdt|ƒƒ g }|D ]8\}}}}ˆ||ddd�}| | |¡| |¡f¡ �q`t|dd„ d�\}
}|	j�sâ|
jdd�\}}
|jdd�\}}t||ƒ}ntdƒ}|
|j ||j  S )aÚ  
    Simplifies a rational expression ``expr`` modulo the prime ideal
    generated by ``G``.  ``G`` should be a Groebner basis of the
    ideal.

    Examples
    ========

    >>> from sympy.simplify.ratsimp import ratsimpmodprime
    >>> from sympy.abc import x, y
    >>> eq = (x + y**5 + y)/(x - y)
    >>> ratsimpmodprime(eq, [x*y**5 - x - y], x, y, order='lex')
    (-x**2 - x*y - x - y)/(-x**2 + x*y)

    If ``polynomial`` is ``False``, the algorithm computes a rational
    simplification which minimizes the sum of the total degrees of
    the numerator and the denominator.

    If ``polynomial`` is ``True``, this function just brings numerator and
    denominator into a canonical form. This is much faster, but has
    potentially worse results.

    References
    ==========

    .. [1] M. Monagan, R. Pearce, Rational Simplification Modulo a Polynomial
        Ideal, https://dl.acm.org/doi/pdf/10.1145/1145768.1145809
        (specifically, the second algorithm)
    r   )ÚsolveÚratsimpmodprimez.Cannot compute rational simplification over %sc                    s   g | ]}|  ˆ j¡‘qS r   )ZLMÚorder)Ú.0r   ©Úoptr   r   Ú
<listcomp>S   s     z#ratsimpmodprime.<locals>.<listcomp>é   Nc                    s”   | dkrdgS g }t ttˆjƒƒ| ƒD ]N}dgtˆjƒ ‰ |D ]}ˆ |  d7  < q>t‡ fdd„ˆD ƒƒr&| ˆ ¡ q&‡fdd„|D ƒˆ| d ƒ S )z‹
        Compute all monomials with degree less than ``n`` that are
        not divisible by any element of ``leading_monomials``.
        r   é   c                 3   s   | ]}t ˆ |ƒd kV  qd S ©N)r   )r"   Zlmg©Úmr   r   Ú	<genexpr>b   s     z5ratsimpmodprime.<locals>.staircase.<locals>.<genexpr>c                    s   g | ]}t |ƒjˆ jŽ ‘qS r   )r   Zas_exprÚgens©r"   Úsr#   r   r   r%   f   s     z6ratsimpmodprime.<locals>.staircase.<locals>.<listcomp>)r   ÚrangeÚlenr,   ÚallÚappend)ÚnÚSÚmiÚi)Úleading_monomialsr$   Ú	staircaser)   r   r8   V   s    ÿz"ratsimpmodprime.<locals>.staircasec              
      s¢  | | }}d}|   ¡ |  ¡  }ˆr,|d }	n|}	|| |	k�rZ||fˆ
krN�qZˆ
 ||f¡ ˆ	|ƒ‰ˆ	|ƒ‰td||ˆˆfƒ tdtˆƒ td�‰ tdtˆƒ td�‰ˆ ˆ }
tt‡ ‡fdd„ttˆƒƒD ƒƒˆj	|
 ƒ}tt‡‡fd	d„ttˆƒƒD ƒƒˆj	|
 ƒ}t
| | ||  ˆˆj	|
 ˆjd
d�d }t|ˆj	d� ¡ }ˆ|ˆ ˆ d
d
d�}|�r@tdd„ | ¡ D ƒƒ�s@| |¡}| |¡}| tttˆ ˆ dgtˆ ƒtˆƒ  ƒƒƒ¡}| tttˆ ˆ dgtˆ ƒtˆƒ  ƒƒƒ¡}t|ˆj	ƒ}t|ˆj	ƒ}|dk�rtdƒ‚| |||ˆ ˆ f¡ || |k�rZ|d g}�qZ|d7 }|d7 }|d7 }q0|dk�r˜ˆ|||||| ƒ\}}}ˆ||||| |ƒ\}}}|||fS )ak  
        Computes a rational simplification of ``a/b`` which minimizes
        the sum of the total degrees of the numerator and the denominator.

        Explanation
        ===========

        The algorithm proceeds by looking at ``a * d - b * c`` modulo
        the ideal generated by ``G`` for some ``c`` and ``d`` with degree
        less than ``a`` and ``b`` respectively.
        The coefficients of ``c`` and ``d`` are indeterminates and thus
        the coefficients of the normalform of ``a * d - b * c`` are
        linear polynomials in these indeterminates.
        If these linear polynomials, considered as system of
        equations, have a nontrivial solution, then `\frac{a}{b}
        \equiv \frac{c}{d}` modulo the ideal generated by ``G``. So,
        by construction, the degree of ``c`` and ``d`` is less than
        the degree of ``a`` and ``b``, so a simpler representation
        has been found.
        After a simpler representation has been found, the algorithm
        tries to reduce the degree of the numerator and denominator
        and returns the result afterwards.

        As an extension, if quick=False, we look at all possible degrees such
        that the total degree is less than *or equal to* the best current
        solution. We retain a list of all solutions of minimal degree, and try
        to find the best one at the end.
        r   r'   z%s / %s: %s, %szc:%d)Úclszd:%dc                 3   s   | ]}ˆ | ˆ|  V  qd S r(   r   ©r"   r6   )ÚCsÚM1r   r   r+   ›   s     z<ratsimpmodprime.<locals>._ratsimpmodprime.<locals>.<genexpr>c                 3   s   | ]}ˆ | ˆ|  V  qd S r(   r   r:   )ÚDsÚM2r   r   r+   �   s     T)r!   Úpolys)r,   ©Z
particularr   c                 s   s   | ]}|d kV  qdS )r   Nr   r-   r   r   r   r+   ¥   s     zIdeal not prime?éÿÿÿÿ)Ztotal_degreeÚaddr   r   r0   r   r   Úsumr/   r,   r
   r!   Zcoeffsr1   ÚvaluesÚsubsÚdictÚlistÚzipÚ
ValueErrorr2   )ÚaÚbÚallsolÚNÚDÚcÚdZstepsZmaxdegÚboundÚngÚc_hatÚd_hatr   r4   Úsol)ÚGÚ_ratsimpmodprimer$   r   r   r8   Útested)r;   r=   r<   r>   r   rW   h   sh    

 ÿ ÿ ÿÿ

..



z)ratsimpmodprime.<locals>._ratsimpmodprime)r!   r'   )Údomainz*Looking for best minimal solution. Got: %sTFr@   c                 S   s    t | d  ¡ ƒt | d  ¡ ƒ S )Nr   r'   )r0   Zterms)Úxr   r   r   Ú<lambda>Õ   ó    z!ratsimpmodprime.<locals>.<lambda>)Úkey)Úconvert)r   r   )Zsympy.solvers.solversr   r   r   r   r	   r   rY   Zhas_assoc_FieldÚ	get_fieldr   Úsetr
   r,   r!   r   r   r0   r2   rE   ÚminZis_FieldZclear_denomsr   ÚqÚp)r   rV   r   r   r,   ÚargsÚnumÚdenomr?   rY   rO   rP   rL   ZnewsolrS   rT   r4   rR   rU   ZcnÚdnr   r   )rV   rW   r7   r$   r   r   r8   rX   r   r       sN    
 
ÿ^  ÿ
r    N)Ú	itertoolsr   Z
sympy.corer   r   r   Zsympy.core.numbersr   Zsympy.polysr   r   r	   r
   r   Zsympy.polys.monomialsr   r   Zsympy.polys.polyerrorsr   r   Zsympy.utilities.miscr   r   r   r    r   r   r   r   Ú<module>   s   