
    wgk                        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 d dlmZmZ d dlmZmZmZ d dl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m Z  d dl!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/m0Z0m1Z1 d#dZ2d Z3d$dZ4d Z5dddZ6d%dZ7d Z8d&dZ9d&dZ:d&dZ;d Z<d Z=d  Z>e=Z?e>Z@e<ZAd! ZBd" ZCy)'    )defaultdict)sympifySMul
DerivativePow)_unevaluated_AddAdd)assumptions)Factors	gcd_terms)_mexpand
expand_mulexpand_power_base)_keep_coeff_unevaluated_Mul_mulsort)Rationalzoonan)global_parameters)ordereddefault_sort_key)DummyWildsymbols)expsqrtlog)Abs)gcd)
sqrtdenest)iterablesiftNTc                   ./ t        |       } t              rngD cg c]  }t        |       c}d }t        |d      \  }}	|	rt        t	        |	|	D cg c]  }t        di t        |       c}            }
D cg c]  }|
j                  ||       c}t        | j                  |
      |||      }|
j                         D ci c]  \  }}||
 }}}t        |t              s|j                  |      S |j                         D ci c]6  \  }}|j                  ||      j                  |      |j                  |      8 c}}S t               }t        j                  |       D ]m  } |j                    r|v r|j"                  s|vr|j%                  |       9 |j&                   |j(                   d    }|vs]|j%                  |       o t+        fd|D              }t-        t/        |            z   |st        | ||d|      S |t0        j2                  }d	 }d
 ..fd//fd}|r| j4                  rR| j7                         xs d} | j8                  | j:                  D cg c]  }||k7  rt        ||d|       c} |z   } n}| j"                  r5 | j8                  | j:                  D cg c]  }t        ||d|       c} S | j<                  r0t        | j>                  |d|      }tA        || jB                        S D cg c]  }tE        |d       c}d}|r4| j7                         }|" |jF                   rd}n| jI                         } t        j                  |       D cg c]  }tE        |d       }}tK        t,              tL        jN                  }}|D ]+  }|jQ                  d      \  }}t-        t/        |            |z   } | D cg c]
  } /|       }!}d}"D ]  }#t        |#tR              r|"rt-        tU        |!            }!|" }" ||!|#      }$|$8|#jV                  stY        d      |$\  }!}%}&}'|'sFg }(|%D ]6  })|)d   |)d   }*n|)d   |)d   z  }*|(j[                  tA        |)d   |*             8 t]        |( }+n ||%      }+tE         ||!      d      }!tE        |+d      }+||+   j[                  |!        & ||z  }. |j                         D ci c]  \  }}|t        |  }}}|tL        jN                  ur||tL        j^                  <   | |j                         D ]  \  },}-|-|z   ||,<    |)|j                         D ,-ci c]  \  },}-|, ||-       }},}-|r,t        |j                         D ,-cg c]
  \  },}-|,|-z   c}-}, S |S c c}w c c}w c c}w c c}}w c c}}w c c}w c c}w c c}w c c}w c c}w c c}}w c c}-},w c c}-},w )a  
    Collect additive terms of an expression.

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

    This function collects additive terms of an expression with respect
    to a list of expression up to powers with rational exponents. By the
    term symbol here are meant arbitrary expressions, which can contain
    powers, products, sums etc. In other words symbol is a pattern which
    will be searched for in the expression's terms.

    The input expression is not expanded by :func:`collect`, so user is
    expected to provide an expression in an appropriate form. This makes
    :func:`collect` more predictable as there is no magic happening behind the
    scenes. However, it is important to note, that powers of products are
    converted to products of powers using the :func:`~.expand_power_base`
    function.

    There are two possible types of output. First, if ``evaluate`` flag is
    set, this function will return an expression with collected terms or
    else it will return a dictionary with expressions up to rational powers
    as keys and collected coefficients as values.

    Examples
    ========

    >>> from sympy import S, collect, expand, factor, Wild
    >>> from sympy.abc import a, b, c, x, y

    This function can collect symbolic coefficients in polynomials or
    rational expressions. It will manage to find all integer or rational
    powers of collection variable::

        >>> collect(a*x**2 + b*x**2 + a*x - b*x + c, x)
        c + x**2*(a + b) + x*(a - b)

    The same result can be achieved in dictionary form::

        >>> d = collect(a*x**2 + b*x**2 + a*x - b*x + c, x, evaluate=False)
        >>> d[x**2]
        a + b
        >>> d[x]
        a - b
        >>> d[S.One]
        c

    You can also work with multivariate polynomials. However, remember that
    this function is greedy so it will care only about a single symbol at time,
    in specification order::

        >>> collect(x**2 + y*x**2 + x*y + y + a*y, [x, y])
        x**2*(y + 1) + x*y + y*(a + 1)

    Also more complicated expressions can be used as patterns::

        >>> from sympy import sin, log
        >>> collect(a*sin(2*x) + b*sin(2*x), sin(2*x))
        (a + b)*sin(2*x)

        >>> collect(a*x*log(x) + b*(x*log(x)), x*log(x))
        x*(a + b)*log(x)

    You can use wildcards in the pattern::

        >>> w = Wild('w1')
        >>> collect(a*x**y - b*x**y, w**y)
        x**y*(a - b)

    It is also possible to work with symbolic powers, although it has more
    complicated behavior, because in this case power's base and symbolic part
    of the exponent are treated as a single symbol::

        >>> collect(a*x**c + b*x**c, x)
        a*x**c + b*x**c
        >>> collect(a*x**c + b*x**c, x**c)
        x**c*(a + b)

    However if you incorporate rationals to the exponents, then you will get
    well known behavior::

        >>> collect(a*x**(2*c) + b*x**(2*c), x**c)
        x**(2*c)*(a + b)

    Note also that all previously stated facts about :func:`collect` function
    apply to the exponential function, so you can get::

        >>> from sympy import exp
        >>> collect(a*exp(2*x) + b*exp(2*x), exp(x))
        (a + b)*exp(2*x)

    If you are interested only in collecting specific powers of some symbols
    then set ``exact`` flag to True::

        >>> collect(a*x**7 + b*x**7, x, exact=True)
        a*x**7 + b*x**7
        >>> collect(a*x**7 + b*x**7, x**7, exact=True)
        x**7*(a + b)

    If you want to collect on any object containing symbols, set
    ``exact`` to None:

        >>> collect(x*exp(x) + sin(x)*y + sin(x)*2 + 3*x, x, exact=None)
        x*exp(x) + 3*x + (y + 2)*sin(x)
        >>> collect(a*x*y + x*y + b*x + x, [x, y], exact=None)
        x*y*(a + 1) + x*(b + 1)

    You can also apply this function to differential equations, where
    derivatives of arbitrary order can be collected. Note that if you
    collect with respect to a function or a derivative of a function, all
    derivatives of that function will also be collected. Use
    ``exact=True`` to prevent this from happening::

        >>> from sympy import Derivative as D, collect, Function
        >>> f = Function('f') (x)

        >>> collect(a*D(f,x) + b*D(f,x), D(f,x))
        (a + b)*Derivative(f(x), x)

        >>> collect(a*D(D(f,x),x) + b*D(D(f,x),x), f)
        (a + b)*Derivative(f(x), (x, 2))

        >>> collect(a*D(D(f,x),x) + b*D(D(f,x),x), D(f,x), exact=True)
        a*Derivative(f(x), (x, 2)) + b*Derivative(f(x), (x, 2))

        >>> collect(a*D(f,x) + b*D(f,x) + a*f + b*f, f)
        (a + b)*f(x) + (a + b)*Derivative(f(x), x)

    Or you can even match both derivative order and exponent at the same time::

        >>> collect(a*D(D(f,x),x)**2 + b*D(D(f,x),x)**2, D(f,x))
        (a + b)*Derivative(f(x), (x, 2))**2

    Finally, you can apply a function to each of the collected coefficients.
    For example you can factorize symbolic coefficients of polynomial::

        >>> f = expand((x + a + 1)**3)

        >>> collect(f, x, factor)
        x**3 + 3*x**2*(a + 1) + 3*x*(a + 1)**2 + (a + 1)**3

    .. note:: Arguments are expected to be in expanded form, so you might have
              to call :func:`~.expand` prior to calling this function.

    See Also
    ========

    collect_const, collect_sqrt, rcollect
    c                 x    | j                   xs- |  j                   xs t        | j                  t                    S N)	is_Symbolboolatomsr   xs    [/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/simplify/radsimp.py<lambda>zcollect.<locals>.<lambda>   s.    Q[[ aRNN d	7     T)binary)funcevaluateexactdistribute_order_termN   c              3   V   K   | ]   }|j                   xr |j                  v  " y wr'   )is_Powbase).0isymss     r-   	<genexpr>zcollect.<locals>.<genexpr>   s%     @QQXX0!&&D.0@s   &)Fc                 4   g }| D ]  \  }}}}|!|\  }}|dkD  rt        ||      |dz
  }}|dkD  r|@|t        j                  u r|j                  |       Q|j                  t	        ||             m|j                  t	        |||z                t        | S )Nr   r5   )r   r   Oneappendr   r   )termsproducttermratsymderivvarorders           r-   make_expressionz collect.<locals>.make_expression   s    %* 	3!D#sE "
