B
    [O                 @   s  d Z ddlmZmZ ddlmZmZmZmZm	Z	m
Z
 ddlmZmZmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZ ddlmZ ddl m!Z! ddl"m#Z# ddl$m%Z% ddl&m'Z' ddl(m)Z) ddl*m+Z+ ddl,m-Z- ddl.m/Z/ ddl0m1Z1 ddl2m3Z3 ddl4m5Z5 e3e!fddZ6e3e!fddZ7e3e!fddZ8e3dd Z9i Z:G d d! d!e1Z;G d"d# d#e)e1eZ<d$S )%z!Sparse rational function fields.     )print_functiondivision)addmulltlegtge)is_sequencereducestring_types)Expr)Mod)Exp1)S)Symbol)CantSympifysympify)ExpBase)PolyElement)lex)CoercionFailed)build_options)_parallel_dict_from_expr)DomainElement)PolynomialRing)FractionField)construct_domain)DefaultPrinting)public)pollutec             C   s   t | ||}|f|j S )zFConstruct new rational function field returning (field, x1, ..., xn). )	FracFieldgens)symbolsdomainorder_field r'   1lib/python3.7/site-packages/sympy/polys/fields.pyfield   s    r)   c             C   s   t | ||}||jfS )zHConstruct new rational function field returning (field, (x1, ..., xn)). )r!   r"   )r#   r$   r%   r&   r'   r'   r(   xfield"   s    r*   c             C   s(   t | ||}tdd |jD |j |S )zSConstruct new rational function field and inject generators into global namespace. c             S   s   g | ]
}|j qS r'   )name).0Zsymr'   r'   r(   
<listcomp>,   s    zvfield.<locals>.<listcomp>)r!   r    r#   r"   )r#   r$   r%   r&   r'   r'   r(   vfield(   s    r.   c          	   O   s   d}t | s| gd } }ttt| } t||}g }x| D ]}||  q:W t||\}}|jdkrt	dd |D g }t
||d\|_}	t|j|j|j}
g }x6tdt|dD ]"}||
t|||d   qW |r|
|d fS |
|fS dS )	a  Construct a field deriving generators and domain
    from options and input expressions.

    Parameters
    ----------
    exprs : :class:`Expr` or sequence of :class:`Expr` (sympifiable)
    symbols : sequence of :class:`Symbol`/:class:`Expr`
    options : keyword arguments understood by :class:`Options`

    Examples
    ========

    >>> from sympy.core import symbols
    >>> from sympy.functions import exp, log
    >>> from sympy.polys.fields import sfield

    >>> x = symbols("x")
    >>> K, f = sfield((x*log(x) + 4*x**2)*exp(1/x + log(x)/3)/x**2)
    >>> K
    Rational function field in x, exp(1/x), log(x), x**(1/3) over ZZ with lex order
    >>> f
    (4*x**2*(exp(1/x)) + x*(exp(1/x))*(log(x)))/((x**(1/3))**5)
    FTNc             S   s   g | ]}t | qS r'   )listvalues)r,   Zrepr'   r'   r(   r-   V   s    zsfield.<locals>.<listcomp>)optr      )r
   r/   mapr   r   extendZas_numer_denomr   r$   sumr   r!   r"   r%   rangelenappendtuple)Zexprsr#   ZoptionsZsingler1   ZnumdensexprZrepsZcoeffs_r&   Zfracsir'   r'   r(   sfield/   s&    


"r=   c               @   s   e Zd ZdZefddZdd Zdd Zdd	 Zd
d Z	dd Z
d!ddZd"ddZdd Zdd Zdd ZeZdd Zdd Zdd Zdd  ZdS )#r!   z2Multivariate distributed rational function field. c             C   s  ddl m} ||||}|j}|j}|j}|j}| j||||f}t|}|d krt	
| }||_t||_||_tdtfd|i|_||_||_||_||_||j|_||j|_| |_x@t|j|jD ].\}	}
t|	tr|	j}t||st|||
 qW |t|< |S )Nr   )PolyRingFracElementr)   )sympy.polys.ringsr>   r#   ngensr$   r%   __name___field_cachegetobject__new___hash_tuplehash_hashringtyper?   dtypezeroone_gensr"   zip
