U
    ZÊ¹jÍE  ã                   @   s  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d„ Z$d dd„Z%dd„ Z&dd„ Z'dd„ Z(d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                    s^   ‡ fdd„| j D ƒ}t|ƒD ]<}d| }||kr||kr| ¡ d tjk	rN|}| |¡ q|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                    s   h | ]}ˆ |j kr|’qS © ©Úfree_symbols)Ú.0Úg©Úsymbolr   úV/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/solvers/bivariate.pyÚ	<setcomp>%   s     
 z!_filtered_gens.<locals>.<setcomp>é   )ÚgensÚlistÚas_numer_denomr   ZOneÚremove)Zpolyr   r!   r   Zagr   r   r   Ú_filtered_gens   s    r%   Nc                    sP   ‡ fdd„|   ˆ¡D ƒ}t|ƒdkr,|d S |rLttt|ƒƒ‡fdd„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                    s4   g | ],}ˆ r,ˆ j rˆ |jks,ˆ j s| ˆ ¡r|‘qS r   )Z	is_Symbolr   Úhas©r   Útmp)ÚXr   r   Ú
<listcomp>J   s      
 
þz_mostfunc.<locals>.<listcomp>r    r   c                    s
   |   ˆ ¡S ©N)Úcount)Úx)Úfuncr   r   Ú<lambda>P   ó    z_mostfunc.<locals>.<lambda>)ÚkeyN)ÚatomsÚlenÚmaxr"   r   )Úlhsr.   r)   Zftermsr   )r)   r.   r   Ú	_mostfunc/   s    r6   c                 C   s–   t |  ¡ ƒ} |  |¡\}}| jrH|jrHt||ƒ\}}}|| || |fS | js^d}|| }}n|}t|ƒj|d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©Zas_Add)r   ÚexpandÚas_independentÚis_MulÚis_AddÚ_linabr   Úcould_extract_minus_sign)Úargr   ÚindÚdepÚaÚbr-   r   r   r   r<   T   s    r<   c                    sà  t t| ƒƒ} t| t|ƒ}|s g S |  |d¡}t| tƒr|| |  ||jd ¡} |jd }t|tƒsfg S | jd  }| |7 } ||jkrŠg S t||ƒ\‰}}t	| | |ƒ}| 
