#NEWLINE# def bivariate_type( f , x , y , **kwargs ) : #NEWLINE# #INDENT# 'Given an expression, f, 3 tests will be done to see what type\n    of composite bivariate it might be, options for u(x, y) are::\n\n        x*y\n        x+y\n        x*y+x\n        x*y+y\n\n    If it matches one of these types, ``u(x, y)``, ``P(u)`` and dummy\n    variable ``u`` will be returned. Solving ``P(u)`` for ``u`` and\n    equating the solutions to ``u(x, y)`` and then solving for ``x`` or\n    ``y`` is equivalent to solving the original expression for ``x`` or\n    ``y``. If ``x`` and ``y`` represent two functions in the same\n    variable, e.g. ``x = g(t)`` and ``y = h(t)``, then if ``u(x, y) - p``\n    can be solved for ``t`` then these represent the solutions to\n    ``P(u) = 0`` when ``p`` are the solutions of ``P(u) = 0``.\n\n    Only positive values of ``u`` are considered.\n\n    Examples\n    ========\n\n    >>> from sympy.solvers.solvers import solve\n    >>> from sympy.solvers.bivariate import bivariate_type\n    >>> from sympy.abc import x, y\n    >>> eq = (x**2 - 3).subs(x, x + y)\n    >>> bivariate_type(eq, x, y)\n    (x + y, _u**2 - 3, _u)\n    >>> uxy, pu, u = _\n    >>> usol = solve(pu, u); usol\n    [sqrt(3)]\n    >>> [solve(uxy - s) for s in solve(pu, u)]\n    [[{x: -y + sqrt(3)}]]\n    >>> all(eq.subs(s).equals(0) for sol in _ for s in sol)\n    True\n\n    ' #NEWLINE# u = Dummy ( 'u' , positive = True ) #NEWLINE# if kwargs . pop ( 'first' , True ) : #NEWLINE# #INDENT# p = Poly ( f , x , y ) #NEWLINE# f = p . as_expr ( ) #NEWLINE# _x = Dummy ( ) #NEWLINE# _y = Dummy ( ) #NEWLINE# rv = bivariate_type ( Poly ( f . subs ( { #NEWLINE# #INDENT# x : _x , #NEWLINE# y : _y , #NEWLINE# #UNINDENT# } ) , _x , _y ) , _x , _y , first = False ) #NEWLINE# if rv : #NEWLINE# #INDENT# reps = { #NEWLINE# #INDENT# _x : x , #NEWLINE# _y : y , #NEWLINE# #UNINDENT# } #NEWLINE# return ( rv [ 0 ] . xreplace ( reps ) , rv [ 1 ] . xreplace ( reps ) , rv [ 2 ] ) #NEWLINE# #UNINDENT# return #NEWLINE# #UNINDENT# p = f #NEWLINE# f = p . as_expr ( ) #NEWLINE# args = Add . make_args ( p . as_expr ( ) ) #NEWLINE# new = [ ] #NEWLINE# for a in args : #NEWLINE# #INDENT# a = _mexpand ( a . subs ( x , ( u / y ) ) ) #NEWLINE# free = a . free_symbols #NEWLINE# if ( ( x in free ) or ( y in free ) ) : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# new . append ( a ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# return ( ( x * y ) , Add ( * new ) , u ) #NEWLINE# #UNINDENT# def ok( f , v , c ) : #NEWLINE# #INDENT# new = _mexpand ( f . subs ( v , c ) ) #NEWLINE# free = new . free_symbols #NEWLINE# return ( None if ( ( x in free ) or ( y in free ) ) else new ) #NEWLINE# #UNINDENT# new = [ ] #NEWLINE# d = p . degree ( x ) #NEWLINE# if ( p . degree ( y ) == d ) : #NEWLINE# #INDENT# a = root ( p . coeff_monomial ( ( x ** d ) ) , d ) #NEWLINE# b = root ( p . coeff_monomial ( ( y ** d ) ) , d ) #NEWLINE# new = ok ( f , x , ( ( u - ( b * y ) ) / a ) ) #NEWLINE# if ( new is not None ) : #NEWLINE# #INDENT# return ( ( ( a * x ) + ( b * y ) ) , new , u ) #NEWLINE# #UNINDENT# #UNINDENT# new = [ ] #NEWLINE# d = p . degree ( x ) #NEWLINE# if ( p . degree ( y ) == d ) : #NEWLINE# #INDENT# for itry in range ( 2 ) : #NEWLINE# #INDENT# a = root ( p . coeff_monomial ( ( ( x ** d ) * ( y ** d ) ) ) , d ) #NEWLINE# b = root ( p . coeff_monomial ( ( y ** d ) ) , d ) #NEWLINE# new = ok ( f , x , ( ( ( u - ( b * y ) ) / a ) / y ) ) #NEWLINE# if ( new is not None ) : #NEWLINE# #INDENT# return ( ( ( ( a * x ) * y ) + ( b * y ) ) , new , u ) #NEWLINE# #UNINDENT# ( x , y ) = ( y , x )