ó
¡¼™\c           @  s8  d  Z  d d l m Z m Z d d l m Z m Z m Z 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 m Z d d l m Z d d l Z i d	 d
 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d  6d! d" 6d# d$ 6d% d& 6d' d( 6d) d* 6d+ d, 6d- d. 6d/ d0 6d1 d2 6d3 d4 6d5 d6 6d7 d8 6d9 d: 6d; d< 6Z d= Z e j d> ƒ Z e d? „ Z d@ „  Z dA „  Z dB „  Z dC „  Z  dD „  Z! dE „  Z" dF „  Z# dG „  Z$ dH „  Z% dI „  Z& dJ „  Z' dK „  Z( dL „  Z) dM „  Z* e& Z+ e( Z, e* Z- dN „  Z. dO e/ f dP „  ƒ  YZ0 d S(Q   s6   Useful utilities for higher level polynomial classes. iÿÿÿÿ(   t   print_functiont   division(   t   St   Addt   Mult   Powt   Exprt
   expand_mult   expand_multinomial(   t   range(   t   decompose_powert   decompose_power_rat(   t   PolynomialErrort   GeneratorsError(   t   build_optionsNi-  t   ai.  t   bi/  t   ci0  t   di1  t   ei2  t   fi3  t   gi4  t   hi5  t   ii6  t   ji7  t   ki8  t   li9  t   mi:  t   ni;  t   oiØ   t   piÙ   t   qiÚ   t   riÛ   t   siÜ   t   tiÝ   t   uiÞ   t   viß   t   wi|   t   xi}   t   yi~   t   ziè  s   ^(.+?)(\d*)$c         C  sM  t  d „  |  Dƒ ƒ s t ‚ n  g  |  D]8 } g  | j ƒ  D] } | j d ƒ j ƒ  d ^ q9 ^ q& } t d „  | Dƒ ƒ r‰ t d ƒ ‚ n  g  | D]' \ } } | r¨ d n d | | f ^ q } t t | |  ƒ ƒ } | r1g  } g  } x@ | D]8 \ \ } } } } | r| j | ƒ që | j | ƒ që W| | f St | Œ  \ } }  t |  ƒ S(   s¼  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  s   |  ] } | j  Vq d  S(   N(   t	   is_number(   t   .0R    (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pys	   <genexpr>&   s    i   i    c         s  s+   |  ]! } | D] } | j  d  k Vq q d S(   i   N(   t   _prec(   R*   R   R   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pys	   <genexpr>,   s    s%   could not compute root with precisioni   (	   t   allt   NotImplementedErrort   as_real_imagR   t   anyt   sortedt   zipt   appendt   list(   t   rootst	   separatedR    R   t   keyt   imt   _R$   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   _nsort   s"    		E4
