o
    8Va!7                     @   s  d Z ddlmZmZmZ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 ddlZi ddd	d
dddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2	Zd3Zed4ejZd]d6d7Zd8d9 Zd:d; Zd<d= Zd>d? Zejejejej gZ!d@dA e!D Z"dBdA e!dCdD D Z#dEdF Z$dGdH Z%dIdJ Z&dKdL Z'dMdN Z(dOdP Z)dQdR Z*dSdT Z+dUdV Z,dWdX Z-e)Z.e+Z/e-Z0dYdZ Z1G d[d\ d\Z2dS )^z6Useful utilities for higher level polynomial classes.     )SAddMulPowEqExpr
expand_mulexpand_multinomial)decompose_powerdecompose_power_rat)PolynomialErrorGeneratorsError)build_optionsNai-  bi.  ci/  di0  ei1  fi2  gi3  hi4  ii5  ji6  ki7  li8  mi9  ni:  oi;  p   q                     |   }   ~   )	rstuvwxyzi  z^(.*?)(\d*)$Fc                 C   s   t dd | D stdd | D }t| dkr%tdd |D r%tddd |D }tt|| }|rTg }g }|D ]\\}}}}|rJ|| q;|| q;||fS t| \}} t| S )	a  Sort the numerical roots putting the real roots first, then sorting
    according to real and imaginary parts. If ``separated`` is True, then
    the real and imaginary roots will be returned in two lists, respectively.

    This routine tries to avoid issue 6137 by separating the roots into real
    and imaginary parts before evaluation. In addition, the sorting will raise
    an error if any computation cannot be done with precision.
    c                 s       | ]}|j V  qd S NZ	is_number.0r+    r9   7/usr/lib/python3/dist-packages/sympy/polys/polyutils.py	<genexpr>$       z_nsort.<locals>.<genexpr>c                 S   s   g | ]}d d |  D qS )c                 S   s   g | ]}| d  d qS )   r   )r   as_real_imagr8   r   r9   r9   r:   
<listcomp>(       z%_nsort.<locals>.<listcomp>.<listcomp>)r>   r7   r9   r9   r:   r@   (   rA   z_nsort.<locals>.<listcomp>   c                 s   s$    | ]}|D ]}|j d kV  qqdS )rB   N)Z_prec)r8   r   r   r9   r9   r:   r;   *   s   " z%could not compute root with precisionc                 S   s"   g | ]\}}|r
d nd||fqS )rB   r   r9   )r8   r+   r   r9   r9   r:   r@   -   s   " )allNotImplementedErrorlenanysortedzipappendlist)roots	separatedkeyr+   r   Zim_r/   r9   r9   r:   _nsort   s"   	rO   c                    s   t |}i d |dur#i |j t|jD ]
\}}|d  |< q fdd}zt| |d} W t| S  tyA   Y t| S w )z1Sort generators in a reasonably intelligent way. NrB   c                    s   t | } d ur zt |  | dfW S  ty   Y nw t|  \}}|r0t|}nd}z | ||fW S  tyC   Y nw zt	| ||fW S  tyU   Y nw t
||fS )Nr   )strrE   index
ValueError_re_genmatchgroupsintKeyError_gens_order
_max_order)gennamerQ   Z
gens_orderwrtr9   r:   	order_keyI   s,   