Uai",T3"7%D ai {!%%<NN4(NN3tS>2s4S12	3 G}r/   c                    | j                   | j                  d   d}}}| j                  dd  D ]  }||k(  r|dz  }t        d       t        |t              rl|j                  d   }|j                  D ]  }||k7  s	t        d       ||k(  r%|j                   |t        |j                        z   }}nnt        |t              rl||t        |      ffS )Nr   r5   z(Improve MV Derivative support in collect)expr	variablesNotImplementedError
isinstancer   lenr   )rE   rJ   rD   rG   ss0s         r-   parse_derivativez!collect.<locals>.parse_derivative   s     !::uq'915c$ 	@ACx
)>@ @		@ z*"B^^ D7-BD DD
 Sy"iiT^^1D)De z* c8E?+++r/   c                    t         j                  d}}| d}}| j                  rt        | j                  t
              r | j                        \  }}n| j                  }| j                  t         j                  k(  r\| j                  }|j                  rt         j                  |}}n|j                  r|j                  d      \  }}t        |      |}}n| j                  j                  r| j                  }n| j                  j                         \  }}|j                  r||}}n| j                  }nt        | t              rZ| j                  }|j                  rt         j                  |}}nJ|j                  r>|j                  d      \  }}t        |      |}}nt        | t
              r |       \  }}||||fS )a  Parses expression expr and outputs tuple (sexpr, rat_expo,
        sym_expo, deriv)
        where:
         - sexpr is the base expression
         - rat_expo is the rational exponent that sexpr is raised to
         - sym_expo is the symbolic exponent that sexpr is raised to
         - deriv contains the derivatives of the expression

         For example, the output of x would be (x, 1, None, None)
         the output of 2**x would be (2, 1, x, None).
        NT)rational)r   r>   r7   rM   r8   r   Exp1r   is_Rationalis_Mulas_coeff_Mul	is_Number)	rJ   rat_exposym_exposexprrE   argcoefftailrQ   s	           r-   
