def _invert(eq, *symbols, **kwargs):
 eq = sympify(eq)
 free = eq.free_symbols
 if (not symbols):
  symbols = free
 if (not (free & set(symbols))):
  return (eq, S.Zero)
 dointpow = bool(kwargs.get('integer_power', False))
 lhs = eq
 rhs = S.Zero
 while True:
  was = lhs
  while True:
   (indep, dep) = lhs.as_independent(*symbols)
   if lhs.is_Add:
    if (indep is S.Zero):
     break
    lhs = dep
    rhs -= indep
   else:
    if (indep is S.One):
     break
    lhs = dep
    rhs /= indep
  if lhs.is_Add:
   terms = {}
   for a in lhs.args:
    (i, d) = a.as_independent(*symbols)
    terms.setdefault(d, []).append(i)
   if any(((len(v) > 1) for v in terms.values())):
    args = []
    for (d, i) in terms.items():
     if (len(i) > 1):
      args.append((Add(*i) * d))
     else:
      args.append((i[0] * d))
    lhs = Add(*args)
  if (lhs.is_Add and (not rhs) and (len(lhs.args) == 2) and (not lhs.is_polynomial(*symbols))):
   (a, b) = ordered(lhs.args)
   (ai, ad) = a.as_independent(*symbols)
   (bi, bd) = b.as_independent(*symbols)
   if any((_ispow(i) for i in (ad, bd))):
    (a_base, a_exp) = ad.as_base_exp()
    (b_base, b_exp) = bd.as_base_exp()
    if (a_base == b_base):
     lhs = powsimp(powdenest((ad / bd)))
     rhs = ((- bi) / ai)
    else:
     rat = (ad / bd)
     _lhs = powsimp((ad / bd))
     if (_lhs != rat):
      lhs = _lhs
      rhs = ((- bi) / ai)
   if ((ai * bi) is S.NegativeOne):
    if (all((isinstance(i, Function) for i in (ad, bd))) and (ad.func == bd.func) and (len(ad.args) == len(bd.args))):
     if (len(ad.args) == 1):
      lhs = (ad.args[0] - bd.args[0])
     else:
      raise NotImplementedError('equal function with more than 1 argument')
  elif (lhs.is_Mul and any((_ispow(a) for a in lhs.args))):
   lhs = powsimp(powdenest(lhs))
  if lhs.is_Function:
   if (hasattr(lhs, 'inverse') and (len(lhs.args) == 1)):
    rhs = lhs.inverse()(rhs)
    lhs = lhs.args[0]
   elif (lhs.func is atan2):
    (y, x) = lhs.args
    lhs = (2 * atan((y / (sqrt(((x ** 2) + (y ** 2))) + x))))
  if (rhs and lhs.is_Pow and lhs.exp.is_Integer and (lhs.exp < 0)):
   lhs = (1 / lhs)
   rhs = (1 / rhs)
  if (lhs.is_Pow and ((lhs.exp.is_Integer and dointpow) or ((not lhs.exp.is_Integer) and (len(symbols) > 1) and (len((lhs.base.free_symbols & set(symbols))) > 1)))):
   rhs = (rhs ** (1 / lhs.exp))
   lhs = lhs.base
  if (lhs == was):
   break
 return (rhs, lhs)

def _invert ( eq , * symbols , ** kwargs ) : eq = sympify ( eq ) free = eq . free_symbols if ( not symbols ) : symbols = free if ( not ( free & set ( symbols ) ) ) : return ( eq , S . Zero ) dointpow = bool ( kwargs . get ( 'integer_power' , False ) ) lhs = eq rhs = S . Zero while True : was = lhs while True : ( indep , dep ) = lhs . as_independent ( * symbols ) if lhs . is_Add : if ( indep is S . Zero ) : break lhs = dep rhs -= indep else : if ( indep is S . One ) : break lhs = dep rhs /= indep if lhs . is_Add : terms = { } for a in lhs . args : ( i , d ) = a . as_independent ( * symbols ) terms . setdefault ( d , [ ] ) . append ( i ) if any ( ( ( len ( v ) > 1 ) for v in terms . values ( ) ) ) : args = [ ] for ( d , i ) in terms . items ( ) : if ( len ( i ) > 1 ) : args . append ( ( Add ( * i ) * d ) ) else : args . append ( ( i [ 0 ] * d ) ) lhs = Add ( * args ) if ( lhs . is_Add and ( not rhs ) and ( len ( lhs . args ) == 2 ) and ( not lhs . is_polynomial ( * symbols ) ) ) : ( a , b ) = ordered ( lhs . args ) ( ai , ad ) = a . as_independent ( * symbols ) ( bi , bd ) = b . as_independent ( * symbols ) if any ( ( _ispow ( i ) for i in ( ad , bd ) ) ) : ( a_base , a_exp ) = ad . as_base_exp ( ) ( b_base , b_exp ) = bd . as_base_exp ( ) if ( a_base == b_base ) : lhs = powsimp ( powdenest ( ( ad / bd ) ) ) rhs = ( ( - bi ) / ai ) else : rat = ( ad / bd ) _lhs = powsimp ( ( ad / bd ) ) if ( _lhs != rat ) : lhs = _lhs rhs = ( ( - bi ) / ai ) if ( ( ai * bi ) is S . NegativeOne ) : if ( all ( ( isinstance ( i , Function ) for i in ( ad , bd ) ) ) and ( ad . func == bd . func ) and ( len ( ad . args ) == len ( bd . args ) ) ) : if ( len ( ad . args ) == 1 ) : lhs = ( ad . args [ 0 ] - bd . args [ 0 ] ) else : raise NotImplementedError ( 'equal function with more than 1 argument' ) elif ( lhs . is_Mul and any ( ( _ispow ( a ) for a in lhs . args ) ) ) : lhs = powsimp ( powdenest ( lhs ) ) if lhs . is_Function : if ( hasattr ( lhs , 'inverse' ) and ( len ( lhs . args ) == 1 ) ) : rhs = lhs . inverse ( ) ( rhs ) lhs = lhs . args [ 0 ] elif ( lhs . func is atan2 ) : ( y , x ) = lhs . args lhs = ( 2 * atan ( ( y / ( sqrt ( ( ( x ** 2 ) + ( y ** 2 ) ) ) + x ) ) ) ) if ( rhs and lhs . is_Pow and lhs . exp . is_Integer and ( lhs . exp < 0 ) ) : lhs = ( 1 / lhs ) rhs = ( 1 / rhs ) if ( lhs . is_Pow and ( ( lhs . exp . is_Integer and dointpow ) or ( ( not lhs . exp . is_Integer ) and ( len ( symbols ) > 1 ) and ( len ( ( lhs . base . free_symbols & set ( symbols ) ) ) > 1 ) ) ) ) : rhs = ( rhs ** ( 1 / lhs . exp ) ) lhs = lhs . base if ( lhs == was ) : break return ( rhs , lhs )
reduce the complex valued equation f(x) = y to a set of equations {g(x) = h_1(y) .