def simplify(expr, ratio=1.7, measure=count_ops, fu=False):
 expr = sympify(expr)
 try:
  return expr._eval_simplify(ratio=ratio, measure=measure)
 except AttributeError:
  pass
 original_expr = expr = signsimp(expr)
 from sympy.simplify.hyperexpand import hyperexpand
 from sympy.functions.special.bessel import BesselBase
 from sympy import Sum, Product
 if ((not isinstance(expr, Basic)) or (not expr.args)):
  return expr
 if (not isinstance(expr, (Add, Mul, Pow, ExpBase))):
  if (isinstance(expr, Function) and hasattr(expr, 'inverse')):
   if ((len(expr.args) == 1) and (len(expr.args[0].args) == 1) and isinstance(expr.args[0], expr.inverse(argindex=1))):
    return simplify(expr.args[0].args[0], ratio=ratio, measure=measure, fu=fu)
  return expr.func(*[simplify(x, ratio=ratio, measure=measure, fu=fu) for x in expr.args])
 def shorter(*choices):
  'Return the choice that has the fewest ops. In case of a tie,\n        the expression listed first is selected.'
  if (not has_variety(choices)):
   return choices[0]
  return min(choices, key=measure)
 expr = bottom_up(expr, (lambda w: w.normal()))
 expr = Mul(*powsimp(expr).as_content_primitive())
 _e = cancel(expr)
 expr1 = shorter(_e, _mexpand(_e).cancel())
 expr2 = shorter(together(expr, deep=True), together(expr1, deep=True))
 if (ratio is S.Infinity):
  expr = expr2
 else:
  expr = shorter(expr2, expr1, expr)
 if (not isinstance(expr, Basic)):
  return expr
 expr = factor_terms(expr, sign=False)
 expr = hyperexpand(expr)
 expr = piecewise_fold(expr)
 if expr.has(BesselBase):
  expr = besselsimp(expr)
 if ((expr.has(TrigonometricFunction) and (not fu)) or expr.has(HyperbolicFunction)):
  expr = trigsimp(expr, deep=True)
 if expr.has(log):
  expr = shorter(expand_log(expr, deep=True), logcombine(expr))
 if expr.has(CombinatorialFunction, gamma):
  expr = combsimp(expr)
 if expr.has(Sum):
  expr = sum_simplify(expr)
 if expr.has(Product):
  expr = product_simplify(expr)
 short = shorter(powsimp(expr, combine='exp', deep=True), powsimp(expr), expr)
 short = shorter(short, factor_terms(short), expand_power_exp(expand_mul(short)))
 if short.has(TrigonometricFunction, HyperbolicFunction, ExpBase):
  short = exptrigsimp(short, simplify=False)
 hollow_mul = Transform((lambda x: Mul(*x.args)), (lambda x: (x.is_Mul and (len(x.args) == 2) and x.args[0].is_Number and x.args[1].is_Add and x.is_commutative)))
 expr = short.xreplace(hollow_mul)
 (numer, denom) = expr.as_numer_denom()
 if denom.is_Add:
  (n, d) = fraction(radsimp((1 / denom), symbolic=False, max_terms=1))
  if (n is not S.One):
   expr = ((numer * n).expand() / d)
 if expr.could_extract_minus_sign():
  (n, d) = fraction(expr)
  if (d != 0):
   expr = signsimp(((- n) / (- d)))
 if (measure(expr) > (ratio * measure(original_expr))):
  expr = original_expr
 return expr

def simplify ( expr , ratio = 1.7 , measure = count_ops , fu = False ) : expr = sympify ( expr ) try : return expr . _eval_simplify ( ratio = ratio , measure = measure ) except AttributeError : pass original_expr = expr = signsimp ( expr ) from sympy . simplify . hyperexpand import hyperexpand from sympy . functions . special . bessel import BesselBase from sympy import Sum , Product if ( ( not isinstance ( expr , Basic ) ) or ( not expr . args ) ) : return expr if ( not isinstance ( expr , ( Add , Mul , Pow , ExpBase ) ) ) : if ( isinstance ( expr , Function ) and hasattr ( expr , 'inverse' ) ) : if ( ( len ( expr . args ) == 1 ) and ( len ( expr . args [ 0 ] . args ) == 1 ) and isinstance ( expr . args [ 0 ] , expr . inverse ( argindex = 1 ) ) ) : return simplify ( expr . args [ 0 ] . args [ 0 ] , ratio = ratio , measure = measure , fu = fu ) return expr . func ( * [ simplify ( x , ratio = ratio , measure = measure , fu = fu ) for x in expr . args ] ) def shorter ( * choices ) : if ( not has_variety ( choices ) ) : return choices [ 0 ] return min ( choices , key = measure ) expr = bottom_up ( expr , ( lambda w : w . normal ( ) ) ) expr = Mul ( * powsimp ( expr ) . as_content_primitive ( ) ) _e = cancel ( expr ) expr1 = shorter ( _e , _mexpand ( _e ) . cancel ( ) ) expr2 = shorter ( together ( expr , deep = True ) , together ( expr1 , deep = True ) ) if ( ratio is S . Infinity ) : expr = expr2 else : expr = shorter ( expr2 , expr1 , expr ) if ( not isinstance ( expr , Basic ) ) : return expr expr = factor_terms ( expr , sign = False ) expr = hyperexpand ( expr ) expr = piecewise_fold ( expr ) if expr . has ( BesselBase ) : expr = besselsimp ( expr ) if ( ( expr . has ( TrigonometricFunction ) and ( not fu ) ) or expr . has ( HyperbolicFunction ) ) : expr = trigsimp ( expr , deep = True ) if expr . has ( log ) : expr = shorter ( expand_log ( expr , deep = True ) , logcombine ( expr ) ) if expr . has ( CombinatorialFunction , gamma ) : expr = combsimp ( expr ) if expr . has ( Sum ) : expr = sum_simplify ( expr ) if expr . has ( Product ) : expr = product_simplify ( expr ) short = shorter ( powsimp ( expr , combine = 'exp' , deep = True ) , powsimp ( expr ) , expr ) short = shorter ( short , factor_terms ( short ) , expand_power_exp ( expand_mul ( short ) ) ) if short . has ( TrigonometricFunction , HyperbolicFunction , ExpBase ) : short = exptrigsimp ( short , simplify = False ) hollow_mul = Transform ( ( lambda x : Mul ( * x . args ) ) , ( lambda x : ( x . is_Mul and ( len ( x . args ) == 2 ) and x . args [ 0 ] . is_Number and x . args [ 1 ] . is_Add and x . is_commutative ) ) ) expr = short . xreplace ( hollow_mul ) ( numer , denom ) = expr . as_numer_denom ( ) if denom . is_Add : ( n , d ) = fraction ( radsimp ( ( 1 / denom ) , symbolic = False , max_terms = 1 ) ) if ( n is not S . One ) : expr = ( ( numer * n ) . expand ( ) / d ) if expr . could_extract_minus_sign ( ) : ( n , d ) = fraction ( expr ) if ( d != 0 ) : expr = signsimp ( ( ( - n ) / ( - d ) ) ) if ( measure ( expr ) > ( ratio * measure ( original_expr ) ) ) : expr = original_expr return expr
cancel units that appear in both numerator and denominator .