parse_termzcollect.<locals>.parse_term  sa    UUD(Tu;;$))Z0/		:u		yyAFF"hh??&'ffc8EZZ"%"2"2D"2"AKE4&)$i8E##88"hh335t??).hH#xxHc"((C"#&&#x!...=t"%d)Uxj)+D1LE5h%//r/   c                 P   t        j                  |      }t        |       t        |      k  ry|D cg c]
  } |       }}| dd } g dd}}}|D ]  \  }}}}|j                  r|dk(  r|t	        t        |             D ]  }	| |	   	| |	   \  }
}}}|d}|
j                  |      )||k(  s|1|4|j                  |      Fdu r||z  }||}n||k7  rd}n||k7  s||k7  rg|j                  | |	          d| |	<      y | D cg c]  }|s|	 c}|||fS c c}w c c}w )zParse terms searching for a pattern.
        Terms is a list of tuples as returned by parse_terms;
        Pattern is an expression treated as a product of factors.
        NFr5   T)r   	make_argsrN   rX   rangematchr?   )r@   patternelemelemscommon_expo	has_derive_rate_syme_ordjrB   t_ratt_symt_ordexpo_fr3   r_   s                   r-   parse_expressionz!collect.<locals>.parse_expression8  s   
 --(u:G$ 4;<Dz$'<G<!HE,.e	;E-4 3 )eUE>>eqjU]s5z* - AQx' 05a-D%
 ($(	

4(4"e^u/@!-!KK.: E> $)5=D*2.2
 $/$#623K  %~% ( U1X.#'aS- Z  g3 j "'-2"B-uk9LLu =t .s   DD#D#r   )deep)split_1z%Can not collect noncommutative symbol    )0r   r#   r$   dictzipr   r   getcollectsubsitemsrM   xreplacesetr
   ra   has_freerV   add_new_rawargsas_coeff_mulalllistr   r   r2   is_AddgetOr1   argsr7   r8   r   r   r   hasremoveOr   r   Zeroargs_cncr   reversedis_commutativeAttributeErrorr?   r   r>   )0rJ   r;   r1   r2   r3   r4   r:   cond_nonsymsrepsrO   rvkvurep_symsgsimplerH   rr   oarB   b
order_termsumma	collecteddislikedrA   cncr   r@   small_firstsymbolresultrf   rg   rh   margsre   eindexkeyvalrQ   r_   s0    `  `                                         @@r-   rz   rz      s   l 4=D)1$dVE1GAJEDDdD.JAwC7!Ka%"9+a."9!KLM(,-1A-TYYt_d"79 "&.A1.."d#;;t$$ !#
,1 HHQN++D11::d3CC , , }t$ 		!A1::t$T	88		! #ANNNANND$9!$<=D=IIaL		! @%@@d75>**4"79 9 $--(,600dFMP ;;		 qA499!YY2!q& AtT48MN2 3567D [[499 II' dD$7LM' ( ( [[		4tU4IKAq$((##6:;ae,;DJYY[
!z~~t$!
||~7:}}T7JK!qu-KEK%d+QVVxI %    /2GAJ"$(,-1A-- 	 F&*-+Xe_-"-o%eV4F!,,()PQQ7=4uk9 !E % 67? $QA $QQASa!_56  KE+E2E)/%*@uM)%e<% ''.9	 > HK% N )2(9:1CG:I:qvv#	!%%!) 	.HC :-IcN	. +4??+<>'sCCcN>	 > Y__->?cSW?@@S	 F "L- /,L2' < L .H ;> @sM   WWWW;WWW#,W(W-=W2W7=W=-X
c           	          | j                   s | j                  | s| S  | j                  | j                  D cg c]  }t	        |g|  c} } | j
                  rt        | |      S | S c c}w )aQ  
    Recursively collect sums in an expression.

    Examples
    ========

    >>> from sympy.simplify import rcollect
    >>> from sympy.abc import x, y

    >>> expr = (x**2*y + x*y + x + y)/(x + y)

    >>> rcollect(expr, y)
    (x + y*(x**2 + x + 1))/(x + y)

    See Also
    ========

    collect, collect_const, collect_sqrt
    )is_Atomr   	__class__r   rcollectr   rz   )rJ   varsr\   s      r-   r   r     sd    ( ||8488T?t~~		J 4t 4JK;;4&&K  Ks   A)c                 t   |t         j                  }| j                         \  }} t               }t	        j
                  |       D ]  }|j                         d   D ]n  }|j                  s|j                  r/|j                  j                  r|j                  j                  dk(  s|t        j                  u s^|j                  |       p  t        | g|ddi}| |k7  }|sd}t!        t#        t	        j
                  |                  }	t%        |	      D ]  \  }
}|j                         \  }}|D ]V  }|j                  r/|j                  j                  r|j                  j                  dk(  s|t        j                  u sQ|dz  } n |	|
xx   |z  cc<    |s|s	t	        |	 g}	t'        |	      |fS ||z  S )aL  Return expr with terms having common square roots collected together.
    If ``evaluate`` is False a count indicating the number of sqrt-containing
    terms will be returned and, if non-zero, the terms of the Add will be
    returned, else the expression itself will be returned as a single term.
    If ``evaluate`` is True, the expression with any collected terms will be
    returned.

    Note: since I = sqrt(-1), it is collected, too.

    Examples
    ========

    >>> from sympy import sqrt
    >>> from sympy.simplify.radsimp import collect_sqrt
    >>> from sympy.abc import a, b

    >>> r2, r3, r5 = [sqrt(i) for i in [2, 3, 5]]
    >>> collect_sqrt(a*r2 + b*r2)
    sqrt(2)*(a + b)
    >>> collect_sqrt(a*r2 + b*r2 + a*r3 + b*r3)
    sqrt(2)*(a + b) + sqrt(3)*(a + b)
    >>> collect_sqrt(a*r2 + b*r2 + a*r3 + b*r5)
    sqrt(3)*a + sqrt(5)*b + sqrt(2)*(a + b)

    If evaluate is False then the arguments will be sorted and
    returned as a list and a count of the number of sqrt-containing
    terms will be returned:

    >>> collect_sqrt(a*r2 + b*r2 + a*r3 + b*r5, evaluate=False)
    ((sqrt(3)*a, sqrt(5)*b, sqrt(2)*(a + b)), 3)
    >>> collect_sqrt(a*sqrt(2) + b, evaluate=False)
    ((b, sqrt(2)*a), 1)
    >>> collect_sqrt(a + b, evaluate=False)
    ((a + b,), 0)

    See Also
    ========

    collect, collect_const, rcollect
    r   ru   NumbersFr5   )r   r2   as_content_primitiver~   r
   ra   r   	is_numberr7   r   rU   qr   ImaginaryUnitr   collect_constr   r   	enumeratetuple)rJ   r2   r]   r   r   mdhitnradr   r:   r   r   cis                 r-   collect_sqrtr     s   R $-- ++-KE45D]]4  a 	A{{HH!2!2quuww!|(		 	d1T151A
!)CGCMM!,-.dO 	DAqJJLEAr 99!3!3Aaoo-AID GuG	 tJ<DT{D  7Nr/   c                 ^    d | j                  d fd      j                  d fd      S )aL  Return ``expr`` with arguments of multiple Abs in a term collected
    under a single instance.

    Examples
    ========

    >>> from sympy.simplify.radsimp import collect_abs
    >>> from sympy.abc import x
    >>> collect_abs(abs(x + 1)/abs(x**2 - 1))
    Abs((x + 1)/(x**2 - 1))
    >>> collect_abs(abs(1/x))
    Abs(1/x)
    c                 D   | j                         \  }}g }g }|D ]  }t        |t              r|j                  |j                  d          2t        |t
              rft        |j                  t              rL|j                  j                  r6|j                  |j                  j                  d   |j                  z         |j                  |        t        |      dk  rt        d |D              s| S t        | }t        |      }|g}|j                  |       |j                  t              s|j                  |       t        | S t        |t              st        |d      }||d<   t        |       |j                  |       t        j                  ||       S )Nr   ru   c              3   j   K   | ]+  }t        |t              s|j                  j                   - y wr'   )rM   r   r   is_negative)r9   r:   s     r-   r<   z,collect_abs.<locals>._abs.<locals>.<genexpr>`  s#     Sa