c           s¬   t  | ƒ } i  d ‰  ‰ | d k	 rf i  | j ‰  ‰ x. t | j ƒ D] \ } } | d ˆ  | <qE Wn  ‡  ‡ f d †  } y t |  d | ƒ}  Wn t k
 r¡ n Xt |  ƒ S(   s1   Sort generators in a reasonably intelligent way. i   c           sé   t  |  ƒ }  ˆ d  k	 rT y% t ˆ ƒ ˆ j |  ƒ |  d f SWqT t k
 rP qT Xn  t j |  ƒ j ƒ  \ } } | r„ t | ƒ } n d } y ˆ  | | | f SWn t	 k
 r² n Xy t
 | | | f SWn t	 k
 rÛ n Xt | | f S(   Ni    (   t   strt   Nonet   lent   indext
   ValueErrort   _re_gent   matcht   groupst   intt   KeyErrort   _gens_ordert
   _max_order(   t   gent   nameR=   (   t
   gens_ordert   wrt(    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt	   order_keyK   s&    %R6   N(   R   R;   RI   t	   enumeratet   sortR0   t	   TypeErrort   tuple(   t   genst   argst   optR   RF   RJ   (    (   RH   RI   s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt
   _sort_gens?   s    c         C  sR  t  |  ƒ }  t  | ƒ } |  | k r. t |  ƒ Sg  g  d } } } x* |  D]" } | | k rI | j | ƒ qI qI WxB t | ƒ D]4 \ } } | | k r| | | | d | | <} q| q| Wxw | D]o } |  j | ƒ } | j |  |  ƒ |  | d }  | j | ƒ } | j | |  ƒ | | d } | j | ƒ q» W| j |  ƒ | j | ƒ t | ƒ S(   s2   Unify generators in a reasonably intelligent way. i    i   (   R3   RN   R2   RK   R=   t   extend(   t   f_genst   g_gensRO   t   commonR   RF   R   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   _unify_genso   s,    
 c         C  sA   t  |  ƒ d k r3 t |  d d ƒ r3 t |  d ƒ St |  ƒ Sd S(   s8   Support for passing generators as `*gens` and `[gens]`. i   i    t   __iter__N(   R<   t   hasattrRN   (   RO   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   _analyze_gens”   s    %c         K  sH   d „  } d „  } | j  d t ƒ r4 t |  d | ƒSt |  d | ƒSd S(   s9   Sort low-level factors in increasing 'complexity' order. c         S  s   |  \ } } t  | ƒ | | f S(   N(   R<   (   t   factorR   R   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   order_if_multiple_keyž   s    c         S  s   t  |  ƒ |  f S(   N(   R<   (   R   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   order_no_multiple_key¢   s    t   multipleR6   N(   t   gett   TrueR0   (   t   factorsRP   R\   R]   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   _sort_factorsœ   s
    		c         C  s"   |  t  j t  j t  j t  j g k S(   sB   Do not treat NaN and infinities as valid polynomial coefficients. (   R   t   NaNt   Infinityt   NegativeInfinityt   ComplexInfinity(   t   expr(    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   _not_a_coeff«   s    c         C  sý  t  | j ƒ i  } } x' t | j ƒ D] \ } } | | | <q& Wg  } x§|  D]Ÿ} i  } | j ru | j | j } n  xgt j | ƒ D]V}	 g  d g | }
 } xø t j |	 ƒ D]ç } t	 | ƒ rÛ | j
 rÛ |
 j | ƒ q¯ yr | j t k r,t | ƒ \ } } | d k  r>| t | t j ƒ } } q>n t | ƒ \ } } | | | | <Wq¯ t k
 r•| j j | j ƒ s‚|
 j | ƒ q–t d | ƒ ‚ q¯ Xq¯ Wt | ƒ } | | k rË| | c t |
 Œ  7<q… t |
 Œ  | | <q… W| j | ƒ qM W| | j f S(   s@   Transform expressions into a multinomial form given generators. i    s0   %s contains an element of the set of generators.(   R<   RO   RK   t   is_Equalityt   lhst   rhsR   t	   make_argsR   Rh   t	   is_NumberR2   t   seriest   FalseR
   R   R   t   OneR   RC   t   free_symbolst   intersectionR   RN   (   t   exprsRQ   R   t   indicesR   R   t   polysRg   t   polyt   termt   coefft   monomR[   t   baset   exp(    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt    _parallel_dict_from_expr_if_gens°   s>    	!c           sÖ  ˆ  j  d k	 r! ‡  f d †  } n? ˆ  j t k r< d „  } n$ ˆ  j t k	 rW d „  } n	 d „  } t g  ƒ g  } } xJ|  D]B} g  } | j r¢ | j | j	 } n  x
