
    EdE                        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mZ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 m!Z! d dl"m#Z# d Z$ddZ%d Z&d Z'd Z(dddZ)dS )    )Add)factor_terms)
expand_log_mexpand)Pow)S)ordered)Dummy)LambertWexplog)root)roots)Polyfactor)separatevars)collect)powsimp)solve_invert)uniqc                     fd| j         D             }t          |          D ]L}d|z  }||v rA||v r=|                                d         t          j        ur|}|                    |           M|S )a  process the generators of ``poly``, returning the set of generators that
    have ``symbol``.  If there are two generators that are inverses of each other,
    prefer the one that has no denominator.

    Examples
    ========

    >>> from sympy.solvers.bivariate import _filtered_gens
    >>> from sympy import Poly, exp
    >>> from sympy.abc import x
    >>> _filtered_gens(Poly(x + 1/x + exp(x)), x)
    {x, exp(x)}

    c                 &    h | ]}|j         v |S  free_symbols).0gsymbols     7lib/python3.11/site-packages/sympy/solvers/bivariate.py	<setcomp>z!_filtered_gens.<locals>.<setcomp>%   s%    ===!Fan$<=A===       )genslistas_numer_denomr   Oneremove)polyr   r$   r   ags    `   r    _filtered_gensr+      s    $ >===ty===D$ZZ  qS9 	t 	  ""1%QU2 KKNNNKr"   Nc                     fd|                                D             }t          |          dk    r|d         S |r.t          t          t	          |                    fd          S dS )a+  Returns the term in lhs which contains the most of the
    func-type things e.g. log(log(x)) wins over log(x) if both terms appear.

    ``func`` can be a function (exp, log, etc...) or any other SymPy object,
    like Pow.

    If ``X`` is not ``None``, then the function returns the term composed with the
    most ``func`` having the specified variable.

    Examples
    ========

    >>> from sympy.solvers.bivariate import _mostfunc
    >>> from sympy import exp
    >>> from sympy.abc import x, y
    >>> _mostfunc(exp(x) + exp(exp(x) + 2), exp)
    exp(exp(x) + 2)
    >>> _mostfunc(exp(x) + exp(exp(y) + 2), exp)
    exp(exp(y) + 2)
    >>> _mostfunc(exp(x) + exp(exp(y) + 2), exp, x)
    exp(x)
    >>> _mostfunc(x, exp, x) is None
    True
    >>> _mostfunc(exp(x) + exp(x*y), exp, x)
    exp(x)
    c                 p    g | ]2}r,j         r	|j        v sj         |                              0|3S r   )	is_Symbolr   has)r   tmpXs     r    
<listcomp>z_mostfunc.<locals>.<listcomp>J   sb     ) ) )cQ )	)S--)K)GGAJJ)c ) ) )r"   r#   r   c                 .    |                                S N)count)xfuncs    r    <lambda>z_mostfunc.<locals>.<lambda>P   s     r"   )keyN)atomslenmaxr%   r	   )lhsr7   r1   ftermss    `` r    	_mostfuncr?   /   s    6) ) ) )SYYt__ ) ) )F 6{{a Gay	 G4((.E.E.E.EFFFF4r"   c                 z   t          |                                           } |                     |          \  }}| j        r&|j        rt          ||          \  }}}||z  ||z  |fS | j        sd}||}}n)|}t          |                              |d          \  }}|                                r| }| }|||fS )a  Return ``a, b, X`` assuming ``arg`` can be written as ``a*X + b``
    where ``X`` is a symbol-dependent factor and ``a`` and ``b`` are
    independent of ``symbol``.

    Examples
    ========

    >>> from sympy.solvers.bivariate import _linab
    >>> from sympy.abc import x, y
    >>> from sympy import exp, S
    >>> _linab(S(2), x)
    (2, 0, 1)
    >>> _linab(2*x, x)
    (2, 0, x)
    >>> _linab(y + y*x + 2*x, x)
    (y + 2, y, x)
    >>> _linab(3 + 2*exp(x), x)
    (2, 3, exp(x))
    r   Fas_Add)r   expandas_independentis_Mulis_Add_linabr   could_extract_minus_sign)argr   inddepabr6   s          r    rG   rG   T   s    ( szz||
$
$C!!&))HC
z cj f%%1a1uc!eQ: FC1C  //u/EE1!!## BBa7Nr"   c                    t          t          |                     } t          | t          |          }|sg S |                     |d          }t          | t                    r\| |z
                      ||j        d                   } |j        d         }t          |t                    sg S | j        d          }| |z  } ||j        vrg S t          ||          \  }}t          | |z
  |          }|
                    |          	|j        v rg S |j        d         }t          ||          \  }}	|	|k    rg S t          d          t          |	z
  |          }
ddg}g }|z  |z  z
  z  z                                  \  }}|                                \  }}t          ||z            }t          d          }fdt!          ||z  |z
  |                                          D             }|D ]R}|D ]M}t%          ||          }|r|j        s| z  z  |z  z   |                    fd|
D                        NS|S )z
    Given an expression assumed to be in the form
        ``F(X, a..f) = a*log(b*X + c) + d*X + f = 0``
    where X = g(x) and x = g^-1(X), return the Lambert solution,
        ``x = g^-1(-c/b + (a/d)*W(d/(a*b)*exp(c*d/a/b)*exp(-f/a)))``.
    r   Nrhstc                 &    g | ]}z  z  |z  S r   r   )r   rQ   rL   rM   ds     r    r2   z_lambert.<locals>.<listcomp>   s%    999!AqsGAI999r"   c              3   D   K   | ]}|                               V  d S r4   )subs)r   xurO   us     r    	<genexpr>z_lambert.<locals>.<genexpr>   s/      992rwwq#999999r"   )r   r   r?   r   rU   
isinstanceargsr   rG   r   as_coefficientr
   r   r&   as_coeff_Mulr   r   keysr   is_realextend)eqr6   mainlogotherfX2logtermlogargcX1xusolnslambert_real_branchessolnumdenperQ   rZ   rI   kwrL   rM   rS   rO   rW   s                         @@@@@r    _lambertrr   y   s    
*R..	!	!BC##G 	GGGQE5&# 5jwQ88,q/'3'' 	I&q!!
e"" 	eQHAq"b5j'**Gw''A A' 	\!_Ffa  HAq"	Rx 	 	eABFAG  G
C 1QqS!A--//HCFAsCGAc

A999999uQTAXq116688999D  : :& 	: 	:Aa  A  "Q$!A#q.CJJ999999999999	: Jr"   c                 p
   fd}|                      d          \  }}| }fdD             }|st                      |j        s|j        rQt	          di j        |                    fdfd          }|j        r|                              r|                    d          }||z
  }	||z
  }
|	j        se|
rc|	                    t          j
        t          j                  s9t          t          |	          t          |
          z
            } ||          S nd|j        r]|r[t          t          |          d	          }t          |          }|                              r|j        r||z
  } ||          S |                    i          }t          t!          |d
                    }t	                      }t#          ||z
            \  }}|                    ||i          }g }|st%          |t                    }|r|j        r4|dk    r.t'          t          |          t          |          z
            }n|j        r|                    |d          }|r|j        sfd|                    t*                    D             rh|s#t          |          t          ||z
            z
  }n%t          ||z
            t          ||z
            z
  }t'          t          |                    }nt'          ||z
            }|st%          |t,                    }|rt/          ||          }|j        rA|dk    r;t'          t          t          |          t          |          z
                      }n|j        r|                    |d          }||z
  }||z
  }|                                r|                                r
|dz  }|dz  }t          |          t          |          z
  }t'          t          |                    }|st%          |t*                    }|rɉ|j        j        v rt/          ||          }|j        rA|dk    r;t'          t          t          |          t          |          z
                      }nc|j        r\|                    |d          }||z
  }||z
  }t          |          t          |          z
  }t'          t          |                    }|st          d| z            t5          t7          |                    S )a  Return solution to ``f`` if it is a Lambert-type expression
    else raise NotImplementedError.

    For ``f(X, a..f) = a*log(b*X + c) + d*X - f = 0`` the solution
    for ``X`` is ``X = -c/b + (a/d)*W(d/(a*b)*exp(c*d/a/b)*exp(f/a))``.
    There are a variety of forms for `f(X, a..f)` as enumerated below:

    1a1)
      if B**B = R for R not in [0, 1] (since those cases would already
      be solved before getting here) then log of both sides gives
      log(B) + log(log(B)) = log(log(R)) and
      X = log(B), a = 1, b = 1, c = 0, d = 1, f = log(log(R))
    1a2)
      if B*(b*log(B) + c)**a = R then log of both sides gives
      log(B) + a*log(b*log(B) + c) = log(R) and
      X = log(B), d=1, f=log(R)
    1b)
      if a*log(b*B + c) + d*B = R and
      X = B, f = R
    2a)
      if (b*B + c)*exp(d*B + g) = R then log of both sides gives
      log(b*B + c) + d*B + g = log(R) and
      X = B, a = 1, f = log(R) - g
    2b)
      if g*exp(d*B + h) - b*B = c then the log form is
      log(g) + d*B + h - log(b*B + c) = 0 and
      X = B, a = -1, f = -h - log(g)
    3)
      if d*p**(a*B + g) - b*B = c then the log form is
      log(d) + (a*B + g)*log(p) - log(b*B + c) = 0 and
      X = B, a = -1, d = a*log(p), f = -log(d) - g*log(p)
    c                       fddD             \  }}t          |          }||k    r$|                    t          |                     t          t          |                    S )a  Return the unique solutions of equations derived from
        ``expr`` by replacing ``t`` with ``+/- symbol``.

        Parameters
        ==========

        expr : Expr
            The expression which includes a dummy variable t to be
            replaced with +symbol and -symbol.

        symbol : Symbol
            The symbol for which a solution is being sought.

        Returns
        =======

        List of unique solution of the two equations generated by
        replacing ``t`` with positive and negative ``symbol``.

        Notes
        =====

        If ``expr = 2*log(t) + x/2` then solutions for
        ``2*log(x) + x/2 = 0`` and ``2*log(-x) + x/2 = 0`` are
        returned by this function. Though this may seem
        counter-intuitive, one must note that the ``expr`` being
        solved here has been derived from a different expression. For
        an expression like ``eq = x**2*g(x) = 1``, if we take the
        log of both sides we obtain ``log(x**2) + log(g(x)) = 0``. If
        x is positive then this simplifies to
        ``2*log(x) + log(g(x)) = 0``; the Lambert-solving routines will
        return solutions for this, but we must also consider the
        solutions for  ``2*log(-x) + log(g(x))`` since those must also
        be a solution of ``eq`` which has the same value when the ``x``
        in ``x**2`` is negated. If `g(x)` does not have even powers of
        symbol then we do not want to replace the ``x`` there with
        ``-x``. So the role of the ``t`` in the expression received by
        this function is to mark where ``+/-x`` should be inserted
        before obtaining the Lambert solutions.

        c                 D    g | ]}                     |z  i          S r   )xreplace)r   sgnexprr   rQ   s     r    r2   zC_solve_lambert.<locals>._solve_even_degree_expr.<locals>.<listcomp>  s:     ? ? ?/2DMM1c&j/**? ? ?r"   )rP   r#   )_solve_lambertr_   r%   r   )rx   rQ   r   nlhsplhssolsr$   s   ```   r    _solve_even_degree_exprz/_solve_lambert.<locals>._solve_even_degree_expr   s    T? ? ? ? ? ?6=? ? ?
ddFD114< 	<KKtVT::;;; DJJr"   TrA   c                 h    g | ].}|j         t          t          fv s|j        |j        j        v ,|/S r   )r7   r   r   is_Powr   r   r0   r   s     r    r2   z"_solve_lambert.<locals>.<listcomp>  s]     B B BHc
*BB &#'*> >B B B Br"   rQ   c                 @    | j         o| j        k    o| j        j        S r4   )r   baser   is_even)ir   s    r    r8   z _solve_lambert.<locals>.<lambda>(  s"    ?QVv-?!%- r"   c                     | j         z  S r4   )r   )r   rQ   s    r    r8   z _solve_lambert.<locals>.<lambda>*  s    15 r"   r   )force)deepc                 &    g | ]}|j         v |S r   r   r   s     r    r2   z"_solve_lambert.<locals>.<listcomp>\  s7     37 37 37 #!S%553737 37 37r"   rP   z:%s does not appear to have a solution in terms of LambertW)rQ   )rD   NotImplementedErrorrF   rE   r
   assumptions0replacer/   rU   r   ComplexInfinityNaNr   r   rv   r   r   r   r?   rr   r:   r   r   r   rH   r   r%   r	   )rc   r   r$   r}   nrhsr=   rO   lamcheckt_indept_term_rhsr`   rr   solnra   rb   diffmainexpmaintermmainpowrQ   s    ``                  @r    ry   ry      s   D4  4  4  4  4 l    55ID#%CB B B Bt B B BH  $!###
z (SZ ( --,--kk@ @ @ @     : 	>#''!** 	>hhq!nnG7]F=D= >T >JJq0!%88>Fc$ii 788..r1f===Z 	>C 	>SXXT222Cc((Cwwqzz >cj >3Y..r1f=== llAv;''
&4(((
)
)C 	AS1Wf%%FAs
**aX

C D 7Cf-- 	7z 7cQh 7C3s88 3V<< 7!,, 
7 
7 37 37 37 37',{{3'7'737 37 37 
7  C"5zzC,<,<<"3;//#cEk2B2BB#Jt$4$4f==DD $C#Iv66D  :Cf-- 	:#w''Cz :cQh :
3s88c#hh+> ? ?HH 
:!,,;Ek5577 0022NH2IC8}}s3xx/
4 0 0&99  :Cf-- 	:v!99 	:#w''Cz 	:cQh 	:
3s88c#hh+> ? ?HH :!,,;Ek8}}s3xx/
4 0 0&99 %! # "##$ % % 	% r"   Tfirstc          
         t          dd          }|rt          |           }|                                } t                      }t                      }t          t          |                     ||i          ||          ||d          }|rC||i}	|d                             |	          |d                             |	          |d         fS d	S | }|                                } t          j        |                                          }
g }|
D ]N}t          |                    |z                      }|j	        }|v s|v r n%|
                    |           Oz  t          | |fS fd
}g }|                              }|                              |k    rrt          |                    |z            |          }t          |                    |z            |          } || ||z  z
  |z            }||z  |z  z   ||fS g }|                              }|                              |k    rt          d          D ]}t          |                    |z  |z  z            |          }t          |                    |z            |          } || ||z  z
  |z  z            }||z  z  |z  z   ||fc S cd	S d	S )a  Given an expression, f, 3 tests will be done to see what type
    of composite bivariate it might be, options for u(x, y) are::

        x*y
        x+y
        x*y+x
        x*y+y

    If it matches one of these types, ``u(x, y)``, ``P(u)`` and dummy
    variable ``u`` will be returned. Solving ``P(u)`` for ``u`` and
    equating the solutions to ``u(x, y)`` and then solving for ``x`` or
    ``y`` is equivalent to solving the original expression for ``x`` or
    ``y``. If ``x`` and ``y`` represent two functions in the same
    variable, e.g. ``x = g(t)`` and ``y = h(t)``, then if ``u(x, y) - p``
    can be solved for ``t`` then these represent the solutions to
    ``P(u) = 0`` when ``p`` are the solutions of ``P(u) = 0``.

    Only positive values of ``u`` are considered.

    Examples
    ========

    >>> from sympy import solve
    >>> from sympy.solvers.bivariate import bivariate_type
    >>> from sympy.abc import x, y
    >>> eq = (x**2 - 3).subs(x, x + y)
    >>> bivariate_type(eq, x, y)
    (x + y, _u**2 - 3, _u)
    >>> uxy, pu, u = _
    >>> usol = solve(pu, u); usol
    [sqrt(3)]
    >>> [solve(uxy - s) for s in solve(pu, u)]
    [[{x: -y + sqrt(3)}]]
    >>> all(eq.subs(s).equals(0) for sol in _ for s in sol)
    True

    rW   T)positiveFr   r   r#      Nc                 p    t          |                     ||                    }|j        }|v s|v rd n|S r4   )r   rU   r   )rc   vrg   newfreer6   ys        r    okzbivariate_type.<locals>.ok  s@    qvva||$$T	8Q$Y8ttS8r"   )r
   r   as_exprbivariate_typerU   rv   r   	make_argsr   r   appenddegreer   coeff_monomialrange)rc   r6   r   r   rW   rn   _x_yrvrepsrZ   r   rL   r   r   rS   rM   itrys    ``               r    r   r     s?   N 	cD!!!A 	AqMMIIKKWWWWDB2!7!7R@@"bPUVVV 	E2q>Da5>>$''A)=)=r!uDD	A			A =%%D
C ! !QVVAqs^^$$~9 	T	 	E

1sCIq  9 9 9 9 9 9 C	Axx{{a %!!!Q$''++!!!Q$''++bAAaC{## 	%Q319c1$$ C	Axx{{a !HH 	 	DQ%%ad1a4i00!44AQ%%ad++Q//A"QA!GQ;q=))C +s1uqs{C****aDAqq 	 	r"   r4   )*sympy.core.addr   sympy.core.exprtoolsr   sympy.core.functionr   r   sympy.core.powerr   sympy.core.singletonr   sympy.core.sortingr	   sympy.core.symbolr
   &sympy.functions.elementary.exponentialr   r   r   (sympy.functions.elementary.miscellaneousr   sympy.polys.polyrootsr   sympy.polys.polytoolsr   r   sympy.simplify.simplifyr   sympy.simplify.radsimpr   r   sympy.solvers.solversr   r   sympy.utilities.iterablesr   r+   r?   rG   rr   ry   r   r   r"   r    <module>r      s         - - - - - - 4 4 4 4 4 4 4 4             " " " " " " & & & & & & # # # # # # G G G G G G G G G G 9 9 9 9 9 9 ' ' ' ' ' ' . . . . . . . . 0 0 0 0 0 0 * * * * * * + + + + + + 0 0 0 0 0 0 0 0 * * * * * *  8" " " "J" " "JE E EP] ] ]@ &* \ \ \ \ \ \ \r"   