1c@R 1 1Ss   33Fr2   )r   )r   rM   r    r?   r   r   r8   r   is_realrN   anyr   extendr   r   
_from_args)	mulr   r   r   r   r:   absargAr   s	            r-   _abszcollect_abs.<locals>._absU  s<   llnea
a
a !3hhqvvay!!S!j&=!%%--hhqvv{{1~quu,-hhqk 
Q!CS1SS*Awf
f+aSd
kk!nUU3Z
++b/d
3&5)!d1gtn
kk"o^^DR88r/   c                 "    t        | t              S r'   )rM   r   r+   s    r-   r.   zcollect_abs.<locals>.<lambda>r  s    *Q$ r/   c                      |       S r'   rv   r,   r   s    r-   r.   zcollect_abs.<locals>.<lambda>s  s    $q' r/   c                 "    t        | t              S r'   )rM   r   r+   s    r-   r.   zcollect_abs.<locals>.<lambda>t  s    jC( r/   c                      |       S r'   rv   r   s    r-   r.   zcollect_abs.<locals>.<lambda>u  s    d1g r/   )replace)rJ   r   s    @r-   collect_absr   G  s1    98 <<$"7(r/   )r   c          	          | j                   s| S d}|sVd}t               }| j                  D ]:  }t        j                  |      D ]   }|j
                  s|j                  |       " < nt        |      }|s|D cg c]  }|j                  r| }}t        t        |            }|D ]  }t        t              }t        |      }t        j                  |       D ]  }t        |      }	|	j                  |      \  }
}|j                  r^|	j                   j#                         |
j                   t%        fdD              s#||   j'                  |
j)                                |t*        j,                     j'                  |        g }d}d}t        |      D ]  }||   }|t*        j,                  u r|j/                  |       ,t1        |      dkD  r#t        | }d}|r|| k7  r|j'                  |       n|d   }|r8|j                  r,|j                   r |j'                  t3        ||d             d}|j'                  ||z          |s|r	t5        | } nt        | } | j                   r | S  | S c c}w )a  A non-greedy collection of terms with similar number coefficients in
    an Add expr. If ``vars`` is given then only those constants will be
    targeted. Although any Number can also be targeted, if this is not
    desired set ``Numbers=False`` and no Float or Rational will be collected.

    Parameters
    ==========

    expr : SymPy expression
        This parameter defines the expression the expression from which
        terms with similar coefficients are to be collected. A non-Add
        expression is returned as it is.

    vars : variable length collection of Numbers, optional
        Specifies the constants to target for collection. Can be multiple in
        number.

    Numbers : bool
        Specifies to target all instance of
        :class:`sympy.core.numbers.Number` class. If ``Numbers=False``, then
        no Float or Rational will be collected.

    Returns
    =======

    expr : Expr
        Returns an expression with similar coefficient terms collected.

    Examples
    ========

    >>> from sympy import sqrt
    >>> from sympy.abc import s, x, y, z
    >>> from sympy.simplify.radsimp import collect_const
    >>> collect_const(sqrt(3) + sqrt(3)*(1 + sqrt(2)))
    sqrt(3)*(sqrt(2) + 2)
    >>> collect_const(sqrt(3)*s + sqrt(7)*s + sqrt(3) + sqrt(7))
    (sqrt(3) + sqrt(7))*(s + 1)
    >>> s = sqrt(2) + 2
    >>> collect_const(sqrt(3)*s + sqrt(3) + sqrt(7)*s + sqrt(7))
    (sqrt(2) + 3)*(sqrt(3) + sqrt(7))
    >>> collect_const(sqrt(3)*s + sqrt(3) + sqrt(7)*s + sqrt(7), sqrt(3))
    sqrt(7) + sqrt(3)*(sqrt(2) + 3) + sqrt(7)*(sqrt(2) + 2)

    The collection is sign-sensitive, giving higher precedence to the
    unsigned values:

    >>> collect_const(x - y - z)
    x - (y + z)
    >>> collect_const(-y - z)
    -(y + z)
    >>> collect_const(2*x - 2*y - 2*z, 2)
    2*(x - y - z)
    >>> collect_const(2*x - 2*y - 2*z, -2)
    2*x - 2*(y + z)

    See Also
    ========

    collect, collect_sqrt, rcollect
    FTc              3   l   K   | ]+  }|v xr! |   j                   xr |   j                     - y wr'   )