isinstancer   r+   hasattrsetattr)clsr#   r$   r%   r>   rJ   rA   rG   objZsymbol	generatorr+   r'   r'   r(   rF   h   s8    






zFracField.__new__c                s   t  fdd jjD S )z(Return a list of polynomial generators. c                s   g | ]}  |qS r'   )rL   )r,   gen)selfr'   r(   r-      s    z#FracField._gens.<locals>.<listcomp>)r9   rJ   r"   )rX   r'   )rX   r(   rO      s    zFracField._gensc             C   s   | j | j| jfS )N)r#   r$   r%   )rX   r'   r'   r(   __getnewargs__   s    zFracField.__getnewargs__c             C   s   | j S )N)rI   )rX   r'   r'   r(   __hash__   s    zFracField.__hash__c             C   s2   t |to0| j| j| j| jf|j|j|j|jfkS )N)rQ   r!   r#   rA   r$   r%   )rX   otherr'   r'   r(   __eq__   s    
zFracField.__eq__c             C   s
   | |k S )Nr'   )rX   r[   r'   r'   r(   __ne__   s    zFracField.__ne__Nc             C   s   |  ||S )N)rL   )rX   numerdenomr'   r'   r(   raw_new   s    zFracField.raw_newc             C   s*   |d kr| j j}||\}}| ||S )N)rJ   rN   cancelr`   )rX   r^   r_   r'   r'   r(   new   s     zFracField.newc             C   s   | j |S )N)r$   convert)rX   elementr'   r'   r(   
domain_new   s    zFracField.domain_newc             C   s   y|  | j|S  tk
r~   | j}|jsx|jrx| j}| }||}||	|}||
|}| ||S  Y nX d S )N)rb   rJ   
ground_newr   r$   is_Fieldhas_assoc_Field	get_fieldrc   r^   r_   r`   )rX   rd   r$   rJ   ground_fieldr^   r_   r'   r'   r(   rf      s    
zFracField.ground_newc             C   s   t |tr"| |jkr|S tdnt |tr\| \}}|| j}| j|}| 	||S t |t
rt|dkrtt| jj|\}}| ||S t |trtdnt |tr| |S | |S d S )NZ
conversionr2   Zparsing)rQ   r?   r)   NotImplementedErrorr   Zclear_denomsset_ringrJ   rf   r`   r9   r7   r/   r3   Zring_newrb   r   r   	from_expr)rX   rd   r_   r^   r'   r'   r(   	field_new   s"    







zFracField.field_newc                s:   | j tdd  D  fdd  t|S )Nc             s   s*   | ]"}|j st|tr|| fV  qd S )N)is_PowrQ   r   as_base_exp)r,   rW   r'   r'   r(   	<genexpr>   s    z*FracField._rebuild_expr.<locals>.<genexpr>c                s   | }|d k	r|S | jr2tttt | jS | jrNtttt | jS | j	sbt
| ttfr|  \}}x@D ]8\}\}}||krtt||dkrt |t||  S qtW |jr|tjk	rЈ |t| S y
| S  tk
r   js
jr
 | S  Y nX d S )Nr   )rD   Zis_Addr   r   r/   r3   argsZis_Mulr   ro   rQ   r   r   rp   r   intZ
is_Integerr   ZOnerc   r   rg   rh   ri   )r:   rV   berW   ZbgZeg)_rebuildr$   mappingpowersr'   r(   rv      s(    