z_sort_gens.<locals>.order_keyrM   )r   r]   	enumeratesortrG   	TypeErrortuple)gensargsoptr   rZ   r^   r9   r\   r:   
_sort_gens=   s   
rg   c                 C   s  t | } t |}| |krt| S g g d}}}| D ]}||v r%|| qt|D ]\}}||v r=|| |d ||< }q*|D ]3}| |}|| d|  | |d d } ||}||d|  ||d d }|| q@||  || t|S )z2Unify generators in a reasonably intelligent way. r   rB   N)rJ   rc   rI   r`   rQ   extend)Zf_gensZg_gensrd   commonr   rZ   r   r9   r9   r:   _unify_gensm   s0   




rj   c                 C   s.   t | dkrt| d drt| d S t| S )z8Support for passing generators as `*gens` and `[gens]`. rB   r   __iter__)rE   hasattrrc   )rd   r9   r9   r:   _analyze_gens   s   rm   c                 K   s4   dd }dd }| ddrt| |dS t| |dS )z9Sort low-level factors in increasing 'complexity' order. c                 S   s   | \}}t |||fS r5   rE   )factorr   r   r9   r9   r:   order_if_multiple_key   s   z,_sort_factors.<locals>.order_if_multiple_keyc                 S   s   t | | fS r5   rn   )r   r9   r9   r:   order_no_multiple_key   s   z,_sort_factors.<locals>.order_no_multiple_keyZmultipleTr_   )getrG   )Zfactorsre   rp   rq   r9   r9   r:   _sort_factors   s
   rs   c                 C      g | ]}t |qS r9   )type)r8   objr9   r9   r:   r@          r@   c                 C   rt   r9   )floatr?   r9   r9   r:   r@      rw   rB      c                 C   s8   t | tv s
| tv rdS t | tu rt| | krdS dS )zBDo not treat NaN and infinities as valid polynomial coefficients. TN)ru   illegal_typesfinfrx   exprr9   r9   r:   _not_a_coeff   s
   r~   c                 C   sj  t |ji }}t|jD ]\}}|||< qg }| D ]}i }|jr'|j|j }t|D ]}}	g dg| }
}t|	D ]T}t	|sJ|j
rJ|
| q;z)|jdu rft|\}}|dk re| t|tj }}nt|\}}|||| < W q; ty   |j|js|
| ntd| Y q;w t|}||v r||  t|
 7  < q,t|
 ||< q,|| q||jfS )z@Transform expressions into a multinomial form given generators. r   Fz0%s contains an element of the set of generators.)rE   rd   r`   is_Equalitylhsrhsr   	make_argsr   r~   	is_NumberrI   seriesr
   r   r   Oner   rW   Zfree_symbolsintersectionr   rc   )exprsrf   r   indicesr   r   polysr}   polytermcoeffmonomro   baseexpr9   r9   r:    _parallel_dict_from_expr_if_gens   sF   


r   c                    s   j dur fdd}n jdu rdd }n jdur dd }ndd }t g }}| D ]o}g }|jr9|j|j }t|D ]W}g i }}	t	|D ]C}
t
|
s]|
jsW||
r]||
 qJ jdu rxt|
\}}|d	k rw| t|tj }}nt|
\}}|	|d	| |	|< || qJ|||	f q>|| q,t| d
}t|i }}t|D ]\}}|||< qg }|D ]=}i }|D ]1\}}d	g| }| D ]
\}}|||| < qt|}||v r||  t	| 7  < qt	| ||< q|| q|t|fS )zITransform expressions into a multinomial form and figure out generators. Nc                    s
   |  j v S r5   )domainro   rf   r9   r:   	_is_coeff      
z3_parallel_dict_from_expr_no_gens.<locals>._is_coeffTc                 S      | j S r5   )Zis_algebraicr   r9   r9   r:   r         Fc                 S   s
   | t ju S r5   )r   ZImaginaryUnitr   r9   r9   r:   r      r   c                 S   r   r5   r6   r   r9   r9   r:   r      r   r   r   )r   	extensionZgreedysetr   r   r   r   r   r   r~   r   rI   r   r
   r   r   r   r   