is_Integer)r9   r   fnowfwass     r-   r<   z collect_const.<locals>.<genexpr>  sK      :/0 9 +a);); +Q**A+ + :s   14r5   r   )sign)r   r~   r   r   ra   r   r   r   rX   r   r   r   r   r
   divis_onefactorscopyr   r?   as_exprr   r>   r   rN   r   r	   )rJ   r   r   recurser   r   r   r@   Fvfr   rr   r   unevalr   r   r   s                   @@r-   r   r   x  sB   | ;;Gu 	 A]]1%  ;;HHQK 	 
 t}3aq{{33D 3D!QZt$ 	#A
A559DAqxx
 yy~~'yy :48: :!HOOAIIK0!%%L"	#   	!AaAAEEzA1vzGqDyKKNaD
 1;;188K1489AaC +	!. '.Dz;;Kk3j Kq 4s   <I;I;c           	         ddl m} t        d      fdd
fd	fd| j                         \  }} | j	                         } t        |       }t         |             \  }}|||fk7  rY|j                  s||f} ||d      } ||d      }t        t        |d	|z              }	t        |	j                  j                         D 
cg c]
  \  }
}|
|z   c}}
 }	t        |	      \  }}|||fk(  r|\  }}t        |      }|j                  s|j                  rt        t        t        |d	|z                    \  }}|j                  s!|j                         |j                         k  rY||fD cg c]
  } ||       c}\  }}|j                   r2|j"                  d   j                  r |j$                  |j"                   }|t        |d	|z        z   S c c}}