z)FracField._rebuild_expr.<locals>._rebuild)r$   r9   keysr   )rX   r:   rw   r'   )rv   r$   rw   rx   r(   _rebuild_expr   s    zFracField._rebuild_exprc             C   sZ   t tt| j| j}y| ||}W n$ tk
rJ   td| |f Y nX | |S d S )NzGexpected an expression convertible to a rational function in %s, got %s)	dictr/   rP   r#   r"   rz   r   
ValueErrorrn   )rX   r:   rw   Zfracr'   r'   r(   rm      s    zFracField.from_exprc             C   s   t | S )N)r   )rX   r'   r'   r(   	to_domain   s    zFracField.to_domainc             C   s   ddl m} || j| j| jS )Nr   )r>   )r@   r>   r#   r$   r%   )rX   r>   r'   r'   r(   to_ring   s    zFracField.to_ring)N)N)rB   
__module____qualname____doc__r   rF   rO   rY   rZ   r\   r]   r`   rb   re   rf   rn   __call__rz   rm   r}   r~   r'   r'   r'   r(   r!   e   s"   &

!
r!   c               @   sH  e Zd ZdZdKddZdd Zdd Zd	d
 Zdd Zd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e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/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Z d9d: Z!d;d< Z"e"Z#d=d> Z$e$Z%d?d@ Z&dAdB Z'dCdD Z(dLdEdFZ)dMdGdHZ*dNdIdJZ+dS )Or?   z=Element of multivariate distributed rational function field. Nc             C   s0   |d kr| j jj}n|s td|| _|| _d S )Nzzero denominator)r)   rJ   rN   ZeroDivisionErrorr^   r_   )rX   r^   r_   r'   r'   r(   __init__  s    zFracElement.__init__c             C   s   |  ||S )N)	__class__)fr^   r_   r'   r'   r(   r`     s    zFracElement.raw_newc             C   s   | j || S )N)r`   ra   )r   r^   r_   r'   r'   r(   rb     s    zFracElement.newc             C   s   | j dkrtd| jS )N   zf.denom should be 1)r_   r|   r^   )r   r'   r'   r(   to_poly  s    
zFracElement.to_polyc             C   s
   | j  S )N)r)   r}   )rX   r'   r'   r(   parent  s    zFracElement.parentc             C   s   | j | j| jfS )N)r)   r^   r_   )rX   r'   r'   r(   rY     s    zFracElement.__getnewargs__c             C   s,   | j }|d kr(t| j| j| jf | _ }|S )N)rI   rH   r)   r^   r_   )rX   rI   r'   r'   r(   rZ   !  s    zFracElement.__hash__c             C   s   |  | j | j S )N)r`   r^   copyr_   )rX   r'   r'   r(   r   '  s    zFracElement.copyc             C   s<   | j |kr| S |j}| j|}| j|}|||S d S )N)r)   rJ   r^   rl   r_   rb   )rX   Z	new_fieldZnew_ringr^   r_   r'   r'   r(   	set_field*  s    
zFracElement.set_fieldc             G   s   | j j| | jj|  S )N)r^   as_exprr_   )rX   r#   r'   r'   r(   r   3  s    zFracElement.as_exprc             C   sL   t |tr.| j|jkr.| j|jko,| j|jkS | j|koF| j| jjjkS d S )N)rQ   r?   r)   r^   r_   rJ   rN   )r   gr'   r'   r(   r\   6  s    zFracElement.__eq__c             C   s
   | |k S )Nr'   )r   r   r'   r'   r(   r]   <  s    zFracElement.__ne__c             C   s
   t | jS )N)boolr^   )r   r'   r'   r(   __nonzero__?  s    zFracElement.__nonzero__c             C   s   | j  | j fS )N)r_   sort_keyr^   )rX   r'   r'   r(   r   D  s    zFracElement.sort_keyc             C   s(   t || jjr ||  | S tS d S )N)rQ   r)   rL   r   NotImplemented)f1f2opr'   r'   r(   _cmpG  s    zFracElement._cmpc             C   s   |  |tS )N)r   r   )r   r   r'   r'   r(   __lt__M  s    zFracElement.__lt__c             C   s   |  |tS )N)r   r   )r   r   r'   r'   r(   __le__O  s    zFracElement.__le__c             C   s   |  |tS )N)r   r   )r   r   r'   r'   r(   __gt__Q  s    zFracElement.__gt__c             C   s   |  |tS )N)r   r	   )r   r   r'   r'   r(   __ge__S  s    zFracElement.__ge__c             C   s   |  | j| jS )z"Negate all coefficients in ``f``. )r`   r^   r_   )r   r'   r'   r(   __pos__V  s    zFracElement.__pos__c             C   s   |  | j | jS )z"Negate all coefficients in ``f``. )r`   r^   r_   )r   r'   r'   r(   __neg__Z  s    zFracElement.__neg__c             C   s   | j j}y||}W nb tk
rx   |jst|jrt| }y||}W n tk
r\   Y nX d||||fS dS X d|d fS d S )N)r   NNr   )	r)   r$   rc   r   rg   rh   ri   r^   r_   )rX   rd   r$   rj   r'   r'   r(   _extract_ground^  s    zFracElement._extract_groundc             C   s(  | j }|s| S | s|S t||jrn| j|jkrD| | j|j | jS | | j|j | j|j  | j|j S nt||jjr| | j| j|  | jS t|trt|jt	r|jj |j krn*t|j jt	r|j jj |kr|
| S tS n6t|trt|jtr|jj|jkrn
|
| S | 
|S )z(Add rational functions ``f`` and ``g``. )r)   rQ   rL   r_   rb   r^   rJ   r?   r$   r   __radd__r   r   r   )r   r   r)   r'   r'   r(   __add__r  s,    *


zFracElement.__add__c             C   s   t || jjjr*| | j| j|  | jS | |\}}}|dkr\| | j| j|  | jS |sdtS | | j| | j|  | j| S d S )Nr   )	rQ   r)   rJ   rL   rb   r^   r_   r   r   )r   cr   g_numerg_denomr'   r'   r(   r     s    zFracElement.__radd__c             C   s  | j }|s| S | s| S t||jrp| j|jkrF| | j|j | jS | | j|j | j|j  | j|j S nt||jjr| | j| j|  | jS t|trt|jt	r|jj |j krn*t|j jt	r|j jj |kr|
| S tS n6t|tr t|jtr|jj|jkrn
|
| S | |\}}}|dkrT| | j| j|  | jS |s^tS | | j| | j|  | j| S dS )z-Subtract rational functions ``f`` and ``g``. r   N)r)   rQ   rL   r_   rb   r^   rJ   r?   r$   r   __rsub__r   r   r   r   )r   r   r)   r   r   r   r'   r'   r(   __sub__  s6    *



zFracElement.__sub__c             C   s   t || jjjr,| | j | j|  | jS | |\}}}|dkr`| | j | j|  | jS |shtS | | j | | j|  | j| S d S )Nr   )	rQ   r)   rJ   rL   rb   r^   r_   r   r   )r   r   r   r   r   r'   r'   r(   r     s    zFracElement.__rsub__c             C   s   | j }| r|s|jS t||jr<| | j|j | j|j S t||jjr^| | j| | jS t|trt|j	t
r|j	j |j krqt|j j	t
r|j j	j |kr|| S tS n0t|trt|j	tr|j	j|jkrn
|| S | |S )z-Multiply rational functions ``f`` and ``g``. )r)   rM   rQ   rL   rb   r^   r_   rJ   r?   r$   r   __rmul__r   r   r   )r   r   r)   r'   r'   r(   __mul__  s$    



zFracElement.__mul__c             C   st   t || jjjr$| | j| | jS | |\}}}|dkrP| | j| | jS |sXtS | | j| | j| S d S )Nr   )	rQ   r)   rJ   rL   rb   r^   r_   r   r   )r   r   r   r   r   r'   r'   r(   r     s    zFracElement.__rmul__c             C   s0  | j }|stnt||jr8| | j|j | j|j S t||jjrZ| | j| j| S t|trt|j	t
r|j	j |j krqt|j j	t
r|j j	j |kr|| S tS n0t|trt|j	tr|j	j|jkrn
|| S | |\}}}|dkr
| | j| j| S |stS | | j| | j| S dS )z0Computes quotient of fractions ``f`` and ``g``. r   N)r)   r   rQ   rL   rb   r^   r_   rJ   r?   r$   r   __rtruediv__r   r   r   r   )r   r   r)   r   r   r   r'   r'   r(   __truediv__  s.    




zFracElement.__truediv__c             C   s~   | s
t n$t|| jjjr.| | j| | jS | |\}}}|dkrZ| | j| | jS |sbt	S | | j| | j| S d S )Nr   )
r   rQ   r)   rJ   rL   rb   r_   r^   r   r   )r   r   r   r   r   r'   r'   r(   r     s    zFracElement.__rtruediv__c             C   sJ   |dkr |  | j| | j| S | s*tn|  | j|  | j|  S dS )z+Raise ``f`` to a non-negative power ``n``. r   N)r`   r^   r_   r   )r   nr'   r'   r(   __pow__,  s
    zFracElement.__pow__c             C   s:   |  }| | j|| j | j| j|  | jd S )a  Computes partial derivative in ``x``.

        Examples
        ========

        >>> from sympy.polys.fields import field
        >>> from sympy.polys.domains import ZZ

        >>> _, x, y, z = field("x,y,z", ZZ)
        >>> ((x**2 + y)/(z + 1)).diff(x)
        2*x/(z + 1)

        r2   )r   rb   r^   diffr_   )r   xr'   r'   r(   r   5  s    zFracElement.diffc             G   sT   dt |  k r| jjkr8n n| tt| jj|S td| jjt |f d S )Nr   z1expected at least 1 and at most %s values, got %s)r7   r)   rA   evaluater/   rP   r"   r|   )r   r0   r'   r'   r(   r   F  s     zFracElement.__call__c             C   sx   t |tr<|d kr<dd |D }| j|| j| }}n&| }| j||| j|| }}|j }|||S )Nc             S   s   g | ]\}}|  |fqS r'   )r   )r,   Xar'   r'   r(   r-   N  s    z(FracElement.evaluate.<locals>.<listcomp>)	rQ   r/   r^   r   r_   r   rJ   Zto_fieldrb   )r   r   r   r^   r_   r)   r'   r'   r(   r   L  s    
zFracElement.evaluatec             C   sn   t |tr<|d kr<dd |D }| j|| j| }}n&| }| j||| j|| }}| ||S )Nc             S   s   g | ]\}}|  |fqS r'   )r   )r,   r   r   r'   r'   r(   r-   Y  s    z$FracElement.subs.<locals>.<listcomp>)rQ   r/   r^   subsr_   r   rb   )r   r   r   r^   r_   r'   r'   r(   r   W  s    zFracElement.subsc             C   s   t d S )N)rk   )r   r   r   r'   r'   r(   composea  s    zFracElement.compose)N)N)N)N),rB   r   r   r   r   r`   rb   r   r   rY   rI   rZ   r   r   r   r\   r]   r   __bool__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Z__div__r   Z__rdiv__r   r   r   r   r   r   r'   r'   r'   r(   r?     sR   
		&!	


r?   N)=r   Z
__future__r   r   operatorr   r   r   r   r   r	   Zsympy.core.compatibilityr
   r   r   Zsympy.core.exprr   Zsympy.core.modr   Zsympy.core.numbersr   Zsympy.core.singletonr   Zsympy.core.symbolr   Zsympy.core.sympifyr   r   Z&sympy.functions.elementary.exponentialr   r@   r   Zsympy.polys.orderingsr   Zsympy.polys.polyerrorsr   Zsympy.polys.polyoptionsr   Zsympy.polys.polyutilsr   Z!sympy.polys.domains.domainelementr   Z"sympy.polys.domains.polynomialringr   Z!sympy.polys.domains.fractionfieldr   Zsympy.polys.constructorr   Zsympy.printing.defaultsr   Zsympy.utilitiesr   Zsympy.utilities.magicr    r)   r*   r.   r=   rC   r!   r?   r'   r'   r'   r(   <module>   sB    4 