setdefaultaddrg   rE   r`   itemsrc   )r   rf   r   rd   Zreprsr}   Ztermsr   r   elementsro   r   r   r   r   r   r   r   r   r   r9   r   r:    _parallel_dict_from_expr_no_gens   sX   








r   c                 C      t | f|\\}}||fS )zBTransform an expression into a multinomial form given generators. )r   r}   rf   r   rd   r9   r9   r:   _dict_from_expr_if_gens1     r   c                 C   r   )zKTransform an expression into a multinomial form and figure out generators. )r   r   r9   r9   r:   _dict_from_expr_no_gens7  r   r   c                 K      t | t|\}}||jfS )/Transform expressions into a multinomial form. )_parallel_dict_from_exprr   rd   )r   re   repsrf   r9   r9   r:   parallel_dict_from_expr=     
r   c                 C   sh   |j durdd | D } tdd | D rtd|jr$t| |\}}nt| |\}}||d|ifS )r   Fc                 S   s   g | ]}|  qS r9   )expandr8   r}   r9   r9   r:   r@   F  rw   z,_parallel_dict_from_expr.<locals>.<listcomp>c                 s   s    | ]}|j d u V  qdS )FN)is_commutativer   r9   r9   r:   r;   H  s    z+_parallel_dict_from_expr.<locals>.<genexpr>-non-commutative expressions are not supportedrd   )r   rF   r   rd   r   r   clone)r   rf   r   rd   r9   r9   r:   r   C  s   
r   c                 K   r   )1Transform an expression into a multinomial form. )_dict_from_exprr   rd   )r}   re   reprf   r9   r9   r:   dict_from_exprS  r   r   c                    s   | j du r	tddd  |jdur]t| ttfstd|  } t fddt| D rAt	| } t fddt| D s/tdd t| D r]t
| } tdd t| D sM|jrht| |\}}nt| |\}}||d	|ifS )
r   Fr   c                 S   s   | j o| jjo| jjo| jjS r5   )Zis_Powr   Zis_positiveZ
is_Integerr   is_Addr|   r9   r9   r:   _is_expandable_pow^  s   z+_dict_from_expr.<locals>._is_expandable_powzexpression must be of type Exprc                 3   s6    | ]} |p|j ot fd d|jD V  qdS )c                 3   s    | ]} |V  qd S r5   r9   r8   r   r   r9   r:   r;   h  s    ,_dict_from_expr.<locals>.<genexpr>.<genexpr>NZis_MulrF   re   r?   r   r9   r:   r;   g  s    
z"_dict_from_expr.<locals>.<genexpr>c                 s   s*    | ]}|j otd d |jD V  qdS )c                 s   r4   r5   )r   r   r9   r9   r:   r;   l  r<   r   Nr   r?   r9   r9   r:   r;   l  s   ( rd   )r   r   r   
isinstancer   r   rF   r   r   r	   r   rd   r   r   r   )r}   rf   r   rd   r9   r   r:   r   Y  s*   

r   c                 G   sZ   g }|   D ]"\}}|g}t||D ]\}}|r |t|| q|t|  qt| S )z/Convert a multinomial form into an expression. )r   rH   rI   r   r   r   )r   rd   resultr   r   r   r   r   r9   r9   r:   expr_from_dictw  s   r   c              	   C   s   t |}|  }|  }dd tt| D }t }|D ]2}z||}|| t||D ]\}	}
|
	|	|  q.W q t
yN   |D ]}
|
	d qDY qw t|D ]\}}||vrh|D ]
}|| rgtdq]qStt||fS )z*Reorder levels using dict representation. c                 S   s   g | ]}g qS r9   r9   )r8   rN   r9   r9   r:   r@     s    z!_dict_reorder.<locals>.<listcomp>r   zunable to drop generators)rJ   keysvaluesrangerE   r   rQ   r   rH   rI   rR   r`   r   maprc   )r   rd   Znew_gensZmonomsZcoeffsZ
new_monomsZused_indicesrZ   r   MZnew_Mr   rN   r   r9   r9   r:   _dict_reorder  s2   

r   c                   @   s&   e Zd ZdZdZdddZdd ZdS )	PicklableWithSlotsa  
    Mixin class that allows to pickle objects with ``__slots__``.

    Examples
    ========

    First define a class that mixes :class:`PicklableWithSlots` in::

        >>> from sympy.polys.polyutils import PicklableWithSlots
        >>> class Some(PicklableWithSlots):
        ...     __slots__ = ('foo', 'bar')
        ...
        ...     def __init__(self, foo, bar):
        ...         self.foo = foo
        ...         self.bar = bar

    To make :mod:`pickle` happy in doctest we have to use these hacks::

        >>> import builtins
        >>> builtins.Some = Some
        >>> from sympy.polys import polyutils
        >>> polyutils.Some = Some

    Next lets see if we can create an instance, pickle it and unpickle::

        >>> some = Some('abc', 10)
        >>> some.foo, some.bar
        ('abc', 10)

        >>> from pickle import dumps, loads
        >>> some2 = loads(dumps(some))

        >>> some2.foo, some2.bar
        ('abc', 10)

    r9   Nc                 C   sb   |d u r| j }i }|jD ]}t|dr||| | q|jD ]}t| |r.t| |||< q |S )N__getstate__)	__class__	__bases__rl   updater   	__slots__getattr)selfclsr   r   r[   r9   r9   r:   r     s   



zPicklableWithSlots.__getstate__c              	   C   s8   |  D ]\}}zt| || W q ty   Y qw d S r5   )r   setattrAttributeError)r   r   r[   valuer9   r9   r:   __setstate__  s   zPicklableWithSlots.__setstate__r5   )__name__
__module____qualname____doc__r   r   r   r9   r9   r9   r:   r     s
    %
r   )F)3r   Z
sympy.corer   r   r   r   r   r   r   r	   Zsympy.core.exprtoolsr
   r   Zsympy.polys.polyerrorsr   r   Zsympy.polys.polyoptionsr   rerX   rY   compile	MULTILINErS   rO   rg   rj   rm   rs   ZNaNZInfinityZNegativeInfinityZComplexInfinityZillegalrz   r{   r~   r   r   r   r   r   r   r   r   r   Zparallel_dict_from_basicZdict_from_basicZbasic_from_dictr   r   r9   r9   r9   r:   <module>   s    (

"0%	3J