w c c}w )a
  
    Rationalize the denominator by removing square roots.

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

    The expression returned from radsimp must be used with caution
    since if the denominator contains symbols, it will be possible to make
    substitutions that violate the assumptions of the simplification process:
    that for a denominator matching a + b*sqrt(c), a != +/-b*sqrt(c). (If
    there are no symbols, this assumptions is made valid by collecting terms
    of sqrt(c) so the match variable ``a`` does not contain ``sqrt(c)``.) If
    you do not want the simplification to occur for symbolic denominators, set
    ``symbolic`` to False.

    If there are more than ``max_terms`` radical terms then the expression is
    returned unchanged.

    Examples
    ========

    >>> from sympy import radsimp, sqrt, Symbol, pprint
    >>> from sympy import factor_terms, fraction, signsimp
    >>> from sympy.simplify.radsimp import collect_sqrt
    >>> from sympy.abc import a, b, c

    >>> radsimp(1/(2 + sqrt(2)))
    (2 - sqrt(2))/2
    >>> x,y = map(Symbol, 'xy')
    >>> e = ((2 + 2*sqrt(2))*x + (2 + sqrt(8))*y)/(2 + sqrt(2))
    >>> radsimp(e)
    sqrt(2)*(x + y)

    No simplification beyond removal of the gcd is done. One might
    want to polish the result a little, however, by collecting
    square root terms:

    >>> r2 = sqrt(2)
    >>> r5 = sqrt(5)
    >>> ans = radsimp(1/(y*r2 + x*r2 + a*r5 + b*r5)); pprint(ans)
        ___       ___       ___       ___
      \/ 5 *a + \/ 5 *b - \/ 2 *x - \/ 2 *y
    ------------------------------------------
       2               2      2              2
    5*a  + 10*a*b + 5*b  - 2*x  - 4*x*y - 2*y

    >>> n, d = fraction(ans)
    >>> pprint(factor_terms(signsimp(collect_sqrt(n))/d, radical=True))
            ___             ___
          \/ 5 *(a + b) - \/ 2 *(x + y)
    ------------------------------------------
       2               2      2              2
    5*a  + 10*a*b + 5*b  - 2*x  - 4*x*y - 2*y

    If radicals in the denominator cannot be removed or there is no denominator,
    the original expression will be returned.

    >>> radsimp(sqrt(2)*x + sqrt(2))
    sqrt(2)*x + sqrt(2)

    Results with symbols will not always be valid for all substitutions:

    >>> eq = 1/(a + b*sqrt(c))
    >>> eq.subs(a, b*sqrt(c))
    1/(2*b*sqrt(c))
    >>> radsimp(eq).subs(a, b*sqrt(c))
    nan

    If ``symbolic=False``, symbolic denominators will not be transformed (but
    numeric denominators will still be processed):

    >>> radsimp(eq, symbolic=False)
    1/(a + b*sqrt(c))

    r   )signsimpza:d A:Dc                    \  }}}}}}}}t        |       dk(  ret        t        t        ||||g| D 	
cg c]  }	|	D ]  }
|
  c}
}	                  }t	        |      |z  t	        |      |z  z
  j                  |      S t        |       dk(  rt        t        t        ||||||g| D 	
cg c]  }	|	D ]  }
|
  c}
}	                  }t	        |      |z  t	        |      |z  z   t	        |      |z  z
  dt	        |      z  t	        |      z  |z  |z  ||dz  z  z
  ||dz  z  z
  ||dz  z  z   z  j                  |      S t        |       dk(  rt        t        t        ||||||||g| D 	
cg c]  }	|	D ]  }
|
  c}
}	                  }t	        |      |z  t	        |      |z  z   t	        |      |z  z
  t	        |      |z  z
  dt	        |      z  t	        |      z  |z  |z  ||dz  z  z
  ||dz  z  z
  dt	        |      z  t	        |      z  |z  |z  z
  ||dz  z  z   ||dz  z  z   z  dt	        |      z  t	        |      z  t	        |      z  t	        |      z  |z  |z  |z  |z  |dz  |dz  z  z   d|z  |z  |dz  z  |dz  z  z
  d|z  |z  |dz  z  |dz  z  z
  d|z  |z  |dz  z  |dz  z  z
  |dz  |dz  z  z   d|z  |z  |dz  z  |dz  z  z
  d|z  |z  |dz  z  |dz  z  z
  |dz  |dz  z  z   d|z  |z  |dz  z  |dz  z  z
  |dz  |dz  z  z   z  j                  |      S t        |       dk(  rt	        | d   d         S t        c c}
}	w c c}
}	w c c}
}	w )Nru         ir5   r   )rN   rw   r   rx   r   r}   rL   )rtermsr   r   r   r   r   BCDr:   rl   r   r;   s               r-   _numzradsimp.<locals>._numO  s    "&1aAq!Qv;!S!Q16/Ma1/Ma/M/MNOPDGAIQ	!88D>2v;!S!Q1a!35SAQR5SAa5Sa5STUVD!WQYa"T!WQY.47471B11DQ1F1a41OadF2q!tV2 &htn- [AS!Q1aAq!9v;Y!WX;YRSA;YA;YZ[\D!WQYa*T!WQY6aBQtAwYtTUwEVWXEXYZEZAqD&FQT6F"$%d1gId1g$5a$7$9F:<=adFFC!Q$F DGDG+DG3DG;A=a?A!Cad1a4iO!Aad
1a4 "#A#a%1*QT/245aCE!Q$Jq!tODFGd1a4iP!Aad
1a4 "#A#a%1*QT/245qDAI>@A!Aad
1a4P 1QT	
 %HTN+ [Aq	!%%%%' 0N 6T
 <Zs   M)M,MFc                 8   | j                   sy| j                  }|j                  r|j                  dk(  srt	        |      dk(  ry|rRd}|j                  r|j                  }nrt	        |      } | j
                  r| }|dk7  rt        |d      j
                  ryy)NFru   Tr5   )r7   r   rU   r   denomr   r   )r   log2r   r   symbolics       r-   ispow2zradsimp.<locals>.ispow2i  s    xxEE==QSSAXeAh!mA}}CC!H<<AAv#a)..r/   c                 	   ddl m} t        |       \  }}| j                  s|j                  r|j                  r| S |j                  sB |j                  |j
                  D cg c]
  } |       c} }t        | d|z              S |t        j                  urt        | d|z              S |j                  r)t        |j
                  D cg c]  } d|z         c} S s|j                  r| S  |      rDt        t        |j                              t        |j                        z  }||k7  re d|z        S |j                   rN|j                  j"                  s|j                  j$                  r" d|j                  z        |j                  z  S |j&                  s8 |      s0d |j                  |j
                  D cg c]
  } |       c} z  S d}t)        |      }|j                  rd|z  S |j*                  r* ||      }|j,                  r|j/                  |      rd|z  S 	 t1        t2              }t5        j6                  |      D ]  }	g }