t
 j | ƒ D]ù } g  i  } }	 xÐ t j | ƒ D]¿ }
 t |
 ƒ r|
 j sý | |
 ƒ r| j |
 ƒ qÕ ˆ  j t k r[t |
 ƒ \ } } | d k  rm| t | t j ƒ } } qmn t |
 ƒ \ } } |	 j | d ƒ | |	 | <| j | ƒ qÕ W| j | |	 f ƒ q² W| j | ƒ qz Wt | d ˆ  ƒ} t | ƒ i  } } x$ t | ƒ D] \ } } | | | <qòWg  } x± | D]© } i  } x | D]… \ } } d g | } x( | j ƒ  D] \ } } | | | | <qRWt | ƒ } | | k r¡| | c t | Œ  7<q,t | Œ  | | <q,W| j | ƒ qW| t | ƒ f S(   sI   Transform expressions into a multinomial form and figure out generators. c           s   |  ˆ  j  k S(   N(   t   domain(   R[   (   RQ   (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt	   _is_coeffæ   s    c         S  s   |  j  S(   N(   t   is_algebraic(   R[   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyR~   é   s    c         S  s   t  S(   N(   Ro   (   R[   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyR~   ì   s    c         S  s   |  j  S(   N(   R)   (   R[   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyR~   ï   s    i    RQ   N(   R}   R;   t	   extensionR`   t   greedyRo   t   setRi   Rj   Rk   R   Rl   R   Rh   Rm   R2   Rn   R
   R   R   Rp   R   t
   setdefaultt   addRR   R<   RK   t   itemsRN   (   Rs   RQ   R~   RO   t   reprsRg   t   termsRw   Rx   t   elementsR[   Rz   R{   R   Rt   R   R   Ru   Rv   Ry   (    (   RQ   s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt    _parallel_dict_from_expr_no_gensã   sV    		"!c         C  s%   t  |  f | ƒ \ \ } } | | f S(   sB   Transform an expression into a multinomial form given generators. (   R|   (   Rg   RQ   Rv   RO   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   _dict_from_expr_if_gens-  s    c         C  s%   t  |  f | ƒ \ \ } } | | f S(   sK   Transform an expression into a multinomial form and figure out generators. (   R‰   (   Rg   RQ   Rv   RO   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   _dict_from_expr_no_gens3  s    c         K  s(   t  |  t | ƒ ƒ \ } } | | j f S(   s/   Transform expressions into a multinomial form. (   t   _parallel_dict_from_exprR   RO   (   Rs   RP   t   repsRQ   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   parallel_dict_from_expr9  s    c         C  s¦   | j  t k	 r1 g  |  D] } | j  ƒ  ^ q }  n  t d „  |  Dƒ ƒ rV t d ƒ ‚ n  | j rw t |  | ƒ \ } } n t |  | ƒ \ } } | | j i | d 6ƒ f S(   s/   Transform expressions into a multinomial form. c         s  s   |  ] } | j  t k Vq d  S(   N(   t   is_commutativeRo   (   R*   Rg   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pys	   <genexpr>D  s    s-   non-commutative expressions are not supportedRO   (   t   expandRo   R/   R   RO   R|   R‰   t   clone(   Rs   RQ   Rg   R   RO   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyRŒ   ?  s    "	c         K  s(   t  |  t | ƒ ƒ \ } } | | j f S(   s1   Transform an expression into a multinomial form. (   t   _dict_from_exprR   RO   (   Rg   RP   t   repRQ   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   dict_from_exprO  s    c           s  |  j  t k r t d ƒ ‚ n  d „  ‰  | j t k	 rÍ t |  t ƒ sT t d ƒ ‚ n  |  j ƒ  }  x5 t ‡  f d †  t j |  ƒ Dƒ ƒ r— t	 |  ƒ }  qc Wx2 t d „  t j |  ƒ Dƒ ƒ rÉ t
 |  ƒ }  q› Wn  | j rî t |  | ƒ \ } } n t |  | ƒ \ } } | | j i | d 6ƒ f S(   s1   Transform an expression into a multinomial form. s-   non-commutative expressions are not supportedc         S  s+   |  j  o* |  j j o* |  j j o* |  j j S(   N(   t   is_PowR{   t   is_positivet
   is_IntegerRz   t   is_Add(   Rg   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   _is_expandable_powZ  s    !s   expression must be of type Exprc         3  sC   |  ]9 } ˆ  | ƒ p: | j  o: t ‡  f d  †  | j Dƒ ƒ Vq d S(   c         3  s   |  ] } ˆ  | ƒ Vq d  S(   N(    (   R*   R   (   R™   (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pys	   <genexpr>d  s    N(   t   is_MulR/   RP   (   R*   R   (   R™   (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pys	   <genexpr>c  s   c         s  s1   |  ]' } | j  o( t d  „  | j Dƒ ƒ Vq d S(   c         s  s   |  ] } | j  Vq d  S(   N(   R˜   (   R*   R   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pys	   <genexpr>h  s    N(   Rš   R/   RP   (   R*   R   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pys	   <genexpr>h  s    RO   (   R   Ro   R   R   t
   isinstanceR   R/   R   Rl   R   R   RO   RŠ   R‹   R‘   (   Rg   RQ   R“   RO   (    (   R™   s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyR’   U  s     	"	c         G  sˆ   g  } xu |  j  ƒ  D]g \ } } | g } x< t | | ƒ D]+ \ } } | r8 | j t | | ƒ ƒ q8 q8 W| j t | Œ  ƒ q Wt | Œ  S(   s/   Convert a multinomial form into an expression. (   R…   R1   R2   R   R   R   (   R“   RO   t   resultRy   Rx   Rw   R   R   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   expr_from_dicts  s    	c         C  sO  t  | ƒ } |  j ƒ  } |  j ƒ  } g  t t |  ƒ ƒ D] } g  ^ q7 } t ƒ  } x‘ | D]‰ } yQ | j | ƒ }	 | j |	 ƒ x. t | | ƒ D] \ }
 } | j	 |
 |	 ƒ qŽ WWqY t
 k
 rá x | D] } | j	 d ƒ qÇ WqY XqY WxS t | ƒ D]E \ } } | | k ró x* | D] } | | rt d ƒ ‚ qqWqó qó Wt t | ƒ | f S(   s*   Reorder levels using dict representation. i    s   unable to drop generators(   R3   t   keyst   valuesR	   R<   R‚   R=   R„   R1   R2   R>   RK   R   t   mapRN   (   R“   RO   t   new_genst   monomst   coeffsR8   t
   new_monomst   used_indicesRF   R   t   Mt   new_MR   Ry   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   _dict_reorder†  s(    %	
t   PicklableWithSlotsc           B  s)   e  Z d  Z g  Z d d „ Z d „  Z RS(   sâ  
    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::

        >>> from sympy.core.compatibility 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)

    c         C  sš   | d  k r |  j } n  i  } x< | j D]1 } t | d ƒ r( | j | j |  | ƒ ƒ q( q( Wx6 | j D]+ } t |  | ƒ rg t |  | ƒ | | <qg qg W| S(   Nt   __getstate__(   R;   t	   __class__t	   __bases__RY   t   updateRª   t	   __slots__t   getattr(   t   selft   clsR   R   RG   (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyRª   Ì  s     c         C  sI   xB | j  ƒ  D]4 \ } } y t |  | | ƒ Wq t k
 r@ q Xq Wd  S(   N(   R…   t   setattrt   AttributeError(   R°   R   RG   t   value(    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   __setstate__ß  s
    N(   t   __name__t
   __module__t   __doc__R®   R;   Rª   Rµ   (    (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyR©   ¤  s   $(1   R¸   t
   __future__R    R   t
   sympy.coreR   R   R   R   R   R   R   t   sympy.core.compatibilityR	   t   sympy.core.exprtoolsR
   R   t   sympy.polys.polyerrorsR   R   t   sympy.polys.polyoptionsR   t   reRD   RE   t   compileR?   Ro   R9   RR   RW   RZ   Rb   Rh   R|   R‰   RŠ   R‹   RŽ   RŒ   R”   R’   R   t   parallel_dict_from_basict   dict_from_basict   basic_from_dictR¨   t   objectR©   (    (    (    s4   lib/python2.7/site-packages/sympy/polys/polyutils.pyt   <module>   sJ   4"	0	%				3	J								