|¡‰ ˆ dksÄ|ˆ jkrÈg S |jd }t||ƒ\‰}}	|	|krîg S tdƒ‰t|	ˆ |ƒ}
ddg}g }|ˆ ˆ|  ˆ  ˆ  ¡ \}}| ¡ \}}t|| ƒ}tdƒ}‡ ‡‡fdd„t|| | |ƒ ¡ D ƒ}|D ]^}|D ]R}t||ƒ}|�r¤|j�s¤�q„| ˆ ˆ ˆ |  ‰| ‡‡fdd	„|
D ƒ¡ �q„�q||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                    s   g | ]}ˆˆ ˆ  | ‘qS r   r   )r   rE   )rA   rB   Údr   r   r*   ³   s     z_lambert.<locals>.<listcomp>c                 3   s   | ]}|  ˆˆ ¡V  qd S r+   )Úsubs)r   Zxu)rC   Úur   r   Ú	<genexpr>½   s     z_lambert.<locals>.<genexpr>)r   r   r6   r   rG   Ú
isinstanceÚargsr   r<   r   Zas_coefficientr	   r   r#   Zas_coeff_Mulr   r   Úkeysr
   Zis_realÚextend)Úeqr-   ÚmainlogÚotherÚfZX2ZlogtermZlogargÚcZX1ZxusolnsZlambert_real_branchesZsolÚnumZdenÚpÚerE   rK   r>   ÚkÚwr   )rA   rB   rF   rC   rH   r   Ú_lamberty   sP    






 (
"rX   c                    s¸  ‡ fdd„}| j ˆdd�\}}| }‡fdd„ˆ D ƒ}|s@tƒ ‚|jsN|j�r:tdˆjŽ‰| ‡fdd	„‡fd
d	„¡}|jrÞ| ˆ¡rÞ| ˆd¡}|| }	|| }
|	jsÜ|
rÜ|	 t	j
t	j¡sÜtt|	ƒt|
ƒ ƒ}||ˆˆƒS nN|j�r,|�r,tt|ƒdd�}t|ƒ}| ˆ¡�r,|j�r,|| }||ˆˆƒS | ˆˆi¡}tt|dd�ƒ}tƒ }t|| ˆƒ\}}| ||i¡}g }|�sDt|tˆƒ}|�rD|j�r¶|dk�r¶tt|ƒt|ƒ ˆƒ}nŽ|j�rD| |d¡}|�r6|j�s6‡fdd„| t¡D ƒ�r6|�st|ƒt|| ƒ }nt|| ƒt|| ƒ }tt|ƒˆƒ}nt|| ˆƒ}|�sút|tˆƒ}|�rút||ƒ}|j�r”|dk�r”ttt|ƒt|ƒ ƒˆƒ}nf|j�rú| |d¡}|| }|| }| ¡ �rÜ| ¡ �rÜ|d9 }|d9 }t|ƒt|ƒ }tt|ƒˆƒ}|�sšt|tˆƒ}|�ršˆ|jjk�ršt||ƒ}|j�rX|dk�rXttt|ƒt|ƒ ƒˆƒ}nB|j�rš| |d¡}|| }|| }t|ƒt|ƒ }tt|ƒˆƒ}|�s¬td|  ƒ‚tt|ƒƒ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                    sL   ‡ ‡‡fd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                    s   g | ]}ˆ   ˆ|ˆ i¡‘qS r   )Úxreplace)r   Zsgn©Úexprr   rE   r   r   r*     s    zC_solve_lambert.<locals>._solve_even_degree_expr.<locals>.<listcomp>)rD   r    )Ú_solve_lambertrM   r"   r   )r[   rE   r   ZnlhsZplhsZsols)r!   rZ   r   Ú_solve_even_degree_exprã   s    *ÿ
z/_solve_lambert.<locals>._solve_even_degree_exprTr7   c                    s0   g | ](}|j ttfks(|jrˆ |jjkr|‘qS r   )r.   r   r   Úis_Powr   r'   r   r   r   r*     s
     þz"_solve_lambert.<locals>.<listcomp>rE   c                    s   | j o| jˆ ko| jjS r+   )r^   Úbaser   Zis_even©Úir   r   r   r/   (  s    z _solve_lambert.<locals>.<lambda>c                    s
   ˆ | j  S r+   )r   r`   )rE   r   r   r/   *  s    r   )Úforce)Údeepc                    s   g | ]}ˆ |j kr|‘qS r   r   r'   r   r   r   r*   \  s   
ÿrD   z:%s does not appear to have a solution in terms of LambertW)rE   )r9   ÚNotImplementedErrorr;   r:   r	   Zassumptions0Úreplacer&   rG   r   ZComplexInfinityÚNaNr   r   rY   r   r   r   r6   rX   r2   r   r   r   r=   r   r"   r   )rQ   r   r!   r]   Znrhsr5   rC   ZlamcheckZt_indepZt_termZ_rhsrN   Úrra   ZsolnrO   rP   ÚdiffZmainexpZmaintermZmainpowr   )r!   r   rE   r   r\   Á   s¤    "6

ý
ÿÿ

ÿ
ÿr\   T©Úfirstc                   s:  t ddd�}|rŒt| ˆ ˆƒ}| ¡ } t ƒ }t ƒ }tt|  ˆ |ˆ|i¡||ƒ||dd�}|rˆ|ˆ |ˆi}	|d  |	¡|d  |	¡|d fS d	S | }| ¡ } t | ¡ ¡}
g }|
D ]<}t| ˆ |ˆ ¡ƒ}|j	}ˆ |ksÜˆ|krà qþ| 
|¡ q®ˆ ˆ t|Ž |fS ‡ ‡fd
d„}g }| ˆ ¡}| ˆ¡|k�rŠt| ˆ | ¡|ƒ}t| ˆ| ¡|ƒ}|| ˆ ||ˆ  | ƒ}|d	k	�rŠ|ˆ  |ˆ  ||fS g }| ˆ ¡}| ˆ¡|k�r6tdƒD ]„}t| ˆ | ˆ|  ¡|ƒ}t| ˆ| ¡|ƒ}|| ˆ ||ˆ  | ˆ ƒ}|d	k	�r(|ˆ  ˆ |ˆ  ||f  S ˆˆ  ‰ ‰�q°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

    rH   T)ZpositiveFri   r   r    é   Nc                    s.   t |  ||¡ƒ}|j}ˆ |ks&ˆ|kr*d S |S r+   )r   rG   r   )rQ   ÚvrR   ÚnewÚfree©r-   Úyr   r   Úokä  s    zbivariate_type.<locals>.ok)r	   r   Zas_exprÚbivariate_typerG   rY   r   Z	make_argsr   r   ÚappendZdegreer   Zcoeff_monomialÚrange)rQ   r-   rp   rj   rH   rT   Z_xZ_yÚrvZrepsrK   rm   rA   rn   rq   rF   rB   Zitryr   ro   r   rr   ¡  sR    '&"



rr   )N)*Zsympy.core.addr   Zsympy.core.exprtoolsr   Zsympy.core.functionr   r   Zsympy.core.powerr   Zsympy.core.singletonr   Zsympy.core.sortingr   Zsympy.core.symbolr	   Z&sympy.functions.elementary.exponentialr
   r   r   Z(sympy.functions.elementary.miscellaneousr   Zsympy.polys.polyrootsr   Zsympy.polys.polytoolsr   r   Zsympy.simplify.simplifyr   Zsympy.simplify.radsimpr   r   Zsympy.solvers.solversr   r   Zsympy.utilities.iterablesr   r%   r6   r<   rX   r\   rr   r   r   r   r   Ú<module>   s,   
%%H a