g }t9        j6                  |	      D ]  } |d      rT|
j;                  |j                  t        j<                  u r|j                  n|j                  d|j                  z  z         a|t        j>                  u r |
j;                  t        j@                         |j;                  |        |tC        tE        |
               j;                  t9        |         t3        tE        t3        |jG                                           }|D cg c]  \  }}t9        | t5        | f }}}tI        |      |d   d   t        j                  u rdndz
  }|dk  rn|kD  rd}ntI        |      dkD  rjtK        d	 |D              rUtM        t        j                  t5        jN                  |D cg c]  \  }}t        |      |z   c}}            \  }}||z  }nd}nmdd
l(m)}m*}  | |            }||z  }||z  } |t)        |            }|jW                  t        jX                  tZ        t\              r| S |j                  rn||s| S t        |d|z        S c c}w c c}w c c}w c c}}w c c}}w )Nr   )	nsimplifyr5   T)r   ru   Fr   c              3   \   K   | ]$  \  }}|j                   xr |d z  j                   & yw)ru   N)r   rU   )r9   r,   ys      r-   r<   z*radsimp.<locals>.handle.<locals>.<genexpr>  s*     Ntq!q||:A(:(::Ns   *,)powsimp	powdenest)force)/sympy.simplify.simplifyr   fractionr   r1   r   r   r   r>   rV   free_symbolsr"   r   r8   numerr   r7   
is_integeris_positiver   r   r   rX   equalsr   r   r
   ra   r   r?   Halfr   NegativeOner   r   r|   rN   r   rad_rationalizer   sympy.simplify.powsimpr   r   r   r   r   r   )rJ   r   nr   r   d2keep_dr   r   p2otherr:   r   rl   r   r,   r   ndr   r   numr   handler   	max_termsr   s                         r-   r  zradsimp.<locals>.handle{  s	    	6~1<<AII!))KAFF3q34A#Avac{33aee^#Avac{33XX#166%BafQqSk%BCC ANNK!9DL)5<7BQwad|#XX155++qvv/A/A!AFF(#QUU**F1IVQVV8AfQi8999  QK 99Q3J ;;1B||		!t#D)I]]1% 
Bq) (Aad+		AEEQVVO!&&!AEE'ARSaoo-		!--0Q( %,-44S%[A
B '$y'8"9:;F5;<TQsAwQ(<F<v;vay|quu'<!!DDax	! 6{Q NvNN+AEE3>>/56tq!a648 9EBGA !DA$v,'CHAHA(1+X6AuuQVVS#&yya d K1Q3''y 4
 &C 9F =$ 7s   "SS	S
9SSr   r5   F)r   r   r   as_coeff_Addnormalr   r   r   r   r   r|   r   rX   r   r   	count_opsrV   r   r1   )rJ   r   r  r   r]   oldr  r   wasur   r   n2r  r:   r   r  r   r;   s    ``            @@@@r-   radsimpr     s   X 19D&4$g( g(R ##%KE4;;=D
4.CF4L!DAq
q!f}yya&CU+AU+A(AaC01A AIIOO4E"FDAq1a4"FGAA;DAqq!f}1qM;;!((i(8AaC(@ABFB||!++- ?.0"X66188q	 3 3A#Aqs+++ #G 7s   G!
<G'c                     |j                   s| |fS t        |      \  }}}|t        |      z  }t        ||z
  | z        } t        |dz  |dz  z
        }t	        | |      S )a\  
    Rationalize ``num/den`` by removing square roots in the denominator;
    num and den are sum of terms whose squares are positive rationals.

    Examples
    ========

    >>> from sympy import sqrt
    >>> from sympy.simplify.radsimp import rad_rationalize
    >>> rad_rationalize(sqrt(3), 1 + sqrt(2)/3)
    (-sqrt(3) + sqrt(6)/3, -7/9)
    ru   )r   split_surdsr   r   r  )r  denr   r   r   s        r-   r  r    sf     ::Cx#GAq!	$q'	A
AE3;
C
1a4!Q$;
C3$$r/   c                    t        |       } g g }}t        j                  |       D ]  }|j                  r9|j                  st        |t              r|j                         \  }}|j                  r|t        j                  u r|j                  |       q|r?|j                         r|j                  t        ||              |j                  |       |j                  t        ||              |j                  r|j                  |       |sH|j                  r<|j!                         \  }}|dk7  r|j                  |       |j                  |       7|j                  |       J|j"                  rS|j$                  sG|j&                  dk7  r|j                  |j&                         |j                  |j(                         |j                  |        t        |d| it        |d| ifS )a  Returns a pair with expression's numerator and denominator.
       If the given expression is not a fraction then this function
       will return the tuple (expr, 1).

       This function will not make any attempt to simplify nested
       fractions or to do any term rewriting at all.

       If only one of the numerator/denominator pair is needed then
       use numer(expr) or denom(expr) functions respectively.

       >>> from sympy import fraction, Rational, Symbol
       >>> from sympy.abc import x, y

       >>> fraction(x/y)
       (x, y)
       >>> fraction(x)
       (x, 1)

       >>> fraction(1/y**2)
       (1, y**2)

       >>> fraction(x*y/2)
       (x*y, 2)
       >>> fraction(Rational(1, 2))
       (1, 2)

       This function will also work fine with assumptions:

       >>> k = Symbol('k', negative=True)
       >>> fraction(x * y**k)
       (x, y**(-k))

       If we know nothing about sign of some exponent and ``exact``
       flag is unset, then the exponent's structure will
       be analyzed and pretty fraction will be returned:

       >>> from sympy import exp, Mul
       >>> fraction(2*x**(-y))
       (2, x**y)

       >>> fraction(exp(-x))
       (1, exp(x))

       >>> fraction(exp(-x), exact=True)
       (exp(-x), 1)

       The ``exact`` flag will also keep any unevaluated Muls from
       being evaluated:

       >>> u = Mul(2, x + 1, evaluate=False)
       >>> fraction(u)
       (2*x + 2, 1)
       >>> fraction(u, exact=True)
       (2*(x  + 1), 1)
    r5   r2   )r   r   ra   r   r7   rM   r   as_base_expr   r   r  r?   is_constantr   r   rV   as_numer_denomrU   r   pr   )	rJ   r3   r   r   rB   r   exr  r   s	            r-   r   r     sz   p 4=Dr5Ed# DKK:dC3H$$&EAr~~&LLO~~'SRC[1T*LLQ-T"ryy**,16LLOQT"doovv{TVV$LL LL78 *E	*C,KU,KKKr/   c                 "    t        | |      d   S )Nr3   r   r   rJ   r3   s     r-   r   r   n      D&q))r/   c                 "    t        | |      d   S )Nr!  r5   r"  r#  s     r-   r   r   r  r$  r/   c                 *     | j                   dddi|S )NfracTrv   )expand)rJ   hintss     r-   fraction_expandr*  v  s    4;;*D*E**r/   c                 p    t        | |j                  dd            \  }} |j                  dddi||z  S )Nr3   Fr!  r   Trv   r   ry   r(  rJ   r)  r   r   s       r-   numer_expandr.  z  s;    D		'5 9:DAq188($(%(1,,r/   c                 p    t        | |j                  dd            \  }}| |j                  dddi|z  S )Nr3   Fr!  r   Trv   r,  r-  s       r-   denom_expandr0    s;    D		'5 9:DAqxqxx,d,e,,,r/   c                    t        | j                  t              }|D cg c]  }|j                          }}|D cg c]  }|d   j                  s|d   dz   }}|j                  t               t        | \  }}}|}|sFt        |      dk\  r8|D cg c]  }||z  	 }	}|	D cg c]
  }|dk7  s	| }	}t        |	 \  }
}	}||
z  }g g }}|D ]  \  }}|j                  rc|j                  t        j                  k(  rF|j                  }||v r!|j                  |t        ||z        z         `|j                  ||z         u|j                  ||z          t        | }t        | }|||fS c c}w c c}w c c}w c c}w )a  
    Split an expression with terms whose squares are positive rationals
    into a sum of terms whose surds squared have gcd equal to g
    and a sum of terms with surds squared prime with g.

    Examples
    ========

    >>> from sympy import sqrt
    >>> from sympy.simplify.radsimp import split_surds
    >>> split_surds(3*sqrt(3) + sqrt(5)/7 + sqrt(6) + sqrt(10) + sqrt(15))
    (3, sqrt(2) + sqrt(5) + 3, sqrt(5)/7 + sqrt(10))
    )r   r5   ru   )sortedr   r   rW   r7   sort
_split_gcdrN   r   r   r   r8   r?   r   r
   )rJ   r   r,   
coeff_mulssurdsr   b1b2g2b1ng1a1va2vr   rO   s1r   r   s                     r-   r  r    st    $))!12D,01q!.."1J1(8AaDKKQqT1W8E8	JJ#J$E"IAr2	
B#b'Q,qqs(Qaq(( #&CrT2C 188BRx

1T"R%[=)

1Q3JJqsO 	S	AS	Aq!8O/ 28
  (s"   E0E5
E5E:(
E?3E?c                      | d   }|g}g }| dd D ]8  }t        ||      }|dk(  r|j                  |       &|}|j                  |       : |||fS )a`  
    Split the list of integers ``a`` into a list of integers, ``a1`` having
    ``g = gcd(a1)``, and a list ``a2`` whose elements are not divisible by
    ``g``.  Returns ``g, a1, a2``.

    Examples
    ========

    >>> from sympy.simplify.radsimp import _split_gcd
    >>> _split_gcd(55, 35, 22, 14, 77, 10)
    (5, [55, 35, 10], [22, 14, 77])
    r   r5   N)r!   r?   )r   r   r7  r8  r,   r;  s         r-   r4  r4    si     	
!A
B	BqrU AY7IIaLAIIaL b"9r/   )NNFTr'   )Tr   r  )Dcollectionsr   
sympy.corer   r   r   r   r   sympy.core.addr	   r
   sympy.core.assumptionsr   sympy.core.exprtoolsr   r   sympy.core.functionr   r   r   sympy.core.mulr   r   r   sympy.core.numbersr   r   r   sympy.core.parametersr   sympy.core.sortingr   r   sympy.core.symbolr   r   r   sympy.functionsr   r   r   $sympy.functions.elementary.complexesr    sympy.polysr!   sympy.simplify.sqrtdenestr"   sympy.utilities.iterablesr#   r$   rz   r   r   r   r   r  r  r   r   r   r*  r.  r0  expand_numerexpand_denomexpand_fractionr  r4  rv   r/   r-   <module>rS     s    # 7 7 0 . 3 G G B B 1 1 3 8 2 2 * * 4  0 4
@F>L^.b (, EPz,z%,XLv**+-- !&Rr/   